aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-09-18 10:32:40 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-09-18 10:32:40 +0100
commit19dc3860dcfde9bc4ec4ef35bb1337e13276f630 (patch)
treee60e9c438f0031a7c4f70196837b74b9fd677d2d /tools
parentf2878b5bb1a0b9c25efca3c594d764c9e13b50c0 (diff)
downloadxen-19dc3860dcfde9bc4ec4ef35bb1337e13276f630.tar.gz
xen-19dc3860dcfde9bc4ec4ef35bb1337e13276f630.tar.bz2
xen-19dc3860dcfde9bc4ec4ef35bb1337e13276f630.zip
Remove internal tools/ioemu tree.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile5
-rw-r--r--tools/ioemu/.CVS/Entries117
-rw-r--r--tools/ioemu/.CVS/Repository1
-rw-r--r--tools/ioemu/.CVS/Root1
-rw-r--r--tools/ioemu/.CVS/Tag1
-rw-r--r--tools/ioemu/.cvsignore45
-rw-r--r--tools/ioemu/COPYING339
-rw-r--r--tools/ioemu/COPYING.LIB504
-rw-r--r--tools/ioemu/Changelog413
-rw-r--r--tools/ioemu/LICENSE15
-rw-r--r--tools/ioemu/Makefile187
-rw-r--r--tools/ioemu/Makefile.target678
-rw-r--r--tools/ioemu/README3
-rw-r--r--tools/ioemu/TODO55
-rw-r--r--tools/ioemu/VERSION1
-rw-r--r--tools/ioemu/a.out.h431
-rw-r--r--tools/ioemu/aes.c1319
-rw-r--r--tools/ioemu/aes.h26
-rw-r--r--tools/ioemu/audio/.CVS/Entries20
-rw-r--r--tools/ioemu/audio/.CVS/Repository1
-rw-r--r--tools/ioemu/audio/.CVS/Root1
-rw-r--r--tools/ioemu/audio/.CVS/Tag1
-rw-r--r--tools/ioemu/audio/alsaaudio.c974
-rw-r--r--tools/ioemu/audio/audio.c1871
-rw-r--r--tools/ioemu/audio/audio.h169
-rw-r--r--tools/ioemu/audio/audio_int.h280
-rw-r--r--tools/ioemu/audio/audio_template.h570
-rw-r--r--tools/ioemu/audio/coreaudio.c554
-rw-r--r--tools/ioemu/audio/dsound_template.h282
-rw-r--r--tools/ioemu/audio/dsoundaudio.c1080
-rw-r--r--tools/ioemu/audio/fmodaudio.c685
-rw-r--r--tools/ioemu/audio/mixeng.c281
-rw-r--r--tools/ioemu/audio/mixeng.h51
-rw-r--r--tools/ioemu/audio/mixeng_template.h177
-rw-r--r--tools/ioemu/audio/noaudio.c172
-rw-r--r--tools/ioemu/audio/ossaudio.c773
-rw-r--r--tools/ioemu/audio/rate_template.h111
-rw-r--r--tools/ioemu/audio/sdlaudio.c433
-rw-r--r--tools/ioemu/audio/sys-queue.h241
-rw-r--r--tools/ioemu/audio/wavaudio.c255
-rw-r--r--tools/ioemu/audio/wavcapture.c163
-rw-r--r--tools/ioemu/block-bochs.c254
-rw-r--r--tools/ioemu/block-cloop.c169
-rw-r--r--tools/ioemu/block-cow.c268
-rw-r--r--tools/ioemu/block-dmg.c297
-rw-r--r--tools/ioemu/block-qcow.c971
-rw-r--r--tools/ioemu/block-qcow2.c2260
-rw-r--r--tools/ioemu/block-raw.c1512
-rw-r--r--tools/ioemu/block-vbd.c375
-rw-r--r--tools/ioemu/block-vmdk.c754
-rw-r--r--tools/ioemu/block-vpc.c239
-rw-r--r--tools/ioemu/block-vvfat.c2804
-rw-r--r--tools/ioemu/block.c1437
-rw-r--r--tools/ioemu/block_int.h135
-rw-r--r--tools/ioemu/bswap.h209
-rwxr-xr-xtools/ioemu/check_ops.sh47
-rw-r--r--tools/ioemu/cocoa.m927
-rwxr-xr-xtools/ioemu/configure1057
-rw-r--r--tools/ioemu/console.c1217
-rw-r--r--tools/ioemu/cpu-all.h1051
-rw-r--r--tools/ioemu/cpu-defs.h133
-rw-r--r--tools/ioemu/cpu-exec.c1487
-rw-r--r--tools/ioemu/cutils.c83
-rw-r--r--tools/ioemu/d3des.c434
-rw-r--r--tools/ioemu/d3des.h51
-rw-r--r--tools/ioemu/dis-asm.h455
-rw-r--r--tools/ioemu/disas.c411
-rw-r--r--tools/ioemu/disas.h23
-rw-r--r--tools/ioemu/dyngen-exec.h279
-rw-r--r--tools/ioemu/dyngen-op.h9
-rw-r--r--tools/ioemu/dyngen.c2783
-rw-r--r--tools/ioemu/dyngen.h465
-rw-r--r--tools/ioemu/elf.h1164
-rw-r--r--tools/ioemu/elf_ops.h207
-rw-r--r--tools/ioemu/exec-all.h619
-rw-r--r--tools/ioemu/exec.c2411
-rw-r--r--tools/ioemu/fpu/.CVS/Entries7
-rw-r--r--tools/ioemu/fpu/.CVS/Repository1
-rw-r--r--tools/ioemu/fpu/.CVS/Root1
-rw-r--r--tools/ioemu/fpu/.CVS/Tag1
-rw-r--r--tools/ioemu/fpu/softfloat-macros.h720
-rw-r--r--tools/ioemu/fpu/softfloat-native.c384
-rw-r--r--tools/ioemu/fpu/softfloat-native.h361
-rw-r--r--tools/ioemu/fpu/softfloat-specialize.h464
-rw-r--r--tools/ioemu/fpu/softfloat.c5331
-rw-r--r--tools/ioemu/fpu/softfloat.h400
-rw-r--r--tools/ioemu/gdbstub.c1251
-rw-r--r--tools/ioemu/gdbstub.h20
-rw-r--r--tools/ioemu/hostregs_helper.h98
-rw-r--r--tools/ioemu/hw/.CVS/Entries98
-rw-r--r--tools/ioemu/hw/.CVS/Repository1
-rw-r--r--tools/ioemu/hw/.CVS/Root1
-rw-r--r--tools/ioemu/hw/.CVS/Tag1
-rw-r--r--tools/ioemu/hw/acpi.c523
-rw-r--r--tools/ioemu/hw/adb.c410
-rw-r--r--tools/ioemu/hw/adlib.c341
-rw-r--r--tools/ioemu/hw/apb_pci.c259
-rw-r--r--tools/ioemu/hw/apic.c1046
-rw-r--r--tools/ioemu/hw/arm_boot.c115
-rw-r--r--tools/ioemu/hw/arm_gic.c547
-rw-r--r--tools/ioemu/hw/arm_pic.c73
-rw-r--r--tools/ioemu/hw/arm_pic.h27
-rw-r--r--tools/ioemu/hw/arm_sysctl.c208
-rw-r--r--tools/ioemu/hw/arm_timer.c383
-rw-r--r--tools/ioemu/hw/cdrom.c156
-rw-r--r--tools/ioemu/hw/cirrus_vga.c3347
-rw-r--r--tools/ioemu/hw/cirrus_vga_rop.h105
-rw-r--r--tools/ioemu/hw/cirrus_vga_rop2.h315
-rw-r--r--tools/ioemu/hw/cs4231.c183
-rw-r--r--tools/ioemu/hw/cuda.c656
-rw-r--r--tools/ioemu/hw/dma.c549
-rw-r--r--tools/ioemu/hw/e100.c2605
-rw-r--r--tools/ioemu/hw/e1000.c1008
-rw-r--r--tools/ioemu/hw/e1000_hw.h865
-rw-r--r--tools/ioemu/hw/es1370.c1062
-rw-r--r--tools/ioemu/hw/esp.c575
-rw-r--r--tools/ioemu/hw/extboot.c125
-rw-r--r--tools/ioemu/hw/fdc.c1758
-rw-r--r--tools/ioemu/hw/fmopl.c1390
-rw-r--r--tools/ioemu/hw/fmopl.h174
-rw-r--r--tools/ioemu/hw/grackle_pci.c161
-rw-r--r--tools/ioemu/hw/gt64xxx.c648
-rw-r--r--tools/ioemu/hw/heathrow_pic.c168
-rw-r--r--tools/ioemu/hw/i8254.c482
-rw-r--r--tools/ioemu/hw/i8259.c568
-rw-r--r--tools/ioemu/hw/ide.c3077
-rw-r--r--tools/ioemu/hw/integratorcp.c546
-rw-r--r--tools/ioemu/hw/iommu.c295
-rw-r--r--tools/ioemu/hw/isa_mmio.c102
-rw-r--r--tools/ioemu/hw/lsi53c895a.c1869
-rw-r--r--tools/ioemu/hw/m48t59.c614
-rw-r--r--tools/ioemu/hw/m48t59.h13
-rw-r--r--tools/ioemu/hw/mc146818rtc.c488
-rw-r--r--tools/ioemu/hw/mips_int.c39
-rw-r--r--tools/ioemu/hw/mips_malta.c590
-rw-r--r--tools/ioemu/hw/mips_r4k.c221
-rw-r--r--tools/ioemu/hw/mips_timer.c83
-rw-r--r--tools/ioemu/hw/ne2000.c864
-rw-r--r--tools/ioemu/hw/openpic.c1027
-rw-r--r--tools/ioemu/hw/parallel.c183
-rw-r--r--tools/ioemu/hw/pass-through.c3146
-rw-r--r--tools/ioemu/hw/pass-through.h296
-rw-r--r--tools/ioemu/hw/pc.c1146
-rw-r--r--tools/ioemu/hw/pci.c674
-rw-r--r--tools/ioemu/hw/pci_emulation.c118
-rw-r--r--tools/ioemu/hw/pci_emulation.h24
-rw-r--r--tools/ioemu/hw/pci_host.h93
-rw-r--r--tools/ioemu/hw/pckbd.c370
-rw-r--r--tools/ioemu/hw/pcnet.c1992
-rw-r--r--tools/ioemu/hw/pcspk.c147
-rw-r--r--tools/ioemu/hw/pflash_cfi02.c623
-rw-r--r--tools/ioemu/hw/piix4acpi.c556
-rw-r--r--tools/ioemu/hw/piix_pci.c384
-rw-r--r--tools/ioemu/hw/pl011.c251
-rw-r--r--tools/ioemu/hw/pl050.c127
-rw-r--r--tools/ioemu/hw/pl080.c344
-rw-r--r--tools/ioemu/hw/pl110.c421
-rw-r--r--tools/ioemu/hw/pl110_template.h252
-rw-r--r--tools/ioemu/hw/pl190.c252
-rw-r--r--tools/ioemu/hw/ppc.c370
-rw-r--r--tools/ioemu/hw/ppc_chrp.c564
-rw-r--r--tools/ioemu/hw/ppc_prep.c693
-rw-r--r--tools/ioemu/hw/prep_pci.c171
-rw-r--r--tools/ioemu/hw/ps2.c566
-rw-r--r--tools/ioemu/hw/pt-msi.c341
-rw-r--r--tools/ioemu/hw/pt-msi.h100
-rw-r--r--tools/ioemu/hw/realview.c138
-rw-r--r--tools/ioemu/hw/rtl8139.c3499
-rw-r--r--tools/ioemu/hw/sb16.c1457
-rw-r--r--tools/ioemu/hw/scsi-disk.c614
-rw-r--r--tools/ioemu/hw/serial.c781
-rw-r--r--tools/ioemu/hw/sh7750.c834
-rw-r--r--tools/ioemu/hw/sh7750_regnames.c128
-rw-r--r--tools/ioemu/hw/sh7750_regnames.h6
-rw-r--r--tools/ioemu/hw/sh7750_regs.h1623
-rw-r--r--tools/ioemu/hw/shix.c111
-rw-r--r--tools/ioemu/hw/slavio_intctl.c400
-rw-r--r--tools/ioemu/hw/slavio_misc.c241
-rw-r--r--tools/ioemu/hw/slavio_serial.c689
-rw-r--r--tools/ioemu/hw/slavio_timer.c288
-rw-r--r--tools/ioemu/hw/smbus.h38
-rw-r--r--tools/ioemu/hw/smbus_eeprom.c94
-rw-r--r--tools/ioemu/hw/smc91c111.c715
-rw-r--r--tools/ioemu/hw/sparc32_dma.c283
-rw-r--r--tools/ioemu/hw/sun4m.c330
-rw-r--r--tools/ioemu/hw/sun4u.c368
-rw-r--r--tools/ioemu/hw/tc58128.c181
-rw-r--r--tools/ioemu/hw/tcx.c376
-rw-r--r--tools/ioemu/hw/tpm_tis.c1149
-rw-r--r--tools/ioemu/hw/unin_pci.c268
-rw-r--r--tools/ioemu/hw/usb-hid.c671
-rw-r--r--tools/ioemu/hw/usb-hub.c553
-rw-r--r--tools/ioemu/hw/usb-msd.c544
-rw-r--r--tools/ioemu/hw/usb-ohci.c1286
-rw-r--r--tools/ioemu/hw/usb-uhci.c872
-rw-r--r--tools/ioemu/hw/usb.c242
-rw-r--r--tools/ioemu/hw/usb.h226
-rw-r--r--tools/ioemu/hw/versatile_pci.c142
-rw-r--r--tools/ioemu/hw/versatilepb.c289
-rw-r--r--tools/ioemu/hw/vga.c2351
-rw-r--r--tools/ioemu/hw/vga_int.h185
-rw-r--r--tools/ioemu/hw/vga_template.h525
-rw-r--r--tools/ioemu/hw/xen_blktap.c643
-rw-r--r--tools/ioemu/hw/xen_blktap.h57
-rw-r--r--tools/ioemu/hw/xen_console.c436
-rw-r--r--tools/ioemu/hw/xen_console.h25
-rw-r--r--tools/ioemu/hw/xen_machine_fv.c295
-rw-r--r--tools/ioemu/hw/xen_machine_pv.c83
-rw-r--r--tools/ioemu/hw/xen_platform.c254
-rw-r--r--tools/ioemu/hw/xenfb.c1341
-rw-r--r--tools/ioemu/hw/xenfb.h15
-rw-r--r--tools/ioemu/i386-dis.c4143
-rw-r--r--tools/ioemu/i386-vl.ld140
-rw-r--r--tools/ioemu/i386.ld140
-rw-r--r--tools/ioemu/ia64.ld211
-rw-r--r--tools/ioemu/keymaps.c239
-rw-r--r--tools/ioemu/keymaps/.CVS/Entries36
-rw-r--r--tools/ioemu/keymaps/.CVS/Repository1
-rw-r--r--tools/ioemu/keymaps/.CVS/Root1
-rw-r--r--tools/ioemu/keymaps/.CVS/Tag1
-rw-r--r--tools/ioemu/keymaps/ar98
-rw-r--r--tools/ioemu/keymaps/common157
-rw-r--r--tools/ioemu/keymaps/da120
-rw-r--r--tools/ioemu/keymaps/de114
-rw-r--r--tools/ioemu/keymaps/de-ch169
-rw-r--r--tools/ioemu/keymaps/en-gb119
-rw-r--r--tools/ioemu/keymaps/en-us35
-rw-r--r--tools/ioemu/keymaps/es105
-rw-r--r--tools/ioemu/keymaps/et86
-rw-r--r--tools/ioemu/keymaps/fi124
-rw-r--r--tools/ioemu/keymaps/fo77
-rw-r--r--tools/ioemu/keymaps/fr181
-rw-r--r--tools/ioemu/keymaps/fr-be140
-rw-r--r--tools/ioemu/keymaps/fr-ca50
-rw-r--r--tools/ioemu/keymaps/fr-ch114
-rw-r--r--tools/ioemu/keymaps/hr125
-rw-r--r--tools/ioemu/keymaps/hu114
-rw-r--r--tools/ioemu/keymaps/is140
-rw-r--r--tools/ioemu/keymaps/it115
-rw-r--r--tools/ioemu/keymaps/ja109
-rw-r--r--tools/ioemu/keymaps/lt57
-rw-r--r--tools/ioemu/keymaps/lv128
-rw-r--r--tools/ioemu/keymaps/mk101
-rw-r--r--tools/ioemu/keymaps/modifiers18
-rw-r--r--tools/ioemu/keymaps/nl60
-rw-r--r--tools/ioemu/keymaps/nl-be69
-rw-r--r--tools/ioemu/keymaps/no119
-rw-r--r--tools/ioemu/keymaps/pl122
-rw-r--r--tools/ioemu/keymaps/pt113
-rw-r--r--tools/ioemu/keymaps/pt-br69
-rw-r--r--tools/ioemu/keymaps/ru109
-rw-r--r--tools/ioemu/keymaps/sl110
-rw-r--r--tools/ioemu/keymaps/sv82
-rw-r--r--tools/ioemu/keymaps/th131
-rw-r--r--tools/ioemu/keymaps/tr123
-rw-r--r--tools/ioemu/kqemu.c912
-rw-r--r--tools/ioemu/kqemu.h132
-rw-r--r--tools/ioemu/loader.c243
-rw-r--r--tools/ioemu/monitor.c2569
-rw-r--r--tools/ioemu/osdep.c239
-rw-r--r--tools/ioemu/osdep.h23
-rw-r--r--tools/ioemu/patches/acpi-poweroff-support46
-rw-r--r--tools/ioemu/patches/acpi-support301
-rw-r--r--tools/ioemu/patches/acpi-timer-support66
-rw-r--r--tools/ioemu/patches/domain-destroy55
-rw-r--r--tools/ioemu/patches/domain-reset87
-rw-r--r--tools/ioemu/patches/domain-timeoffset87
-rw-r--r--tools/ioemu/patches/fix-interrupt-routing507
-rw-r--r--tools/ioemu/patches/fix-vga-scanning-code-overflow45
-rw-r--r--tools/ioemu/patches/hypervisor-pit58
-rw-r--r--tools/ioemu/patches/hypervisor-rtc164
-rw-r--r--tools/ioemu/patches/ide-cd-dma23
-rw-r--r--tools/ioemu/patches/ide-error-reporting81
-rw-r--r--tools/ioemu/patches/ide-hd-multithread224
-rw-r--r--tools/ioemu/patches/ioemu-buffer-pio-ia64224
-rw-r--r--tools/ioemu/patches/ioemu-ia6493
-rw-r--r--tools/ioemu/patches/ioemu-save-restore180
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-acpi38
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-ide137
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-logdirty190
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-ne200013
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-pcnet32
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-rtl813923
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-timer27
-rw-r--r--tools/ioemu/patches/ioemu-save-restore-usb262
-rw-r--r--tools/ioemu/patches/limit-fdc-sector-size-to-16K32
-rw-r--r--tools/ioemu/patches/ne2000-bounds-checks113
-rw-r--r--tools/ioemu/patches/nodelay-serial-over-tcp29
-rw-r--r--tools/ioemu/patches/qemu-64bit111
-rw-r--r--tools/ioemu/patches/qemu-allow-disable-sdl28
-rw-r--r--tools/ioemu/patches/qemu-block-device-bounds-checks23
-rw-r--r--tools/ioemu/patches/qemu-bootorder183
-rw-r--r--tools/ioemu/patches/qemu-bugfixes50
-rw-r--r--tools/ioemu/patches/qemu-cirrus-bounds-checks350
-rw-r--r--tools/ioemu/patches/qemu-cleanup115
-rw-r--r--tools/ioemu/patches/qemu-daemonize20
-rw-r--r--tools/ioemu/patches/qemu-dm526
-rw-r--r--tools/ioemu/patches/qemu-dma-null-pointer-check13
-rw-r--r--tools/ioemu/patches/qemu-fix-memset-args18
-rw-r--r--tools/ioemu/patches/qemu-hvm-banner23
-rw-r--r--tools/ioemu/patches/qemu-init-vgabios150
-rw-r--r--tools/ioemu/patches/qemu-logging61
-rw-r--r--tools/ioemu/patches/qemu-no-apic51
-rw-r--r--tools/ioemu/patches/qemu-nobios62
-rwxr-xr-xtools/ioemu/patches/qemu-pci75
-rw-r--r--tools/ioemu/patches/qemu-pci-vendor-ids47
-rw-r--r--tools/ioemu/patches/qemu-serial-fixes133
-rw-r--r--tools/ioemu/patches/qemu-smp48
-rw-r--r--tools/ioemu/patches/qemu-target-i386-dm1446
-rw-r--r--tools/ioemu/patches/qemu-timer54
-rw-r--r--tools/ioemu/patches/qemu-tunable-ide-write-cache56
-rw-r--r--tools/ioemu/patches/remove-pci-bridge-setup240
-rw-r--r--tools/ioemu/patches/rtl8139-bound-chaining36
-rw-r--r--tools/ioemu/patches/scsi194
-rw-r--r--tools/ioemu/patches/sdl-mouse-invisible-wall25
-rw-r--r--tools/ioemu/patches/serial-non-block48
-rw-r--r--tools/ioemu/patches/serial-port-rate-limit118
-rw-r--r--tools/ioemu/patches/series80
-rw-r--r--tools/ioemu/patches/shadow-vram177
-rw-r--r--tools/ioemu/patches/shared-vram353
-rw-r--r--tools/ioemu/patches/support-xm-console174
-rw-r--r--tools/ioemu/patches/tpm-tis-device1196
-rw-r--r--tools/ioemu/patches/usb-mouse-tablet-status-check193
-rw-r--r--tools/ioemu/patches/usb-uhci-buffer-size25
-rw-r--r--tools/ioemu/patches/vnc-altgr-keysym24
-rw-r--r--tools/ioemu/patches/vnc-backoff-screen-scan385
-rw-r--r--tools/ioemu/patches/vnc-cleanup107
-rw-r--r--tools/ioemu/patches/vnc-display-find-unused143
-rw-r--r--tools/ioemu/patches/vnc-fix-signedness176
-rw-r--r--tools/ioemu/patches/vnc-fix-text-display-shift-key13
-rw-r--r--tools/ioemu/patches/vnc-fix-version-check13
-rw-r--r--tools/ioemu/patches/vnc-fixes531
-rw-r--r--tools/ioemu/patches/vnc-japan-keymap39
-rw-r--r--tools/ioemu/patches/vnc-keypad-handling190
-rw-r--r--tools/ioemu/patches/vnc-monitor-shift-key-processing60
-rw-r--r--tools/ioemu/patches/vnc-password801
-rw-r--r--tools/ioemu/patches/vnc-protocol-fixes63
-rw-r--r--tools/ioemu/patches/vnc-start-vncviewer111
-rw-r--r--tools/ioemu/patches/vnc-title-domain-name25
-rw-r--r--tools/ioemu/patches/xen-build274
-rw-r--r--tools/ioemu/patches/xen-domain-name78
-rw-r--r--tools/ioemu/patches/xen-domid49
-rw-r--r--tools/ioemu/patches/xen-mapcache441
-rw-r--r--tools/ioemu/patches/xen-mm136
-rw-r--r--tools/ioemu/patches/xen-network74
-rw-r--r--tools/ioemu/patches/xen-platform-device199
-rw-r--r--tools/ioemu/patches/xen-support-buffered-ioreqs182
-rw-r--r--tools/ioemu/patches/xenstore197
-rw-r--r--tools/ioemu/patches/xenstore-block-device-config453
-rw-r--r--tools/ioemu/patches/xenstore-device-info-functions192
-rw-r--r--tools/ioemu/patches/xenstore-write-vnc-port63
-rw-r--r--tools/ioemu/pc-bios/.CVS/Entries17
-rw-r--r--tools/ioemu/pc-bios/.CVS/Repository1
-rw-r--r--tools/ioemu/pc-bios/.CVS/Root1
-rw-r--r--tools/ioemu/pc-bios/.CVS/Tag1
-rw-r--r--tools/ioemu/pc-bios/Makefile24
-rw-r--r--tools/ioemu/pc-bios/README22
-rw-r--r--tools/ioemu/pc-bios/bios.diff35
-rw-r--r--tools/ioemu/pc-bios/linux_boot.S29
-rw-r--r--tools/ioemu/pc-bios/ohw.diff1843
-rw-r--r--tools/ioemu/pc-bios/pxe-ne2k_pci.binbin32768 -> 0 bytes
-rw-r--r--tools/ioemu/pc-bios/pxe-pcnet.binbin32768 -> 0 bytes
-rw-r--r--tools/ioemu/pc-bios/pxe-rtl8139.binbin32768 -> 0 bytes
-rw-r--r--tools/ioemu/pc-bios/vgabios.diff896
-rw-r--r--tools/ioemu/pc-bios/video.xbin12192 -> 0 bytes
-rw-r--r--tools/ioemu/qemu-binfmt-conf.sh39
-rw-r--r--tools/ioemu/qemu-doc.texi2057
-rw-r--r--tools/ioemu/qemu-img.c688
-rw-r--r--tools/ioemu/qemu-img.texi130
-rw-r--r--tools/ioemu/qemu-tech.texi595
-rw-r--r--tools/ioemu/qemu_socket.h38
-rw-r--r--tools/ioemu/readline.c425
-rw-r--r--tools/ioemu/sdl.c796
-rw-r--r--tools/ioemu/sdl_keysym.h278
-rw-r--r--tools/ioemu/softmmu_exec.h65
-rw-r--r--tools/ioemu/softmmu_header.h385
-rw-r--r--tools/ioemu/softmmu_template.h313
-rw-r--r--tools/ioemu/tap-win32.c679
-rw-r--r--tools/ioemu/tapdisk-ioemu.c156
-rw-r--r--tools/ioemu/target-i386-dm/cpu.h93
-rw-r--r--tools/ioemu/target-i386-dm/exec-dm.c629
-rw-r--r--tools/ioemu/target-i386-dm/helper2.c596
-rw-r--r--tools/ioemu/target-i386-dm/i8259-dm.c67
-rw-r--r--tools/ioemu/target-i386-dm/piix_pci-dm.c222
-rw-r--r--tools/ioemu/target-i386-dm/qemu-dm.debug10
-rw-r--r--tools/ioemu/target-i386-dm/qemu-ifup37
-rw-r--r--tools/ioemu/target-i386-dm/rtc-dm.c124
-rw-r--r--tools/ioemu/target-i386/.CVS/Entries13
-rw-r--r--tools/ioemu/target-i386/.CVS/Repository1
-rw-r--r--tools/ioemu/target-i386/.CVS/Root1
-rw-r--r--tools/ioemu/target-i386/.CVS/Tag1
-rw-r--r--tools/ioemu/target-i386/cpu.h664
-rw-r--r--tools/ioemu/target-i386/exec.h577
-rw-r--r--tools/ioemu/target-i386/helper.c3840
-rw-r--r--tools/ioemu/target-i386/helper2.c1036
-rw-r--r--tools/ioemu/target-i386/op.c2449
-rw-r--r--tools/ioemu/target-i386/opreg_template.h190
-rw-r--r--tools/ioemu/target-i386/ops_mem.h156
-rw-r--r--tools/ioemu/target-i386/ops_sse.h1393
-rw-r--r--tools/ioemu/target-i386/ops_template.h597
-rw-r--r--tools/ioemu/target-i386/ops_template_mem.h483
-rw-r--r--tools/ioemu/target-i386/translate-copy.c1323
-rw-r--r--tools/ioemu/target-i386/translate.c6621
-rw-r--r--tools/ioemu/tests/.CVS/Entries19
-rw-r--r--tools/ioemu/tests/.CVS/Repository1
-rw-r--r--tools/ioemu/tests/.CVS/Root1
-rw-r--r--tools/ioemu/tests/.CVS/Tag1
-rw-r--r--tools/ioemu/tests/.cvsignore23
-rw-r--r--tools/ioemu/tests/Makefile100
-rw-r--r--tools/ioemu/tests/hello-arm.c113
-rw-r--r--tools/ioemu/tests/hello-i386.c26
-rw-r--r--tools/ioemu/tests/hello-mips.c64
-rw-r--r--tools/ioemu/tests/linux-test.c536
-rw-r--r--tools/ioemu/tests/qruncom.c327
-rw-r--r--tools/ioemu/tests/runcom.c195
-rw-r--r--tools/ioemu/tests/sha1.c242
-rw-r--r--tools/ioemu/tests/test-i386-code16.S79
-rw-r--r--tools/ioemu/tests/test-i386-muldiv.h76
-rw-r--r--tools/ioemu/tests/test-i386-shift.h187
-rw-r--r--tools/ioemu/tests/test-i386-vm86.S104
-rw-r--r--tools/ioemu/tests/test-i386.c2665
-rw-r--r--tools/ioemu/tests/test-i386.h152
-rw-r--r--tools/ioemu/tests/test_path.c152
-rw-r--r--tools/ioemu/tests/testthread.c51
-rw-r--r--tools/ioemu/texi2pod.pl428
-rw-r--r--tools/ioemu/thunk.c243
-rw-r--r--tools/ioemu/thunk.h158
-rw-r--r--tools/ioemu/translate-all.c313
-rw-r--r--tools/ioemu/translate-op.c37
-rw-r--r--tools/ioemu/usb-linux.c523
-rw-r--r--tools/ioemu/vgafont.h4611
-rw-r--r--tools/ioemu/vl.c7995
-rw-r--r--tools/ioemu/vl.h1589
-rw-r--r--tools/ioemu/vnc.c2868
-rw-r--r--tools/ioemu/vnc_keysym.h386
-rw-r--r--tools/ioemu/vnchextile.h209
-rw-r--r--tools/ioemu/x86_64.ld171
-rw-r--r--tools/ioemu/x_keymap.c110
-rw-r--r--tools/ioemu/xenfbfront.c315
-rw-r--r--tools/ioemu/xenstore.c931
440 files changed, 0 insertions, 203961 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 71770a76ad..4d27b26fe0 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -23,12 +23,7 @@ SUBDIRS-y += blktap
SUBDIRS-y += libfsimage
SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
SUBDIRS-y += fs-back
-
-ifeq (ioemu,$(CONFIG_QEMU))
-SUBDIRS-$(CONFIG_IOEMU) += ioemu
-else
SUBDIRS-$(CONFIG_IOEMU) += ioemu-dir
-endif
# These don't cross-compile
ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
diff --git a/tools/ioemu/.CVS/Entries b/tools/ioemu/.CVS/Entries
deleted file mode 100644
index a13b39b05e..0000000000
--- a/tools/ioemu/.CVS/Entries
+++ /dev/null
@@ -1,117 +0,0 @@
-D/audio////
-D/hw////
-D/pc-bios////
-D/target-i386////
-D/tests////
-D/fpu////
-D/keymaps////
-/.cvsignore/1.16/Thu May 3 17:17:53 2007//Trelease_0_9_0
-/COPYING/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/COPYING.LIB/1.2/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/Changelog/1.128/Thu May 3 17:17:53 2007//Trelease_0_9_0
-/LICENSE/1.3/Thu May 3 17:17:53 2007//Trelease_0_9_0
-/Makefile/1.112/Thu May 3 17:17:53 2007//Trelease_0_9_0
-/Makefile.target/1.144/Thu May 3 17:17:53 2007//Trelease_0_9_0
-/README/1.12/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/TODO/1.39/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/VERSION/1.30/Thu May 3 17:17:53 2007//Trelease_0_9_0
-/a.out.h/1.2/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/aes.c/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/aes.h/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/alpha-dis.c/1.3/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/alpha.ld/1.1/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/arm-dis.c/1.3/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/arm-semi.c/1.2/Sun Jan 28 03:10:55 2007//Trelease_0_9_0
-/arm.ld/1.2/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/block-bochs.c/1.3/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/block-cloop.c/1.4/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/block-cow.c/1.7/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/block-dmg.c/1.5/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/block-qcow.c/1.11/Thu May 3 17:17:54 2007//Trelease_0_9_0
-/block-qcow2.c/1.4/Mon Aug 7 02:38:06 2006//Trelease_0_9_0
-/block-raw.c/1.17/Thu Jan 18 00:22:11 2007//Trelease_0_9_0
-/block-vmdk.c/1.10/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/block-vpc.c/1.4/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/block-vvfat.c/1.8/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/block.c/1.42/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/block_int.h/1.10/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/bswap.h/1.5/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/check_ops.sh/1.1/Sun Jan 7 19:38:08 2007//Trelease_0_9_0
-/cocoa.m/1.10/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/configure/1.120/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/console.c/1.11/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/cpu-all.h/1.60/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/cpu-defs.h/1.17/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/cpu-exec.c/1.93/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/cutils.c/1.1/Sun Jan 7 22:04:40 2007//Trelease_0_9_0
-/dis-asm.h/1.11/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/disas.c/1.34/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/disas.h/1.7/Thu May 3 17:17:36 2007//Trelease_0_9_0
-/dyngen-exec.h/1.31/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/dyngen-op.h/1.1/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/dyngen.c/1.47/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/dyngen.h/1.12/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/elf.h/1.8/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/elf_ops.h/1.5/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/exec-all.h/1.49/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/exec.c/1.85/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/gdbstub.c/1.47/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/gdbstub.h/1.5/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/hostregs_helper.h/1.1/Sun Feb 4 13:37:44 2007//Trelease_0_9_0
-/i386-dis.c/1.5/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/i386-vl.ld/1.3/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/i386.ld/1.2/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/ia64.ld/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/keymaps.c/1.2/Thu May 3 17:17:34 2007//Trelease_0_9_0
-/kqemu.c/1.15/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/kqemu.h/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/loader.c/1.4/Thu May 3 17:17:55 2007//Trelease_0_9_0
-/m68k-dis.c/1.1/Thu May 3 17:17:56 2007//Trelease_0_9_0
-/m68k.ld/1.1/Thu May 3 17:17:56 2007//Trelease_0_9_0
-/mips-dis.c/1.4/Thu May 3 17:17:57 2007//Trelease_0_9_0
-/monitor.c/1.64/Thu May 3 17:17:57 2007//Trelease_0_9_0
-/osdep.c/1.15/Thu May 3 17:17:57 2007//Trelease_0_9_0
-/osdep.h/1.8/Thu May 3 17:17:57 2007//Trelease_0_9_0
-/ppc-dis.c/1.7/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/ppc.ld/1.2/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/qemu-binfmt-conf.sh/1.4/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/qemu-doc.texi/1.128/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/qemu-img.c/1.16/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/qemu-img.texi/1.3/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/qemu-tech.texi/1.9/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/qemu_socket.h/1.2/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/readline.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/s390.ld/1.1/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/sdl.c/1.34/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/sdl_keysym.h/1.3/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/sh4-dis.c/1.1/Thu May 3 17:17:58 2007//Trelease_0_9_0
-/softmmu_exec.h/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/softmmu_header.h/1.13/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/softmmu_template.h/1.16/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/sparc-dis.c/1.3/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/sparc.ld/1.1/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/sparc64.ld/1.1/Fri Aug 4 21:55:15 2006//Trelease_0_9_0
-/tap-win32.c/1.4/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/texi2pod.pl/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/thunk.c/1.6/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/thunk.h/1.13/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/translate-all.c/1.15/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/translate-op.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/usb-linux.c/1.10/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/vgafont.h/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/vl.c/1.248/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/vl.h/1.184/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/vnc.c/1.12/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/vnc_keysym.h/1.2/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/vnchextile.h/1.3/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/x86_64.ld/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/x_keymap.c/1.1/Wed Jan 24 21:40:21 2007//Trelease_0_9_0
-D/darwin-user////
-D/linux-user////
-D/slirp////
-D/target-arm////
-D/target-m68k////
-D/target-mips////
-D/target-ppc////
-D/target-sh4////
-D/target-sparc////
diff --git a/tools/ioemu/.CVS/Repository b/tools/ioemu/.CVS/Repository
deleted file mode 100644
index 1750fe828d..0000000000
--- a/tools/ioemu/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu
diff --git a/tools/ioemu/.CVS/Root b/tools/ioemu/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/.CVS/Tag b/tools/ioemu/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/.cvsignore b/tools/ioemu/.cvsignore
deleted file mode 100644
index ae68e450c8..0000000000
--- a/tools/ioemu/.cvsignore
+++ /dev/null
@@ -1,45 +0,0 @@
-arm-linux-user
-arm-softmmu
-armeb-linux-user
-config-host.*
-dyngen
-i386
-i386-softmmu
-i386-darwin-user
-i386-linux-user
-ppc-softmmu
-ppc64-softmmu
-ppc-darwin-user
-ppc-linux-user
-qemu-doc.html
-qemu-tech.html
-qemu-doc.info
-qemu-tech.info
-qemu.1
-qemu.pod
-qemu-img.1
-qemu-img.pod
-sparc-linux-user
-qemu-img
-sparc-softmmu
-x86_64-softmmu
-sparc64-linux-user
-sparc64-softmmu
-mips-softmmu
-mipsel-softmmu
-mips-linux-user
-mipsel-linux-user
-m68k-linux-user
-.gdbinit
-sh4-linux-user
-sh4-softmmu
-*.aux
-*.cp
-*.dvi
-*.fn
-*.ky
-*.log
-*.pg
-*.toc
-*.tp
-*.vr
diff --git a/tools/ioemu/COPYING b/tools/ioemu/COPYING
deleted file mode 100644
index e77696ae8d..0000000000
--- a/tools/ioemu/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/tools/ioemu/COPYING.LIB b/tools/ioemu/COPYING.LIB
deleted file mode 100644
index 223ede7de3..0000000000
--- a/tools/ioemu/COPYING.LIB
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/tools/ioemu/Changelog b/tools/ioemu/Changelog
deleted file mode 100644
index ea9ea7492f..0000000000
--- a/tools/ioemu/Changelog
+++ /dev/null
@@ -1,413 +0,0 @@
-version 0.9.0:
-
- - Support for relative paths in backing files for disk images
- - Async file I/O API
- - New qcow2 disk image format
- - Support of multiple VM snapshots
- - Linux: specific host CDROM and floppy support
- - SMM support
- - Moved PCI init, MP table init and ACPI table init to Bochs BIOS
- - Support for MIPS32 Release 2 instruction set (Thiemo Seufer)
- - MIPS Malta system emulation (Aurelien Jarno, Stefan Weil)
- - Darwin userspace emulation (Pierre d'Herbemont)
- - m68k user support (Paul Brook)
- - several x86 and x86_64 emulation fixes
- - Mouse relative offset VNC extension (Anthony Liguori)
- - PXE boot support (Anthony Liguori)
- - '-daemonize' option (Anthony Liguori)
-
-version 0.8.2:
-
- - ACPI support
- - PC VGA BIOS fixes
- - switch to OpenBios for SPARC targets (Blue Swirl)
- - VNC server fixes
- - MIPS FPU support (Marius Groeger)
- - Solaris/SPARC host support (Ben Taylor)
- - PPC breakpoints and single stepping (Jason Wessel)
- - USB updates (Paul Brook)
- - UDP/TCP/telnet character devices (Jason Wessel)
- - Windows sparse file support (Frediano Ziglio)
- - RTL8139 NIC TCP segmentation offloading (Igor Kovalenko)
- - PCNET NIC support (Antony T Curtis)
- - Support for variable frequency host CPUs
- - Workaround for win32 SMP hosts
- - Support for AMD Flash memories (Jocelyn Mayer)
- - Audio capture to WAV files support (malc)
-
-version 0.8.1:
-
- - USB tablet support (Brad Campbell, Anthony Liguori)
- - win32 host serial support (Kazu)
- - PC speaker support (Joachim Henke)
- - IDE LBA48 support (Jens Axboe)
- - SSE3 support
- - Solaris port (Ben Taylor)
- - Preliminary SH4 target (Samuel Tardieu)
- - VNC server (Anthony Liguori)
- - slirp fixes (Ed Swierk et al.)
- - USB fixes
- - ARM Versatile Platform Baseboard emulation (Paul Brook)
-
-version 0.8.0:
-
- - ARM system emulation: Arm Integrator/CP board with an arm1026ej-s
- cpu (Paul Brook)
- - SMP support
- - Mac OS X cocoa improvements (Mike Kronenberg)
- - Mac OS X CoreAudio driver (Mike Kronenberg)
- - DirectSound driver (malc)
- - ALSA audio driver (malc)
- - new audio options: '-soundhw' and '-audio-help' (malc)
- - ES1370 PCI audio device (malc)
- - Initial USB support
- - Linux host serial port access
- - Linux host low level parallel port access
- - New network emulation code supporting VLANs.
- - MIPS and MIPSel User Linux emulation
- - MIPS fixes to boot Linux (Daniel Jacobowitz)
- - NX bit support
- - Initial SPARC SMP support (Blue Swirl)
- - Major overhaul of the virtual FAT driver for read/write support
- (Johannes Schindelin)
-
-version 0.7.2:
-
- - x86_64 fixes (Win2000 and Linux 2.6 boot in 32 bit)
- - merge self modifying code handling in dirty ram page mecanism.
- - MIPS fixes (Ralf Baechle)
- - better user net performances
-
-version 0.7.1:
-
- - read-only Virtual FAT support (Johannes Schindelin)
- - Windows 2000 install disk full hack (original idea from Vladimir
- N. Oleynik)
- - VMDK disk image creation (Filip Navara)
- - SPARC64 progress (Blue Swirl)
- - initial MIPS support (Jocelyn mayer)
- - MIPS improvements (Ralf Baechle)
- - 64 bit fixes in user networking (initial patch by Gwenole Beauchesne)
- - IOAPIC support (Filip Navara)
-
-version 0.7.0:
-
- - better BIOS translation and HDD geometry auto-detection
- - user mode networking bug fix
- - undocumented FPU ops support
- - Cirrus VGA: support for 1280x1024x[8,15,16] modes
- - 'pidfile' option
- - .dmg disk image format support (Johannes Schindelin)
- - keymaps support (initial patch by Johannes Schindelin)
- - big endian ARM support (Lennert Buytenhek)
- - added generic 64 bit target support
- - x86_64 target support
- - initial APIC support
- - MMX/SSE/SSE2/PNI support
- - PC parallel port support (Mark Jonckheere)
- - initial SPARC64 support (Blue Swirl)
- - SPARC target boots Linux (Blue Swirl)
- - armv5te user mode support (Paul Brook)
- - ARM VFP support (Paul Brook)
- - ARM "Angel" semihosting syscalls (Paul Brook)
- - user mode gdb stub support (Paul Brook)
- - Samba 3 support
- - initial Cocoa support (Pierre d'Herbemont)
- - generic FPU emulation code
- - Virtual PC read-only disk image support (Alex Beregszaszi)
-
-version 0.6.1:
-
- - Mac OS X port (Pierre d'Herbemont)
- - Virtual console support
- - Better monitor line edition
- - New block device layer
- - New 'qcow' growable disk image support with AES encryption and
- transparent decompression
- - VMware 3 and 4 read-only disk image support (untested)
- - Support for up to 4 serial ports
- - TFTP server support (Magnus Damm)
- - Port redirection support in user mode networking
- - Support for not executable data sections
- - Compressed loop disk image support (Johannes Schindelin)
- - Level triggered IRQ fix (aka NE2000 PCI performance fix) (Steve
- Wormley)
- - Fixed Fedora Core 2 problems (now you can run qemu without any
- LD_ASSUME_KERNEL tricks on FC2)
- - DHCP fix for Windows (accept DHCPREQUEST alone)
- - SPARC system emulation (Blue Swirl)
- - Automatic Samba configuration for host file access from Windows.
- - '-loadvm' and '-full-screen' options
- - ne2000 savevm support (Johannes Schindelin)
- - Ctrl-Alt is now the default grab key. Ctrl-Alt-[0-9] switches to
- the virtual consoles.
- - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert)
- - Floppy fixes for NT4 and NT5 (Mike Nordell)
- - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
- - SDL Audio support and SB16 fixes (malc)
- - ENTER instruction bug fix (initial patch by Stefan Kisdaroczi)
- - VGA font change fix
- - VGA read-only CRTC register fix
-
-version 0.6.0:
-
- - minimalist FPU exception support (NetBSD FPU probe fix)
- - cr0.ET fix (Win95 boot)
- - *BSD port (Markus Niemisto)
- - I/O access fix (signaled by Mark Jonckheere)
- - IDE drives serial number fix (Mike Nordell)
- - int13 CDROM BIOS fix (aka Solaris x86 install CD fix)
- - int15, ah=86 BIOS fix (aka Solaris x86 hardware probe hang up fix)
- - BSR/BSF "undefined behaviour" fix
- - vmdk2raw: convert VMware disk images to raw images
- - PCI support
- - NE2K PCI support
- - dummy VGA PCI support
- - VGA font selection fix (Daniel Serpell)
- - PIC reset fix (Hidemi KAWAI)
- - PIC spurious irq support (aka Solaris install bug)
- - added '-localtime' option
- - Cirrus CL-GD54xx VGA support (initial patch by Makoto Suzuki (suzu))
- - APM and system shutdown support
- - Fixed system reset
- - Support for other PC BIOSes
- - Initial PowerMac hardware emulation
- - PowerMac/PREP OpenFirmware compatible BIOS (Jocelyn Mayer)
- - initial IDE BMDMA support (needed for Darwin x86)
- - Set the default memory size for PC emulation to 128 MB
-
-version 0.5.5:
-
- - SDL full screen support (initial patch by malc)
- - VGA support on PowerPC PREP
- - VBE fixes (Matthew Mastracci)
- - PIT fixes (aka Win98 hardware probe and "VGA slowness" bug)
- - IDE master only fixes (aka Win98 CD-ROM probe bug)
- - ARM load/store half word fix (Ulrich Hecht)
- - FDC fixes for Win98
-
-version 0.5.4:
-
- - qemu-fast fixes
- - BIOS area protection fix (aka EMM386.EXE fix) (Mike Nordell)
- - keyboard/mouse fix (Mike Nordell)
- - IDE fixes (Linux did not recognized slave drivers)
- - VM86 EIP masking fix (aka NT5 install fix) (Mike Nordell)
- - QEMU can now boot a PowerPC Linux kernel (Jocelyn Mayer)
- - User mode network stack
- - imul imm8 fix + 0x82 opcode support (Hidemi KAWAI)
- - precise self modifying code (aka BeOS install bug)
-
-version 0.5.3:
-
- - added Bochs VESA VBE support
- - VGA memory map mode 3 access fix (OS/2 install fix)
- - IDE fixes (Jens Axboe)
- - CPU interrupt fixes
- - fixed various TLB invalidation cases (NT install)
- - fixed cr0.WP semantics (XP install)
- - direct chaining support for SPARC and PowerPC (faster)
- - ARM NWFPE support (initial patch by Ulrich Hecht)
- - added specific x86 to x86 translator (close to native performance
- in qemu-i386 and qemu-fast)
- - shm syscalls support (Paul McKerras)
- - added accurate CR0.MP/ME/TS emulation
- - fixed DMA memory write access (Win95 boot floppy fix)
- - graphical x86 linux loader
- - command line monitor
- - generic removable device support
- - support of CD-ROM change
- - multiple network interface support
- - initial x86-64 host support (Gwenole Beauchesne)
- - lret to outer priviledge fix (OS/2 install fix)
- - task switch fixes (SkyOS boot)
- - VM save/restore commands
- - new timer API
- - more precise RTC emulation (periodic timers + time updates)
- - Win32 port (initial patch by Kazu)
-
-version 0.5.2:
-
- - improved soft MMU speed (assembly functions and specializing)
- - improved multitasking speed by avoiding flushing TBs when
- switching tasks
- - improved qemu-fast speed
- - improved self modifying code handling (big performance gain in
- softmmu mode).
- - fixed IO checking
- - fixed CD-ROM detection (win98 install CD)
- - fixed addseg real mode bug (GRUB boot fix)
- - added ROM memory support (win98 boot)
- - fixed 'call Ev' in case of paging exception
- - updated the script 'qemu-binfmt-conf.sh' to use QEMU automagically
- when launching executables for the supported target CPUs.
- - PowerPC system emulation update (Jocelyn Mayer)
- - PC floppy emulation and DMA fixes (Jocelyn Mayer)
- - polled mode for PIC (Jocelyn Mayer)
- - fixed PTE dirty bit handling
- - fixed xadd same reg bug
- - fixed cmpxchg exception safeness
- - access to virtual memory in gdb stub
- - task gate and NT flag fixes
- - eflags optimisation fix for string operations
-
-version 0.5.1:
-
- - float access fixes when using soft mmu
- - PC emulation support on PowerPC
- - A20 support
- - IDE CD-ROM emulation
- - ARM fixes (Ulrich Hecht)
- - SB16 emulation (malc)
- - IRET and INT fixes in VM86 mode with IOPL=3
- - Port I/Os use TSS io map
- - Full task switching/task gate support
- - added verr, verw, arpl, fcmovxx
- - PowerPC target support (Jocelyn Mayer)
- - Major SPARC target fixes (dynamically linked programs begin to work)
-
-version 0.5.0:
-
- - full hardware level VGA emulation
- - graphical display with SDL
- - added PS/2 mouse and keyboard emulation
- - popw (%esp) fix
- - mov to/from segment data width fix
- - added real mode support
- - added Bochs BIOS and LGPL'ed VGA BIOS loader in qemu
- - m68k host port (Richard Zidlicky)
- - partial soft MMU support for memory mapped I/Os
- - multi-target build
- - fixed: no error code in hardware interrupts
- - fixed: pop ss, mov ss, x and sti disable hardware irqs for the next insn
- - correct single stepping thru string operations
- - preliminary SPARC target support (Thomas M. Ogrisegg)
- - tun-fd option (Rusty Russell)
- - automatic IDE geometry detection
- - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}.
- - added man page
- - added full soft mmu mode to launch unpatched OSes.
-
-version 0.4.3:
-
- - x86 exception fix in case of nop instruction.
- - gcc 3.2.2 bug workaround (RedHat 9 fix)
- - sparc and Alpha host fixes
- - many ARM target fixes: 'ls' and 'bash' can be launched.
-
-version 0.4.2:
-
- - many exception handling fixes (can compile a Linux kernel inside vl)
- - IDE emulation support
- - initial GDB stub support
- - deferred update support for disk images (Rusty Russell)
- - accept User Mode Linux Copy On Write disk images
- - SMP kernels can at least be booted
-
-version 0.4.1:
-
- - more accurate timer support in vl.
- - more reliable NE2000 probe in vl.
- - added 2.5.66 kernel in vl-test.
- - added VLTMPDIR environment variable in vl.
-
-version 0.4:
-
- - initial support for ring 0 x86 processor emulation
- - fixed signal handling for correct dosemu DPMI emulation
- - fast x86 MMU emulation with mmap()
- - fixed popl (%esp) case
- - Linux kernel can be executed by QEMU with the 'vl' command.
-
-version 0.3:
-
- - initial support for ARM emulation
- - added fnsave, frstor, fnstenv, fldenv FPU instructions
- - added FPU register save in signal emulation
- - initial ARM port
- - Sparc and Alpha ports work on the regression test
- - generic ioctl number conversion
- - fixed ioctl type conversion
-
-version 0.2:
-
- - PowerPC disassembly and ELF symbols output (Rusty Russell)
- - flock support (Rusty Russell)
- - ugetrlimit support (Rusty Russell)
- - fstat64 fix (Rusty Russell)
- - initial Alpha port (Falk Hueffner)
- - initial IA64 port (Matt Wilson)
- - initial Sparc and Sparc64 port (David S. Miller)
- - added HLT instruction
- - LRET instruction fix.
- - added GPF generation for I/Os.
- - added INT3 and TF flag support.
- - SHL instruction C flag fix.
- - mmap emulation for host page size > 4KB
- - self-modifying code support
- - better VM86 support (dosemu works on non trivial programs)
- - precise exception support (EIP is computed correctly in most cases)
- - more precise LDT/GDT/IDT emulation
- - faster segment load in vm86 mode
- - direct chaining of basic blocks (faster emulation)
-
-version 0.1.6:
-
- - automatic library search system. QEMU can now work with unpatched
- ELF dynamic loader and libc (Rusty Russell).
- - ISO C warning fixes (Alistair Strachan)
- - first self-virtualizable version (works only as long as the
- translation cache is not flushed)
- - RH9 fixes
-
-version 0.1.5:
-
- - ppc64 support + personality() patch (Rusty Russell)
- - first Alpha CPU patches (Falk Hueffner)
- - removed bfd.h dependancy
- - fixed shrd, shld, idivl and divl on PowerPC.
- - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
-
-version 0.1.4:
-
- - more accurate VM86 emulation (can launch small DOS 16 bit
- executables in wine).
- - fixed push/pop fs/gs
- - added iret instruction.
- - added times() syscall and SIOCATMARK ioctl.
-
-version 0.1.3:
-
- - S390 support (Ulrich Weigand)
- - glibc 2.3.x compile fix (Ulrich Weigand)
- - socketcall endian fix (Ulrich Weigand)
- - struct sockaddr endian fix (Ulrich Weigand)
- - sendmsg/recvmsg endian fix (Ulrich Weigand)
- - execve endian fix (Ulrich Weigand)
- - fdset endian fix (Ulrich Weigand)
- - partial setsockopt syscall support (Ulrich Weigand)
- - more accurate pushf/popf emulation
- - first partial vm86() syscall support (can be used with runcom example).
- - added bound, cmpxchg8b, cpuid instructions
- - added 16 bit addressing support/override for string operations
- - poll() fix
-
-version 0.1.2:
-
- - compile fixes
- - xlat instruction
- - xchg instruction memory lock
- - added simple vm86 example (not working with QEMU yet). The 54 byte
- DOS executable 'pi_10.com' program was released by Bertram
- Felgenhauer (more information at http://www.boo.net/~jasonp/pipage.html).
-
-version 0.1.1:
-
- - glibc 2.2 compilation fixes
- - added -s and -L options
- - binary distribution of x86 glibc and wine
- - big endian fixes in ELF loader and getdents.
-
-version 0.1:
-
- - initial public release.
diff --git a/tools/ioemu/LICENSE b/tools/ioemu/LICENSE
deleted file mode 100644
index 8bf5f94fad..0000000000
--- a/tools/ioemu/LICENSE
+++ /dev/null
@@ -1,15 +0,0 @@
-The following points clarify the QEMU license:
-
-1) QEMU as a whole is released under the GNU General Public License
-
-2) Parts of QEMU have specific licenses which are compatible with the
-GNU General Public License. Hence each source file contains its own
-licensing information.
-
-In particular, the QEMU virtual CPU core library (libqemu.a) is
-released under the GNU Lesser General Public License. Many hardware
-device emulation sources are released under the BSD license.
-
-3) QEMU is a trademark of Fabrice Bellard.
-
-Fabrice Bellard. \ No newline at end of file
diff --git a/tools/ioemu/Makefile b/tools/ioemu/Makefile
deleted file mode 100644
index 3b31c2459a..0000000000
--- a/tools/ioemu/Makefile
+++ /dev/null
@@ -1,187 +0,0 @@
-# Makefile for QEMU.
-
-XEN_ROOT=../..
-include $(XEN_ROOT)/tools/Rules.mk
-
--include config-host.mak
-
-.PHONY: all clean distclean dvi info install install-doc tar tarbin \
- speed test test2 html dvi info
-
-BASE_CFLAGS=
-BASE_LDFLAGS=
-
-BASE_CFLAGS += $(OS_CFLAGS)
-ifeq ($(ARCH),sparc)
-BASE_CFLAGS += -mcpu=ultrasparc
-endif
-CPPFLAGS += -I. -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LIBS=
-TOOLS=qemu-img$(EXESUF)
-ifdef CONFIG_STATIC
-BASE_LDFLAGS += -static
-endif
-ifdef BUILD_DOCS
-DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1
-else
-DOCS=
-endif
-
-ifndef CONFIG_DARWIN
-ifndef CONFIG_WIN32
-ifndef CONFIG_SOLARIS
-LIBS+=-lrt
-endif
-endif
-endif
-
-TOOLS=tapdisk-ioemu
-
-all: $(TOOLS) $(DOCS) recurse-all
-
-subdir-%:
- $(MAKE) -C $(subst subdir-,,$@) all
-
-recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))
-
-tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/libxc
-tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/blktap/lib
-tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/xenstore
-tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/include
-tapdisk-ioemu: tapdisk-ioemu.c cutils.c block.c block-raw.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 block-qcow2.c hw/xen_blktap.c osdep.c
- $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
-
-qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.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 block-qcow2.c
- $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
-
-dyngen$(EXESUF): dyngen.c
- $(HOST_CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -o $@ $^
-
-clean:
-# avoid old build problems by removing potentially incorrect old files
- rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
- rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
- $(MAKE) -C tests clean
- for d in $(TARGET_DIRS); do \
- [ -d $$d ] && $(MAKE) -C $$d $@ || exit 0 ; \
- done
-
-distclean: clean
- rm -f config-host.mak config-host.h $(DOCS)
- rm -f qemu-{doc,tech}.{info,aux,cp,dvi,fn,info,ky,log,pg,toc,tp,vr}
- for d in $(TARGET_DIRS); do \
- rm -rf $$d || exit 1 ; \
- done
-
-KEYMAPS=da en-gb et fr fr-ch is lt modifiers no pt-br sv \
-ar de en-us fi fr-be hr it lv nl pl ru th \
-common de-ch es fo fr-ca hu ja mk nl-be pt sl tr
-
-install-doc: $(DOCS)
- mkdir -p "$(DESTDIR)$(docdir)"
- $(INSTALL_DATA) -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)"
-ifndef CONFIG_WIN32
- mkdir -p "$(DESTDIR)$(mandir)/man1"
- $(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
-endif
-
-install: all $(if $(BUILD_DOCS),install-doc)
- mkdir -p "$(DESTDIR)$(bindir)"
- $(INSTALL) -m 755 $(TOOLS) "$(DESTDIR)$(SBINDIR)"
-# mkdir -p "$(DESTDIR)$(datadir)"
-# for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
-# video.x openbios-sparc32 linux_boot.bin pxe-ne2k_pci.bin \
-# pxe-rtl8139.bin pxe-pcnet.bin; do \
-# $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
-# done
-ifndef CONFIG_WIN32
- mkdir -p "$(DESTDIR)$(datadir)/keymaps"
- set -e; for x in $(KEYMAPS); do \
- $(INSTALL_DATA) -m 644 $(SRC_PATH)/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps"; \
- done
-endif
- for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
- done
-
-# various test targets
-test speed test2: all
- $(MAKE) -C tests $@
-
-TAGS:
- etags *.[ch] target-i386-dm/*.[ch] hw/*.[ch]
-
-cscope:
- rm -f ./cscope.*
- find . -name "*.[ch]" -print > ./cscope.files
- cscope -b
-
-# documentation
-%.html: %.texi
- texi2html -monolithic -number $<
-
-%.info: %.texi
- makeinfo $< -o $@
-
-%.dvi: %.texi
- texi2dvi $<
-
-qemu.1: qemu-doc.texi
- perl -w $(SRC_PATH)/texi2pod.pl $< qemu.pod
- pod2man --section=1 --center=" " --release=" " qemu.pod > $@
-
-qemu-img.1: qemu-img.texi
- perl -w $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
- pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@
-
-info: qemu-doc.info qemu-tech.info
-
-dvi: qemu-doc.dvi qemu-tech.dvi
-
-html: qemu-doc.html qemu-tech.html
-
-VERSION ?= $(shell cat VERSION)
-FILE = qemu-$(VERSION)
-
-# tar release (use 'make -k tar' on a checkouted tree)
-tar:
- rm -rf /tmp/$(FILE)
- cp -r . /tmp/$(FILE)
- cd /tmp && tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS
- rm -rf /tmp/$(FILE)
-
-# generate a binary distribution
-tarbin:
- cd / && tar zcvf ~/qemu-$(VERSION)-i386.tar.gz \
- $(bindir)/qemu \
- $(bindir)/qemu-system-ppc \
- $(bindir)/qemu-system-sparc \
- $(bindir)/qemu-system-x86_64 \
- $(bindir)/qemu-system-mips \
- $(bindir)/qemu-system-mipsel \
- $(bindir)/qemu-system-arm \
- $(bindir)/qemu-i386 \
- $(bindir)/qemu-arm \
- $(bindir)/qemu-armeb \
- $(bindir)/qemu-sparc \
- $(bindir)/qemu-ppc \
- $(bindir)/qemu-mips \
- $(bindir)/qemu-mipsel \
- $(bindir)/qemu-img \
- $(datadir)/bios.bin \
- $(datadir)/vgabios.bin \
- $(datadir)/vgabios-cirrus.bin \
- $(datadir)/ppc_rom.bin \
- $(datadir)/video.x \
- $(datadir)/openbios-sparc32 \
- $(datadir)/linux_boot.bin \
- $(datadir)/pxe-ne2k_pci.bin \
- $(datadir)/pxe-rtl8139.bin \
- $(datadir)/pxe-pcnet.bin \
- $(docdir)/qemu-doc.html \
- $(docdir)/qemu-tech.html \
- $(mandir)/man1/qemu.1 $(mandir)/man1/qemu-img.1
-
-ifneq ($(wildcard .depend),)
-include .depend
-endif
diff --git a/tools/ioemu/Makefile.target b/tools/ioemu/Makefile.target
deleted file mode 100644
index 4beaafcf98..0000000000
--- a/tools/ioemu/Makefile.target
+++ /dev/null
@@ -1,678 +0,0 @@
-include config.mak
-
-XEN_ROOT=../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-TARGET_BASE_ARCH:=$(TARGET_ARCH)
-ifeq ($(TARGET_ARCH), x86_64)
-TARGET_BASE_ARCH:=i386
-endif
-ifeq ($(TARGET_ARCH), ppc64)
-TARGET_BASE_ARCH:=ppc
-endif
-ifeq ($(TARGET_ARCH), sparc64)
-TARGET_BASE_ARCH:=sparc
-endif
-TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)$(TARGET_SUB)
-VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
-CPPFLAGS+=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
-CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc
-CPPFLAGS+= -I$(XEN_ROOT)/tools/blktap/lib
-CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore
-CPPFLAGS+= -I$(XEN_ROOT)/tools/include
-ifdef CONFIG_DARWIN_USER
-VPATH+=:$(SRC_PATH)/darwin-user
-CPPFLAGS+=-I$(SRC_PATH)/darwin-user -I$(SRC_PATH)/darwin-user/$(TARGET_ARCH)
-endif
-ifdef CONFIG_LINUX_USER
-VPATH+=:$(SRC_PATH)/linux-user
-CPPFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
-endif
-BASE_CFLAGS=
-BASE_LDFLAGS=
-SSE2 := $(call cc-option,$(CC),-msse2,)
-ifeq ($(SSE2),-msse2)
-CFLAGS += -DUSE_SSE2=1 -msse2
-endif
-#CFLAGS+=-Werror
-LIBS=
-HELPER_CFLAGS=$(CFLAGS)
-DYNGEN=../dyngen$(EXESUF)
-# user emulator name
-TARGET_ARCH2=$(TARGET_ARCH)
-ifeq ($(TARGET_ARCH),arm)
- ifeq ($(TARGET_WORDS_BIGENDIAN),yes)
- TARGET_ARCH2=armeb
- endif
-endif
-ifeq ($(TARGET_ARCH),sh4)
- ifeq ($(TARGET_WORDS_BIGENDIAN),yes)
- TARGET_ARCH2=sh4eb
- endif
-endif
-ifeq ($(TARGET_ARCH),mips)
- ifneq ($(TARGET_WORDS_BIGENDIAN),yes)
- TARGET_ARCH2=mipsel
- endif
-endif
-QEMU_USER=qemu-$(TARGET_ARCH2)
-# system emulator name
-ifdef CONFIG_SOFTMMU
-ifeq ($(TARGET_ARCH), i386)
-QEMU_SYSTEM=qemu$(EXESUF)
-else
-QEMU_SYSTEM=qemu-system-$(TARGET_ARCH2)$(EXESUF)
-endif
-else
-QEMU_SYSTEM=qemu-fast
-endif
-
-ifdef CONFIG_STUBDOM
-QEMU_SYSTEM=qemu.a
-else
-QEMU_SYSTEM=qemu-dm
-endif
-
-ifdef CONFIG_USER_ONLY
-PROGS=$(QEMU_USER)
-else
-PROGS+=$(QEMU_SYSTEM)
-ifndef CONFIG_SOFTMMU
-CONFIG_STATIC=y
-endif
-endif # !CONFIG_USER_ONLY
-
-ifdef CONFIG_STATIC
-BASE_LDFLAGS+=-static
-endif
-
-# We require -O2 to avoid the stack setup prologue in EXIT_TB
-OP_CFLAGS = -Wall -O2 -g -fno-strict-aliasing
-
-ifeq ($(ARCH),i386)
-HELPER_CFLAGS+=-fomit-frame-pointer
-OP_CFLAGS+=-mpreferred-stack-boundary=2 -fomit-frame-pointer
-ifeq ($(HAVE_GCC3_OPTIONS),yes)
-OP_CFLAGS+= -falign-functions=0 -fno-gcse
-else
-OP_CFLAGS+= -malign-functions=0
-endif
-ifdef TARGET_GPROF
-USE_I386_LD=y
-endif
-ifdef CONFIG_STATIC
-USE_I386_LD=y
-endif
-ifdef USE_I386_LD
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-else
-ifdef CONFIG_LINUX_USER
-# WARNING: this LDFLAGS is _very_ tricky : qemu is an ELF shared object
-# that the kernel ELF loader considers as an executable. I think this
-# is the simplest way to make it self virtualizable!
-BASE_LDFLAGS+=-Wl,-shared
-endif
-endif
-endif
-
-ifeq ($(ARCH),x86_64)
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-
-ifeq ($(ARCH),ppc)
-CPPFLAGS+= -D__powerpc__
-ifdef CONFIG_LINUX_USER
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-endif
-
-ifeq ($(ARCH),s390)
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-
-ifeq ($(ARCH),sparc)
-ifeq ($(CONFIG_SOLARIS),yes)
-BASE_CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g2 -ffixed-g3
-BASE_LDFLAGS+=-m32
-OP_CFLAGS+=-fno-delayed-branch -fno-omit-frame-pointer -ffixed-i0
-else
-BASE_CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
-BASE_LDFLAGS+=-m32
-OP_CFLAGS+=-fno-delayed-branch -ffixed-i0
-HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
-# -static is used to avoid g1/g3 usage by the dynamic linker
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld -static
-endif
-endif
-
-ifeq ($(ARCH),sparc64)
-BASE_CFLAGS+=-mcpu=ultrasparc -m64 -ffixed-g1 -ffixed-g4 -ffixed-g5 -ffixed-g7
-BASE_LDFLAGS+=-m64
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-OP_CFLAGS+=-mcpu=ultrasparc -m64 -ffixed-g1 -ffixed-g4 -ffixed-g5 -ffixed-g7 -fno-delayed-branch -ffixed-i0
-endif
-
-ifeq ($(ARCH),alpha)
-# -msmall-data is not used for OP_CFLAGS because we want two-instruction
-# relocations for the constant constructions
-# Ensure there's only a single GP
-BASE_CFLAGS+=-msmall-data
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-
-ifeq ($(ARCH),ia64)
-BASE_CFLAGS+=-mno-sdata
-OP_CFLAGS+=-mno-sdata
-BASE_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-
-ifeq ($(ARCH),arm)
-OP_CFLAGS+=-mno-sched-prolog -fno-omit-frame-pointer
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-
-ifeq ($(ARCH),m68k)
-OP_CFLAGS+=-fomit-frame-pointer
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-
-ifeq ($(ARCH),mips)
-BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
-endif
-
-ifeq ($(HAVE_GCC3_OPTIONS),yes)
-# very important to generate a return at the end of every operation
-OP_CFLAGS+=-fno-reorder-blocks -fno-optimize-sibling-calls
-endif
-
-ifeq ($(CONFIG_DARWIN),yes)
-LIBS+=-lmx
-endif
-
-ifdef CONFIG_DARWIN_USER
-# Leave some space for the regular program loading zone
-BASE_LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000
-endif
-
-OP_CFLAGS+=$(OS_CFLAGS)
-
-#########################################################
-
-CPPFLAGS+=-D_GNU_SOURCE
-# -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LIBS+=-lm
-LIBS+=-L../../libxc -lxenctrl -lxenguest
-LIBS+=-L../../xenstore -lxenstore
-ifndef CONFIG_USER_ONLY
-LIBS+=-lz
-endif
-ifdef CONFIG_WIN32
-LIBS+=-lwinmm -lws2_32 -liphlpapi
-endif
-ifdef CONFIG_SOLARIS
-LIBS+=-lsocket -lnsl -lresolv
-endif
-
-# profiling code
-ifdef TARGET_GPROF
-BASE_LDFLAGS+=-p
-main.o: BASE_CFLAGS+=-p
-endif
-
-ifdef CONFIG_LINUX_USER
-OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \
- elfload.o linuxload.o
-ifdef TARGET_HAS_BFLT
-OBJS+= flatload.o
-endif
-
-ifeq ($(TARGET_ARCH), i386)
-OBJS+= vm86.o
-endif
-ifeq ($(TARGET_ARCH), arm)
-OBJS+=nwfpe/fpa11.o nwfpe/fpa11_cpdo.o \
-nwfpe/fpa11_cpdt.o nwfpe/fpa11_cprt.o nwfpe/fpopcode.o nwfpe/single_cpdo.o \
- nwfpe/double_cpdo.o nwfpe/extended_cpdo.o arm-semi.o
-endif
-ifeq ($(TARGET_ARCH), m68k)
-OBJS+= m68k-sim.o m68k-semi.o
-endif
-endif #CONFIG_LINUX_USER
-
-ifdef CONFIG_DARWIN_USER
-OBJS= main.o commpage.o machload.o mmap.o osdep.o signal.o syscall.o thunk.o
-endif
-
-SRCS:= $(OBJS:.o=.c)
-OBJS+= libqemu.a
-
-# cpu emulator library
-LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
- translate.o op.o
-ifdef CONFIG_SOFTFLOAT
-LIBOBJS+=fpu/softfloat.o
-else
-LIBOBJS+=fpu/softfloat-native.o
-endif
-CPPFLAGS+=-I$(SRC_PATH)/fpu
-
-ifeq ($(TARGET_ARCH), i386)
-LIBOBJS+=helper.o helper2.o
-ifeq ($(ARCH), i386)
-LIBOBJS+=translate-copy.o
-endif
-endif
-
-ifeq ($(TARGET_ARCH), x86_64)
-LIBOBJS+=helper.o helper2.o
-endif
-
-ifeq ($(TARGET_BASE_ARCH), ppc)
-LIBOBJS+= op_helper.o helper.o
-endif
-
-ifeq ($(TARGET_ARCH), mips)
-LIBOBJS+= op_helper.o helper.o
-endif
-
-ifeq ($(TARGET_BASE_ARCH), sparc)
-LIBOBJS+= op_helper.o helper.o
-endif
-
-ifeq ($(TARGET_BASE_ARCH), arm)
-LIBOBJS+= op_helper.o helper.o
-endif
-
-ifeq ($(TARGET_BASE_ARCH), sh4)
-LIBOBJS+= op_helper.o helper.o
-endif
-
-ifeq ($(TARGET_BASE_ARCH), m68k)
-LIBOBJS+= helper.o
-endif
-
-# NOTE: the disassembler code is only needed for debugging
-LIBOBJS+=disas.o
-ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
-USE_I386_DIS=y
-endif
-ifeq ($(findstring x86_64, $(TARGET_ARCH) $(ARCH)),x86_64)
-USE_I386_DIS=y
-endif
-ifdef USE_I386_DIS
-LIBOBJS+=i386-dis.o
-endif
-ifeq ($(findstring alpha, $(TARGET_ARCH) $(ARCH)),alpha)
-LIBOBJS+=alpha-dis.o
-endif
-ifeq ($(findstring ppc, $(TARGET_BASE_ARCH) $(ARCH)),ppc)
-LIBOBJS+=ppc-dis.o
-endif
-ifeq ($(findstring mips, $(TARGET_ARCH) $(ARCH)),mips)
-LIBOBJS+=mips-dis.o
-endif
-ifeq ($(findstring sparc, $(TARGET_BASE_ARCH) $(ARCH)),sparc)
-LIBOBJS+=sparc-dis.o
-endif
-ifeq ($(findstring arm, $(TARGET_ARCH) $(ARCH)),arm)
-LIBOBJS+=arm-dis.o
-endif
-ifeq ($(findstring m68k, $(TARGET_ARCH) $(ARCH)),m68k)
-LIBOBJS+=m68k-dis.o
-endif
-ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4)
-LIBOBJS+=sh4-dis.o
-endif
-
-ifdef CONFIG_GDBSTUB
-OBJS+=gdbstub.o
-endif
-
-# qemu-dm objects
-ifeq ($(ARCH),ia64)
-LIBOBJS=helper2.o exec-dm.o i8259-dm.o piix_pci-dm.o
-else
-LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o
-endif
-
-all: $(PROGS)
-
-$(QEMU_USER): $(OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ $(LIBS)
-ifeq ($(ARCH),alpha)
-# Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
-# the address space (31 bit so sign extending doesn't matter)
- echo -ne '\001\000\000\000' | dd of=qemu bs=1 seek=48 count=4 conv=notrunc
-endif
-
-# must use static linking to avoid leaving stuff in virtual address space
-VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o isa_mmio.o
-VL_OBJS+=cutils.o
-VL_OBJS+=block.o block-raw.o
-VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
-ifdef CONFIG_STUBDOM
-VL_OBJS+=block-vbd.o
-endif
-ifdef CONFIG_WIN32
-VL_OBJS+=tap-win32.o
-endif
-
-ifdef CONFIG_STUBDOM
-CONFIG_PASSTHROUGH=1
-else
- ifeq (,$(wildcard /usr/include/pci))
-$(warning *** pciutils-devl package not found - missing /usr/include/pci)
-$(warning *** PCI passthrough capability has been disabled)
- else
-CONFIG_PASSTHROUGH=1
- endif
-endif
-
-ifdef CONFIG_PASSTHROUGH
-LIBS+=-lpci
-VL_OBJS+= pass-through.o pt-msi.o
-CFLAGS += -DCONFIG_PASSTHROUGH
-$(info *** PCI passthrough capability has been enabled ***)
-endif
-
-SOUND_HW = sb16.o es1370.o
-AUDIODRV = audio.o noaudio.o wavaudio.o
-ifdef CONFIG_SDL
-AUDIODRV += sdlaudio.o
-endif
-ifdef CONFIG_OSS
-AUDIODRV += ossaudio.o
-endif
-ifdef CONFIG_COREAUDIO
-AUDIODRV += coreaudio.o
-endif
-ifdef CONFIG_ALSA
-AUDIODRV += alsaaudio.o
-LIBS += -lasound
-endif
-ifdef CONFIG_DSOUND
-AUDIODRV += dsoundaudio.o
-LIBS += -lole32 -ldxguid
-endif
-ifdef CONFIG_FMOD
-AUDIODRV += fmodaudio.o
-audio.o fmodaudio.o: CPPFLAGS := -I$(CONFIG_FMOD_INC) $(CPPFLAGS)
-LIBS += $(CONFIG_FMOD_LIB)
-endif
-ifdef CONFIG_ADLIB
-SOUND_HW += fmopl.o adlib.o
-endif
-AUDIODRV+= wavcapture.o
-
-ifdef CONFIG_VNC_TLS
-CPPFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
-LIBS += $(CONFIG_VNC_TLS_LIBS)
-endif
-
-# SCSI layer
-VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
-
-# USB layer
-VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
-
-# PCI network cards
-VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o e1000.o
-
-ifeq ($(TARGET_BASE_ARCH), i386)
-# Hardware support
-VL_OBJS+= ide.o pckbd.o ps2.o vga.o dma.o extboot.o
-ifeq ($(ARCH),ia64)
-VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
-else
-VL_OBJS+= fdc.o serial.o pc.o
-endif
-VL_OBJS+= cirrus_vga.o parallel.o acpi.o
-VL_OBJS+= usb-uhci.o smbus_eeprom.o
-VL_OBJS+= piix4acpi.o
-VL_OBJS+= xenstore.o
-ifndef CONFIG_STUBDOM
-VL_OBJS+= xen_blktap.o
-endif
-VL_OBJS+= xen_platform.o
-VL_OBJS+= xen_machine_fv.o
-VL_OBJS+= xen_machine_pv.o
-VL_OBJS+= xenfb.o
-ifdef CONFIG_STUBDOM
-VL_OBJS+= xenfbfront.o
-endif
-VL_OBJS+= xen_console.o
-VL_OBJS+= pci_emulation.o
-ifndef CONFIG_STUBDOM
-VL_OBJS+= tpm_tis.o
-VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o
-CPPFLAGS += -DHAS_TPM
-CPPFLAGS += -DHAS_AUDIO
-endif
-endif
-ifeq ($(TARGET_BASE_ARCH), ppc)
-VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o dma.o
-VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
-VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
-VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o
-ifndef CONFIG_STUBDOM
-VL_OBJS+= $(SOUND_HW) $(AUDIODRV)
-CPPFLAGS += -DHAS_AUDIO
-endif
-endif
-ifeq ($(TARGET_ARCH), mips)
-VL_OBJS+= mips_r4k.o mips_malta.o mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
-VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o
-VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o
-ifndef CONFIG_STUBDOM
-VL_OBJS+= $(SOUND_HW) $(AUDIODRV)
-DEFINES += -DHAS_AUDIO
-endif
-endif
-ifeq ($(TARGET_BASE_ARCH), sparc)
-ifeq ($(TARGET_ARCH), sparc64)
-VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
-VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
-VL_OBJS+= cirrus_vga.o parallel.o
-else
-VL_OBJS+= sun4m.o tcx.o pcnet.o iommu.o m48t59.o slavio_intctl.o
-VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o sparc32_dma.o
-VL_OBJS+= cs4231.o
-endif
-endif
-ifeq ($(TARGET_BASE_ARCH), arm)
-VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
-VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
-VL_OBJS+= versatile_pci.o
-VL_OBJS+= arm_gic.o realview.o arm_sysctl.o
-VL_OBJS+= arm-semi.o
-endif
-ifeq ($(TARGET_BASE_ARCH), sh4)
-VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
-endif
-ifdef CONFIG_GDBSTUB
-VL_OBJS+=gdbstub.o
-endif
-ifdef CONFIG_SDL
-VL_OBJS+=sdl.o x_keymap.o
-endif
-VL_OBJS+=vnc.o d3des.o
-ifdef CONFIG_COCOA
-VL_OBJS+=cocoa.o
-COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
-ifdef CONFIG_COREAUDIO
-COCOA_LIBS+=-framework CoreAudio
-endif
-endif
-ifdef CONFIG_SLIRP
-CPPFLAGS+=-I$(SRC_PATH)/slirp
-SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
-slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o \
-tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
-VL_OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
-endif
-
-VL_LDFLAGS=
-# specific flags are needed for non soft mmu emulator
-ifdef CONFIG_STATIC
-VL_LDFLAGS+=-static
-endif
-ifndef CONFIG_SOFTMMU
-VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386-vl.ld
-endif
-ifndef CONFIG_DARWIN
-ifndef CONFIG_WIN32
-ifndef CONFIG_SOLARIS
-VL_LIBS=-lutil -lrt
-endif
-endif
-endif
-ifdef TARGET_GPROF
-vl.o: BASE_CFLAGS+=-p
-VL_LDFLAGS+=-p
-endif
-
-ifeq ($(ARCH),sparc64)
-VL_LDFLAGS+=-m64
-VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc64.ld
-endif
-
-ifdef CONFIG_WIN32
-SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole
-endif
-
-$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
-ifdef CONFIG_STUBDOM
- $(AR) rcs $@ $(VL_OBJS)
-else
- $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)
-endif
-
-cocoa.o: cocoa.m
- $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-sdl.o: sdl.c keymaps.c sdl_keysym.h
- $(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
- $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-sdlaudio.o: sdlaudio.c
- $(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-depend: $(SRCS)
- $(CC) -MM $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $^ 1>.depend
-
-vldepend: $(VL_OBJS:.o=.c)
- $(CC) -MM $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $^ 1>.depend
-
-# libqemu
-
-libqemu.a: $(LIBOBJS)
- rm -f $@
- $(AR) rcs $@ $(LIBOBJS)
-
-translate.o: translate.c gen-op.h opc.h cpu.h
-
-translate-all.o: translate-all.c opc.h cpu.h
-
-translate-op.o: translate-all.c op.h opc.h cpu.h
-
-op.h: op.o $(DYNGEN)
- $(DYNGEN) -o $@ $<
-
-opc.h: op.o $(DYNGEN)
- $(DYNGEN) -c -o $@ $<
-
-gen-op.h: op.o $(DYNGEN)
- $(DYNGEN) -g -o $@ $<
-
-op.o: op.c
- $(CC) $(OP_CFLAGS) $(CPPFLAGS) -c -o $@ $<
-
-# HELPER_CFLAGS is used for all the code compiled with static register
-# variables
-ifeq ($(TARGET_BASE_ARCH), i386)
-# XXX: rename helper.c to op_helper.c
-helper.o: helper.c
- $(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-else
-op_helper.o: op_helper.c
- $(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-endif
-
-cpu-exec.o: cpu-exec.c
- $(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-# Note: this is a workaround. The real fix is to avoid compiling
-# cpu_signal_handler() in cpu-exec.c.
-signal.o: signal.c
- $(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-ifeq ($(TARGET_BASE_ARCH), i386)
-op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h ops_sse.h
-endif
-
-ifeq ($(TARGET_ARCH), arm)
-op.o: op.c op_template.h
-pl110.o: pl110_template.h
-endif
-
-ifeq ($(TARGET_BASE_ARCH), sparc)
-op.o: op.c op_template.h op_mem.h fop_template.h fbranch_template.h
-magic_load.o: elf_op.h
-endif
-
-ifeq ($(TARGET_BASE_ARCH), ppc)
-op.o: op.c op_template.h op_mem.h
-op_helper.o: op_helper_mem.h
-translate.o: translate.c translate_init.c
-endif
-
-ifeq ($(TARGET_ARCH), mips)
-op.o: op.c op_template.c fop_template.c op_mem.c
-op_helper.o: op_helper_mem.c
-endif
-
-loader.o: loader.c elf_ops.h
-
-ifeq ($(TARGET_ARCH), sh4)
-op.o: op.c op_mem.c cpu.h
-op_helper.o: op_helper.c exec.h cpu.h
-helper.o: helper.c exec.h cpu.h
-sh7750.o: sh7750.c sh7750_regs.h sh7750_regnames.h cpu.h
-shix.o: shix.c sh7750_regs.h sh7750_regnames.h
-sh7750_regnames.o: sh7750_regnames.c sh7750_regnames.h sh7750_regs.h
-tc58128.o: tc58128.c
-endif
-
-$(OBJS) $(LIBOBJS) $(VL_OBJS): config.h ../config-host.h
-
-%.o: %.c
- $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-%.o: %.S
- $(CC) $(CPPFLAGS) -c -o $@ $<
-
-clean:
- rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o
-
-distclean: clean
- rm -rf config.mak config.h
-
-install: all
- mkdir -p "$(DESTDIR)$(bindir)" "$(DESTDIR)$(configdir)"
-ifneq ($(PROGS),)
- $(INSTALL_PROG) $(PROGS) "$(DESTDIR)$(bindir)"
-endif
- $(INSTALL_PROG) $(TARGET_PATH)/qemu-dm.debug "$(DESTDIR)$(bindir)"
- $(INSTALL_PROG) $(TARGET_PATH)/qemu-ifup "$(DESTDIR)$(configdir)"
-
-ifneq ($(wildcard .depend),)
-include .depend
-endif
-
-ifeq (1, 0)
-audio.o sdlaudio.o dsoundaudio.o ossaudio.o wavaudio.o noaudio.o \
-fmodaudio.o alsaaudio.o mixeng.o sb16.o es1370.o gus.o adlib.o: \
-CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare
-endif
diff --git a/tools/ioemu/README b/tools/ioemu/README
deleted file mode 100644
index 1a39500b78..0000000000
--- a/tools/ioemu/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Read the documentation in qemu-doc.html.
-
-Fabrice Bellard. \ No newline at end of file
diff --git a/tools/ioemu/TODO b/tools/ioemu/TODO
deleted file mode 100644
index 516ea87bf4..0000000000
--- a/tools/ioemu/TODO
+++ /dev/null
@@ -1,55 +0,0 @@
-short term:
-----------
-- cycle counter for all archs
-- cpu_interrupt() win32/SMP fix
-- support variable tsc freq
-- USB host async
-- IDE async
-- debug option in 'configure' script + disable -fomit-frame-pointer
-- Precise VGA timings for old games/demos (malc patch)
-- merge PIC spurious interrupt patch
-- warning for OS/2: must not use 128 MB memory (merge bochs cmos patch ?)
-- config file (at least for windows/Mac OS X)
-- update doc: PCI infos.
-- basic VGA optimizations
-- better code fetch (different exception handling + CS.limit support)
-- do not resize vga if invalid size.
-- avoid looping if only exceptions
-- TLB code protection support for PPC
-- see openMosix Doc
-- disable SMC handling for ARM/SPARC/PPC (not finished)
-- see undefined flags for BTx insn
-- user/kernel PUSHL/POPL in helper.c
-- keyboard output buffer filling timing emulation
-- return UD exception if LOCK prefix incorrectly used
-- test ldt limit < 7 ?
-- tests for each target CPU
-- fix CCOP optimisation
-- fix all remaining thread lock issues (must put TBs in a specific invalid
- state, find a solution for tb_flush()).
-
-ppc specific:
-------------
-- TLB invalidate not needed if msr_pr changes
-- enable shift optimizations ?
-
-linux-user specific:
--------------------
-- add IPC syscalls
-- handle rare page fault cases (in particular if page fault in helpers or
- in syscall emulation code).
-- more syscalls (in particular all 64 bit ones, IPCs, fix 64 bit
- issues, fix 16 bit uid issues)
-- use page_unprotect_range in every suitable syscall to handle all
- cases of self modifying code.
-- fix thread stack freeing (use kernel 2.5.x CLONE_CHILD_CLEARTID)
-- use kernel traps for unaligned accesses on ARM ?
-
-
-lower priority:
---------------
-- int15 ah=86: use better timing
-- suppress shift_mem ops
-- fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret)
-- optimize FPU operations (evaluate x87 stack pointer statically)
-- use -msoft-float on ARM
diff --git a/tools/ioemu/VERSION b/tools/ioemu/VERSION
deleted file mode 100644
index 899f24fc75..0000000000
--- a/tools/ioemu/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.9.0 \ No newline at end of file
diff --git a/tools/ioemu/a.out.h b/tools/ioemu/a.out.h
deleted file mode 100644
index 1f978c1c04..0000000000
--- a/tools/ioemu/a.out.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/* a.out.h
-
- Copyright 1997, 1998, 1999, 2001 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#ifndef _A_OUT_H_
-#define _A_OUT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#define COFF_IMAGE_WITH_PE
-#define COFF_LONG_SECTION_NAMES
-
-/*** coff information for Intel 386/486. */
-
-
-/********************** FILE HEADER **********************/
-
-struct external_filehdr {
- short f_magic; /* magic number */
- short f_nscns; /* number of sections */
- unsigned long f_timdat; /* time & date stamp */
- unsigned long f_symptr; /* file pointer to symtab */
- unsigned long f_nsyms; /* number of symtab entries */
- short f_opthdr; /* sizeof(optional hdr) */
- short f_flags; /* flags */
-};
-
-/* Bits for f_flags:
- * F_RELFLG relocation info stripped from file
- * F_EXEC file is executable (no unresolved external references)
- * F_LNNO line numbers stripped from file
- * F_LSYMS local symbols stripped from file
- * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
- */
-
-#define F_RELFLG (0x0001)
-#define F_EXEC (0x0002)
-#define F_LNNO (0x0004)
-#define F_LSYMS (0x0008)
-
-
-
-#define I386MAGIC 0x14c
-#define I386PTXMAGIC 0x154
-#define I386AIXMAGIC 0x175
-
-/* This is Lynx's all-platform magic number for executables. */
-
-#define LYNXCOFFMAGIC 0415
-
-#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \
- && (x).f_magic != I386AIXMAGIC \
- && (x).f_magic != I386PTXMAGIC \
- && (x).f_magic != LYNXCOFFMAGIC)
-
-#define FILHDR struct external_filehdr
-#define FILHSZ 20
-
-
-/********************** AOUT "OPTIONAL HEADER"=
- **********************/
-
-
-typedef struct
-{
- unsigned short magic; /* type of file */
- unsigned short vstamp; /* version stamp */
- unsigned long tsize; /* text size in bytes, padded to FW bdry*/
- unsigned long dsize; /* initialized data " " */
- unsigned long bsize; /* uninitialized data " " */
- unsigned long entry; /* entry pt. */
- unsigned long text_start; /* base of text used for this file */
- unsigned long data_start; /* base of data used for this file=
- */
-}
-AOUTHDR;
-
-#define AOUTSZ 28
-#define AOUTHDRSZ 28
-
-#define OMAGIC 0404 /* object files, eg as output */
-#define ZMAGIC 0413 /* demand load format, eg normal ld output */
-#define STMAGIC 0401 /* target shlib */
-#define SHMAGIC 0443 /* host shlib */
-
-
-/* define some NT default values */
-/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
-#define NT_SECTION_ALIGNMENT 0x1000
-#define NT_FILE_ALIGNMENT 0x200
-#define NT_DEF_RESERVE 0x100000
-#define NT_DEF_COMMIT 0x1000
-
-/********************** SECTION HEADER **********************/
-
-
-struct external_scnhdr {
- char s_name[8]; /* section name */
- unsigned long s_paddr; /* physical address, offset
- of last addr in scn */
- unsigned long s_vaddr; /* virtual address */
- unsigned long s_size; /* section size */
- unsigned long s_scnptr; /* file ptr to raw data for section */
- unsigned long s_relptr; /* file ptr to relocation */
- unsigned long s_lnnoptr; /* file ptr to line numbers */
- unsigned short s_nreloc; /* number of relocation entries */
- unsigned short s_nlnno; /* number of line number entries*/
- unsigned long s_flags; /* flags */
-};
-
-#define SCNHDR struct external_scnhdr
-#define SCNHSZ 40
-
-/*
- * names of "special" sections
- */
-#define _TEXT ".text"
-#define _DATA ".data"
-#define _BSS ".bss"
-#define _COMMENT ".comment"
-#define _LIB ".lib"
-
-/********************** LINE NUMBERS **********************/
-
-/* 1 line number entry for every "breakpointable" source line in a section.
- * Line numbers are grouped on a per function basis; first entry in a function
- * grouping will have l_lnno = 0 and in place of physical address will be the
- * symbol table index of the function name.
- */
-struct external_lineno {
- union {
- unsigned long l_symndx; /* function name symbol index, iff l_lnno 0 */
- unsigned long l_paddr; /* (physical) address of line number */
- } l_addr;
- unsigned short l_lnno; /* line number */
-};
-
-#define LINENO struct external_lineno
-#define LINESZ 6
-
-/********************** SYMBOLS **********************/
-
-#define E_SYMNMLEN 8 /* # characters in a symbol name */
-#define E_FILNMLEN 14 /* # characters in a file name */
-#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
-
-struct __attribute__((packed)) external_syment
-{
- union {
- char e_name[E_SYMNMLEN];
- struct {
- unsigned long e_zeroes;
- unsigned long e_offset;
- } e;
- } e;
- unsigned long e_value;
- unsigned short e_scnum;
- unsigned short e_type;
- char e_sclass[1];
- char e_numaux[1];
-};
-
-#define N_BTMASK (0xf)
-#define N_TMASK (0x30)
-#define N_BTSHFT (4)
-#define N_TSHIFT (2)
-
-union external_auxent {
- struct {
- unsigned long x_tagndx; /* str, un, or enum tag indx */
- union {
- struct {
- unsigned short x_lnno; /* declaration line number */
- unsigned short x_size; /* str/union/array size */
- } x_lnsz;
- unsigned long x_fsize; /* size of function */
- } x_misc;
- union {
- struct { /* if ISFCN, tag, or .bb */
- unsigned long x_lnnoptr;/* ptr to fcn line # */
- unsigned long x_endndx; /* entry ndx past block end */
- } x_fcn;
- struct { /* if ISARY, up to 4 dimen. */
- char x_dimen[E_DIMNUM][2];
- } x_ary;
- } x_fcnary;
- unsigned short x_tvndx; /* tv index */
- } x_sym;
-
- union {
- char x_fname[E_FILNMLEN];
- struct {
- unsigned long x_zeroes;
- unsigned long x_offset;
- } x_n;
- } x_file;
-
- struct {
- unsigned long x_scnlen; /* section length */
- unsigned short x_nreloc; /* # relocation entries */
- unsigned short x_nlinno; /* # line numbers */
- unsigned long x_checksum; /* section COMDAT checksum */
- unsigned short x_associated;/* COMDAT associated section index */
- char x_comdat[1]; /* COMDAT selection number */
- } x_scn;
-
- struct {
- unsigned long x_tvfill; /* tv fill value */
- unsigned short x_tvlen; /* length of .tv */
- char x_tvran[2][2]; /* tv range */
- } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
-
-};
-
-#define SYMENT struct external_syment
-#define SYMESZ 18
-#define AUXENT union external_auxent
-#define AUXESZ 18
-
-#define _ETEXT "etext"
-
-/********************** RELOCATION DIRECTIVES **********************/
-
-struct external_reloc {
- char r_vaddr[4];
- char r_symndx[4];
- char r_type[2];
-};
-
-#define RELOC struct external_reloc
-#define RELSZ 10
-
-/* end of coff/i386.h */
-
-/* PE COFF header information */
-
-#ifndef _PE_H
-#define _PE_H
-
-/* NT specific file attributes */
-#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
-#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
-#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
-#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
-#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
-#define IMAGE_FILE_32BIT_MACHINE 0x0100
-#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
-#define IMAGE_FILE_SYSTEM 0x1000
-#define IMAGE_FILE_DLL 0x2000
-#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
-
-/* additional flags to be set for section headers to allow the NT loader to
- read and write to the section data (to replace the addresses of data in
- dlls for one thing); also to execute the section in .text's case=
- */
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
-#define IMAGE_SCN_MEM_EXECUTE 0x20000000
-#define IMAGE_SCN_MEM_READ 0x40000000
-#define IMAGE_SCN_MEM_WRITE 0x80000000
-
-/*
- * Section characteristics added for ppc-nt
- */
-
-#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
-
-#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
-
-#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
-#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
-#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
-#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
-
-#define IMAGE_SCN_MEM_FARDATA 0x00008000
-
-#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
-#define IMAGE_SCN_MEM_16BIT 0x00020000
-#define IMAGE_SCN_MEM_LOCKED 0x00040000
-#define IMAGE_SCN_MEM_PRELOAD 0x00080000
-
-#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
-#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
-#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
-#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
-#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
-#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
-#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
-
-
-#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
-#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */
-#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
-#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
-
-/* COMDAT selection codes. */
-
-#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
-#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
-#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
-#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
-#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
-
-/* Magic values that are true for all dos/nt implementations */
-#define DOSMAGIC 0x5a4d
-#define NT_SIGNATURE 0x00004550
-
-/* NT allows long filenames, we want to accommodate this. This may break
- some of the bfd functions */
-#undef FILNMLEN
-#define FILNMLEN 18 /* # characters in a file name */
-
-
-#ifdef COFF_IMAGE_WITH_PE
-/* The filehdr is only weired in images */
-
-#undef FILHDR
-struct external_PE_filehdr
-{
- /* DOS header fields */
- unsigned short e_magic; /* Magic number, 0x5a4d */
- unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
- unsigned short e_cp; /* Pages in file, 0x3 */
- unsigned short e_crlc; /* Relocations, 0x0 */
- unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
- unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
- unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
- unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
- unsigned short e_sp; /* Initial SP value, 0xb8 */
- unsigned short e_csum; /* Checksum, 0x0 */
- unsigned short e_ip; /* Initial IP value, 0x0 */
- unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
- unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
- unsigned short e_ovno; /* Overlay number, 0x0 */
- char e_res[4][2]; /* Reserved words, all 0x0 */
- unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
- unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
- char e_res2[10][2]; /* Reserved words, all 0x0 */
- unsigned long e_lfanew; /* File address of new exe header, 0x80 */
- char dos_message[16][4]; /* other stuff, always follow DOS header */
- unsigned int nt_signature; /* required NT signature, 0x4550 */
-
- /* From standard header */
-
- unsigned short f_magic; /* magic number */
- unsigned short f_nscns; /* number of sections */
- unsigned long f_timdat; /* time & date stamp */
- unsigned long f_symptr; /* file pointer to symtab */
- unsigned long f_nsyms; /* number of symtab entries */
- unsigned short f_opthdr; /* sizeof(optional hdr) */
- unsigned short f_flags; /* flags */
-};
-
-
-#define FILHDR struct external_PE_filehdr
-#undef FILHSZ
-#define FILHSZ 152
-
-#endif
-
-typedef struct
-{
- unsigned short magic; /* type of file */
- unsigned short vstamp; /* version stamp */
- unsigned long tsize; /* text size in bytes, padded to FW bdry*/
- unsigned long dsize; /* initialized data " " */
- unsigned long bsize; /* uninitialized data " " */
- unsigned long entry; /* entry pt. */
- unsigned long text_start; /* base of text used for this file */
- unsigned long data_start; /* base of all data used for this file */
-
- /* NT extra fields; see internal.h for descriptions */
- unsigned long ImageBase;
- unsigned long SectionAlignment;
- unsigned long FileAlignment;
- unsigned short MajorOperatingSystemVersion;
- unsigned short MinorOperatingSystemVersion;
- unsigned short MajorImageVersion;
- unsigned short MinorImageVersion;
- unsigned short MajorSubsystemVersion;
- unsigned short MinorSubsystemVersion;
- char Reserved1[4];
- unsigned long SizeOfImage;
- unsigned long SizeOfHeaders;
- unsigned long CheckSum;
- unsigned short Subsystem;
- unsigned short DllCharacteristics;
- unsigned long SizeOfStackReserve;
- unsigned long SizeOfStackCommit;
- unsigned long SizeOfHeapReserve;
- unsigned long SizeOfHeapCommit;
- unsigned long LoaderFlags;
- unsigned long NumberOfRvaAndSizes;
- /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
- char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
-
-} PEAOUTHDR;
-
-
-#undef AOUTSZ
-#define AOUTSZ (AOUTHDRSZ + 196)
-
-#undef E_FILNMLEN
-#define E_FILNMLEN 18 /* # characters in a file name */
-#endif
-
-/* end of coff/pe.h */
-
-#define DT_NON (0) /* no derived type */
-#define DT_PTR (1) /* pointer */
-#define DT_FCN (2) /* function */
-#define DT_ARY (3) /* array */
-
-#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
-#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
-#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _A_OUT_H_ */
-
diff --git a/tools/ioemu/aes.c b/tools/ioemu/aes.c
deleted file mode 100644
index e75b168a80..0000000000
--- a/tools/ioemu/aes.c
+++ /dev/null
@@ -1,1319 +0,0 @@
-/**
- *
- * aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project.
- */
-/*
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "vl.h"
-#include "aes.h"
-
-#define NDEBUG
-#include <assert.h>
-
-#ifndef CONFIG_STUBDOM
-typedef uint32_t u32;
-typedef uint16_t u16;
-typedef uint8_t u8;
-#endif
-
-#define MAXKC (256/32)
-#define MAXKB (256/8)
-#define MAXNR 14
-
-/* This controls loop-unrolling in aes_core.c */
-#undef FULL_UNROLL
-# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-
-/*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-static const u32 Te0[256] = {
- 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
- 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
- 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
- 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
- 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
- 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
- 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
- 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
- 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
- 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
- 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
- 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
- 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
- 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
- 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
- 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
- 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
- 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
- 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
- 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
- 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
- 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
- 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
- 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
- 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
- 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
- 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
- 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
- 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
- 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
- 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
- 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
- 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
- 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
- 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
- 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
- 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
- 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
- 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
- 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
- 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
- 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
- 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
- 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
- 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
- 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
- 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
- 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
- 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
- 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
- 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
- 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
- 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
- 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
- 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
- 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
- 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
- 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
- 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
- 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
- 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
- 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
- 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
- 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-static const u32 Te1[256] = {
- 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
- 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
- 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
- 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
- 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
- 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
- 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
- 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
- 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
- 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
- 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
- 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
- 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
- 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
- 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
- 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
- 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
- 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
- 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
- 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
- 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
- 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
- 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
- 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
- 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
- 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
- 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
- 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
- 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
- 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
- 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
- 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
- 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
- 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
- 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
- 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
- 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
- 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
- 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
- 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
- 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
- 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
- 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
- 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
- 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
- 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
- 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
- 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
- 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
- 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
- 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
- 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
- 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
- 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
- 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
- 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
- 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
- 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
- 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
- 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
- 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
- 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
- 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
- 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-static const u32 Te2[256] = {
- 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
- 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
- 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
- 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
- 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
- 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
- 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
- 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
- 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
- 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
- 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
- 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
- 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
- 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
- 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
- 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
- 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
- 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
- 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
- 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
- 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
- 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
- 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
- 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
- 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
- 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
- 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
- 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
- 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
- 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
- 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
- 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
- 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
- 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
- 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
- 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
- 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
- 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
- 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
- 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
- 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
- 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
- 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
- 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
- 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
- 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
- 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
- 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
- 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
- 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
- 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
- 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
- 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
- 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
- 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
- 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
- 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
- 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
- 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
- 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
- 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
- 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
- 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
- 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-static const u32 Te3[256] = {
-
- 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
- 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
- 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
- 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
- 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
- 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
- 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
- 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
- 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
- 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
- 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
- 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
- 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
- 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
- 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
- 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
- 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
- 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
- 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
- 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
- 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
- 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
- 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
- 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
- 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
- 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
- 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
- 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
- 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
- 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
- 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
- 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
- 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
- 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
- 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
- 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
- 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
- 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
- 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
- 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
- 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
- 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
- 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
- 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
- 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
- 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
- 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
- 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
- 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
- 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
- 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
- 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
- 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
- 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
- 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
- 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
- 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
- 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
- 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
- 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
- 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
- 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
- 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
- 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-static const u32 Te4[256] = {
- 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
- 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
- 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
- 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
- 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
- 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
- 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
- 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
- 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
- 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
- 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
- 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
- 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
- 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
- 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
- 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
- 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
- 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
- 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
- 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
- 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
- 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
- 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
- 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
- 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
- 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
- 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
- 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
- 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
- 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
- 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
- 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
- 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
- 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
- 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
- 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
- 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
- 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
- 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
- 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
- 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
- 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
- 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
- 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
- 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
- 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
- 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
- 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
- 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
- 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
- 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
- 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
- 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
- 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
- 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
- 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
- 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
- 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
- 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
- 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
- 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
- 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
- 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
- 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-};
-static const u32 Td0[256] = {
- 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
- 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
- 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
- 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
- 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
- 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
- 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
- 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
- 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
- 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
- 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
- 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
- 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
- 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
- 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
- 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
- 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
- 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
- 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
- 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
- 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
- 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
- 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
- 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
- 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
- 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
- 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
- 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
- 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
- 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
- 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
- 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
- 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
- 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
- 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
- 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
- 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
- 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
- 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
- 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
- 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
- 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
- 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
- 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
- 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
- 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
- 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
- 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
- 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
- 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
- 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
- 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
- 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
- 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
- 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
- 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
- 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
- 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
- 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
- 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
- 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
- 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
- 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
- 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-static const u32 Td1[256] = {
- 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
- 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
- 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
- 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
- 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
- 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
- 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
- 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
- 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
- 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
- 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
- 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
- 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
- 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
- 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
- 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
- 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
- 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
- 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
- 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
- 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
- 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
- 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
- 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
- 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
- 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
- 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
- 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
- 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
- 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
- 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
- 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
- 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
- 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
- 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
- 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
- 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
- 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
- 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
- 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
- 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
- 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
- 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
- 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
- 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
- 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
- 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
- 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
- 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
- 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
- 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
- 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
- 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
- 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
- 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
- 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
- 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
- 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
- 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
- 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
- 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
- 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
- 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
- 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-static const u32 Td2[256] = {
- 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
- 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
- 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
- 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
- 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
- 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
- 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
- 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
- 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
- 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
- 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
- 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
- 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
- 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
- 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
- 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
- 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
- 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
- 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
- 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
- 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
- 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
- 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
- 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
- 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
- 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
- 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
- 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
- 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
- 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
- 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
- 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
- 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
- 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
- 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
- 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
- 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
- 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
- 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
- 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
- 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
- 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
- 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
- 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
- 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
- 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
- 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
- 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
- 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
- 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
- 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
- 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
- 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
- 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
- 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
- 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
- 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
- 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
- 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
- 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
- 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
- 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
- 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
- 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-static const u32 Td3[256] = {
- 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
- 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
- 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
- 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
- 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
- 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
- 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
- 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
- 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
- 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
- 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
- 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
- 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
- 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
- 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
- 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
- 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
- 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
- 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
- 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
- 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
- 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
- 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
- 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
- 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
- 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
- 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
- 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
- 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
- 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
- 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
- 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
- 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
- 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
- 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
- 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
- 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
- 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
- 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
- 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
- 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
- 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
- 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
- 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
- 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
- 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
- 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
- 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
- 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
- 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
- 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
- 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
- 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
- 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
- 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
- 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
- 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
- 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
- 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
- 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
- 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
- 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
- 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
- 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-static const u32 Td4[256] = {
- 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
- 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
- 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
- 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
- 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
- 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
- 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
- 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
- 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
- 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
- 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
- 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
- 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
- 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
- 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
- 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
- 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
- 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
- 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
- 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
- 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
- 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
- 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
- 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
- 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
- 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
- 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
- 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
- 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
- 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
- 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
- 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
- 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
- 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
- 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
- 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
- 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
- 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
- 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
- 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
- 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
- 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
- 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
- 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
- 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
- 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
- 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
- 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
- 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
- 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
- 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
- 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
- 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
- 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
- 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
- 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
- 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
- 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
- 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
- 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
- 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
- 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
- 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
- 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-};
-static const u32 rcon[] = {
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-/**
- * Expand the cipher key into the encryption key schedule.
- */
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i = 0;
- u32 temp;
-
- if (!userKey || !key)
- return -1;
- if (bits != 128 && bits != 192 && bits != 256)
- return -2;
-
- rk = key->rd_key;
-
- if (bits==128)
- key->rounds = 10;
- else if (bits==192)
- key->rounds = 12;
- else
- key->rounds = 14;
-
- rk[0] = GETU32(userKey );
- rk[1] = GETU32(userKey + 4);
- rk[2] = GETU32(userKey + 8);
- rk[3] = GETU32(userKey + 12);
- if (bits == 128) {
- while (1) {
- temp = rk[3];
- rk[4] = rk[0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10) {
- return 0;
- }
- rk += 4;
- }
- }
- rk[4] = GETU32(userKey + 16);
- rk[5] = GETU32(userKey + 20);
- if (bits == 192) {
- while (1) {
- temp = rk[ 5];
- rk[ 6] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8) {
- return 0;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETU32(userKey + 24);
- rk[7] = GETU32(userKey + 28);
- if (bits == 256) {
- while (1) {
- temp = rk[ 7];
- rk[ 8] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7) {
- return 0;
- }
- temp = rk[11];
- rk[12] = rk[ 4] ^
- (Te4[(temp >> 24) ] & 0xff000000) ^
- (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(temp ) & 0xff] & 0x000000ff);
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
-
- rk += 8;
- }
- }
- return 0;
-}
-
-/**
- * Expand the cipher key into the decryption key schedule.
- */
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i, j, status;
- u32 temp;
-
- /* first, start with an encryption schedule */
- status = AES_set_encrypt_key(userKey, bits, key);
- if (status < 0)
- return status;
-
- rk = key->rd_key;
-
- /* invert the order of the round keys: */
- for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
- temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
- temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
- temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
- temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
- }
- /* apply the inverse MixColumn transform to all round keys but the first and the last: */
- for (i = 1; i < (key->rounds); i++) {
- rk += 4;
- rk[0] =
- Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[0] ) & 0xff] & 0xff];
- rk[1] =
- Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[1] ) & 0xff] & 0xff];
- rk[2] =
- Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[2] ) & 0xff] & 0xff];
- rk[3] =
- Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[3] ) & 0xff] & 0xff];
- }
- return 0;
-}
-
-#ifndef AES_ASM
-/*
- * Encrypt a single block
- * in and out can overlap
- */
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- Te0[(s0 >> 24) ] ^
- Te1[(s1 >> 16) & 0xff] ^
- Te2[(s2 >> 8) & 0xff] ^
- Te3[(s3 ) & 0xff] ^
- rk[4];
- t1 =
- Te0[(s1 >> 24) ] ^
- Te1[(s2 >> 16) & 0xff] ^
- Te2[(s3 >> 8) & 0xff] ^
- Te3[(s0 ) & 0xff] ^
- rk[5];
- t2 =
- Te0[(s2 >> 24) ] ^
- Te1[(s3 >> 16) & 0xff] ^
- Te2[(s0 >> 8) & 0xff] ^
- Te3[(s1 ) & 0xff] ^
- rk[6];
- t3 =
- Te0[(s3 >> 24) ] ^
- Te1[(s0 >> 16) & 0xff] ^
- Te2[(s1 >> 8) & 0xff] ^
- Te3[(s2 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Te0[(t0 >> 24) ] ^
- Te1[(t1 >> 16) & 0xff] ^
- Te2[(t2 >> 8) & 0xff] ^
- Te3[(t3 ) & 0xff] ^
- rk[0];
- s1 =
- Te0[(t1 >> 24) ] ^
- Te1[(t2 >> 16) & 0xff] ^
- Te2[(t3 >> 8) & 0xff] ^
- Te3[(t0 ) & 0xff] ^
- rk[1];
- s2 =
- Te0[(t2 >> 24) ] ^
- Te1[(t3 >> 16) & 0xff] ^
- Te2[(t0 >> 8) & 0xff] ^
- Te3[(t1 ) & 0xff] ^
- rk[2];
- s3 =
- Te0[(t3 >> 24) ] ^
- Te1[(t0 >> 16) & 0xff] ^
- Te2[(t1 >> 8) & 0xff] ^
- Te3[(t2 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Te4[(t0 >> 24) ] & 0xff000000) ^
- (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (Te4[(t1 >> 24) ] & 0xff000000) ^
- (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (Te4[(t2 >> 24) ] & 0xff000000) ^
- (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (Te4[(t3 >> 24) ] & 0xff000000) ^
- (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-/*
- * Decrypt a single block
- * in and out can overlap
- */
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- Td0[(s0 >> 24) ] ^
- Td1[(s3 >> 16) & 0xff] ^
- Td2[(s2 >> 8) & 0xff] ^
- Td3[(s1 ) & 0xff] ^
- rk[4];
- t1 =
- Td0[(s1 >> 24) ] ^
- Td1[(s0 >> 16) & 0xff] ^
- Td2[(s3 >> 8) & 0xff] ^
- Td3[(s2 ) & 0xff] ^
- rk[5];
- t2 =
- Td0[(s2 >> 24) ] ^
- Td1[(s1 >> 16) & 0xff] ^
- Td2[(s0 >> 8) & 0xff] ^
- Td3[(s3 ) & 0xff] ^
- rk[6];
- t3 =
- Td0[(s3 >> 24) ] ^
- Td1[(s2 >> 16) & 0xff] ^
- Td2[(s1 >> 8) & 0xff] ^
- Td3[(s0 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Td0[(t0 >> 24) ] ^
- Td1[(t3 >> 16) & 0xff] ^
- Td2[(t2 >> 8) & 0xff] ^
- Td3[(t1 ) & 0xff] ^
- rk[0];
- s1 =
- Td0[(t1 >> 24) ] ^
- Td1[(t0 >> 16) & 0xff] ^
- Td2[(t3 >> 8) & 0xff] ^
- Td3[(t2 ) & 0xff] ^
- rk[1];
- s2 =
- Td0[(t2 >> 24) ] ^
- Td1[(t1 >> 16) & 0xff] ^
- Td2[(t0 >> 8) & 0xff] ^
- Td3[(t3 ) & 0xff] ^
- rk[2];
- s3 =
- Td0[(t3 >> 24) ] ^
- Td1[(t2 >> 16) & 0xff] ^
- Td2[(t1 >> 8) & 0xff] ^
- Td3[(t0 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Td4[(t0 >> 24) ] & 0xff000000) ^
- (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (Td4[(t1 >> 24) ] & 0xff000000) ^
- (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (Td4[(t2 >> 24) ] & 0xff000000) ^
- (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (Td4[(t3 >> 24) ] & 0xff000000) ^
- (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-#endif /* AES_ASM */
-
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc)
-{
-
- unsigned long n;
- unsigned long len = length;
- unsigned char tmp[AES_BLOCK_SIZE];
-
- assert(in && out && key && ivec);
-
- if (enc) {
- while (len >= AES_BLOCK_SIZE) {
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = in[n] ^ ivec[n];
- AES_encrypt(tmp, out, key);
- memcpy(ivec, out, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- for(n=0; n < len; ++n)
- tmp[n] = in[n] ^ ivec[n];
- for(n=len; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = ivec[n];
- AES_encrypt(tmp, tmp, key);
- memcpy(out, tmp, AES_BLOCK_SIZE);
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- } else {
- while (len >= AES_BLOCK_SIZE) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(in, out, key);
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- out[n] ^= ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(tmp, tmp, key);
- for(n=0; n < len; ++n)
- out[n] = tmp[n] ^ ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- }
-}
diff --git a/tools/ioemu/aes.h b/tools/ioemu/aes.h
deleted file mode 100644
index a0167eb7d5..0000000000
--- a/tools/ioemu/aes.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef QEMU_AES_H
-#define QEMU_AES_H
-
-#define AES_MAXNR 14
-#define AES_BLOCK_SIZE 16
-
-struct aes_key_st {
- uint32_t rd_key[4 *(AES_MAXNR + 1)];
- int rounds;
-};
-typedef struct aes_key_st AES_KEY;
-
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc);
-
-#endif
diff --git a/tools/ioemu/audio/.CVS/Entries b/tools/ioemu/audio/.CVS/Entries
deleted file mode 100644
index 5f39d877d6..0000000000
--- a/tools/ioemu/audio/.CVS/Entries
+++ /dev/null
@@ -1,20 +0,0 @@
-/alsaaudio.c/1.7/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/audio.c/1.15/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/audio.h/1.8/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/audio_int.h/1.10/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/audio_template.h/1.8/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/coreaudio.c/1.7/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/dsound_template.h/1.4/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/dsoundaudio.c/1.3/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/fmodaudio.c/1.7/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/mixeng.c/1.4/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/mixeng.h/1.2/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/mixeng_template.h/1.2/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/noaudio.c/1.7/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/ossaudio.c/1.11/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/rate_template.h/1.3/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/sdlaudio.c/1.8/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/sys-queue.h/1.1/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/wavaudio.c/1.9/Thu May 3 17:17:59 2007//Trelease_0_9_0
-/wavcapture.c/1.7/Thu May 3 17:17:59 2007//Trelease_0_9_0
-D
diff --git a/tools/ioemu/audio/.CVS/Repository b/tools/ioemu/audio/.CVS/Repository
deleted file mode 100644
index 582b845b1e..0000000000
--- a/tools/ioemu/audio/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu/audio
diff --git a/tools/ioemu/audio/.CVS/Root b/tools/ioemu/audio/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/audio/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/audio/.CVS/Tag b/tools/ioemu/audio/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/audio/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/audio/alsaaudio.c b/tools/ioemu/audio/alsaaudio.c
deleted file mode 100644
index 71e5235664..0000000000
--- a/tools/ioemu/audio/alsaaudio.c
+++ /dev/null
@@ -1,974 +0,0 @@
-/*
- * QEMU ALSA audio driver
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <alsa/asoundlib.h>
-#include "vl.h"
-
-#define AUDIO_CAP "alsa"
-#include "audio_int.h"
-
-typedef struct ALSAVoiceOut {
- HWVoiceOut hw;
- void *pcm_buf;
- snd_pcm_t *handle;
-} ALSAVoiceOut;
-
-typedef struct ALSAVoiceIn {
- HWVoiceIn hw;
- snd_pcm_t *handle;
- void *pcm_buf;
-} ALSAVoiceIn;
-
-static struct {
- int size_in_usec_in;
- int size_in_usec_out;
- const char *pcm_name_in;
- const char *pcm_name_out;
- unsigned int buffer_size_in;
- unsigned int period_size_in;
- unsigned int buffer_size_out;
- unsigned int period_size_out;
- unsigned int threshold;
-
- int buffer_size_in_overriden;
- int period_size_in_overriden;
-
- int buffer_size_out_overriden;
- int period_size_out_overriden;
- int verbose;
-} conf = {
-#ifdef HIGH_LATENCY
- .size_in_usec_in = 1,
- .size_in_usec_out = 1,
-#endif
- .pcm_name_out = "default",
- .pcm_name_in = "default",
-#ifdef HIGH_LATENCY
- .buffer_size_in = 400000,
- .period_size_in = 400000 / 4,
- .buffer_size_out = 400000,
- .period_size_out = 400000 / 4,
-#else
-#define DEFAULT_BUFFER_SIZE 1024
-#define DEFAULT_PERIOD_SIZE 256
- .buffer_size_in = DEFAULT_BUFFER_SIZE * 4,
- .period_size_in = DEFAULT_PERIOD_SIZE * 4,
- .buffer_size_out = DEFAULT_BUFFER_SIZE,
- .period_size_out = DEFAULT_PERIOD_SIZE,
- .buffer_size_in_overriden = 0,
- .buffer_size_out_overriden = 0,
- .period_size_in_overriden = 0,
- .period_size_out_overriden = 0,
-#endif
- .threshold = 0,
- .verbose = 0
-};
-
-struct alsa_params_req {
- int freq;
- audfmt_e fmt;
- int nchannels;
- unsigned int buffer_size;
- unsigned int period_size;
-};
-
-struct alsa_params_obt {
- int freq;
- audfmt_e fmt;
- int nchannels;
- snd_pcm_uframes_t samples;
-};
-
-static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
-}
-
-static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
- int err,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
-}
-
-static void alsa_anal_close (snd_pcm_t **handlep)
-{
- int err = snd_pcm_close (*handlep);
- if (err) {
- alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
- }
- *handlep = NULL;
-}
-
-static int alsa_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int aud_to_alsafmt (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_S8:
- return SND_PCM_FORMAT_S8;
-
- case AUD_FMT_U8:
- return SND_PCM_FORMAT_U8;
-
- case AUD_FMT_S16:
- return SND_PCM_FORMAT_S16_LE;
-
- case AUD_FMT_U16:
- return SND_PCM_FORMAT_U16_LE;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_AUDIO
- abort ();
-#endif
- return SND_PCM_FORMAT_U8;
- }
-}
-
-static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness)
-{
- switch (alsafmt) {
- case SND_PCM_FORMAT_S8:
- *endianness = 0;
- *fmt = AUD_FMT_S8;
- break;
-
- case SND_PCM_FORMAT_U8:
- *endianness = 0;
- *fmt = AUD_FMT_U8;
- break;
-
- case SND_PCM_FORMAT_S16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_S16;
- break;
-
- case SND_PCM_FORMAT_U16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_U16;
- break;
-
- case SND_PCM_FORMAT_S16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_S16;
- break;
-
- case SND_PCM_FORMAT_U16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_U16;
- break;
-
- default:
- dolog ("Unrecognized audio format %d\n", alsafmt);
- return -1;
- }
-
- return 0;
-}
-
-#if defined DEBUG_MISMATCHES || defined DEBUG
-static void alsa_dump_info (struct alsa_params_req *req,
- struct alsa_params_obt *obt)
-{
- dolog ("parameter | requested value | obtained value\n");
- dolog ("format | %10d | %10d\n", req->fmt, obt->fmt);
- dolog ("channels | %10d | %10d\n",
- req->nchannels, obt->nchannels);
- dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
- dolog ("============================================\n");
- dolog ("requested: buffer size %d period size %d\n",
- req->buffer_size, req->period_size);
- dolog ("obtained: samples %ld\n", obt->samples);
-}
-#endif
-
-static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
-{
- int err;
- snd_pcm_sw_params_t *sw_params;
-
- snd_pcm_sw_params_alloca (&sw_params);
-
- err = snd_pcm_sw_params_current (handle, sw_params);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to get current software parameters\n");
- return;
- }
-
- err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to set software threshold to %ld\n",
- threshold);
- return;
- }
-
- err = snd_pcm_sw_params (handle, sw_params);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to set software parameters\n");
- return;
- }
-}
-
-static int alsa_open (int in, struct alsa_params_req *req,
- struct alsa_params_obt *obt, snd_pcm_t **handlep)
-{
- snd_pcm_t *handle;
- snd_pcm_hw_params_t *hw_params;
- int err, freq, nchannels;
- const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
- unsigned int period_size, buffer_size;
- snd_pcm_uframes_t obt_buffer_size;
- const char *typ = in ? "ADC" : "DAC";
-
- freq = req->freq;
- period_size = req->period_size;
- buffer_size = req->buffer_size;
- nchannels = req->nchannels;
-
- snd_pcm_hw_params_alloca (&hw_params);
-
- err = snd_pcm_open (
- &handle,
- pcm_name,
- in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
- SND_PCM_NONBLOCK
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
- return -1;
- }
-
- err = snd_pcm_hw_params_any (handle, hw_params);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
- goto err;
- }
-
- err = snd_pcm_hw_params_set_access (
- handle,
- hw_params,
- SND_PCM_ACCESS_RW_INTERLEAVED
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set access type\n");
- goto err;
- }
-
- err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
- goto err;
- }
-
- err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
- goto err;
- }
-
- err = snd_pcm_hw_params_set_channels_near (
- handle,
- hw_params,
- &nchannels
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
- req->nchannels);
- goto err;
- }
-
- if (nchannels != 1 && nchannels != 2) {
- alsa_logerr2 (err, typ,
- "Can not handle obtained number of channels %d\n",
- nchannels);
- goto err;
- }
-
- if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) {
- if (!buffer_size) {
- buffer_size = DEFAULT_BUFFER_SIZE;
- period_size= DEFAULT_PERIOD_SIZE;
- }
- }
-
- if (buffer_size) {
- if ((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out)) {
- if (period_size) {
- err = snd_pcm_hw_params_set_period_time_near (
- handle,
- hw_params,
- &period_size,
- 0
- );
- if (err < 0) {
- alsa_logerr2 (err, typ,
- "Failed to set period time %d\n",
- req->period_size);
- goto err;
- }
- }
-
- err = snd_pcm_hw_params_set_buffer_time_near (
- handle,
- hw_params,
- &buffer_size,
- 0
- );
-
- if (err < 0) {
- alsa_logerr2 (err, typ,
- "Failed to set buffer time %d\n",
- req->buffer_size);
- goto err;
- }
- }
- else {
- int dir;
- snd_pcm_uframes_t minval;
-
- if (period_size) {
- minval = period_size;
- dir = 0;
-
- err = snd_pcm_hw_params_get_period_size_min (
- hw_params,
- &minval,
- &dir
- );
- if (err < 0) {
- alsa_logerr (
- err,
- "Could not get minmal period size for %s\n",
- typ
- );
- }
- else {
- if (period_size < minval) {
- if ((in && conf.period_size_in_overriden)
- || (!in && conf.period_size_out_overriden)) {
- dolog ("%s period size(%d) is less "
- "than minmal period size(%ld)\n",
- typ,
- period_size,
- minval);
- }
- period_size = minval;
- }
- }
-
- err = snd_pcm_hw_params_set_period_size (
- handle,
- hw_params,
- period_size,
- 0
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set period size %d\n",
- req->period_size);
- goto err;
- }
- }
-
- minval = buffer_size;
- err = snd_pcm_hw_params_get_buffer_size_min (
- hw_params,
- &minval
- );
- if (err < 0) {
- alsa_logerr (err, "Could not get minmal buffer size for %s\n",
- typ);
- }
- else {
- if (buffer_size < minval) {
- if ((in && conf.buffer_size_in_overriden)
- || (!in && conf.buffer_size_out_overriden)) {
- dolog (
- "%s buffer size(%d) is less "
- "than minimal buffer size(%ld)\n",
- typ,
- buffer_size,
- minval
- );
- }
- buffer_size = minval;
- }
- }
-
- err = snd_pcm_hw_params_set_buffer_size (
- handle,
- hw_params,
- buffer_size
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set buffer size %d\n",
- req->buffer_size);
- goto err;
- }
- }
- }
- else {
- dolog ("warning: Buffer size is not set\n");
- }
-
- err = snd_pcm_hw_params (handle, hw_params);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
- goto err;
- }
-
- err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to get buffer size\n");
- goto err;
- }
-
- err = snd_pcm_prepare (handle);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
- goto err;
- }
-
- if (!in && conf.threshold) {
- snd_pcm_uframes_t threshold;
- int bytes_per_sec;
-
- bytes_per_sec = freq
- << (nchannels == 2)
- << (req->fmt == AUD_FMT_S16 || req->fmt == AUD_FMT_U16);
-
- threshold = (conf.threshold * bytes_per_sec) / 1000;
- alsa_set_threshold (handle, threshold);
- }
-
- obt->fmt = req->fmt;
- obt->nchannels = nchannels;
- obt->freq = freq;
- obt->samples = obt_buffer_size;
- *handlep = handle;
-
-#if defined DEBUG_MISMATCHES || defined DEBUG
- if (obt->fmt != req->fmt ||
- obt->nchannels != req->nchannels ||
- obt->freq != req->freq) {
- dolog ("Audio paramters mismatch for %s\n", typ);
- alsa_dump_info (req, obt);
- }
-#endif
-
-#ifdef DEBUG
- alsa_dump_info (req, obt);
-#endif
- return 0;
-
- err:
- alsa_anal_close (&handle);
- return -1;
-}
-
-static int alsa_recover (snd_pcm_t *handle)
-{
- int err = snd_pcm_prepare (handle);
- if (err < 0) {
- alsa_logerr (err, "Failed to prepare handle %p\n", handle);
- return -1;
- }
- return 0;
-}
-
-static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
-{
- snd_pcm_sframes_t avail;
-
- avail = snd_pcm_avail_update (handle);
- if (avail < 0) {
- if (avail == -EPIPE) {
- if (!alsa_recover (handle)) {
- avail = snd_pcm_avail_update (handle);
- }
- }
-
- if (avail < 0) {
- alsa_logerr (avail,
- "Could not obtain number of available frames\n");
- return -1;
- }
- }
-
- return avail;
-}
-
-static int alsa_run_out (HWVoiceOut *hw)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
- int rpos, live, decr;
- int samples;
- uint8_t *dst;
- st_sample_t *src;
- snd_pcm_sframes_t avail;
-
- live = audio_pcm_hw_get_live_out (hw);
- if (!live) {
- return 0;
- }
-
- avail = alsa_get_avail (alsa->handle);
- if (avail < 0) {
- dolog ("Could not get number of available playback frames\n");
- return 0;
- }
-
- decr = audio_MIN (live, avail);
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int len = audio_MIN (samples, left_till_end_samples);
- snd_pcm_sframes_t written;
-
- src = hw->mix_buf + rpos;
- dst = advance (alsa->pcm_buf, rpos << hw->info.shift);
-
- hw->clip (dst, src, len);
-
- while (len) {
- written = snd_pcm_writei (alsa->handle, dst, len);
-
- if (written <= 0) {
- switch (written) {
- case 0:
- if (conf.verbose) {
- dolog ("Failed to write %d frames (wrote zero)\n", len);
- }
- goto exit;
-
- case -EPIPE:
- if (alsa_recover (alsa->handle)) {
- alsa_logerr (written, "Failed to write %d frames\n",
- len);
- goto exit;
- }
- if (conf.verbose) {
- dolog ("Recovering from playback xrun\n");
- }
- continue;
-
- case -EAGAIN:
- goto exit;
-
- default:
- alsa_logerr (written, "Failed to write %d frames to %p\n",
- len, dst);
- goto exit;
- }
- }
-
- rpos = (rpos + written) % hw->samples;
- samples -= written;
- len -= written;
- dst = advance (dst, written << hw->info.shift);
- src += written;
- }
- }
-
- exit:
- hw->rpos = rpos;
- return decr;
-}
-
-static void alsa_fini_out (HWVoiceOut *hw)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
-
- ldebug ("alsa_fini\n");
- alsa_anal_close (&alsa->handle);
-
- if (alsa->pcm_buf) {
- qemu_free (alsa->pcm_buf);
- alsa->pcm_buf = NULL;
- }
-}
-
-static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
- struct alsa_params_req req;
- struct alsa_params_obt obt;
- audfmt_e effective_fmt;
- int endianness;
- int err;
- snd_pcm_t *handle;
- audsettings_t obt_as;
-
- req.fmt = aud_to_alsafmt (as->fmt);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.period_size = conf.period_size_out;
- req.buffer_size = conf.buffer_size_out;
-
- if (alsa_open (0, &req, &obt, &handle)) {
- return -1;
- }
-
- err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness);
- if (err) {
- alsa_anal_close (&handle);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
- if (!alsa->pcm_buf) {
- dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- alsa_anal_close (&handle);
- return -1;
- }
-
- alsa->handle = handle;
- return 0;
-}
-
-static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
-{
- int err;
-
- if (pause) {
- err = snd_pcm_drop (handle);
- if (err < 0) {
- alsa_logerr (err, "Could not stop %s\n", typ);
- return -1;
- }
- }
- else {
- err = snd_pcm_prepare (handle);
- if (err < 0) {
- alsa_logerr (err, "Could not prepare handle for %s\n", typ);
- return -1;
- }
- }
-
- return 0;
-}
-
-static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- ldebug ("enabling voice\n");
- return alsa_voice_ctl (alsa->handle, "playback", 0);
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- return alsa_voice_ctl (alsa->handle, "playback", 1);
- }
-
- return -1;
-}
-
-static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
- struct alsa_params_req req;
- struct alsa_params_obt obt;
- int endianness;
- int err;
- audfmt_e effective_fmt;
- snd_pcm_t *handle;
- audsettings_t obt_as;
-
- req.fmt = aud_to_alsafmt (as->fmt);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.period_size = conf.period_size_in;
- req.buffer_size = conf.buffer_size_in;
-
- if (alsa_open (1, &req, &obt, &handle)) {
- return -1;
- }
-
- err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness);
- if (err) {
- alsa_anal_close (&handle);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!alsa->pcm_buf) {
- dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- alsa_anal_close (&handle);
- return -1;
- }
-
- alsa->handle = handle;
- return 0;
-}
-
-static void alsa_fini_in (HWVoiceIn *hw)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
-
- alsa_anal_close (&alsa->handle);
-
- if (alsa->pcm_buf) {
- qemu_free (alsa->pcm_buf);
- alsa->pcm_buf = NULL;
- }
-}
-
-static int alsa_run_in (HWVoiceIn *hw)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
- int hwshift = hw->info.shift;
- int i;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- int decr;
- struct {
- int add;
- int len;
- } bufs[2] = {
- { hw->wpos, 0 },
- { 0, 0 }
- };
- snd_pcm_sframes_t avail;
- snd_pcm_uframes_t read_samples = 0;
-
- if (!dead) {
- return 0;
- }
-
- avail = alsa_get_avail (alsa->handle);
- if (avail < 0) {
- dolog ("Could not get number of captured frames\n");
- return 0;
- }
-
- if (!avail && (snd_pcm_state (alsa->handle) == SND_PCM_STATE_PREPARED)) {
- avail = hw->samples;
- }
-
- decr = audio_MIN (dead, avail);
- if (!decr) {
- return 0;
- }
-
- if (hw->wpos + decr > hw->samples) {
- bufs[0].len = (hw->samples - hw->wpos);
- bufs[1].len = (decr - (hw->samples - hw->wpos));
- }
- else {
- bufs[0].len = decr;
- }
-
- for (i = 0; i < 2; ++i) {
- void *src;
- st_sample_t *dst;
- snd_pcm_sframes_t nread;
- snd_pcm_uframes_t len;
-
- len = bufs[i].len;
-
- src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
- dst = hw->conv_buf + bufs[i].add;
-
- while (len) {
- nread = snd_pcm_readi (alsa->handle, src, len);
-
- if (nread <= 0) {
- switch (nread) {
- case 0:
- if (conf.verbose) {
- dolog ("Failed to read %ld frames (read zero)\n", len);
- }
- goto exit;
-
- case -EPIPE:
- if (alsa_recover (alsa->handle)) {
- alsa_logerr (nread, "Failed to read %ld frames\n", len);
- goto exit;
- }
- if (conf.verbose) {
- dolog ("Recovering from capture xrun\n");
- }
- continue;
-
- case -EAGAIN:
- goto exit;
-
- default:
- alsa_logerr (
- nread,
- "Failed to read %ld frames from %p\n",
- len,
- src
- );
- goto exit;
- }
- }
-
- hw->conv (dst, src, nread, &nominal_volume);
-
- src = advance (src, nread << hwshift);
- dst += nread;
-
- read_samples += nread;
- len -= nread;
- }
- }
-
- exit:
- hw->wpos = (hw->wpos + read_samples) % hw->samples;
- return read_samples;
-}
-
-static int alsa_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- ldebug ("enabling voice\n");
- return alsa_voice_ctl (alsa->handle, "capture", 0);
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- return alsa_voice_ctl (alsa->handle, "capture", 1);
- }
-
- return -1;
-}
-
-static void *alsa_audio_init (void)
-{
- return &conf;
-}
-
-static void alsa_audio_fini (void *opaque)
-{
- (void) opaque;
-}
-
-static struct audio_option alsa_options[] = {
- {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out,
- "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
- {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out,
- "DAC period size", &conf.period_size_out_overriden, 0},
- {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out,
- "DAC buffer size", &conf.buffer_size_out_overriden, 0},
-
- {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in,
- "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
- {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in,
- "ADC period size", &conf.period_size_in_overriden, 0},
- {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in,
- "ADC buffer size", &conf.buffer_size_in_overriden, 0},
-
- {"THRESHOLD", AUD_OPT_INT, &conf.threshold,
- "(undocumented)", NULL, 0},
-
- {"DAC_DEV", AUD_OPT_STR, &conf.pcm_name_out,
- "DAC device name (for instance dmix)", NULL, 0},
-
- {"ADC_DEV", AUD_OPT_STR, &conf.pcm_name_in,
- "ADC device name", NULL, 0},
-
- {"VERBOSE", AUD_OPT_BOOL, &conf.verbose,
- "Behave in a more verbose way", NULL, 0},
-
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops alsa_pcm_ops = {
- alsa_init_out,
- alsa_fini_out,
- alsa_run_out,
- alsa_write,
- alsa_ctl_out,
-
- alsa_init_in,
- alsa_fini_in,
- alsa_run_in,
- alsa_read,
- alsa_ctl_in
-};
-
-struct audio_driver alsa_audio_driver = {
- INIT_FIELD (name = ) "alsa",
- INIT_FIELD (descr = ) "ALSA http://www.alsa-project.org",
- INIT_FIELD (options = ) alsa_options,
- INIT_FIELD (init = ) alsa_audio_init,
- INIT_FIELD (fini = ) alsa_audio_fini,
- INIT_FIELD (pcm_ops = ) &alsa_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) INT_MAX,
- INIT_FIELD (voice_size_out = ) sizeof (ALSAVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (ALSAVoiceIn)
-};
diff --git a/tools/ioemu/audio/audio.c b/tools/ioemu/audio/audio.c
deleted file mode 100644
index 65e1de8118..0000000000
--- a/tools/ioemu/audio/audio.c
+++ /dev/null
@@ -1,1871 +0,0 @@
-/*
- * QEMU Audio subsystem
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define AUDIO_CAP "audio"
-#include "audio_int.h"
-
-/* #define DEBUG_PLIVE */
-/* #define DEBUG_LIVE */
-/* #define DEBUG_OUT */
-/* #define DEBUG_CAPTURE */
-
-#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
-
-static struct audio_driver *drvtab[] = {
-#ifdef CONFIG_OSS
- &oss_audio_driver,
-#endif
-#ifdef CONFIG_ALSA
- &alsa_audio_driver,
-#endif
-#ifdef CONFIG_COREAUDIO
- &coreaudio_audio_driver,
-#endif
-#ifdef CONFIG_DSOUND
- &dsound_audio_driver,
-#endif
-#ifdef CONFIG_FMOD
- &fmod_audio_driver,
-#endif
-#ifdef CONFIG_SDL
- &sdl_audio_driver,
-#endif
- &no_audio_driver,
- &wav_audio_driver
-};
-
-struct fixed_settings {
- int enabled;
- int nb_voices;
- int greedy;
- audsettings_t settings;
-};
-
-static struct {
- struct fixed_settings fixed_out;
- struct fixed_settings fixed_in;
- union {
- int hz;
- int64_t ticks;
- } period;
- int plive;
- int log_to_monitor;
-} conf = {
- { /* DAC fixed settings */
- 1, /* enabled */
- 1, /* nb_voices */
- 1, /* greedy */
- {
- 44100, /* freq */
- 2, /* nchannels */
- AUD_FMT_S16 /* fmt */
- }
- },
-
- { /* ADC fixed settings */
- 1, /* enabled */
- 1, /* nb_voices */
- 1, /* greedy */
- {
- 44100, /* freq */
- 2, /* nchannels */
- AUD_FMT_S16 /* fmt */
- }
- },
-
- { 0 }, /* period */
- 0, /* plive */
- 0 /* log_to_monitor */
-};
-
-static AudioState glob_audio_state;
-
-volume_t nominal_volume = {
- 0,
-#ifdef FLOAT_MIXENG
- 1.0,
- 1.0
-#else
- UINT_MAX,
- UINT_MAX
-#endif
-};
-
-/* http://www.df.lth.se/~john_e/gems/gem002d.html */
-/* http://www.multi-platforms.com/Tips/PopCount.htm */
-uint32_t popcount (uint32_t u)
-{
- u = ((u&0x55555555) + ((u>>1)&0x55555555));
- u = ((u&0x33333333) + ((u>>2)&0x33333333));
- u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
- u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
- u = ( u&0x0000ffff) + (u>>16);
- return u;
-}
-
-inline uint32_t lsbindex (uint32_t u)
-{
- return popcount ((u&-u)-1);
-}
-
-#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
-#error No its not
-#else
-int audio_bug (const char *funcname, int cond)
-{
- if (cond) {
- static int shown;
-
- AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
- if (!shown) {
- shown = 1;
- AUD_log (NULL, "Save all your work and restart without audio\n");
- AUD_log (NULL, "Please send bug report to malc@pulsesoft.com\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 ((uint8_t)u[i]);
- }
- }
- return r;
-}
-
-const char *audio_audfmt_to_string (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_U8:
- return "U8";
-
- case AUD_FMT_U16:
- return "U16";
-
- case AUD_FMT_S8:
- return "S8";
-
- case AUD_FMT_S16:
- return "S16";
- }
-
- dolog ("Bogus audfmt %d returning S16\n", fmt);
- return "S16";
-}
-
-audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp)
-{
- if (!strcasecmp (s, "u8")) {
- *defaultp = 0;
- return AUD_FMT_U8;
- }
- else if (!strcasecmp (s, "u16")) {
- *defaultp = 0;
- return AUD_FMT_U16;
- }
- else if (!strcasecmp (s, "s8")) {
- *defaultp = 0;
- return AUD_FMT_S8;
- }
- else if (!strcasecmp (s, "s16")) {
- *defaultp = 0;
- return AUD_FMT_S16;
- }
- else {
- dolog ("Bogus audio format `%s' using %s\n",
- s, audio_audfmt_to_string (defval));
- *defaultp = 1;
- return defval;
- }
-}
-
-static audfmt_e audio_get_conf_fmt (const char *envname,
- audfmt_e defval,
- int *defaultp)
-{
- const char *var = getenv (envname);
- if (!var) {
- *defaultp = 1;
- return defval;
- }
- return audio_string_to_audfmt (var, defval, defaultp);
-}
-
-static int audio_get_conf_int (const char *key, int defval, int *defaultp)
-{
- int val;
- char *strval;
-
- strval = getenv (key);
- if (strval) {
- *defaultp = 0;
- val = atoi (strval);
- return val;
- }
- else {
- *defaultp = 1;
- return defval;
- }
-}
-
-static const char *audio_get_conf_str (const char *key,
- const char *defval,
- int *defaultp)
-{
- const char *val = getenv (key);
- if (!val) {
- *defaultp = 1;
- return defval;
- }
- else {
- *defaultp = 0;
- return val;
- }
-}
-
-void AUD_vlog (const char *cap, const char *fmt, va_list ap)
-{
- if (conf.log_to_monitor) {
- if (cap) {
- term_printf ("%s: ", cap);
- }
-
- term_vprintf (fmt, ap);
- }
- else {
- if (cap) {
- fprintf (stderr, "%s: ", cap);
- }
-
- vfprintf (stderr, fmt, ap);
- }
-}
-
-void AUD_log (const char *cap, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (cap, fmt, ap);
- va_end (ap);
-}
-
-static void audio_print_options (const char *prefix,
- struct audio_option *opt)
-{
- char *uprefix;
-
- if (!prefix) {
- dolog ("No prefix specified\n");
- return;
- }
-
- if (!opt) {
- dolog ("No options\n");
- return;
- }
-
- uprefix = audio_alloc_prefix (prefix);
-
- for (; opt->name; opt++) {
- const char *state = "default";
- printf (" %s_%s: ", uprefix, opt->name);
-
- if (opt->overridenp && *opt->overridenp) {
- state = "current";
- }
-
- switch (opt->tag) {
- case AUD_OPT_BOOL:
- {
- int *intp = opt->valp;
- printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
- }
- break;
-
- case AUD_OPT_INT:
- {
- int *intp = opt->valp;
- printf ("integer, %s = %d\n", state, *intp);
- }
- break;
-
- case AUD_OPT_FMT:
- {
- audfmt_e *fmtp = opt->valp;
- printf (
- "format, %s = %s, (one of: U8 S8 U16 S16)\n",
- state,
- audio_audfmt_to_string (*fmtp)
- );
- }
- break;
-
- case AUD_OPT_STR:
- {
- const char **strp = opt->valp;
- printf ("string, %s = %s\n",
- state,
- *strp ? *strp : "(not set)");
- }
- break;
-
- default:
- printf ("???\n");
- dolog ("Bad value tag for option %s_%s %d\n",
- uprefix, opt->name, opt->tag);
- break;
- }
- printf (" %s\n", opt->descr);
- }
-
- qemu_free (uprefix);
-}
-
-static void audio_process_options (const char *prefix,
- struct audio_option *opt)
-{
- char *optname;
- const char qemu_prefix[] = "QEMU_";
- size_t preflen;
-
- if (audio_bug (AUDIO_FUNC, !prefix)) {
- dolog ("prefix = NULL\n");
- return;
- }
-
- if (audio_bug (AUDIO_FUNC, !opt)) {
- dolog ("opt = NULL\n");
- return;
- }
-
- preflen = strlen (prefix);
-
- for (; opt->name; opt++) {
- size_t len, i;
- int def;
-
- if (!opt->valp) {
- dolog ("Option value pointer for `%s' is not set\n",
- opt->name);
- continue;
- }
-
- len = strlen (opt->name);
- /* len of opt->name + len of prefix + size of qemu_prefix
- * (includes trailing zero) + zero + underscore (on behalf of
- * sizeof) */
- optname = qemu_malloc (len + preflen + sizeof (qemu_prefix) + 1);
- if (!optname) {
- dolog ("Could not allocate memory for option name `%s'\n",
- opt->name);
- continue;
- }
-
- strcpy (optname, qemu_prefix);
-
- /* copy while upper-casing, including trailing zero */
- for (i = 0; i <= preflen; ++i) {
- optname[i + sizeof (qemu_prefix) - 1] = toupper ((uint8_t)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, " endianness=");
- switch (as->endianness) {
- case 0:
- AUD_log (NULL, "little");
- break;
- case 1:
- AUD_log (NULL, "big");
- break;
- default:
- AUD_log (NULL, "invalid");
- break;
- }
- AUD_log (NULL, "\n");
-}
-
-static int audio_validate_settings (audsettings_t *as)
-{
- int invalid;
-
- invalid = as->nchannels != 1 && as->nchannels != 2;
- invalid |= as->endianness != 0 && as->endianness != 1;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- break;
- default:
- invalid = 1;
- break;
- }
-
- invalid |= as->freq <= 0;
- return invalid ? -1 : 0;
-}
-
-static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
-{
- int bits = 8, sign = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- sign = 1;
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- sign = 1;
- case AUD_FMT_U16:
- bits = 16;
- break;
- }
- return info->freq == as->freq
- && info->nchannels == as->nchannels
- && info->sign == sign
- && info->bits == bits
- && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
-}
-
-void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as)
-{
- int bits = 8, sign = 0;
-
- 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_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
-}
-
-void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
-{
- if (!len) {
- return;
- }
-
- if (info->sign) {
- memset (buf, 0x00, len << info->shift);
- }
- else {
- if (info->bits == 8) {
- memset (buf, 0x80, len << info->shift);
- }
- else {
- int i;
- uint16_t *p = buf;
- int shift = info->nchannels - 1;
- short s = INT16_MAX;
-
- if (info->swap_endianness) {
- s = bswap16 (s);
- }
-
- for (i = 0; i < len << shift; i++) {
- p[i] = s;
- }
- }
- }
-}
-
-/*
- * Capture
- */
-static void noop_conv (st_sample_t *dst, const void *src,
- int samples, volume_t *vol)
-{
- (void) src;
- (void) dst;
- (void) samples;
- (void) vol;
-}
-
-static CaptureVoiceOut *audio_pcm_capture_find_specific (
- AudioState *s,
- audsettings_t *as
- )
-{
- CaptureVoiceOut *cap;
-
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- if (audio_pcm_info_eq (&cap->hw.info, as)) {
- return cap;
- }
- }
- return NULL;
-}
-
-static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
-{
- struct capture_callback *cb;
-
-#ifdef DEBUG_CAPTURE
- dolog ("notification %d sent\n", cmd);
-#endif
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.notify (cb->opaque, cmd);
- }
-}
-
-static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
-{
- if (cap->hw.enabled != enabled) {
- audcnotification_e cmd;
- cap->hw.enabled = enabled;
- cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
- audio_notify_capture (cap, cmd);
- }
-}
-
-static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
-{
- HWVoiceOut *hw = &cap->hw;
- SWVoiceOut *sw;
- int enabled = 0;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active) {
- enabled = 1;
- break;
- }
- }
- audio_capture_maybe_changed (cap, enabled);
-}
-
-static void audio_detach_capture (HWVoiceOut *hw)
-{
- SWVoiceCap *sc = hw->cap_head.lh_first;
-
- while (sc) {
- SWVoiceCap *sc1 = sc->entries.le_next;
- SWVoiceOut *sw = &sc->sw;
- CaptureVoiceOut *cap = sc->cap;
- int was_active = sw->active;
-
- if (sw->rate) {
- st_rate_stop (sw->rate);
- sw->rate = NULL;
- }
-
- LIST_REMOVE (sw, entries);
- LIST_REMOVE (sc, entries);
- qemu_free (sc);
- if (was_active) {
- /* We have removed soft voice from the capture:
- this might have changed the overall status of the capture
- since this might have been the only active voice */
- audio_recalc_and_notify_capture (cap);
- }
- sc = sc1;
- }
-}
-
-static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
-{
- CaptureVoiceOut *cap;
-
- audio_detach_capture (hw);
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- SWVoiceCap *sc;
- SWVoiceOut *sw;
- HWVoiceOut *hw_cap = &cap->hw;
-
- sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
- if (!sc) {
- dolog ("Could not allocate soft capture voice (%zu bytes)\n",
- sizeof (*sc));
- return -1;
- }
-
- sc->cap = cap;
- sw = &sc->sw;
- sw->hw = hw_cap;
- sw->info = hw->info;
- sw->empty = 1;
- sw->active = hw->enabled;
- sw->conv = noop_conv;
- sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
- sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
- if (!sw->rate) {
- dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
- qemu_free (sw);
- return -1;
- }
- LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
- LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
-#ifdef DEBUG_CAPTURE
- asprintf (&sw->name, "for %p %d,%d,%d",
- hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
- dolog ("Added %s active = %d\n", sw->name, sw->active);
-#endif
- if (sw->active) {
- audio_capture_maybe_changed (cap, 1);
- }
- }
- return 0;
-}
-
-/*
- * Hard voice (capture)
- */
-static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
-{
- SWVoiceIn *sw;
- int m = hw->total_samples_captured;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active) {
- m = audio_MIN (m, sw->total_hw_samples_acquired);
- }
- }
- return m;
-}
-
-int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
-{
- int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
- return live;
-}
-
-/*
- * Soft voice (capture)
- */
-static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
-{
- HWVoiceIn *hw = sw->hw;
- int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
- int rpos;
-
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
-
- rpos = hw->wpos - live;
- if (rpos >= 0) {
- return rpos;
- }
- else {
- return hw->samples + rpos;
- }
-}
-
-int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
-{
- HWVoiceIn *hw = sw->hw;
- int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
- st_sample_t *src, *dst = sw->buf;
-
- rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
-
- live = hw->total_samples_captured - sw->total_hw_samples_acquired;
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
-
- samples = size >> sw->info.shift;
- if (!live) {
- return 0;
- }
-
- swlim = (live * sw->ratio) >> 32;
- swlim = audio_MIN (swlim, samples);
-
- while (swlim) {
- src = hw->conv_buf + rpos;
- isamp = hw->wpos - rpos;
- /* XXX: <= ? */
- if (isamp <= 0) {
- isamp = hw->samples - rpos;
- }
-
- if (!isamp) {
- break;
- }
- osamp = swlim;
-
- if (audio_bug (AUDIO_FUNC, osamp < 0)) {
- dolog ("osamp=%d\n", osamp);
- return 0;
- }
-
- st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
- swlim -= osamp;
- rpos = (rpos + isamp) % hw->samples;
- dst += osamp;
- ret += osamp;
- total += isamp;
- }
-
- sw->clip (buf, sw->buf, ret);
- sw->total_hw_samples_acquired += total;
- return ret << sw->info.shift;
-}
-
-/*
- * Hard voice (playback)
- */
-static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
-{
- SWVoiceOut *sw;
- int m = INT_MAX;
- int nb_live = 0;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active || !sw->empty) {
- m = audio_MIN (m, sw->total_hw_samples_mixed);
- nb_live += 1;
- }
- }
-
- *nb_livep = nb_live;
- return m;
-}
-
-int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live)
-{
- int smin;
-
- smin = audio_pcm_hw_find_min_out (hw, nb_live);
-
- if (!*nb_live) {
- return 0;
- }
- else {
- int live = smin;
-
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
- return live;
- }
-}
-
-int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
-{
- int nb_live;
- int live;
-
- live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
- return live;
-}
-
-/*
- * Soft voice (playback)
- */
-int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
-{
- int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
- int ret = 0, pos = 0, total = 0;
-
- if (!sw) {
- return size;
- }
-
- hwsamples = sw->hw->samples;
-
- live = sw->total_hw_samples_mixed;
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
- dolog ("live=%d hw->samples=%d\n", live, hwsamples);
- return 0;
- }
-
- if (live == hwsamples) {
-#ifdef DEBUG_OUT
- dolog ("%s is full %d\n", sw->name, live);
-#endif
- return 0;
- }
-
- wpos = (sw->hw->rpos + live) % hwsamples;
- samples = size >> sw->info.shift;
-
- dead = hwsamples - live;
- swlim = ((int64_t) dead << 32) / sw->ratio;
- swlim = audio_MIN (swlim, samples);
- if (swlim) {
- sw->conv (sw->buf, buf, swlim, &sw->vol);
- }
-
- while (swlim) {
- dead = hwsamples - live;
- left = hwsamples - wpos;
- blck = audio_MIN (dead, left);
- if (!blck) {
- break;
- }
- isamp = swlim;
- osamp = blck;
- st_rate_flow_mix (
- sw->rate,
- sw->buf + pos,
- sw->hw->mix_buf + wpos,
- &isamp,
- &osamp
- );
- ret += isamp;
- swlim -= isamp;
- pos += isamp;
- live += osamp;
- wpos = (wpos + osamp) % hwsamples;
- total += osamp;
- }
-
- sw->total_hw_samples_mixed += total;
- sw->empty = sw->total_hw_samples_mixed == 0;
-
-#ifdef DEBUG_OUT
- dolog (
- "%s: write size %d ret %d total sw %d\n",
- SW_NAME (sw),
- size >> sw->info.shift,
- ret,
- sw->total_hw_samples_mixed
- );
-#endif
-
- return ret << sw->info.shift;
-}
-
-#ifdef DEBUG_AUDIO
-static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
-{
- dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
- cap, info->bits, info->sign, info->freq, info->nchannels);
-}
-#endif
-
-#define DAC
-#include "audio_template.h"
-#undef DAC
-#include "audio_template.h"
-
-int AUD_write (SWVoiceOut *sw, void *buf, int size)
-{
- int bytes;
-
- if (!sw) {
- /* XXX: Consider options */
- return size;
- }
-
- if (!sw->hw->enabled) {
- dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
- return 0;
- }
-
- bytes = sw->hw->pcm_ops->write (sw, buf, size);
- return bytes;
-}
-
-int AUD_read (SWVoiceIn *sw, void *buf, int size)
-{
- int bytes;
-
- if (!sw) {
- /* XXX: Consider options */
- return size;
- }
-
- if (!sw->hw->enabled) {
- dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
- return 0;
- }
-
- bytes = sw->hw->pcm_ops->read (sw, buf, size);
- return bytes;
-}
-
-int AUD_get_buffer_size_out (SWVoiceOut *sw)
-{
- return sw->hw->samples << sw->hw->info.shift;
-}
-
-void AUD_set_active_out (SWVoiceOut *sw, int on)
-{
- HWVoiceOut *hw;
-
- if (!sw) {
- return;
- }
-
- hw = sw->hw;
- if (sw->active != on) {
- SWVoiceOut *temp_sw;
- SWVoiceCap *sc;
-
- if (on) {
- hw->pending_disable = 0;
- if (!hw->enabled) {
- hw->enabled = 1;
- hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
- }
- }
- else {
- if (hw->enabled) {
- int nb_active = 0;
-
- for (temp_sw = hw->sw_head.lh_first; temp_sw;
- temp_sw = temp_sw->entries.le_next) {
- nb_active += temp_sw->active != 0;
- }
-
- hw->pending_disable = nb_active == 1;
- }
- }
-
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- sc->sw.active = hw->enabled;
- if (hw->enabled) {
- audio_capture_maybe_changed (sc->cap, 1);
- }
- }
- sw->active = on;
- }
-}
-
-void AUD_set_active_in (SWVoiceIn *sw, int on)
-{
- HWVoiceIn *hw;
-
- if (!sw) {
- return;
- }
-
- hw = sw->hw;
- if (sw->active != on) {
- SWVoiceIn *temp_sw;
-
- if (on) {
- if (!hw->enabled) {
- hw->enabled = 1;
- hw->pcm_ops->ctl_in (hw, VOICE_ENABLE);
- }
- sw->total_hw_samples_acquired = hw->total_samples_captured;
- }
- else {
- if (hw->enabled) {
- int nb_active = 0;
-
- for (temp_sw = hw->sw_head.lh_first; temp_sw;
- temp_sw = temp_sw->entries.le_next) {
- nb_active += temp_sw->active != 0;
- }
-
- if (nb_active == 1) {
- hw->enabled = 0;
- hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
- }
- }
- }
- sw->active = on;
- }
-}
-
-static int audio_get_avail (SWVoiceIn *sw)
-{
- int live;
-
- if (!sw) {
- return 0;
- }
-
- live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
- if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
- dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
- return 0;
- }
-
- ldebug (
- "%s: get_avail live %d ret %" PRId64 "\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 %" PRId64 "\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_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
-{
- int n;
-
- if (hw->enabled) {
- SWVoiceCap *sc;
-
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- SWVoiceOut *sw = &sc->sw;
- int rpos2 = rpos;
-
- n = samples;
- while (n) {
- int till_end_of_hw = hw->samples - rpos2;
- int to_write = audio_MIN (till_end_of_hw, n);
- int bytes = to_write << hw->info.shift;
- int written;
-
- sw->buf = hw->mix_buf + rpos2;
- written = audio_pcm_sw_write (sw, NULL, bytes);
- if (written - bytes) {
- dolog ("Could not mix %d bytes into a capture "
- "buffer, mixed %d\n",
- bytes, written);
- break;
- }
- n -= to_write;
- rpos2 = (rpos2 + to_write) % hw->samples;
- }
- }
- }
-
- n = audio_MIN (samples, hw->samples - rpos);
- mixeng_clear (hw->mix_buf + rpos, n);
- mixeng_clear (hw->mix_buf, samples - n);
-}
-
-static void audio_run_out (AudioState *s)
-{
- HWVoiceOut *hw = NULL;
- SWVoiceOut *sw;
-
- while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
- int played;
- int live, free, nb_live, cleanup_required, prev_rpos;
-
- 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) {
- SWVoiceCap *sc;
-#ifdef DEBUG_OUT
- dolog ("Disabling voice\n");
-#endif
- hw->enabled = 0;
- hw->pending_disable = 0;
- hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- sc->sw.active = 0;
- audio_recalc_and_notify_capture (sc->cap);
- }
- continue;
- }
-
- 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;
- }
-
- prev_rpos = hw->rpos;
- played = hw->pcm_ops->run_out (hw);
- if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
- dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
- hw->rpos, hw->samples, played);
- hw->rpos = 0;
- }
-
-#ifdef DEBUG_OUT
- dolog ("played=%d\n", played);
-#endif
-
- if (played) {
- hw->ts_helper += played;
- audio_capture_mix_and_clear (hw, prev_rpos, 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) {
- SWVoiceOut *sw1;
-
- sw = hw->sw_head.lh_first;
- while (sw) {
- sw1 = sw->entries.le_next;
- if (!sw->active && !sw->callback.fn) {
-#ifdef DEBUG_PLIVE
- dolog ("Finishing with old voice\n");
-#endif
- audio_close_out (s, sw);
- }
- sw = sw1;
- }
- }
- }
-}
-
-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_run_capture (AudioState *s)
-{
- CaptureVoiceOut *cap;
-
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- int live, rpos, captured;
- HWVoiceOut *hw = &cap->hw;
- SWVoiceOut *sw;
-
- captured = live = audio_pcm_hw_get_live_out (hw);
- rpos = hw->rpos;
- while (live) {
- int left = hw->samples - rpos;
- int to_capture = audio_MIN (live, left);
- st_sample_t *src;
- struct capture_callback *cb;
-
- src = hw->mix_buf + rpos;
- hw->clip (cap->buf, src, to_capture);
- mixeng_clear (src, to_capture);
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.capture (cb->opaque, cap->buf,
- to_capture << hw->info.shift);
- }
- rpos = (rpos + to_capture) % hw->samples;
- live -= to_capture;
- }
- hw->rpos = rpos;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (!sw->active && sw->empty) {
- continue;
- }
-
- if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
- dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
- captured, sw->total_hw_samples_mixed);
- captured = sw->total_hw_samples_mixed;
- }
-
- sw->total_hw_samples_mixed -= captured;
- sw->empty = sw->total_hw_samples_mixed == 0;
- }
- }
-}
-
-static void audio_timer (void *opaque)
-{
- AudioState *s = opaque;
-
- audio_run_out (s);
- audio_run_in (s);
- audio_run_capture (s);
-
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
-}
-
-static struct audio_option audio_options[] = {
- /* DAC */
- {"DAC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_out.enabled,
- "Use fixed settings for host DAC", NULL, 0},
-
- {"DAC_FIXED_FREQ", AUD_OPT_INT, &conf.fixed_out.settings.freq,
- "Frequency for fixed host DAC", NULL, 0},
-
- {"DAC_FIXED_FMT", AUD_OPT_FMT, &conf.fixed_out.settings.fmt,
- "Format for fixed host DAC", NULL, 0},
-
- {"DAC_FIXED_CHANNELS", AUD_OPT_INT, &conf.fixed_out.settings.nchannels,
- "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0},
-
- {"DAC_VOICES", AUD_OPT_INT, &conf.fixed_out.nb_voices,
- "Number of voices for DAC", NULL, 0},
-
- /* ADC */
- {"ADC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_in.enabled,
- "Use fixed settings for host ADC", NULL, 0},
-
- {"ADC_FIXED_FREQ", AUD_OPT_INT, &conf.fixed_in.settings.freq,
- "Frequency for fixed host ADC", NULL, 0},
-
- {"ADC_FIXED_FMT", AUD_OPT_FMT, &conf.fixed_in.settings.fmt,
- "Format for fixed host ADC", NULL, 0},
-
- {"ADC_FIXED_CHANNELS", AUD_OPT_INT, &conf.fixed_in.settings.nchannels,
- "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0},
-
- {"ADC_VOICES", AUD_OPT_INT, &conf.fixed_in.nb_voices,
- "Number of voices for ADC", NULL, 0},
-
- /* Misc */
- {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hz,
- "Timer period in HZ (0 - use lowest possible)", NULL, 0},
-
- {"PLIVE", AUD_OPT_BOOL, &conf.plive,
- "(undocumented)", NULL, 0},
-
- {"LOG_TO_MONITOR", AUD_OPT_BOOL, &conf.log_to_monitor,
- "print logging messages to montior instead of stderr", NULL, 0},
-
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static void audio_pp_nb_voices (const char *typ, int nb)
-{
- switch (nb) {
- case 0:
- printf ("Does not support %s\n", typ);
- break;
- case 1:
- printf ("One %s voice\n", typ);
- break;
- case INT_MAX:
- printf ("Theoretically supports many %s voices\n", typ);
- break;
- default:
- printf ("Theoretically supports upto %d %s voices\n", nb, typ);
- break;
- }
-
-}
-
-void AUD_help (void)
-{
- size_t i;
-
- audio_process_options ("AUDIO", audio_options);
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- struct audio_driver *d = drvtab[i];
- if (d->options) {
- audio_process_options (d->name, d->options);
- }
- }
-
- printf ("Audio options:\n");
- audio_print_options ("AUDIO", audio_options);
- printf ("\n");
-
- printf ("Available drivers:\n");
-
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- struct audio_driver *d = drvtab[i];
-
- printf ("Name: %s\n", d->name);
- printf ("Description: %s\n", d->descr);
-
- audio_pp_nb_voices ("playback", d->max_voices_out);
- audio_pp_nb_voices ("capture", d->max_voices_in);
-
- if (d->options) {
- printf ("Options:\n");
- audio_print_options (d->name, d->options);
- }
- else {
- printf ("No options\n");
- }
- printf ("\n");
- }
-
- printf (
- "Options are settable through environment variables.\n"
- "Example:\n"
-#ifdef _WIN32
- " set QEMU_AUDIO_DRV=wav\n"
- " set QEMU_WAV_PATH=c:\\tune.wav\n"
-#else
- " export QEMU_AUDIO_DRV=wav\n"
- " export QEMU_WAV_PATH=$HOME/tune.wav\n"
- "(for csh replace export with setenv in the above)\n"
-#endif
- " qemu ...\n\n"
- );
-}
-
-static int audio_driver_init (AudioState *s, struct audio_driver *drv)
-{
- if (drv->options) {
- audio_process_options (drv->name, drv->options);
- }
- s->drv_opaque = drv->init ();
-
- if (s->drv_opaque) {
- audio_init_nb_voices_out (s, drv);
- audio_init_nb_voices_in (s, drv);
- s->drv = drv;
- return 0;
- }
- else {
- dolog ("Could not init `%s' audio driver\n", drv->name);
- return -1;
- }
-}
-
-static void audio_vm_change_state_handler (void *opaque, int running)
-{
- AudioState *s = opaque;
- HWVoiceOut *hwo = NULL;
- HWVoiceIn *hwi = NULL;
- int op = running ? VOICE_ENABLE : VOICE_DISABLE;
-
- while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
- hwo->pcm_ops->ctl_out (hwo, op);
- }
-
- while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
- hwi->pcm_ops->ctl_in (hwi, op);
- }
-}
-
-static void audio_atexit (void)
-{
- AudioState *s = &glob_audio_state;
- HWVoiceOut *hwo = NULL;
- HWVoiceIn *hwi = NULL;
-
- while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
- SWVoiceCap *sc;
-
- hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
- hwo->pcm_ops->fini_out (hwo);
-
- for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- CaptureVoiceOut *cap = sc->cap;
- struct capture_callback *cb;
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.destroy (cb->opaque);
- }
- }
- }
-
- while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
- hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
- hwi->pcm_ops->fini_in (hwi);
- }
-
- if (s->drv) {
- s->drv->fini (s->drv_opaque);
- }
-}
-
-static void audio_save (QEMUFile *f, void *opaque)
-{
- (void) f;
- (void) opaque;
-}
-
-static int audio_load (QEMUFile *f, void *opaque, int version_id)
-{
- (void) f;
- (void) opaque;
-
- if (version_id != 1) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card)
-{
- card->audio = s;
- card->name = qemu_strdup (name);
- memset (&card->entries, 0, sizeof (card->entries));
- LIST_INSERT_HEAD (&s->card_head, card, entries);
-}
-
-void AUD_remove_card (QEMUSoundCard *card)
-{
- LIST_REMOVE (card, entries);
- card->audio = NULL;
- qemu_free (card->name);
-}
-
-AudioState *AUD_init (void)
-{
- size_t i;
- int done = 0;
- const char *drvname;
- AudioState *s = &glob_audio_state;
-
- LIST_INIT (&s->hw_head_out);
- LIST_INIT (&s->hw_head_in);
- LIST_INIT (&s->cap_head);
- atexit (audio_atexit);
-
- s->ts = qemu_new_timer (vm_clock, audio_timer, s);
- if (!s->ts) {
- dolog ("Could not create audio timer\n");
- return NULL;
- }
-
- audio_process_options ("AUDIO", audio_options);
-
- s->nb_hw_voices_out = conf.fixed_out.nb_voices;
- s->nb_hw_voices_in = conf.fixed_in.nb_voices;
-
- if (s->nb_hw_voices_out <= 0) {
- dolog ("Bogus number of playback voices %d, setting to 1\n",
- s->nb_hw_voices_out);
- s->nb_hw_voices_out = 1;
- }
-
- if (s->nb_hw_voices_in <= 0) {
- dolog ("Bogus number of capture voices %d, setting to 0\n",
- s->nb_hw_voices_in);
- s->nb_hw_voices_in = 0;
- }
-
- {
- int def;
- drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);
- }
-
- if (drvname) {
- int found = 0;
-
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (!strcmp (drvname, drvtab[i]->name)) {
- done = !audio_driver_init (s, drvtab[i]);
- found = 1;
- break;
- }
- }
-
- if (!found) {
- dolog ("Unknown audio driver `%s'\n", drvname);
- dolog ("Run with -audio-help to list available drivers\n");
- }
- }
-
- if (!done) {
- for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (drvtab[i]->can_be_default) {
- done = !audio_driver_init (s, drvtab[i]);
- }
- }
- }
-
- if (!done) {
- done = !audio_driver_init (s, &no_audio_driver);
- if (!done) {
- dolog ("Could not initialize audio subsystem\n");
- }
- else {
- dolog ("warning: Using timer based audio emulation\n");
- }
- }
-
- if (done) {
- VMChangeStateEntry *e;
-
- if (conf.period.hz <= 0) {
- if (conf.period.hz < 0) {
- dolog ("warning: Timer period is negative - %d "
- "treating as zero\n",
- conf.period.hz);
- }
- conf.period.ticks = 1;
- }
- else {
- conf.period.ticks = ticks_per_sec / conf.period.hz;
- }
-
- e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
- if (!e) {
- dolog ("warning: Could not register change state handler\n"
- "(Audio can continue looping even after stopping the VM)\n");
- }
- }
- else {
- qemu_del_timer (s->ts);
- return NULL;
- }
-
- LIST_INIT (&s->card_head);
- register_savevm ("audio", 0, 1, audio_save, audio_load, s);
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
- return s;
-}
-
-CaptureVoiceOut *AUD_add_capture (
- AudioState *s,
- audsettings_t *as,
- struct audio_capture_ops *ops,
- void *cb_opaque
- )
-{
- CaptureVoiceOut *cap;
- struct capture_callback *cb;
-
- if (!s) {
- /* XXX suppress */
- s = &glob_audio_state;
- }
-
- if (audio_validate_settings (as)) {
- dolog ("Invalid settings were passed when trying to add capture\n");
- audio_print_settings (as);
- goto err0;
- }
-
- cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
- if (!cb) {
- dolog ("Could not allocate capture callback information, size %zu\n",
- sizeof (*cb));
- goto err0;
- }
- cb->ops = *ops;
- cb->opaque = cb_opaque;
-
- cap = audio_pcm_capture_find_specific (s, as);
- if (cap) {
- LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
- return cap;
- }
- else {
- HWVoiceOut *hw;
- CaptureVoiceOut *cap;
-
- cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
- if (!cap) {
- dolog ("Could not allocate capture voice, size %zu\n",
- sizeof (*cap));
- goto err1;
- }
-
- hw = &cap->hw;
- LIST_INIT (&hw->sw_head);
- LIST_INIT (&cap->cb_head);
-
- /* XXX find a more elegant way */
- hw->samples = 4096 * 4;
- hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
- sizeof (st_sample_t));
- if (!hw->mix_buf) {
- dolog ("Could not allocate capture mix buffer (%d samples)\n",
- hw->samples);
- goto err2;
- }
-
- audio_pcm_init_info (&hw->info, as);
-
- cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!cap->buf) {
- dolog ("Could not allocate capture buffer "
- "(%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- goto err3;
- }
-
- hw->clip = mixeng_clip
- [hw->info.nchannels == 2]
- [hw->info.sign]
- [hw->info.swap_endianness]
- [hw->info.bits == 16];
-
- LIST_INSERT_HEAD (&s->cap_head, cap, entries);
- LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
-
- hw = NULL;
- while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
- audio_attach_capture (s, hw);
- }
- return cap;
-
- err3:
- qemu_free (cap->hw.mix_buf);
- err2:
- qemu_free (cap);
- err1:
- qemu_free (cb);
- err0:
- return NULL;
- }
-}
-
-void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
-{
- struct capture_callback *cb;
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- if (cb->opaque == cb_opaque) {
- cb->ops.destroy (cb_opaque);
- LIST_REMOVE (cb, entries);
- qemu_free (cb);
-
- if (!cap->cb_head.lh_first) {
- SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
-
- while (sw) {
- SWVoiceCap *sc = (SWVoiceCap *) sw;
-#ifdef DEBUG_CAPTURE
- dolog ("freeing %s\n", sw->name);
-#endif
-
- sw1 = sw->entries.le_next;
- if (sw->rate) {
- st_rate_stop (sw->rate);
- sw->rate = NULL;
- }
- LIST_REMOVE (sw, entries);
- LIST_REMOVE (sc, entries);
- qemu_free (sc);
- sw = sw1;
- }
- LIST_REMOVE (cap, entries);
- qemu_free (cap);
- }
- return;
- }
- }
-}
diff --git a/tools/ioemu/audio/audio.h b/tools/ioemu/audio/audio.h
deleted file mode 100644
index c097f391bb..0000000000
--- a/tools/ioemu/audio/audio.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_AUDIO_H
-#define QEMU_AUDIO_H
-
-#include "config.h"
-#include "sys-queue.h"
-
-typedef void (*audio_callback_fn_t) (void *opaque, int avail);
-
-typedef enum {
- AUD_FMT_U8,
- AUD_FMT_S8,
- AUD_FMT_U16,
- AUD_FMT_S16
-} audfmt_e;
-
-#ifdef WORDS_BIGENDIAN
-#define AUDIO_HOST_ENDIANNESS 1
-#else
-#define AUDIO_HOST_ENDIANNESS 0
-#endif
-
-typedef struct {
- int freq;
- int nchannels;
- audfmt_e fmt;
- int endianness;
-} audsettings_t;
-
-typedef enum {
- AUD_CNOTIFY_ENABLE,
- AUD_CNOTIFY_DISABLE
-} audcnotification_e;
-
-struct audio_capture_ops {
- void (*notify) (void *opaque, audcnotification_e cmd);
- void (*capture) (void *opaque, void *buf, int size);
- void (*destroy) (void *opaque);
-};
-
-struct capture_ops {
- void (*info) (void *opaque);
- void (*destroy) (void *opaque);
-};
-
-typedef struct CaptureState {
- void *opaque;
- struct capture_ops ops;
- LIST_ENTRY (CaptureState) entries;
-} CaptureState;
-
-typedef struct AudioState AudioState;
-typedef struct SWVoiceOut SWVoiceOut;
-typedef struct CaptureVoiceOut CaptureVoiceOut;
-typedef struct SWVoiceIn SWVoiceIn;
-
-typedef struct QEMUSoundCard {
- 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);
-CaptureVoiceOut *AUD_add_capture (
- AudioState *s,
- audsettings_t *as,
- struct audio_capture_ops *ops,
- void *opaque
- );
-void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque);
-
-SWVoiceOut *AUD_open_out (
- QEMUSoundCard *card,
- SWVoiceOut *sw,
- const char *name,
- void *callback_opaque,
- audio_callback_fn_t callback_fn,
- audsettings_t *settings
- );
-
-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
- );
-
-void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
-int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
-void AUD_set_active_in (SWVoiceIn *sw, int on);
-int AUD_is_active_in (SWVoiceIn *sw);
-
-void AUD_init_time_stamp_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
-uint64_t AUD_get_elapsed_usec_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
-
-static inline void *advance (void *p, int incr)
-{
- uint8_t *d = p;
- return (d + incr);
-}
-
-uint32_t popcount (uint32_t u);
-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 --git a/tools/ioemu/audio/audio_int.h b/tools/ioemu/audio/audio_int.h
deleted file mode 100644
index 1a15d4ced8..0000000000
--- a/tools/ioemu/audio/audio_int.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_AUDIO_INT_H
-#define QEMU_AUDIO_INT_H
-
-#ifdef CONFIG_COREAUDIO
-#define FLOAT_MIXENG
-/* #define RECIPROCAL */
-#endif
-#include "mixeng.h"
-
-struct audio_pcm_ops;
-
-typedef enum {
- AUD_OPT_INT,
- AUD_OPT_FMT,
- AUD_OPT_STR,
- AUD_OPT_BOOL
-} audio_option_tag_e;
-
-struct audio_option {
- const char *name;
- audio_option_tag_e tag;
- void *valp;
- const char *descr;
- int *overridenp;
- int overriden;
-};
-
-struct audio_callback {
- void *opaque;
- audio_callback_fn_t fn;
-};
-
-struct audio_pcm_info {
- int bits;
- int sign;
- int freq;
- int nchannels;
- int align;
- int shift;
- int bytes_per_second;
- int swap_endianness;
-};
-
-typedef struct SWVoiceCap SWVoiceCap;
-
-typedef struct HWVoiceOut {
- int enabled;
- int pending_disable;
- struct audio_pcm_info info;
-
- f_sample *clip;
-
- int rpos;
- uint64_t ts_helper;
-
- st_sample_t *mix_buf;
-
- int samples;
- LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
- LIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
- struct audio_pcm_ops *pcm_ops;
- LIST_ENTRY (HWVoiceOut) entries;
-} HWVoiceOut;
-
-typedef struct HWVoiceIn {
- int enabled;
- struct audio_pcm_info info;
-
- t_sample *conv;
-
- int wpos;
- int total_samples_captured;
- uint64_t ts_helper;
-
- st_sample_t *conv_buf;
-
- int samples;
- LIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
- struct audio_pcm_ops *pcm_ops;
- LIST_ENTRY (HWVoiceIn) entries;
-} HWVoiceIn;
-
-struct SWVoiceOut {
- struct audio_pcm_info info;
- t_sample *conv;
- int64_t ratio;
- st_sample_t *buf;
- void *rate;
- int total_hw_samples_mixed;
- int active;
- int empty;
- HWVoiceOut *hw;
- char *name;
- volume_t vol;
- struct audio_callback callback;
- LIST_ENTRY (SWVoiceOut) entries;
-};
-
-struct SWVoiceIn {
- int active;
- struct audio_pcm_info info;
- int64_t ratio;
- void *rate;
- int total_hw_samples_acquired;
- st_sample_t *buf;
- f_sample *clip;
- HWVoiceIn *hw;
- char *name;
- volume_t vol;
- struct audio_callback callback;
- LIST_ENTRY (SWVoiceIn) entries;
-};
-
-struct audio_driver {
- const char *name;
- const char *descr;
- struct audio_option *options;
- void *(*init) (void);
- void (*fini) (void *);
- struct audio_pcm_ops *pcm_ops;
- int can_be_default;
- int max_voices_out;
- int max_voices_in;
- int voice_size_out;
- int voice_size_in;
-};
-
-struct audio_pcm_ops {
- int (*init_out)(HWVoiceOut *hw, audsettings_t *as);
- void (*fini_out)(HWVoiceOut *hw);
- int (*run_out) (HWVoiceOut *hw);
- int (*write) (SWVoiceOut *sw, void *buf, int size);
- int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
-
- int (*init_in) (HWVoiceIn *hw, audsettings_t *as);
- void (*fini_in) (HWVoiceIn *hw);
- int (*run_in) (HWVoiceIn *hw);
- int (*read) (SWVoiceIn *sw, void *buf, int size);
- int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
-};
-
-struct capture_callback {
- struct audio_capture_ops ops;
- void *opaque;
- LIST_ENTRY (capture_callback) entries;
-};
-
-struct CaptureVoiceOut {
- HWVoiceOut hw;
- void *buf;
- LIST_HEAD (cb_listhead, capture_callback) cb_head;
- LIST_ENTRY (CaptureVoiceOut) entries;
-};
-
-struct SWVoiceCap {
- SWVoiceOut sw;
- CaptureVoiceOut *cap;
- LIST_ENTRY (SWVoiceCap) entries;
-};
-
-struct AudioState {
- struct audio_driver *drv;
- void *drv_opaque;
-
- QEMUTimer *ts;
- LIST_HEAD (card_listhead, QEMUSoundCard) card_head;
- LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
- LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
- LIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
- int nb_hw_voices_out;
- int nb_hw_voices_in;
-};
-
-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);
-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);
-}
-
-#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 --git a/tools/ioemu/audio/audio_template.h b/tools/ioemu/audio/audio_template.h
deleted file mode 100644
index 13e1c3efbb..0000000000
--- a/tools/ioemu/audio/audio_template.h
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifdef DAC
-#define NAME "playback"
-#define HWBUF hw->mix_buf
-#define TYPE out
-#define HW HWVoiceOut
-#define SW SWVoiceOut
-#else
-#define NAME "capture"
-#define TYPE in
-#define HW HWVoiceIn
-#define SW SWVoiceIn
-#define HWBUF hw->conv_buf
-#endif
-
-static void glue (audio_init_nb_voices_, TYPE) (
- AudioState *s,
- struct audio_driver *drv
- )
-{
- int max_voices = glue (drv->max_voices_, TYPE);
- int voice_size = glue (drv->voice_size_, TYPE);
-
- if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
- if (!max_voices) {
-#ifdef DAC
- dolog ("Driver `%s' does not support " NAME "\n", drv->name);
-#endif
- }
- else {
- dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
- drv->name,
- glue (s->nb_hw_voices_, TYPE),
- max_voices);
- }
- glue (s->nb_hw_voices_, TYPE) = max_voices;
- }
-
- if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
- dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
- drv->name, max_voices);
- glue (s->nb_hw_voices_, TYPE) = 0;
- }
-
- if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
- dolog ("drv=`%s' voice_size=%d max_voices=0\n",
- drv->name, voice_size);
- }
-}
-
-static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
-{
- if (HWBUF) {
- qemu_free (HWBUF);
- }
-
- HWBUF = NULL;
-}
-
-static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
-{
- HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));
- if (!HWBUF) {
- dolog ("Could not allocate " NAME " buffer (%d samples)\n",
- hw->samples);
- return -1;
- }
-
- return 0;
-}
-
-static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
-{
- if (sw->buf) {
- qemu_free (sw->buf);
- }
-
- if (sw->rate) {
- st_rate_stop (sw->rate);
- }
-
- sw->buf = NULL;
- sw->rate = NULL;
-}
-
-static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
-{
- int samples;
-
-#ifdef DAC
- samples = sw->hw->samples;
-#else
- samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
-#endif
-
- sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));
- if (!sw->buf) {
- dolog ("Could not allocate buffer for `%s' (%d samples)\n",
- SW_NAME (sw), samples);
- return -1;
- }
-
-#ifdef DAC
- sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
-#else
- sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
-#endif
- if (!sw->rate) {
- qemu_free (sw->buf);
- sw->buf = NULL;
- return -1;
- }
- return 0;
-}
-
-static int glue (audio_pcm_sw_init_, TYPE) (
- SW *sw,
- HW *hw,
- const char *name,
- audsettings_t *as
- )
-{
- int err;
-
- audio_pcm_init_info (&sw->info, as);
- sw->hw = hw;
- sw->active = 0;
-#ifdef DAC
- sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
- sw->total_hw_samples_mixed = 0;
- sw->empty = 1;
-#else
- sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
-#endif
-
-#ifdef DAC
- sw->conv = mixeng_conv
-#else
- sw->clip = mixeng_clip
-#endif
- [sw->info.nchannels == 2]
- [sw->info.sign]
- [sw->info.swap_endianness]
- [sw->info.bits == 16];
-
- sw->name = qemu_strdup (name);
- err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
- if (err) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- return err;
-}
-
-static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
-{
- glue (audio_pcm_sw_free_resources_, TYPE) (sw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
-}
-
-static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
-{
- LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
-}
-
-static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
-{
- LIST_REMOVE (sw, entries);
-}
-
-static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
-{
- HW *hw = *hwp;
-
- if (!hw->sw_head.lh_first) {
-#ifdef DAC
- audio_detach_capture (hw);
-#endif
- LIST_REMOVE (hw, entries);
- glue (s->nb_hw_voices_, TYPE) += 1;
- glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
- glue (hw->pcm_ops->fini_, TYPE) (hw);
- qemu_free (hw);
- *hwp = NULL;
- }
-}
-
-static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
-{
- return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
-}
-
-static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
-{
- while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
- if (hw->enabled) {
- return hw;
- }
- }
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
- AudioState *s,
- HW *hw,
- audsettings_t *as
- )
-{
- while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
- if (audio_pcm_info_eq (&hw->info, as)) {
- return hw;
- }
- }
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
-{
- HW *hw;
- struct audio_driver *drv = s->drv;
-
- if (!glue (s->nb_hw_voices_, TYPE)) {
- return NULL;
- }
-
- if (audio_bug (AUDIO_FUNC, !drv)) {
- dolog ("No host audio driver\n");
- return NULL;
- }
-
- if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
- dolog ("Host audio driver without pcm_ops\n");
- return NULL;
- }
-
- hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
- if (!hw) {
- dolog ("Can not allocate voice `%s' size %d\n",
- drv->name, glue (drv->voice_size_, TYPE));
- return NULL;
- }
-
- hw->pcm_ops = drv->pcm_ops;
- LIST_INIT (&hw->sw_head);
-#ifdef DAC
- LIST_INIT (&hw->cap_head);
-#endif
- if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
- goto err0;
- }
-
- if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
- dolog ("hw->samples=%d\n", hw->samples);
- goto err1;
- }
-
-#ifdef DAC
- hw->clip = mixeng_clip
-#else
- hw->conv = mixeng_conv
-#endif
- [hw->info.nchannels == 2]
- [hw->info.sign]
- [hw->info.swap_endianness]
- [hw->info.bits == 16];
-
- if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
- goto err1;
- }
-
- LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
- glue (s->nb_hw_voices_, TYPE) -= 1;
-#ifdef DAC
- audio_attach_capture (s, hw);
-#endif
- return hw;
-
- err1:
- glue (hw->pcm_ops->fini_, TYPE) (hw);
- err0:
- qemu_free (hw);
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
-{
- HW *hw;
-
- if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
- hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
- if (hw) {
- return hw;
- }
- }
-
- hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
- if (hw) {
- return hw;
- }
-
- hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
- if (hw) {
- return hw;
- }
-
- return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
-}
-
-static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
- AudioState *s,
- const char *sw_name,
- audsettings_t *as
- )
-{
- SW *sw;
- HW *hw;
- audsettings_t hw_as;
-
- if (glue (conf.fixed_, TYPE).enabled) {
- hw_as = glue (conf.fixed_, TYPE).settings;
- }
- else {
- hw_as = *as;
- }
-
- sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
- if (!sw) {
- dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
- sw_name ? sw_name : "unknown", sizeof (*sw));
- goto err1;
- }
-
- hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
- if (!hw) {
- goto err2;
- }
-
- glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
-
- if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
- goto err3;
- }
-
- return sw;
-
-err3:
- glue (audio_pcm_hw_del_sw_, TYPE) (sw);
- glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
-err2:
- qemu_free (sw);
-err1:
- return NULL;
-}
-
-static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
-{
- glue (audio_pcm_sw_fini_, TYPE) (sw);
- glue (audio_pcm_hw_del_sw_, TYPE) (sw);
- glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
- qemu_free (sw);
-}
-
-void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
-{
- if (sw) {
- if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
- dolog ("card=%p card->audio=%p\n",
- card, card ? card->audio : NULL);
- return;
- }
-
- glue (audio_close_, TYPE) (card->audio, sw);
- }
-}
-
-SW *glue (AUD_open_, TYPE) (
- QEMUSoundCard *card,
- SW *sw,
- const char *name,
- void *callback_opaque ,
- audio_callback_fn_t callback_fn,
- audsettings_t *as
- )
-{
- AudioState *s;
-#ifdef DAC
- int live = 0;
- SW *old_sw = NULL;
-#endif
-
- ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
- name, as->freq, as->nchannels, as->fmt);
-
- if (audio_bug (AUDIO_FUNC,
- !card || !card->audio || !name || !callback_fn || !as)) {
- dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
- card, card ? card->audio : NULL, name, callback_fn, as);
- goto fail;
- }
-
- s = card->audio;
-
- if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
- audio_print_settings (as);
- goto fail;
- }
-
- if (audio_bug (AUDIO_FUNC, !s->drv)) {
- dolog ("Can not open `%s' (no host audio driver)\n", name);
- goto fail;
- }
-
- if (sw && audio_pcm_info_eq (&sw->info, as)) {
- return sw;
- }
-
-#ifdef DAC
- if (conf.plive && sw && (!sw->active && !sw->empty)) {
- live = sw->total_hw_samples_mixed;
-
-#ifdef DEBUG_PLIVE
- dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
- dolog ("Old %s freq %d, bits %d, channels %d\n",
- SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
- dolog ("New %s freq %d, bits %d, channels %d\n",
- name,
- freq,
- (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
- nchannels);
-#endif
-
- if (live) {
- old_sw = sw;
- old_sw->callback.fn = NULL;
- sw = NULL;
- }
- }
-#endif
-
- if (!glue (conf.fixed_, TYPE).enabled && sw) {
- glue (AUD_close_, TYPE) (card, sw);
- sw = NULL;
- }
-
- if (sw) {
- HW *hw = sw->hw;
-
- if (!hw) {
- dolog ("Internal logic error voice `%s' has no hardware store\n",
- SW_NAME (sw));
- goto fail;
- }
-
- glue (audio_pcm_sw_fini_, TYPE) (sw);
- if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
- goto fail;
- }
- }
- else {
- sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
- if (!sw) {
- dolog ("Failed to create voice `%s'\n", name);
- return NULL;
- }
- }
-
- if (sw) {
- sw->vol = nominal_volume;
- sw->callback.fn = callback_fn;
- sw->callback.opaque = callback_opaque;
-
-#ifdef DAC
- if (live) {
- int mixed =
- (live << old_sw->info.shift)
- * old_sw->info.bytes_per_second
- / sw->info.bytes_per_second;
-
-#ifdef DEBUG_PLIVE
- dolog ("Silence will be mixed %d\n", mixed);
-#endif
- sw->total_hw_samples_mixed += mixed;
- }
-#endif
-
-#ifdef DEBUG_AUDIO
- dolog ("%s\n", name);
- audio_pcm_print_info ("hw", &sw->hw->info);
- audio_pcm_print_info ("sw", &sw->info);
-#endif
- }
-
- return sw;
-
- fail:
- glue (AUD_close_, TYPE) (card, sw);
- return NULL;
-}
-
-int glue (AUD_is_active_, TYPE) (SW *sw)
-{
- return sw ? sw->active : 0;
-}
-
-void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
-{
- if (!sw) {
- return;
- }
-
- ts->old_ts = sw->hw->ts_helper;
-}
-
-uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
-{
- uint64_t delta, cur_ts, old_ts;
-
- if (!sw) {
- return 0;
- }
-
- cur_ts = sw->hw->ts_helper;
- old_ts = ts->old_ts;
- /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
-
- if (cur_ts >= old_ts) {
- delta = cur_ts - old_ts;
- }
- else {
- delta = UINT64_MAX - old_ts + cur_ts;
- }
-
- if (!delta) {
- return 0;
- }
-
- return (delta * sw->hw->info.freq) / 1000000;
-}
-
-#undef TYPE
-#undef HW
-#undef SW
-#undef HWBUF
-#undef NAME
diff --git a/tools/ioemu/audio/coreaudio.c b/tools/ioemu/audio/coreaudio.c
deleted file mode 100644
index 8512f122b0..0000000000
--- a/tools/ioemu/audio/coreaudio.c
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * QEMU OS X CoreAudio audio driver
- *
- * Copyright (c) 2005 Mike Kronenberg
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <CoreAudio/CoreAudio.h>
-#include <string.h> /* strerror */
-#include <pthread.h> /* pthread_X */
-
-#include "vl.h"
-
-#define AUDIO_CAP "coreaudio"
-#include "audio_int.h"
-
-struct {
- int buffer_frames;
- int nbuffers;
- int isAtexit;
-} conf = {
- .buffer_frames = 512,
- .nbuffers = 4,
- .isAtexit = 0
-};
-
-typedef struct coreaudioVoiceOut {
- HWVoiceOut hw;
- pthread_mutex_t mutex;
- int isAtexit;
- AudioDeviceID outputDeviceID;
- UInt32 audioDevicePropertyBufferFrameSize;
- AudioStreamBasicDescription outputStreamBasicDescription;
- int live;
- int decr;
- int rpos;
-} coreaudioVoiceOut;
-
-static void coreaudio_logstatus (OSStatus status)
-{
- char *str = "BUG";
-
- switch(status) {
- case kAudioHardwareNoError:
- str = "kAudioHardwareNoError";
- break;
-
- case kAudioHardwareNotRunningError:
- str = "kAudioHardwareNotRunningError";
- break;
-
- case kAudioHardwareUnspecifiedError:
- str = "kAudioHardwareUnspecifiedError";
- break;
-
- case kAudioHardwareUnknownPropertyError:
- str = "kAudioHardwareUnknownPropertyError";
- break;
-
- case kAudioHardwareBadPropertySizeError:
- str = "kAudioHardwareBadPropertySizeError";
- break;
-
- case kAudioHardwareIllegalOperationError:
- str = "kAudioHardwareIllegalOperationError";
- break;
-
- case kAudioHardwareBadDeviceError:
- str = "kAudioHardwareBadDeviceError";
- break;
-
- case kAudioHardwareBadStreamError:
- str = "kAudioHardwareBadStreamError";
- break;
-
- case kAudioHardwareUnsupportedOperationError:
- str = "kAudioHardwareUnsupportedOperationError";
- break;
-
- case kAudioDeviceUnsupportedFormatError:
- str = "kAudioDeviceUnsupportedFormatError";
- break;
-
- case kAudioDevicePermissionsError:
- str = "kAudioDevicePermissionsError";
- break;
-
- default:
- AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);
- return;
- }
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", str);
-}
-
-static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (
- OSStatus status,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_log (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- coreaudio_logstatus (status);
-}
-
-static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
- OSStatus status,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- coreaudio_logstatus (status);
-}
-
-static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
-{
- OSStatus status;
- UInt32 result = 0;
- UInt32 propertySize = sizeof(outputDeviceID);
- status = AudioDeviceGetProperty(
- outputDeviceID, 0, 0,
- kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr(status,
- "Could not determine whether Device is playing\n");
- }
- return result;
-}
-
-static void coreaudio_atexit (void)
-{
- conf.isAtexit = 1;
-}
-
-static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
-{
- int err;
-
- err = pthread_mutex_lock (&core->mutex);
- if (err) {
- dolog ("Could not lock voice for %s\nReason: %s\n",
- fn_name, strerror (err));
- return -1;
- }
- return 0;
-}
-
-static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
-{
- int err;
-
- err = pthread_mutex_unlock (&core->mutex);
- if (err) {
- dolog ("Could not unlock voice for %s\nReason: %s\n",
- fn_name, strerror (err));
- return -1;
- }
- return 0;
-}
-
-static int coreaudio_run_out (HWVoiceOut *hw)
-{
- int live, decr;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
-
- if (coreaudio_lock (core, "coreaudio_run_out")) {
- return 0;
- }
-
- live = audio_pcm_hw_get_live_out (hw);
-
- if (core->decr > live) {
- ldebug ("core->decr %d live %d core->live %d\n",
- core->decr,
- live,
- core->live);
- }
-
- decr = audio_MIN (core->decr, live);
- core->decr -= decr;
-
- core->live = live - decr;
- hw->rpos = core->rpos;
-
- coreaudio_unlock (core, "coreaudio_run_out");
- return decr;
-}
-
-/* callback to feed audiooutput buffer */
-static OSStatus audioDeviceIOProc(
- AudioDeviceID inDevice,
- const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData,
- const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData,
- const AudioTimeStamp* inOutputTime,
- void* hwptr)
-{
- UInt32 frame, frameCount;
- float *out = outOutputData->mBuffers[0].mData;
- HWVoiceOut *hw = hwptr;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
- int rpos, live;
- st_sample_t *src;
-#ifndef FLOAT_MIXENG
-#ifdef RECIPROCAL
- const float scale = 1.f / UINT_MAX;
-#else
- const float scale = UINT_MAX;
-#endif
-#endif
-
- if (coreaudio_lock (core, "audioDeviceIOProc")) {
- inInputTime = 0;
- return 0;
- }
-
- frameCount = core->audioDevicePropertyBufferFrameSize;
- live = core->live;
-
- /* if there are not enough samples, set signal and return */
- if (live < frameCount) {
- inInputTime = 0;
- coreaudio_unlock (core, "audioDeviceIOProc(empty)");
- return 0;
- }
-
- rpos = core->rpos;
- src = hw->mix_buf + rpos;
-
- /* fill buffer */
- for (frame = 0; frame < frameCount; frame++) {
-#ifdef FLOAT_MIXENG
- *out++ = src[frame].l; /* left channel */
- *out++ = src[frame].r; /* right channel */
-#else
-#ifdef RECIPROCAL
- *out++ = src[frame].l * scale; /* left channel */
- *out++ = src[frame].r * scale; /* right channel */
-#else
- *out++ = src[frame].l / scale; /* left channel */
- *out++ = src[frame].r / scale; /* right channel */
-#endif
-#endif
- }
-
- rpos = (rpos + frameCount) % hw->samples;
- core->decr += frameCount;
- core->rpos = rpos;
-
- coreaudio_unlock (core, "audioDeviceIOProc");
- return 0;
-}
-
-static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- OSStatus status;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
- UInt32 propertySize;
- int err;
- int bits = 8;
- const char *typ = "playback";
- AudioValueRange frameRange;
-
- /* create mutex */
- err = pthread_mutex_init(&core->mutex, NULL);
- if (err) {
- dolog("Could not create mutex\nReason: %s\n", strerror (err));
- return -1;
- }
-
- if (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) {
- bits = 16;
- }
-
- audio_pcm_init_info (&hw->info, as);
-
- /* open default output device */
- propertySize = sizeof(core->outputDeviceID);
- status = AudioHardwareGetProperty(
- kAudioHardwarePropertyDefaultOutputDevice,
- &propertySize,
- &core->outputDeviceID);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get default output Device\n");
- return -1;
- }
- if (core->outputDeviceID == kAudioDeviceUnknown) {
- dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
- return -1;
- }
-
- /* get minimum and maximum buffer frame sizes */
- propertySize = sizeof(frameRange);
- status = AudioDeviceGetProperty(
- core->outputDeviceID,
- 0,
- 0,
- kAudioDevicePropertyBufferFrameSizeRange,
- &propertySize,
- &frameRange);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame range\n");
- return -1;
- }
-
- if (frameRange.mMinimum > conf.buffer_frames) {
- core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum;
- dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum);
- }
- else if (frameRange.mMaximum < conf.buffer_frames) {
- core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum;
- dolog ("warning: Downsizing Buffer Frames to %f\n", frameRange.mMaximum);
- }
- else {
- core->audioDevicePropertyBufferFrameSize = conf.buffer_frames;
- }
-
- /* set Buffer Frame Size */
- propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
- status = AudioDeviceSetProperty(
- core->outputDeviceID,
- NULL,
- 0,
- false,
- kAudioDevicePropertyBufferFrameSize,
- propertySize,
- &core->audioDevicePropertyBufferFrameSize);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not set device buffer frame size %ld\n",
- core->audioDevicePropertyBufferFrameSize);
- return -1;
- }
-
- /* get Buffer Frame Size */
- propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
- status = AudioDeviceGetProperty(
- core->outputDeviceID,
- 0,
- false,
- kAudioDevicePropertyBufferFrameSize,
- &propertySize,
- &core->audioDevicePropertyBufferFrameSize);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame size\n");
- return -1;
- }
- hw->samples = conf.nbuffers * core->audioDevicePropertyBufferFrameSize;
-
- /* get StreamFormat */
- propertySize = sizeof(core->outputStreamBasicDescription);
- status = AudioDeviceGetProperty(
- core->outputDeviceID,
- 0,
- false,
- kAudioDevicePropertyStreamFormat,
- &propertySize,
- &core->outputStreamBasicDescription);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get Device Stream properties\n");
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* set Samplerate */
- core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
- propertySize = sizeof(core->outputStreamBasicDescription);
- status = AudioDeviceSetProperty(
- core->outputDeviceID,
- 0,
- 0,
- 0,
- kAudioDevicePropertyStreamFormat,
- propertySize,
- &core->outputStreamBasicDescription);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
- as->freq);
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* set Callback */
- status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* start Playback */
- if (!isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not start playback\n");
- AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
- }
-
- return 0;
-}
-
-static void coreaudio_fini_out (HWVoiceOut *hw)
-{
- OSStatus status;
- int err;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
-
- if (!conf.isAtexit) {
- /* stop playback */
- if (isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not stop playback\n");
- }
- }
-
- /* remove callback */
- status = AudioDeviceRemoveIOProc(core->outputDeviceID,
- audioDeviceIOProc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not remove IOProc\n");
- }
- }
- core->outputDeviceID = kAudioDeviceUnknown;
-
- /* destroy mutex */
- err = pthread_mutex_destroy(&core->mutex);
- if (err) {
- dolog("Could not destroy mutex\nReason: %s\n", strerror (err));
- }
-}
-
-static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- OSStatus status;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- /* start playback */
- if (!isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not resume playback\n");
- }
- }
- break;
-
- case VOICE_DISABLE:
- /* stop playback */
- if (!conf.isAtexit) {
- if (isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not pause playback\n");
- }
- }
- }
- break;
- }
- return 0;
-}
-
-static void *coreaudio_audio_init (void)
-{
- atexit(coreaudio_atexit);
- return &coreaudio_audio_init;
-}
-
-static void coreaudio_audio_fini (void *opaque)
-{
- (void) opaque;
-}
-
-static struct audio_option coreaudio_options[] = {
- {"BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_frames,
- "Size of the buffer in frames", NULL, 0},
- {"BUFFER_COUNT", AUD_OPT_INT, &conf.nbuffers,
- "Number of buffers", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops coreaudio_pcm_ops = {
- coreaudio_init_out,
- coreaudio_fini_out,
- coreaudio_run_out,
- coreaudio_write,
- coreaudio_ctl_out,
-
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-struct audio_driver coreaudio_audio_driver = {
- INIT_FIELD (name = ) "coreaudio",
- INIT_FIELD (descr = )
- "CoreAudio http://developer.apple.com/audio/coreaudio.html",
- INIT_FIELD (options = ) coreaudio_options,
- INIT_FIELD (init = ) coreaudio_audio_init,
- INIT_FIELD (fini = ) coreaudio_audio_fini,
- INIT_FIELD (pcm_ops = ) &coreaudio_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) 1,
- INIT_FIELD (max_voices_in = ) 0,
- INIT_FIELD (voice_size_out = ) sizeof (coreaudioVoiceOut),
- INIT_FIELD (voice_size_in = ) 0
-};
diff --git a/tools/ioemu/audio/dsound_template.h b/tools/ioemu/audio/dsound_template.h
deleted file mode 100644
index 0896b04a03..0000000000
--- a/tools/ioemu/audio/dsound_template.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * QEMU DirectSound audio driver header
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifdef DSBTYPE_IN
-#define NAME "capture buffer"
-#define TYPE in
-#define IFACE IDirectSoundCaptureBuffer
-#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
-#define FIELD dsound_capture_buffer
-#else
-#define NAME "playback buffer"
-#define TYPE out
-#define IFACE IDirectSoundBuffer
-#define BUFPTR LPDIRECTSOUNDBUFFER
-#define FIELD dsound_buffer
-#endif
-
-static int glue (dsound_unlock_, TYPE) (
- BUFPTR buf,
- LPVOID p1,
- LPVOID p2,
- DWORD blen1,
- DWORD blen2
- )
-{
- HRESULT hr;
-
- hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not unlock " NAME "\n");
- return -1;
- }
-
- return 0;
-}
-
-static int glue (dsound_lock_, TYPE) (
- BUFPTR buf,
- struct audio_pcm_info *info,
- DWORD pos,
- DWORD len,
- LPVOID *p1p,
- LPVOID *p2p,
- DWORD *blen1p,
- DWORD *blen2p,
- int entire
- )
-{
- HRESULT hr;
- int i;
- LPVOID p1 = NULL, p2 = NULL;
- DWORD blen1 = 0, blen2 = 0;
- DWORD flag;
-
-#ifdef DSBTYPE_IN
- flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
-#else
- flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
-#endif
- for (i = 0; i < conf.lock_retries; ++i) {
- hr = glue (IFACE, _Lock) (
- buf,
- pos,
- len,
- &p1,
- &blen1,
- &p2,
- &blen2,
- flag
- );
-
- if (FAILED (hr)) {
-#ifndef DSBTYPE_IN
- if (hr == DSERR_BUFFERLOST) {
- if (glue (dsound_restore_, TYPE) (buf)) {
- dsound_logerr (hr, "Could not lock " NAME "\n");
- goto fail;
- }
- continue;
- }
-#endif
- dsound_logerr (hr, "Could not lock " NAME "\n");
- goto fail;
- }
-
- break;
- }
-
- if (i == conf.lock_retries) {
- dolog ("%d attempts to lock " NAME " failed\n", i);
- goto fail;
- }
-
- if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
- dolog ("DirectSound returned misaligned buffer %ld %ld\n",
- blen1, blen2);
- glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
- goto fail;
- }
-
- if (!p1 && blen1) {
- dolog ("warning: !p1 && blen1=%ld\n", blen1);
- blen1 = 0;
- }
-
- if (!p2 && blen2) {
- dolog ("warning: !p2 && blen2=%ld\n", blen2);
- blen2 = 0;
- }
-
- *p1p = p1;
- *p2p = p2;
- *blen1p = blen1;
- *blen2p = blen2;
- return 0;
-
- fail:
- *p1p = NULL - 1;
- *p2p = NULL - 1;
- *blen1p = -1;
- *blen2p = -1;
- return -1;
-}
-
-#ifdef DSBTYPE_IN
-static void dsound_fini_in (HWVoiceIn *hw)
-#else
-static void dsound_fini_out (HWVoiceOut *hw)
-#endif
-{
- HRESULT hr;
-#ifdef DSBTYPE_IN
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
-#else
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
-#endif
-
- if (ds->FIELD) {
- hr = glue (IFACE, _Stop) (ds->FIELD);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop " NAME "\n");
- }
-
- hr = glue (IFACE, _Release) (ds->FIELD);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release " NAME "\n");
- }
- ds->FIELD = NULL;
- }
-}
-
-#ifdef DSBTYPE_IN
-static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
-#else
-static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
-#endif
-{
- int err;
- HRESULT hr;
- dsound *s = &glob_dsound;
- WAVEFORMATEX wfx;
- audsettings_t obt_as;
-#ifdef DSBTYPE_IN
- const char *typ = "ADC";
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- DSCBUFFERDESC bd;
- DSCBCAPS bc;
-#else
- const char *typ = "DAC";
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- DSBUFFERDESC bd;
- DSBCAPS bc;
-#endif
-
- err = waveformat_from_audio_settings (&wfx, as);
- if (err) {
- return -1;
- }
-
- memset (&bd, 0, sizeof (bd));
- bd.dwSize = sizeof (bd);
- bd.lpwfxFormat = &wfx;
-#ifdef DSBTYPE_IN
- bd.dwBufferBytes = conf.bufsize_in;
- hr = IDirectSoundCapture_CreateCaptureBuffer (
- s->dsound_capture,
- &bd,
- &ds->dsound_capture_buffer,
- NULL
- );
-#else
- bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
- bd.dwBufferBytes = conf.bufsize_out;
- hr = IDirectSound_CreateSoundBuffer (
- s->dsound,
- &bd,
- &ds->dsound_buffer,
- NULL
- );
-#endif
-
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
- return -1;
- }
-
- hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
- goto fail0;
- }
-
-#ifdef DEBUG_DSOUND
- dolog (NAME "\n");
- print_wave_format (&wfx);
-#endif
-
- memset (&bc, 0, sizeof (bc));
- bc.dwSize = sizeof (bc);
-
- hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
- goto fail0;
- }
-
- err = waveformat_to_audio_settings (&wfx, &obt_as);
- if (err) {
- goto fail0;
- }
-
- ds->first_time = 1;
- obt_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &obt_as);
-
- if (bc.dwBufferBytes & hw->info.align) {
- dolog (
- "GetCaps returned misaligned buffer size %ld, alignment %d\n",
- bc.dwBufferBytes, hw->info.align + 1
- );
- }
- hw->samples = bc.dwBufferBytes >> hw->info.shift;
-
-#ifdef DEBUG_DSOUND
- dolog ("caps %ld, desc %ld\n",
- bc.dwBufferBytes, bd.dwBufferBytes);
-
- dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
- hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
-#endif
- return 0;
-
- fail0:
- glue (dsound_fini_, TYPE) (hw);
- return -1;
-}
-
-#undef NAME
-#undef TYPE
-#undef IFACE
-#undef BUFPTR
-#undef FIELD
diff --git a/tools/ioemu/audio/dsoundaudio.c b/tools/ioemu/audio/dsoundaudio.c
deleted file mode 100644
index 90a0333f13..0000000000
--- a/tools/ioemu/audio/dsoundaudio.c
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- * QEMU DirectSound audio driver
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * SEAL 1.07 by Carlos 'pel' Hasan was used as documentation
- */
-
-#include "vl.h"
-
-#define AUDIO_CAP "dsound"
-#include "audio_int.h"
-
-#include <windows.h>
-#include <objbase.h>
-#include <dsound.h>
-
-/* #define DEBUG_DSOUND */
-
-static struct {
- int lock_retries;
- int restore_retries;
- int getstatus_retries;
- int set_primary;
- int bufsize_in;
- int bufsize_out;
- audsettings_t settings;
- int latency_millis;
-} conf = {
- 1,
- 1,
- 1,
- 0,
- 16384,
- 16384,
- {
- 44100,
- 2,
- AUD_FMT_S16
- },
- 10
-};
-
-typedef struct {
- LPDIRECTSOUND dsound;
- LPDIRECTSOUNDCAPTURE dsound_capture;
- LPDIRECTSOUNDBUFFER dsound_primary_buffer;
- audsettings_t settings;
-} dsound;
-
-static dsound glob_dsound;
-
-typedef struct {
- HWVoiceOut hw;
- LPDIRECTSOUNDBUFFER dsound_buffer;
- DWORD old_pos;
- int first_time;
-#ifdef DEBUG_DSOUND
- DWORD old_ppos;
- DWORD played;
- DWORD mixed;
-#endif
-} DSoundVoiceOut;
-
-typedef struct {
- HWVoiceIn hw;
- int first_time;
- LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
-} DSoundVoiceIn;
-
-static void dsound_log_hresult (HRESULT hr)
-{
- const char *str = "BUG";
-
- switch (hr) {
- case DS_OK:
- str = "The method succeeded";
- break;
-#ifdef DS_NO_VIRTUALIZATION
- case DS_NO_VIRTUALIZATION:
- str = "The buffer was created, but another 3D algorithm was substituted";
- break;
-#endif
-#ifdef DS_INCOMPLETE
- case DS_INCOMPLETE:
- str = "The method succeeded, but not all the optional effects were obtained";
- break;
-#endif
-#ifdef DSERR_ACCESSDENIED
- case DSERR_ACCESSDENIED:
- str = "The request failed because access was denied";
- break;
-#endif
-#ifdef DSERR_ALLOCATED
- case DSERR_ALLOCATED:
- str = "The request failed because resources, such as a priority level, were already in use by another caller";
- break;
-#endif
-#ifdef DSERR_ALREADYINITIALIZED
- case DSERR_ALREADYINITIALIZED:
- str = "The object is already initialized";
- break;
-#endif
-#ifdef DSERR_BADFORMAT
- case DSERR_BADFORMAT:
- str = "The specified wave format is not supported";
- break;
-#endif
-#ifdef DSERR_BADSENDBUFFERGUID
- case DSERR_BADSENDBUFFERGUID:
- str = "The GUID specified in an audiopath file does not match a valid mix-in buffer";
- break;
-#endif
-#ifdef DSERR_BUFFERLOST
- case DSERR_BUFFERLOST:
- str = "The buffer memory has been lost and must be restored";
- break;
-#endif
-#ifdef DSERR_BUFFERTOOSMALL
- case DSERR_BUFFERTOOSMALL:
- str = "The buffer size is not great enough to enable effects processing";
- break;
-#endif
-#ifdef DSERR_CONTROLUNAVAIL
- case DSERR_CONTROLUNAVAIL:
- str = "The buffer control (volume, pan, and so on) requested by the caller is not available. Controls must be specified when the buffer is created, using the dwFlags member of DSBUFFERDESC";
- break;
-#endif
-#ifdef DSERR_DS8_REQUIRED
- case DSERR_DS8_REQUIRED:
- str = "A DirectSound object of class CLSID_DirectSound8 or later is required for the requested functionality. For more information, see IDirectSound8 Interface";
- break;
-#endif
-#ifdef DSERR_FXUNAVAILABLE
- case DSERR_FXUNAVAILABLE:
- str = "The effects requested could not be found on the system, or they are in the wrong order or in the wrong location; for example, an effect expected in hardware was found in software";
- break;
-#endif
-#ifdef DSERR_GENERIC
- case DSERR_GENERIC :
- str = "An undetermined error occurred inside the DirectSound subsystem";
- break;
-#endif
-#ifdef DSERR_INVALIDCALL
- case DSERR_INVALIDCALL:
- str = "This function is not valid for the current state of this object";
- break;
-#endif
-#ifdef DSERR_INVALIDPARAM
- case DSERR_INVALIDPARAM:
- str = "An invalid parameter was passed to the returning function";
- break;
-#endif
-#ifdef DSERR_NOAGGREGATION
- case DSERR_NOAGGREGATION:
- str = "The object does not support aggregation";
- break;
-#endif
-#ifdef DSERR_NODRIVER
- case DSERR_NODRIVER:
- str = "No sound driver is available for use, or the given GUID is not a valid DirectSound device ID";
- break;
-#endif
-#ifdef DSERR_NOINTERFACE
- case DSERR_NOINTERFACE:
- str = "The requested COM interface is not available";
- break;
-#endif
-#ifdef DSERR_OBJECTNOTFOUND
- case DSERR_OBJECTNOTFOUND:
- str = "The requested object was not found";
- break;
-#endif
-#ifdef DSERR_OTHERAPPHASPRIO
- case DSERR_OTHERAPPHASPRIO:
- str = "Another application has a higher priority level, preventing this call from succeeding";
- break;
-#endif
-#ifdef DSERR_OUTOFMEMORY
- case DSERR_OUTOFMEMORY:
- str = "The DirectSound subsystem could not allocate sufficient memory to complete the caller's request";
- break;
-#endif
-#ifdef DSERR_PRIOLEVELNEEDED
- case DSERR_PRIOLEVELNEEDED:
- str = "A cooperative level of DSSCL_PRIORITY or higher is required";
- break;
-#endif
-#ifdef DSERR_SENDLOOP
- case DSERR_SENDLOOP:
- str = "A circular loop of send effects was detected";
- break;
-#endif
-#ifdef DSERR_UNINITIALIZED
- case DSERR_UNINITIALIZED:
- str = "The Initialize method has not been called or has not been called successfully before other methods were called";
- break;
-#endif
-#ifdef DSERR_UNSUPPORTED
- case DSERR_UNSUPPORTED:
- str = "The function called is not supported at this time";
- break;
-#endif
- default:
- AUD_log (AUDIO_CAP, "Reason: Unknown (HRESULT %#lx)\n", hr);
- return;
- }
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", str);
-}
-
-static void GCC_FMT_ATTR (2, 3) dsound_logerr (
- HRESULT hr,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- dsound_log_hresult (hr);
-}
-
-static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
- HRESULT hr,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- dsound_log_hresult (hr);
-}
-
-static DWORD millis_to_bytes (struct audio_pcm_info *info, DWORD millis)
-{
- return (millis * info->bytes_per_second) / 1000;
-}
-
-#ifdef DEBUG_DSOUND
-static void print_wave_format (WAVEFORMATEX *wfx)
-{
- dolog ("tag = %d\n", wfx->wFormatTag);
- dolog ("nChannels = %d\n", wfx->nChannels);
- dolog ("nSamplesPerSec = %ld\n", wfx->nSamplesPerSec);
- dolog ("nAvgBytesPerSec = %ld\n", wfx->nAvgBytesPerSec);
- dolog ("nBlockAlign = %d\n", wfx->nBlockAlign);
- dolog ("wBitsPerSample = %d\n", wfx->wBitsPerSample);
- dolog ("cbSize = %d\n", wfx->cbSize);
-}
-#endif
-
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
-{
- HRESULT hr;
- int i;
-
- for (i = 0; i < conf.restore_retries; ++i) {
- hr = IDirectSoundBuffer_Restore (dsb);
-
- switch (hr) {
- case DS_OK:
- return 0;
-
- case DSERR_BUFFERLOST:
- continue;
-
- default:
- dsound_logerr (hr, "Could not restore playback buffer\n");
- return -1;
- }
- }
-
- dolog ("%d attempts to restore playback buffer failed\n", i);
- return -1;
-}
-
-static int waveformat_from_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
-{
- memset (wfx, 0, sizeof (*wfx));
-
- wfx->wFormatTag = WAVE_FORMAT_PCM;
- wfx->nChannels = as->nchannels;
- wfx->nSamplesPerSec = as->freq;
- wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
- wfx->nBlockAlign = 1 << (as->nchannels == 2);
- wfx->cbSize = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- wfx->wBitsPerSample = 8;
- break;
-
- case AUD_FMT_U8:
- wfx->wBitsPerSample = 8;
- break;
-
- case AUD_FMT_S16:
- wfx->wBitsPerSample = 16;
- wfx->nAvgBytesPerSec <<= 1;
- wfx->nBlockAlign <<= 1;
- break;
-
- case AUD_FMT_U16:
- wfx->wBitsPerSample = 16;
- wfx->nAvgBytesPerSec <<= 1;
- wfx->nBlockAlign <<= 1;
- break;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", as->freq);
- return -1;
- }
-
- return 0;
-}
-
-static int waveformat_to_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
-{
- if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
- dolog ("Invalid wave format, tag is not PCM, but %d\n",
- wfx->wFormatTag);
- return -1;
- }
-
- if (!wfx->nSamplesPerSec) {
- dolog ("Invalid wave format, frequency is zero\n");
- return -1;
- }
- as->freq = wfx->nSamplesPerSec;
-
- switch (wfx->nChannels) {
- case 1:
- as->nchannels = 1;
- break;
-
- case 2:
- as->nchannels = 2;
- break;
-
- default:
- dolog (
- "Invalid wave format, number of channels is not 1 or 2, but %d\n",
- wfx->nChannels
- );
- return -1;
- }
-
- switch (wfx->wBitsPerSample) {
- case 8:
- as->fmt = AUD_FMT_U8;
- break;
-
- case 16:
- as->fmt = AUD_FMT_S16;
- break;
-
- default:
- dolog ("Invalid wave format, bits per sample is not 8 or 16, but %d\n",
- wfx->wBitsPerSample);
- return -1;
- }
-
- return 0;
-}
-
-#include "dsound_template.h"
-#define DSBTYPE_IN
-#include "dsound_template.h"
-#undef DSBTYPE_IN
-
-static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
-{
- HRESULT hr;
- int i;
-
- for (i = 0; i < conf.getstatus_retries; ++i) {
- hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get playback buffer status\n");
- return -1;
- }
-
- if (*statusp & DSERR_BUFFERLOST) {
- if (dsound_restore_out (dsb)) {
- return -1;
- }
- continue;
- }
- break;
- }
-
- return 0;
-}
-
-static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
- DWORD *statusp)
-{
- HRESULT hr;
-
- hr = IDirectSoundCaptureBuffer_GetStatus (dscb, statusp);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer status\n");
- return -1;
- }
-
- return 0;
-}
-
-static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
-{
- int src_len1 = dst_len;
- int src_len2 = 0;
- int pos = hw->rpos + dst_len;
- st_sample_t *src1 = hw->mix_buf + hw->rpos;
- st_sample_t *src2 = NULL;
-
- if (pos > hw->samples) {
- src_len1 = hw->samples - hw->rpos;
- src2 = hw->mix_buf;
- src_len2 = dst_len - src_len1;
- pos = src_len2;
- }
-
- if (src_len1) {
- hw->clip (dst, src1, src_len1);
- }
-
- if (src_len2) {
- dst = advance (dst, src_len1 << hw->info.shift);
- hw->clip (dst, src2, src_len2);
- }
-
- hw->rpos = pos % hw->samples;
-}
-
-static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb)
-{
- int err;
- LPVOID p1, p2;
- DWORD blen1, blen2, len1, len2;
-
- err = dsound_lock_out (
- dsb,
- &hw->info,
- 0,
- hw->samples << hw->info.shift,
- &p1, &p2,
- &blen1, &blen2,
- 1
- );
- if (err) {
- return;
- }
-
- len1 = blen1 >> hw->info.shift;
- len2 = blen2 >> hw->info.shift;
-
-#ifdef DEBUG_DSOUND
- dolog ("clear %p,%ld,%ld %p,%ld,%ld\n",
- p1, blen1, len1,
- p2, blen2, len2);
-#endif
-
- if (p1 && len1) {
- audio_pcm_info_clear_buf (&hw->info, p1, len1);
- }
-
- if (p2 && len2) {
- audio_pcm_info_clear_buf (&hw->info, p2, len2);
- }
-
- dsound_unlock_out (dsb, p1, p2, blen1, blen2);
-}
-
-static void dsound_close (dsound *s)
-{
- HRESULT hr;
-
- if (s->dsound_primary_buffer) {
- hr = IDirectSoundBuffer_Release (s->dsound_primary_buffer);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release primary buffer\n");
- }
- s->dsound_primary_buffer = NULL;
- }
-}
-
-static int dsound_open (dsound *s)
-{
- int err;
- HRESULT hr;
- WAVEFORMATEX wfx;
- DSBUFFERDESC dsbd;
- HWND hwnd;
-
- hwnd = GetForegroundWindow ();
- hr = IDirectSound_SetCooperativeLevel (
- s->dsound,
- hwnd,
- DSSCL_PRIORITY
- );
-
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not set cooperative level for window %p\n",
- hwnd);
- return -1;
- }
-
- if (!conf.set_primary) {
- return 0;
- }
-
- err = waveformat_from_audio_settings (&wfx, &conf.settings);
- if (err) {
- return -1;
- }
-
- memset (&dsbd, 0, sizeof (dsbd));
- dsbd.dwSize = sizeof (dsbd);
- dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
- dsbd.dwBufferBytes = 0;
- dsbd.lpwfxFormat = NULL;
-
- hr = IDirectSound_CreateSoundBuffer (
- s->dsound,
- &dsbd,
- &s->dsound_primary_buffer,
- NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create primary playback buffer\n");
- return -1;
- }
-
- hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not set primary playback buffer format\n");
- }
-
- hr = IDirectSoundBuffer_GetFormat (
- s->dsound_primary_buffer,
- &wfx,
- sizeof (wfx),
- NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get primary playback buffer format\n");
- goto fail0;
- }
-
-#ifdef DEBUG_DSOUND
- dolog ("Primary\n");
- print_wave_format (&wfx);
-#endif
-
- err = waveformat_to_audio_settings (&wfx, &s->settings);
- if (err) {
- goto fail0;
- }
-
- return 0;
-
- fail0:
- dsound_close (s);
- return -1;
-}
-
-static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- HRESULT hr;
- DWORD status;
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
-
- if (!dsb) {
- dolog ("Attempt to control voice without a buffer\n");
- return 0;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (dsound_get_status_out (dsb, &status)) {
- return -1;
- }
-
- if (status & DSBSTATUS_PLAYING) {
- dolog ("warning: Voice is already playing\n");
- return 0;
- }
-
- dsound_clear_sample (hw, dsb);
-
- hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not start playing buffer\n");
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- if (dsound_get_status_out (dsb, &status)) {
- return -1;
- }
-
- if (status & DSBSTATUS_PLAYING) {
- hr = IDirectSoundBuffer_Stop (dsb);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop playing buffer\n");
- return -1;
- }
- }
- else {
- dolog ("warning: Voice is not playing\n");
- }
- break;
- }
- return 0;
-}
-
-static int dsound_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int dsound_run_out (HWVoiceOut *hw)
-{
- int err;
- HRESULT hr;
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
- int live, len, hwshift;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD wpos, ppos, old_pos;
- LPVOID p1, p2;
- int bufsize;
-
- if (!dsb) {
- dolog ("Attempt to run empty with playback buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
- bufsize = hw->samples << hwshift;
-
- live = audio_pcm_hw_get_live_out (hw);
-
- hr = IDirectSoundBuffer_GetCurrentPosition (
- dsb,
- &ppos,
- ds->first_time ? &wpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get playback buffer position\n");
- return 0;
- }
-
- len = live << hwshift;
-
- if (ds->first_time) {
- if (conf.latency_millis) {
- DWORD cur_blat;
-
- cur_blat = audio_ring_dist (wpos, ppos, bufsize);
- ds->first_time = 0;
- old_pos = wpos;
- old_pos +=
- millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat;
- old_pos %= bufsize;
- old_pos &= ~hw->info.align;
- }
- else {
- old_pos = wpos;
- }
-#ifdef DEBUG_DSOUND
- ds->played = 0;
- ds->mixed = 0;
-#endif
- }
- else {
- if (ds->old_pos == ppos) {
-#ifdef DEBUG_DSOUND
- dolog ("old_pos == ppos\n");
-#endif
- return 0;
- }
-
-#ifdef DEBUG_DSOUND
- ds->played += audio_ring_dist (ds->old_pos, ppos, hw->bufsize);
-#endif
- old_pos = ds->old_pos;
- }
-
- if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
- len = ppos - old_pos;
- }
- else {
- if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
- len = bufsize - old_pos + ppos;
- }
- }
-
- if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
- dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
- len, bufsize, old_pos, ppos);
- return 0;
- }
-
- len &= ~hw->info.align;
- if (!len) {
- return 0;
- }
-
-#ifdef DEBUG_DSOUND
- ds->old_ppos = ppos;
-#endif
- err = dsound_lock_out (
- dsb,
- &hw->info,
- old_pos,
- len,
- &p1, &p2,
- &blen1, &blen2,
- 0
- );
- if (err) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && len1) {
- dsound_write_sample (hw, p1, len1);
- }
-
- if (p2 && len2) {
- dsound_write_sample (hw, p2, len2);
- }
-
- dsound_unlock_out (dsb, p1, p2, blen1, blen2);
- ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;
-
-#ifdef DEBUG_DSOUND
- ds->mixed += decr << hwshift;
-
- dolog ("played %lu mixed %lu diff %ld sec %f\n",
- ds->played,
- ds->mixed,
- ds->mixed - ds->played,
- abs (ds->mixed - ds->played) / (double) hw->info.bytes_per_second);
-#endif
- return decr;
-}
-
-static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- HRESULT hr;
- DWORD status;
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
-
- if (!dscb) {
- dolog ("Attempt to control capture voice without a buffer\n");
- return -1;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- dolog ("warning: Voice is already capturing\n");
- return 0;
- }
-
- /* clear ?? */
-
- hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not start capturing\n");
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- hr = IDirectSoundCaptureBuffer_Stop (dscb);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop capturing\n");
- return -1;
- }
- }
- else {
- dolog ("warning: Voice is not capturing\n");
- }
- break;
- }
- return 0;
-}
-
-static int dsound_read (SWVoiceIn *sw, void *buf, int len)
-{
- return audio_pcm_sw_read (sw, buf, len);
-}
-
-static int dsound_run_in (HWVoiceIn *hw)
-{
- int err;
- HRESULT hr;
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
- int live, len, dead;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD cpos, rpos;
- LPVOID p1, p2;
- int hwshift;
-
- if (!dscb) {
- dolog ("Attempt to run without capture buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- if (!dead) {
- return 0;
- }
-
- hr = IDirectSoundCaptureBuffer_GetCurrentPosition (
- dscb,
- &cpos,
- ds->first_time ? &rpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer position\n");
- return 0;
- }
-
- if (ds->first_time) {
- ds->first_time = 0;
- if (rpos & hw->info.align) {
- ldebug ("warning: Misaligned capture read position %ld(%d)\n",
- rpos, hw->info.align);
- }
- hw->wpos = rpos >> hwshift;
- }
-
- if (cpos & hw->info.align) {
- ldebug ("warning: Misaligned capture position %ld(%d)\n",
- cpos, hw->info.align);
- }
- cpos >>= hwshift;
-
- len = audio_ring_dist (cpos, hw->wpos, hw->samples);
- if (!len) {
- return 0;
- }
- len = audio_MIN (len, dead);
-
- err = dsound_lock_in (
- dscb,
- &hw->info,
- hw->wpos << hwshift,
- len << hwshift,
- &p1,
- &p2,
- &blen1,
- &blen2,
- 0
- );
- if (err) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && len1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
- }
-
- if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
- }
-
- dsound_unlock_in (dscb, p1, p2, blen1, blen2);
- hw->wpos = (hw->wpos + decr) % hw->samples;
- return decr;
-}
-
-static void dsound_audio_fini (void *opaque)
-{
- HRESULT hr;
- dsound *s = opaque;
-
- if (!s->dsound) {
- return;
- }
-
- hr = IDirectSound_Release (s->dsound);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSound\n");
- }
- s->dsound = NULL;
-
- if (!s->dsound_capture) {
- return;
- }
-
- hr = IDirectSoundCapture_Release (s->dsound_capture);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSoundCapture\n");
- }
- s->dsound_capture = NULL;
-}
-
-static void *dsound_audio_init (void)
-{
- int err;
- HRESULT hr;
- dsound *s = &glob_dsound;
-
- hr = CoInitialize (NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize COM\n");
- return NULL;
- }
-
- hr = CoCreateInstance (
- &CLSID_DirectSound,
- NULL,
- CLSCTX_ALL,
- &IID_IDirectSound,
- (void **) &s->dsound
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create DirectSound instance\n");
- return NULL;
- }
-
- hr = IDirectSound_Initialize (s->dsound, NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize DirectSound\n");
-
- hr = IDirectSound_Release (s->dsound);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSound\n");
- }
- s->dsound = NULL;
- return NULL;
- }
-
- hr = CoCreateInstance (
- &CLSID_DirectSoundCapture,
- NULL,
- CLSCTX_ALL,
- &IID_IDirectSoundCapture,
- (void **) &s->dsound_capture
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
- }
- else {
- hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
-
- hr = IDirectSoundCapture_Release (s->dsound_capture);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSoundCapture\n");
- }
- s->dsound_capture = NULL;
- }
- }
-
- err = dsound_open (s);
- if (err) {
- dsound_audio_fini (s);
- return NULL;
- }
-
- return s;
-}
-
-static struct audio_option dsound_options[] = {
- {"LOCK_RETRIES", AUD_OPT_INT, &conf.lock_retries,
- "Number of times to attempt locking the buffer", NULL, 0},
- {"RESTOURE_RETRIES", AUD_OPT_INT, &conf.restore_retries,
- "Number of times to attempt restoring the buffer", NULL, 0},
- {"GETSTATUS_RETRIES", AUD_OPT_INT, &conf.getstatus_retries,
- "Number of times to attempt getting status of the buffer", NULL, 0},
- {"SET_PRIMARY", AUD_OPT_BOOL, &conf.set_primary,
- "Set the parameters of primary buffer", NULL, 0},
- {"LATENCY_MILLIS", AUD_OPT_INT, &conf.latency_millis,
- "(undocumented)", NULL, 0},
- {"PRIMARY_FREQ", AUD_OPT_INT, &conf.settings.freq,
- "Primary buffer frequency", NULL, 0},
- {"PRIMARY_CHANNELS", AUD_OPT_INT, &conf.settings.nchannels,
- "Primary buffer number of channels (1 - mono, 2 - stereo)", NULL, 0},
- {"PRIMARY_FMT", AUD_OPT_FMT, &conf.settings.fmt,
- "Primary buffer format", NULL, 0},
- {"BUFSIZE_OUT", AUD_OPT_INT, &conf.bufsize_out,
- "(undocumented)", NULL, 0},
- {"BUFSIZE_IN", AUD_OPT_INT, &conf.bufsize_in,
- "(undocumented)", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops dsound_pcm_ops = {
- dsound_init_out,
- dsound_fini_out,
- dsound_run_out,
- dsound_write,
- dsound_ctl_out,
-
- dsound_init_in,
- dsound_fini_in,
- dsound_run_in,
- dsound_read,
- dsound_ctl_in
-};
-
-struct audio_driver dsound_audio_driver = {
- INIT_FIELD (name = ) "dsound",
- INIT_FIELD (descr = )
- "DirectSound http://wikipedia.org/wiki/DirectSound",
- INIT_FIELD (options = ) dsound_options,
- INIT_FIELD (init = ) dsound_audio_init,
- INIT_FIELD (fini = ) dsound_audio_fini,
- INIT_FIELD (pcm_ops = ) &dsound_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) 1,
- INIT_FIELD (voice_size_out = ) sizeof (DSoundVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (DSoundVoiceIn)
-};
diff --git a/tools/ioemu/audio/fmodaudio.c b/tools/ioemu/audio/fmodaudio.c
deleted file mode 100644
index 5875ba15e1..0000000000
--- a/tools/ioemu/audio/fmodaudio.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * QEMU FMOD audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <fmod.h>
-#include <fmod_errors.h>
-#include "vl.h"
-
-#define AUDIO_CAP "fmod"
-#include "audio_int.h"
-
-typedef struct FMODVoiceOut {
- HWVoiceOut hw;
- unsigned int old_pos;
- FSOUND_SAMPLE *fmod_sample;
- int channel;
-} FMODVoiceOut;
-
-typedef struct FMODVoiceIn {
- HWVoiceIn hw;
- FSOUND_SAMPLE *fmod_sample;
-} FMODVoiceIn;
-
-static struct {
- const char *drvname;
- int nb_samples;
- int freq;
- int nb_channels;
- int bufsize;
- int threshold;
- int broken_adc;
-} conf = {
- NULL,
- 2048 * 2,
- 44100,
- 2,
- 0,
- 0,
- 0
-};
-
-static void GCC_FMT_ATTR (1, 2) fmod_logerr (const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n",
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n",
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static int fmod_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static void fmod_clear_sample (FMODVoiceOut *fmd)
-{
- HWVoiceOut *hw = &fmd->hw;
- int status;
- void *p1 = 0, *p2 = 0;
- unsigned int len1 = 0, len2 = 0;
-
- status = FSOUND_Sample_Lock (
- fmd->fmod_sample,
- 0,
- hw->samples << hw->info.shift,
- &p1,
- &p2,
- &len1,
- &len2
- );
-
- if (!status) {
- fmod_logerr ("Failed to lock sample\n");
- return;
- }
-
- if ((len1 & hw->info.align) || (len2 & hw->info.align)) {
- dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
- len1, len2, hw->info.align + 1);
- goto fail;
- }
-
- if ((len1 + len2) - (hw->samples << hw->info.shift)) {
- dolog ("Lock returned incomplete length %d, %d\n",
- len1 + len2, hw->samples << hw->info.shift);
- goto fail;
- }
-
- audio_pcm_info_clear_buf (&hw->info, p1, hw->samples);
-
- fail:
- status = FSOUND_Sample_Unlock (fmd->fmod_sample, p1, p2, len1, len2);
- if (!status) {
- fmod_logerr ("Failed to unlock sample\n");
- }
-}
-
-static void fmod_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
-{
- int src_len1 = dst_len;
- int src_len2 = 0;
- int pos = hw->rpos + dst_len;
- st_sample_t *src1 = hw->mix_buf + hw->rpos;
- st_sample_t *src2 = NULL;
-
- if (pos > hw->samples) {
- src_len1 = hw->samples - hw->rpos;
- src2 = hw->mix_buf;
- src_len2 = dst_len - src_len1;
- pos = src_len2;
- }
-
- if (src_len1) {
- hw->clip (dst, src1, src_len1);
- }
-
- if (src_len2) {
- dst = advance (dst, src_len1 << hw->info.shift);
- hw->clip (dst, src2, src_len2);
- }
-
- hw->rpos = pos % hw->samples;
-}
-
-static int fmod_unlock_sample (FSOUND_SAMPLE *sample, void *p1, void *p2,
- unsigned int blen1, unsigned int blen2)
-{
- int status = FSOUND_Sample_Unlock (sample, p1, p2, blen1, blen2);
- if (!status) {
- fmod_logerr ("Failed to unlock sample\n");
- return -1;
- }
- return 0;
-}
-
-static int fmod_lock_sample (
- FSOUND_SAMPLE *sample,
- struct audio_pcm_info *info,
- int pos,
- int len,
- void **p1,
- void **p2,
- unsigned int *blen1,
- unsigned int *blen2
- )
-{
- int status;
-
- status = FSOUND_Sample_Lock (
- sample,
- pos << info->shift,
- len << info->shift,
- p1,
- p2,
- blen1,
- blen2
- );
-
- if (!status) {
- fmod_logerr ("Failed to lock sample\n");
- return -1;
- }
-
- if ((*blen1 & info->align) || (*blen2 & info->align)) {
- dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
- *blen1, *blen2, info->align + 1);
-
- fmod_unlock_sample (sample, *p1, *p2, *blen1, *blen2);
-
- *p1 = NULL - 1;
- *p2 = NULL - 1;
- *blen1 = ~0U;
- *blen2 = ~0U;
- return -1;
- }
-
- if (!*p1 && *blen1) {
- dolog ("warning: !p1 && blen1=%d\n", *blen1);
- *blen1 = 0;
- }
-
- if (!p2 && *blen2) {
- dolog ("warning: !p2 && blen2=%d\n", *blen2);
- *blen2 = 0;
- }
-
- return 0;
-}
-
-static int fmod_run_out (HWVoiceOut *hw)
-{
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
- int live, decr;
- void *p1 = 0, *p2 = 0;
- unsigned int blen1 = 0, blen2 = 0;
- unsigned int len1 = 0, len2 = 0;
- int nb_live;
-
- live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
- if (!live) {
- return 0;
- }
-
- if (!hw->pending_disable
- && nb_live
- && (conf.threshold && live <= conf.threshold)) {
- ldebug ("live=%d nb_live=%d\n", live, nb_live);
- return 0;
- }
-
- decr = live;
-
- if (fmd->channel >= 0) {
- int len = decr;
- int old_pos = fmd->old_pos;
- int ppos = FSOUND_GetCurrentPosition (fmd->channel);
-
- if (ppos == old_pos || !ppos) {
- return 0;
- }
-
- if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
- len = ppos - old_pos;
- }
- else {
- if ((old_pos > ppos) && ((old_pos + len) > (ppos + hw->samples))) {
- len = hw->samples - old_pos + ppos;
- }
- }
- decr = len;
-
- if (audio_bug (AUDIO_FUNC, decr < 0)) {
- dolog ("decr=%d live=%d ppos=%d old_pos=%d len=%d\n",
- decr, live, ppos, old_pos, len);
- return 0;
- }
- }
-
-
- if (!decr) {
- return 0;
- }
-
- if (fmod_lock_sample (fmd->fmod_sample, &fmd->hw.info,
- fmd->old_pos, decr,
- &p1, &p2,
- &blen1, &blen2)) {
- return 0;
- }
-
- len1 = blen1 >> hw->info.shift;
- len2 = blen2 >> hw->info.shift;
- ldebug ("%p %p %d %d %d %d\n", p1, p2, len1, len2, blen1, blen2);
- decr = len1 + len2;
-
- if (p1 && len1) {
- fmod_write_sample (hw, p1, len1);
- }
-
- if (p2 && len2) {
- fmod_write_sample (hw, p2, len2);
- }
-
- fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);
-
- fmd->old_pos = (fmd->old_pos + decr) % hw->samples;
- return decr;
-}
-
-static int aud_to_fmodfmt (audfmt_e fmt, int stereo)
-{
- int mode = FSOUND_LOOP_NORMAL;
-
- switch (fmt) {
- case AUD_FMT_S8:
- mode |= FSOUND_SIGNED | FSOUND_8BITS;
- break;
-
- case AUD_FMT_U8:
- mode |= FSOUND_UNSIGNED | FSOUND_8BITS;
- break;
-
- case AUD_FMT_S16:
- mode |= FSOUND_SIGNED | FSOUND_16BITS;
- break;
-
- case AUD_FMT_U16:
- mode |= FSOUND_UNSIGNED | FSOUND_16BITS;
- break;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_FMOD
- abort ();
-#endif
- mode |= FSOUND_8BITS;
- }
- mode |= stereo ? FSOUND_STEREO : FSOUND_MONO;
- return mode;
-}
-
-static void fmod_fini_out (HWVoiceOut *hw)
-{
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-
- if (fmd->fmod_sample) {
- FSOUND_Sample_Free (fmd->fmod_sample);
- fmd->fmod_sample = 0;
-
- if (fmd->channel >= 0) {
- FSOUND_StopSound (fmd->channel);
- }
- }
-}
-
-static int fmod_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- int bits16, mode, channel;
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
- audsettings_t obt_as = *as;
-
- mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
- fmd->fmod_sample = FSOUND_Sample_Alloc (
- FSOUND_FREE, /* index */
- conf.nb_samples, /* length */
- mode, /* mode */
- as->freq, /* freq */
- 255, /* volume */
- 128, /* pan */
- 255 /* priority */
- );
-
- if (!fmd->fmod_sample) {
- fmod_logerr2 ("DAC", "Failed to allocate FMOD sample\n");
- return -1;
- }
-
- channel = FSOUND_PlaySoundEx (FSOUND_FREE, fmd->fmod_sample, 0, 1);
- if (channel < 0) {
- fmod_logerr2 ("DAC", "Failed to start playing sound\n");
- FSOUND_Sample_Free (fmd->fmod_sample);
- return -1;
- }
- fmd->channel = channel;
-
- /* FMOD always operates on little endian frames? */
- obt_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &obt_as);
- bits16 = (mode & FSOUND_16BITS) != 0;
- hw->samples = conf.nb_samples;
- return 0;
-}
-
-static int fmod_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- int status;
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- fmod_clear_sample (fmd);
- status = FSOUND_SetPaused (fmd->channel, 0);
- if (!status) {
- fmod_logerr ("Failed to resume channel %d\n", fmd->channel);
- }
- break;
-
- case VOICE_DISABLE:
- status = FSOUND_SetPaused (fmd->channel, 1);
- if (!status) {
- fmod_logerr ("Failed to pause channel %d\n", fmd->channel);
- }
- break;
- }
- return 0;
-}
-
-static int fmod_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- int bits16, mode;
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
- audsettings_t obt_as = *as;
-
- if (conf.broken_adc) {
- return -1;
- }
-
- mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
- fmd->fmod_sample = FSOUND_Sample_Alloc (
- FSOUND_FREE, /* index */
- conf.nb_samples, /* length */
- mode, /* mode */
- as->freq, /* freq */
- 255, /* volume */
- 128, /* pan */
- 255 /* priority */
- );
-
- if (!fmd->fmod_sample) {
- fmod_logerr2 ("ADC", "Failed to allocate FMOD sample\n");
- return -1;
- }
-
- /* FMOD always operates on little endian frames? */
- obt_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &obt_as);
- bits16 = (mode & FSOUND_16BITS) != 0;
- hw->samples = conf.nb_samples;
- return 0;
-}
-
-static void fmod_fini_in (HWVoiceIn *hw)
-{
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-
- if (fmd->fmod_sample) {
- FSOUND_Record_Stop ();
- FSOUND_Sample_Free (fmd->fmod_sample);
- fmd->fmod_sample = 0;
- }
-}
-
-static int fmod_run_in (HWVoiceIn *hw)
-{
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
- int hwshift = hw->info.shift;
- int live, dead, new_pos, len;
- unsigned int blen1 = 0, blen2 = 0;
- unsigned int len1, len2;
- unsigned int decr;
- void *p1, *p2;
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- if (!dead) {
- return 0;
- }
-
- new_pos = FSOUND_Record_GetPosition ();
- if (new_pos < 0) {
- fmod_logerr ("Could not get recording position\n");
- return 0;
- }
-
- len = audio_ring_dist (new_pos, hw->wpos, hw->samples);
- if (!len) {
- return 0;
- }
- len = audio_MIN (len, dead);
-
- if (fmod_lock_sample (fmd->fmod_sample, &fmd->hw.info,
- hw->wpos, len,
- &p1, &p2,
- &blen1, &blen2)) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && blen1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
- }
- if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
- }
-
- fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);
- hw->wpos = (hw->wpos + decr) % hw->samples;
- return decr;
-}
-
-static struct {
- const char *name;
- int type;
-} drvtab[] = {
- {"none", FSOUND_OUTPUT_NOSOUND},
-#ifdef _WIN32
- {"winmm", FSOUND_OUTPUT_WINMM},
- {"dsound", FSOUND_OUTPUT_DSOUND},
- {"a3d", FSOUND_OUTPUT_A3D},
- {"asio", FSOUND_OUTPUT_ASIO},
-#endif
-#ifdef __linux__
- {"oss", FSOUND_OUTPUT_OSS},
- {"alsa", FSOUND_OUTPUT_ALSA},
- {"esd", FSOUND_OUTPUT_ESD},
-#endif
-#ifdef __APPLE__
- {"mac", FSOUND_OUTPUT_MAC},
-#endif
-#if 0
- {"xbox", FSOUND_OUTPUT_XBOX},
- {"ps2", FSOUND_OUTPUT_PS2},
- {"gcube", FSOUND_OUTPUT_GC},
-#endif
- {"none-realtime", FSOUND_OUTPUT_NOSOUND_NONREALTIME}
-};
-
-static void *fmod_audio_init (void)
-{
- size_t i;
- double ver;
- int status;
- int output_type = -1;
- const char *drv = conf.drvname;
-
- ver = FSOUND_GetVersion ();
- if (ver < FMOD_VERSION) {
- dolog ("Wrong FMOD version %f, need at least %f\n", ver, FMOD_VERSION);
- return NULL;
- }
-
-#ifdef __linux__
- if (ver < 3.75) {
- dolog ("FMOD before 3.75 has bug preventing ADC from working\n"
- "ADC will be disabled.\n");
- conf.broken_adc = 1;
- }
-#endif
-
- if (drv) {
- int found = 0;
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (!strcmp (drv, drvtab[i].name)) {
- output_type = drvtab[i].type;
- found = 1;
- break;
- }
- }
- if (!found) {
- dolog ("Unknown FMOD driver `%s'\n", drv);
- dolog ("Valid drivers:\n");
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- dolog (" %s\n", drvtab[i].name);
- }
- }
- }
-
- if (output_type != -1) {
- status = FSOUND_SetOutput (output_type);
- if (!status) {
- fmod_logerr ("FSOUND_SetOutput(%d) failed\n", output_type);
- return NULL;
- }
- }
-
- if (conf.bufsize) {
- status = FSOUND_SetBufferSize (conf.bufsize);
- if (!status) {
- fmod_logerr ("FSOUND_SetBufferSize (%d) failed\n", conf.bufsize);
- }
- }
-
- status = FSOUND_Init (conf.freq, conf.nb_channels, 0);
- if (!status) {
- fmod_logerr ("FSOUND_Init failed\n");
- return NULL;
- }
-
- return &conf;
-}
-
-static int fmod_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int fmod_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- int status;
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- status = FSOUND_Record_StartSample (fmd->fmod_sample, 1);
- if (!status) {
- fmod_logerr ("Failed to start recording\n");
- }
- break;
-
- case VOICE_DISABLE:
- status = FSOUND_Record_Stop ();
- if (!status) {
- fmod_logerr ("Failed to stop recording\n");
- }
- break;
- }
- return 0;
-}
-
-static void fmod_audio_fini (void *opaque)
-{
- (void) opaque;
- FSOUND_Close ();
-}
-
-static struct audio_option fmod_options[] = {
- {"DRV", AUD_OPT_STR, &conf.drvname,
- "FMOD driver", NULL, 0},
- {"FREQ", AUD_OPT_INT, &conf.freq,
- "Default frequency", NULL, 0},
- {"SAMPLES", AUD_OPT_INT, &conf.nb_samples,
- "Buffer size in samples", NULL, 0},
- {"CHANNELS", AUD_OPT_INT, &conf.nb_channels,
- "Number of default channels (1 - mono, 2 - stereo)", NULL, 0},
- {"BUFSIZE", AUD_OPT_INT, &conf.bufsize,
- "(undocumented)", NULL, 0},
-#if 0
- {"THRESHOLD", AUD_OPT_INT, &conf.threshold,
- "(undocumented)"},
-#endif
-
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops fmod_pcm_ops = {
- fmod_init_out,
- fmod_fini_out,
- fmod_run_out,
- fmod_write,
- fmod_ctl_out,
-
- fmod_init_in,
- fmod_fini_in,
- fmod_run_in,
- fmod_read,
- fmod_ctl_in
-};
-
-struct audio_driver fmod_audio_driver = {
- INIT_FIELD (name = ) "fmod",
- INIT_FIELD (descr = ) "FMOD 3.xx http://www.fmod.org",
- INIT_FIELD (options = ) fmod_options,
- INIT_FIELD (init = ) fmod_audio_init,
- INIT_FIELD (fini = ) fmod_audio_fini,
- INIT_FIELD (pcm_ops = ) &fmod_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 (FMODVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (FMODVoiceIn)
-};
diff --git a/tools/ioemu/audio/mixeng.c b/tools/ioemu/audio/mixeng.c
deleted file mode 100644
index 74f79958a3..0000000000
--- a/tools/ioemu/audio/mixeng.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * 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
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define AUDIO_CAP "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 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
-#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
-#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
-#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] = {
-#ifndef _BSD
- {
- {
- {
- 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_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
- }
- }
- }
-#endif /* !_BSD */
-};
-
-f_sample *mixeng_clip[2][2][2][2] = {
-#ifndef _BSD
- {
- {
- {
- 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_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
- }
- }
- }
-#endif /* !_BSD */
-};
-
-/*
- * August 21, 1998
- * Copyright 1998 Fabrice Bellard.
- *
- * [Rewrote completly the code of Lance Norskog And Sundry
- * 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.
- */
-
-/*
- * Sound Tools rate change effect file.
- */
-/*
- * Linear Interpolation.
- *
- * The use of fractional increment allows us to use no buffer. It
- * avoid the problems at the end of the buffer we had with the old
- * method which stored a possibly big buffer of size
- * lcm(in_rate,out_rate).
- *
- * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
- * the input & output frequencies are equal, a delay of one sample is
- * introduced. Limited to processing 32-bit count worth of samples.
- *
- * 1 << FRAC_BITS evaluating to zero in several places. Changed with
- * an (unsigned long) cast to make it safe. MarkMLl 2/1/99
- */
-
-/* Private data */
-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 */
-};
-
-/*
- * Prepare processing.
- */
-void *st_rate_start (int inrate, int outrate)
-{
- struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
-
- if (!rate) {
- dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
- return NULL;
- }
-
- rate->opos = 0;
-
- /* increment */
- rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
-
- rate->ipos = 0;
- rate->ilast.l = 0;
- rate->ilast.r = 0;
- return rate;
-}
-
-#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 --git a/tools/ioemu/audio/mixeng.h b/tools/ioemu/audio/mixeng.h
deleted file mode 100644
index 9e3bac1744..0000000000
--- a/tools/ioemu/audio/mixeng.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * QEMU Mixing engine header
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_MIXENG_H
-#define QEMU_MIXENG_H
-
-#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
-
-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 --git a/tools/ioemu/audio/mixeng_template.h b/tools/ioemu/audio/mixeng_template.h
deleted file mode 100644
index d726441e2e..0000000000
--- a/tools/ioemu/audio/mixeng_template.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * Tusen tack till Mike Nordell
- * dec++'ified by Dscho
- */
-
-#ifndef SIGNED
-#define HALF (IN_MAX >> 1)
-#endif
-
-#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 nv * (1.f / (real_t) (IN_MAX - IN_MIN));
-#else
- 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_, ET) (real_t v)
-{
- if (v >= 0.5) {
- return IN_MAX;
- }
- else if (v < -0.5) {
- return IN_MIN;
- }
-
-#ifdef SIGNED
- return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
-#else
- return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
-#endif
-}
-
-#else /* !FLOAT_MIXENG */
-
-static inline int64_t glue (conv_, ET) (IN_T v)
-{
- 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 = VOL (glue (conv_, ET) (*in++), vol->l);
- out->r = VOL (glue (conv_, ET) (*in++), vol->r);
- out += 1;
- }
-}
-
-static void glue (glue (conv_, ET), _to_mono)
- (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 = VOL (glue (conv_, ET) (in[0]), vol->l);
- out->r = out->l;
- out += 1;
- in += 1;
- }
-}
-
-static void glue (glue (clip_, ET), _from_stereo)
- (void *dst, const st_sample_t *src, int samples)
-{
- const st_sample_t *in = src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue (clip_, ET) (in->l);
- *out++ = glue (clip_, ET) (in->r);
- in += 1;
- }
-}
-
-static void glue (glue (clip_, ET), _from_mono)
- (void *dst, const st_sample_t *src, int samples)
-{
- const st_sample_t *in = src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue (clip_, ET) (in->l + in->r);
- in += 1;
- }
-}
-
-#undef ET
-#undef HALF
-#undef VOL
diff --git a/tools/ioemu/audio/noaudio.c b/tools/ioemu/audio/noaudio.c
deleted file mode 100644
index a3423e5eb1..0000000000
--- a/tools/ioemu/audio/noaudio.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define AUDIO_CAP "noaudio"
-#include "audio_int.h"
-
-typedef struct NoVoiceOut {
- HWVoiceOut hw;
- int64_t old_ticks;
-} NoVoiceOut;
-
-typedef struct NoVoiceIn {
- HWVoiceIn hw;
- int64_t old_ticks;
-} NoVoiceIn;
-
-static int no_run_out (HWVoiceOut *hw)
-{
- NoVoiceOut *no = (NoVoiceOut *) hw;
- int live, decr, samples;
- int64_t now;
- int64_t ticks;
- int64_t bytes;
-
- live = audio_pcm_hw_get_live_out (&no->hw);
- if (!live) {
- return 0;
- }
-
- now = qemu_get_clock (vm_clock);
- ticks = now - no->old_ticks;
- bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
- bytes = audio_MIN (bytes, INT_MAX);
- samples = bytes >> hw->info.shift;
-
- no->old_ticks = now;
- decr = audio_MIN (live, samples);
- hw->rpos = (hw->rpos + decr) % hw->samples;
- return decr;
-}
-
-static int no_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int no_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- audio_pcm_init_info (&hw->info, as);
- hw->samples = 1024;
- return 0;
-}
-
-static void no_fini_out (HWVoiceOut *hw)
-{
- (void) hw;
-}
-
-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);
- 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;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- int samples = 0;
-
- if (dead) {
- int64_t now = qemu_get_clock (vm_clock);
- int64_t ticks = now - no->old_ticks;
- int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
-
- no->old_ticks = now;
- bytes = audio_MIN (bytes, INT_MAX);
- samples = bytes >> hw->info.shift;
- samples = audio_MIN (samples, dead);
- }
- return samples;
-}
-
-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;
- return 0;
-}
-
-static void *no_audio_init (void)
-{
- return &no_audio_init;
-}
-
-static void no_audio_fini (void *opaque)
-{
- (void) opaque;
-}
-
-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_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 --git a/tools/ioemu/audio/ossaudio.c b/tools/ioemu/audio/ossaudio.c
deleted file mode 100644
index bf5932e114..0000000000
--- a/tools/ioemu/audio/ossaudio.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * 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
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#if defined(__OpenBSD__)
-#include <soundcard.h>
-#else
-#include <sys/soundcard.h>
-#endif
-#include "vl.h"
-
-#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;
-} 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 *devpath_out;
- const char *devpath_in;
- int debug;
-} conf = {
- .try_mmap = 0,
- .nfrags = 4,
- .fragsize = 4096,
- .devpath_out = "/dev/dsp",
- .devpath_in = "/dev/dsp",
- .debug = 0
-};
-
-struct oss_params {
- int freq;
- audfmt_e fmt;
- int nchannels;
- int nfrags;
- int fragsize;
-};
-
-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;
-
- default:
- 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 ("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 ("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);
-}
-#endif
-
-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 = 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) {
- oss_logerr2 (errno, typ, "Failed to open `%s'\n", dspname);
- return -1;
- }
-
- freq = req->freq;
- nchannels = req->nchannels;
- fmt = req->fmt;
-
- if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
- oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
- oss_logerr2 (errno, typ, "Failed to set number of channels %d\n",
- req->nchannels);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
- oss_logerr2 (errno, typ, "Failed to set frequency %d\n", req->freq);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_NONBLOCK, NULL)) {
- 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)) {
- oss_logerr2 (errno, typ, "Failed to set buffer length (%d, %d)\n",
- req->nfrags, req->fragsize);
- goto err;
- }
-
- if (ioctl (fd, in ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) {
- oss_logerr2 (errno, typ, "Failed to get buffer length\n");
- goto err;
- }
-
- obt->fmt = fmt;
- obt->nchannels = nchannels;
- obt->freq = freq;
- obt->nfrags = abinfo.fragstotal;
- 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)) {
- dolog ("Audio parameters mismatch\n");
- oss_dump_info (req, obt);
- }
-#endif
-
-#ifdef DEBUG
- oss_dump_info (req, obt);
-#endif
- return 0;
-
- err:
- oss_anal_close (&fd);
- return -1;
-}
-
-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;
- 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) {
- oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
- return 0;
- }
-
- if (cntinfo.ptr == oss->old_optr) {
- 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 = 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) {
- oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
- return 0;
- }
-
- if (abinfo.bytes > bufsize) {
- if (conf.debug) {
- dolog ("warning: Invalid available size, size=%d bufsize=%d\n"
- "please report your OS/audio hw to malc@pulsesoft.com\n",
- abinfo.bytes, bufsize);
- }
- abinfo.bytes = bufsize;
- }
-
- if (abinfo.bytes < 0) {
- if (conf.debug) {
- dolog ("warning: Invalid available size, size=%d bufsize=%d\n",
- abinfo.bytes, bufsize);
- }
- return 0;
- }
-
- decr = audio_MIN (abinfo.bytes >> hw->info.shift, live);
- if (!decr) {
- return 0;
- }
- }
-
- 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 = 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->info.shift);
- /* XXX: follow errno recommendations ? */
- if (written == -1) {
- 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->info.shift) {
- int wsamples = written >> hw->info.shift;
- int wbytes = wsamples << hw->info.shift;
- if (wbytes != written) {
- dolog ("warning: Misaligned write %d (requested %d), "
- "alignment %d\n",
- wbytes, written, hw->info.align + 1);
- }
- decr -= wsamples;
- rpos = (rpos + wsamples) % hw->samples;
- break;
- }
- }
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- }
- if (oss->mmapped) {
- oss->old_optr = cntinfo.ptr;
- }
-
- hw->rpos = rpos;
- return decr;
-}
-
-static void oss_fini_out (HWVoiceOut *hw)
-{
- int err;
- 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->samples << hw->info.shift);
- if (err) {
- oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",
- oss->pcm_buf, hw->samples << hw->info.shift);
- }
- }
- else {
- qemu_free (oss->pcm_buf);
- }
- oss->pcm_buf = NULL;
- }
-}
-
-static int oss_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- OSSVoiceOut *oss = (OSSVoiceOut *) 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 (0, &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;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- oss->nfrags = obt.nfrags;
- oss->fragsize = 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->samples << hw->info.shift,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- fd,
- 0
- );
- if (oss->pcm_buf == MAP_FAILED) {
- oss_logerr (errno, "Failed to map %d bytes of DAC\n",
- hw->samples << hw->info.shift);
- } else {
- int err;
- int trig = 0;
- if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
- }
- else {
- trig = PCM_ENABLE_OUTPUT;
- if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (
- errno,
- "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- );
- }
- else {
- oss->mmapped = 1;
- }
- }
-
- if (!oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
- if (err) {
- 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 = audio_calloc (
- AUDIO_FUNC,
- hw->samples,
- 1 << hw->info.shift
- );
- if (!oss->pcm_buf) {
- 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_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- int trig;
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
-
- if (!oss->mmapped) {
- return 0;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- ldebug ("enabling voice\n");
- 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) {
- oss_logerr (
- errno,
- "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- );
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- trig = 0;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
- return -1;
- }
- break;
- }
- 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;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- 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)
-{
- return &conf;
-}
-
-static void oss_audio_fini (void *opaque)
-{
- (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},
- {"DEBUG", AUD_OPT_BOOL, &conf.debug,
- "Turn on some debugging messages", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-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 --git a/tools/ioemu/audio/rate_template.h b/tools/ioemu/audio/rate_template.h
deleted file mode 100644
index 398d305e92..0000000000
--- a/tools/ioemu/audio/rate_template.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * 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
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-void NAME (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
- int *isamp, int *osamp)
-{
- struct rate *rate = opaque;
- st_sample_t *istart, *iend;
- st_sample_t *ostart, *oend;
- st_sample_t ilast, icur, out;
-#ifdef FLOAT_MIXENG
- real_t t;
-#else
- int64_t t;
-#endif
-
- ilast = rate->ilast;
-
- istart = ibuf;
- iend = ibuf + *isamp;
-
- ostart = obuf;
- oend = obuf + *osamp;
-
- if (rate->opos_inc == (1ULL + UINT_MAX)) {
- int i, n = *isamp > *osamp ? *osamp : *isamp;
- for (i = 0; i < n; i++) {
- OP (obuf[i].l, ibuf[i].l);
- OP (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 */
-#ifdef FLOAT_MIXENG
-#ifdef RECIPROCAL
- t = (rate->opos & UINT_MAX) * (1.f / UINT_MAX);
-#else
- t = (rate->opos & UINT_MAX) / (real_t) UINT_MAX;
-#endif
- out.l = (ilast.l * (1.0 - t)) + icur.l * t;
- out.r = (ilast.r * (1.0 - t)) + icur.r * t;
-#else
- t = rate->opos & 0xffffffff;
- out.l = (ilast.l * ((int64_t) UINT_MAX - t) + icur.l * t) >> 32;
- out.r = (ilast.r * ((int64_t) UINT_MAX - t) + icur.r * t) >> 32;
-#endif
-
- /* output sample & increment position */
- OP (obuf->l, out.l);
- OP (obuf->r, out.r);
- obuf += 1;
- rate->opos += rate->opos_inc;
- }
-
-the_end:
- *isamp = ibuf - istart;
- *osamp = obuf - ostart;
- rate->ilast = ilast;
-}
-
-#undef NAME
-#undef OP
diff --git a/tools/ioemu/audio/sdlaudio.c b/tools/ioemu/audio/sdlaudio.c
deleted file mode 100644
index f2a6896a52..0000000000
--- a/tools/ioemu/audio/sdlaudio.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * 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
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <SDL.h>
-#include <SDL_thread.h>
-#include "vl.h"
-
-#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;
-} conf = {
- 1024
-};
-
-struct SDLAudioState {
- int exit;
- SDL_mutex *mutex;
- SDL_sem *sem;
- int initialized;
-} glob_sdl;
-typedef struct SDLAudioState SDLAudioState;
-
-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)) {
- 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)) {
- 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)) {
- 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)) {
- 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:
- *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\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 ("Unrecognized SDL audio format %d\n", sdlfmt);
- return -1;
- }
-
- return 0;
-}
-
-static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
-{
- int status;
-
- status = SDL_OpenAudio (req, obt);
- if (status) {
- sdl_logerr ("SDL_OpenAudio failed\n");
- }
- return status;
-}
-
-static void sdl_close (SDLAudioState *s)
-{
- if (s->initialized) {
- sdl_lock (s, "sdl_close");
- s->exit = 1;
- sdl_unlock_and_post (s, "sdl_close");
- SDL_PauseAudio (1);
- SDL_CloseAudio ();
- s->initialized = 0;
- }
-}
-
-static void sdl_callback (void *opaque, Uint8 *buf, int len)
-{
- SDLVoiceOut *sdl = opaque;
- SDLAudioState *s = &glob_sdl;
- HWVoiceOut *hw = &sdl->hw;
- int samples = len >> hw->info.shift;
-
- if (s->exit) {
- return;
- }
-
- while (samples) {
- int to_mix, decr;
-
- /* dolog ("in callback samples=%d\n", samples); */
- sdl_wait (s, "sdl_callback");
- if (s->exit) {
- return;
- }
-
- 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, sdl->live);
- decr = to_mix;
- while (to_mix) {
- int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
- st_sample_t *src = hw->mix_buf + hw->rpos;
-
- /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
- hw->clip (buf, src, chunk);
- sdl->rpos = (sdl->rpos + chunk) % hw->samples;
- to_mix -= chunk;
- buf += chunk << hw->info.shift;
- }
- samples -= decr;
- sdl->live -= decr;
- sdl->decr += decr;
-
- again:
- if (sdl_unlock (s, "sdl_callback")) {
- return;
- }
- }
- /* dolog ("done len=%d\n", len); */
-}
-
-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_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
- SDLAudioState *s = &glob_sdl;
- SDL_AudioSpec req, obt;
- int shift;
- 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;
- req.callback = sdl_callback;
- req.userdata = sdl;
-
- 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;
- obt_as.endianness = endianess;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- s->initialized = 1;
- s->exit = 0;
- SDL_PauseAudio (0);
- return 0;
-}
-
-static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- SDL_PauseAudio (0);
- break;
-
- case VOICE_DISABLE:
- SDL_PauseAudio (1);
- break;
- }
- return 0;
-}
-
-static void *sdl_audio_init (void)
-{
- SDLAudioState *s = &glob_sdl;
-
- if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
- sdl_logerr ("SDL failed to initialize audio subsystem\n");
- return NULL;
- }
-
- s->mutex = SDL_CreateMutex ();
- if (!s->mutex) {
- sdl_logerr ("Failed to create SDL mutex\n");
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-
- s->sem = SDL_CreateSemaphore (0);
- if (!s->sem) {
- sdl_logerr ("Failed to create SDL semaphore\n");
- SDL_DestroyMutex (s->mutex);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-
- return s;
-}
-
-static void sdl_audio_fini (void *opaque)
-{
- SDLAudioState *s = opaque;
- sdl_close (s);
- SDL_DestroySemaphore (s->sem);
- SDL_DestroyMutex (s->mutex);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
-}
-
-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}
-};
-
-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 --git a/tools/ioemu/audio/sys-queue.h b/tools/ioemu/audio/sys-queue.h
deleted file mode 100644
index 857e1f3998..0000000000
--- a/tools/ioemu/audio/sys-queue.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.3 (Berkeley) 12/13/93
- */
-
-#ifndef _SYS_QUEUE_H
-#define _SYS_QUEUE_H 1
-
-/*
- * This file defines three types of data structures: lists, tail queues,
- * and circular queues.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list after
- * an existing element or at the head of the list. A list may only be
- * traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list after
- * an existing element, at the head of the list, or at the end of the
- * list. A tail queue may only be traversed in the forward direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) { \
- (head)->lh_first = NULL; \
-}
-
-#define LIST_INSERT_AFTER(listelm, elm, field) { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-}
-
-#define LIST_INSERT_HEAD(head, elm, field) { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-}
-
-#define LIST_REMOVE(elm, field) { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-}
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-}
-
-#define TAILQ_INSERT_HEAD(head, elm, field) { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-}
-
-#define TAILQ_INSERT_TAIL(head, elm, field) { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-}
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-}
-
-#define TAILQ_REMOVE(head, elm, field) { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-}
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-}
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-}
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-}
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-}
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-}
-
-#define CIRCLEQ_REMOVE(head, elm, field) { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-}
-#endif /* sys/queue.h */
diff --git a/tools/ioemu/audio/wavaudio.c b/tools/ioemu/audio/wavaudio.c
deleted file mode 100644
index a552b7e973..0000000000
--- a/tools/ioemu/audio/wavaudio.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * 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
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define AUDIO_CAP "wav"
-#include "audio_int.h"
-
-typedef struct WAVVoiceOut {
- HWVoiceOut hw;
- QEMUFile *f;
- int64_t old_ticks;
- void *pcm_buf;
- int total_samples;
-} WAVVoiceOut;
-
-static struct {
- audsettings_t settings;
- const char *wav_path;
-} conf = {
- {
- 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->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);
- 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 = 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->info.shift);
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- wav->total_samples += convert_samples;
- }
-
- hw->rpos = rpos;
- 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. */
-static void le_store (uint8_t *buf, uint32_t val, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- buf[i] = (uint8_t) (val & 0xff);
- val >>= 8;
- }
-}
-
-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
- };
- 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:
- case AUD_FMT_U16:
- bits16 = 1;
- break;
- }
-
- hdr[34] = bits16 ? 0x10 : 0x08;
-
- wav_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &wav_as);
-
- hw->samples = 1024;
- wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!wav->pcm_buf) {
- dolog ("Could not allocate buffer (%d bytes)\n",
- hw->samples << hw->info.shift);
- return -1;
- }
-
- 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 = qemu_fopen (conf.wav_path, "wb");
- if (!wav->f) {
- dolog ("Failed to open wave file `%s'\nReason: %s\n",
- conf.wav_path, strerror (errno));
- qemu_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
- return -1;
- }
-
- qemu_put_buffer (wav->f, hdr, sizeof (hdr));
- return 0;
-}
-
-static void wav_fini_out (HWVoiceOut *hw)
-{
- WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- uint8_t rlen[4];
- uint8_t dlen[4];
- 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);
-
- qemu_fseek (wav->f, 4, SEEK_SET);
- qemu_put_buffer (wav->f, rlen, 4);
-
- qemu_fseek (wav->f, 32, SEEK_CUR);
- qemu_put_buffer (wav->f, dlen, 4);
-
- qemu_fclose (wav->f);
- wav->f = NULL;
-
- qemu_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
-}
-
-static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static void *wav_audio_init (void)
-{
- return &conf;
-}
-
-static void wav_audio_fini (void *opaque)
-{
- (void) opaque;
- ldebug ("wav_fini");
-}
-
-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 --git a/tools/ioemu/audio/wavcapture.c b/tools/ioemu/audio/wavcapture.c
deleted file mode 100644
index d915fa02bf..0000000000
--- a/tools/ioemu/audio/wavcapture.c
+++ /dev/null
@@ -1,163 +0,0 @@
-#include "vl.h"
-
-typedef struct {
- QEMUFile *f;
- int bytes;
- char *path;
- int freq;
- int bits;
- int nchannels;
- CaptureVoiceOut *cap;
-} WAVState;
-
-/* VICE code: Store number as little endian. */
-static void le_store (uint8_t *buf, uint32_t val, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- buf[i] = (uint8_t) (val & 0xff);
- val >>= 8;
- }
-}
-
-static void wav_notify (void *opaque, audcnotification_e cmd)
-{
- (void) opaque;
- (void) cmd;
-}
-
-static void wav_destroy (void *opaque)
-{
- WAVState *wav = opaque;
- uint8_t rlen[4];
- uint8_t dlen[4];
- uint32_t datalen = wav->bytes;
- uint32_t rifflen = datalen + 36;
-
- if (wav->f) {
- le_store (rlen, rifflen, 4);
- le_store (dlen, datalen, 4);
-
- qemu_fseek (wav->f, 4, SEEK_SET);
- qemu_put_buffer (wav->f, rlen, 4);
-
- qemu_fseek (wav->f, 32, SEEK_CUR);
- qemu_put_buffer (wav->f, dlen, 4);
- qemu_fclose (wav->f);
- }
-
- qemu_free (wav->path);
-}
-
-static void wav_capture (void *opaque, void *buf, int size)
-{
- WAVState *wav = opaque;
-
- qemu_put_buffer (wav->f, buf, size);
- wav->bytes += size;
-}
-
-static void wav_capture_destroy (void *opaque)
-{
- WAVState *wav = opaque;
-
- AUD_del_capture (wav->cap, wav);
-}
-
-static void wav_capture_info (void *opaque)
-{
- WAVState *wav = opaque;
- char *path = wav->path;
-
- term_printf ("Capturing audio(%d,%d,%d) to %s: %d bytes\n",
- wav->freq, wav->bits, wav->nchannels,
- path ? path : "<not available>", wav->bytes);
-}
-
-static struct capture_ops wav_capture_ops = {
- .destroy = wav_capture_destroy,
- .info = wav_capture_info
-};
-
-int wav_start_capture (CaptureState *s, const char *path, int freq,
- int bits, int nchannels)
-{
- WAVState *wav;
- 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
- };
- audsettings_t as;
- struct audio_capture_ops ops;
- int stereo, bits16, shift;
- CaptureVoiceOut *cap;
-
- if (bits != 8 && bits != 16) {
- term_printf ("incorrect bit count %d, must be 8 or 16\n", bits);
- return -1;
- }
-
- if (nchannels != 1 && nchannels != 2) {
- term_printf ("incorrect channel count %d, must be 1 or 2\n",
- nchannels);
- return -1;
- }
-
- stereo = nchannels == 2;
- bits16 = bits == 16;
-
- as.freq = freq;
- as.nchannels = 1 << stereo;
- as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
- as.endianness = 0;
-
- ops.notify = wav_notify;
- ops.capture = wav_capture;
- ops.destroy = wav_destroy;
-
- wav = qemu_mallocz (sizeof (*wav));
- if (!wav) {
- term_printf ("Could not allocate memory for wav capture (%zu bytes)",
- sizeof (*wav));
- return -1;
- }
-
- shift = bits16 + stereo;
- hdr[34] = bits16 ? 0x10 : 0x08;
-
- le_store (hdr + 22, as.nchannels, 2);
- le_store (hdr + 24, freq, 4);
- le_store (hdr + 28, freq << shift, 4);
- le_store (hdr + 32, 1 << shift, 2);
-
- wav->f = qemu_fopen (path, "wb");
- if (!wav->f) {
- term_printf ("Failed to open wave file `%s'\nReason: %s\n",
- path, strerror (errno));
- qemu_free (wav);
- return -1;
- }
-
- wav->path = qemu_strdup (path);
- wav->bits = bits;
- wav->nchannels = nchannels;
- wav->freq = freq;
-
- qemu_put_buffer (wav->f, hdr, sizeof (hdr));
-
- cap = AUD_add_capture (NULL, &as, &ops, wav);
- if (!cap) {
- term_printf ("Failed to add audio capture\n");
- qemu_free (wav->path);
- qemu_fclose (wav->f);
- qemu_free (wav);
- return -1;
- }
-
- wav->cap = cap;
- s->opaque = wav;
- s->ops = wav_capture_ops;
- return 0;
-}
diff --git a/tools/ioemu/block-bochs.c b/tools/ioemu/block-bochs.c
deleted file mode 100644
index 35e2a6cf01..0000000000
--- a/tools/ioemu/block-bochs.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Block driver for the various disk image formats used by Bochs
- * Currently only for "growing" type in read-only mode
- *
- * Copyright (c) 2005 Alex Beregszaszi
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-
-/**************************************************************/
-
-#define HEADER_MAGIC "Bochs Virtual HD Image"
-#define HEADER_VERSION 0x00020000
-#define HEADER_V1 0x00010000
-#define HEADER_SIZE 512
-
-#define REDOLOG_TYPE "Redolog"
-#define GROWING_TYPE "Growing"
-
-// not allocated: 0xffffffff
-
-// always little-endian
-struct bochs_header_v1 {
- char magic[32]; // "Bochs Virtual HD Image"
- char type[16]; // "Redolog"
- char subtype[16]; // "Undoable" / "Volatile" / "Growing"
- uint32_t version;
- uint32_t header; // size of header
-
- union {
- struct {
- uint32_t catalog; // num of entries
- uint32_t bitmap; // bitmap size
- uint32_t extent; // extent size
- uint64_t disk; // disk size
- char padding[HEADER_SIZE - 64 - 8 - 20];
- } redolog;
- char padding[HEADER_SIZE - 64 - 8];
- } extra;
-};
-
-// always little-endian
-struct bochs_header {
- char magic[32]; // "Bochs Virtual HD Image"
- char type[16]; // "Redolog"
- char subtype[16]; // "Undoable" / "Volatile" / "Growing"
- uint32_t version;
- uint32_t header; // size of header
-
- union {
- struct {
- uint32_t catalog; // num of entries
- uint32_t bitmap; // bitmap size
- uint32_t extent; // extent size
- uint32_t reserved; // for ???
- uint64_t disk; // disk size
- char padding[HEADER_SIZE - 64 - 8 - 24];
- } redolog;
- char padding[HEADER_SIZE - 64 - 8];
- } extra;
-};
-
-typedef struct BDRVBochsState {
- int fd;
-
- uint32_t *catalog_bitmap;
- int catalog_size;
-
- int data_offset;
-
- int bitmap_blocks;
- int extent_blocks;
- int extent_size;
-} BDRVBochsState;
-
-static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const struct bochs_header *bochs = (const void *)buf;
-
- if (buf_size < HEADER_SIZE)
- return 0;
-
- if (!strcmp(bochs->magic, HEADER_MAGIC) &&
- !strcmp(bochs->type, REDOLOG_TYPE) &&
- !strcmp(bochs->subtype, GROWING_TYPE) &&
- ((le32_to_cpu(bochs->version) == HEADER_VERSION) ||
- (le32_to_cpu(bochs->version) == HEADER_V1)))
- return 100;
-
- return 0;
-}
-
-static int bochs_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVBochsState *s = bs->opaque;
- int fd, i;
- struct bochs_header bochs;
- struct bochs_header_v1 header_v1;
-
- fd = open(filename, O_RDWR | O_BINARY);
- if (fd < 0) {
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- }
-
- bs->read_only = 1; // no write support yet
-
- s->fd = fd;
-
- if (read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) {
- goto fail;
- }
-
- if (strcmp(bochs.magic, HEADER_MAGIC) ||
- strcmp(bochs.type, REDOLOG_TYPE) ||
- strcmp(bochs.subtype, GROWING_TYPE) ||
- ((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
- (le32_to_cpu(bochs.version) != HEADER_V1))) {
- goto fail;
- }
-
- if (le32_to_cpu(bochs.version) == HEADER_V1) {
- memcpy(&header_v1, &bochs, sizeof(bochs));
- bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512;
- } else {
- bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
- }
-
- lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);
-
- s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
- s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);
- if (!s->catalog_bitmap)
- goto fail;
- if (read(s->fd, s->catalog_bitmap, s->catalog_size * 4) !=
- s->catalog_size * 4)
- goto fail;
- for (i = 0; i < s->catalog_size; i++)
- le32_to_cpus(&s->catalog_bitmap[i]);
-
- s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
-
- s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;
- s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;
-
- s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
-
- return 0;
- fail:
- close(fd);
- return -1;
-}
-
-static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
-{
- BDRVBochsState *s = bs->opaque;
- int64_t offset = sector_num * 512;
- int64_t extent_index, extent_offset, bitmap_offset, block_offset;
- char bitmap_entry;
-
- // seek to sector
- extent_index = offset / s->extent_size;
- extent_offset = (offset % s->extent_size) / 512;
-
- if (s->catalog_bitmap[extent_index] == 0xffffffff)
- {
-// fprintf(stderr, "page not allocated [%x - %x:%x]\n",
-// sector_num, extent_index, extent_offset);
- return -1; // not allocated
- }
-
- bitmap_offset = s->data_offset + (512 * s->catalog_bitmap[extent_index] *
- (s->extent_blocks + s->bitmap_blocks));
- block_offset = bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
-
-// fprintf(stderr, "sect: %x [ext i: %x o: %x] -> %x bitmap: %x block: %x\n",
-// sector_num, extent_index, extent_offset,
-// le32_to_cpu(s->catalog_bitmap[extent_index]),
-// bitmap_offset, block_offset);
-
- // read in bitmap for current extent
- lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
-
- read(s->fd, &bitmap_entry, 1);
-
- if (!((bitmap_entry >> (extent_offset % 8)) & 1))
- {
-// fprintf(stderr, "sector (%x) in bitmap not allocated\n",
-// sector_num);
- return -1; // not allocated
- }
-
- lseek(s->fd, block_offset, SEEK_SET);
-
- return 0;
-}
-
-static int bochs_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVBochsState *s = bs->opaque;
- int ret;
-
- while (nb_sectors > 0) {
- if (!seek_to_sector(bs, sector_num))
- {
- ret = read(s->fd, buf, 512);
- if (ret != 512)
- return -1;
- }
- else
- memset(buf, 0, 512);
- nb_sectors--;
- sector_num++;
- buf += 512;
- }
- return 0;
-}
-
-static void bochs_close(BlockDriverState *bs)
-{
- BDRVBochsState *s = bs->opaque;
- qemu_free(s->catalog_bitmap);
- close(s->fd);
-}
-
-BlockDriver bdrv_bochs = {
- "bochs",
- sizeof(BDRVBochsState),
- bochs_probe,
- bochs_open,
- bochs_read,
- NULL,
- bochs_close,
-};
diff --git a/tools/ioemu/block-cloop.c b/tools/ioemu/block-cloop.c
deleted file mode 100644
index f51c32d1bd..0000000000
--- a/tools/ioemu/block-cloop.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * QEMU Block driver for CLOOP images
- *
- * Copyright (c) 2004 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include <zlib.h>
-
-typedef struct BDRVCloopState {
- int fd;
- uint32_t block_size;
- uint32_t n_blocks;
- uint64_t* offsets;
- uint32_t sectors_per_block;
- uint32_t current_block;
- uint8_t *compressed_block;
- uint8_t *uncompressed_block;
- z_stream zstream;
-} BDRVCloopState;
-
-static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const char* magic_version_2_0="#!/bin/sh\n"
- "#V2.0 Format\n"
- "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
- int length=strlen(magic_version_2_0);
- if(length>buf_size)
- length=buf_size;
- if(!memcmp(magic_version_2_0,buf,length))
- return 2;
- return 0;
-}
-
-static int cloop_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVCloopState *s = bs->opaque;
- uint32_t offsets_size,max_compressed_block_size=1,i;
-
- s->fd = open(filename, O_RDONLY | O_BINARY);
- if (s->fd < 0)
- return -errno;
- bs->read_only = 1;
-
- /* read header */
- if(lseek(s->fd,128,SEEK_SET)<0) {
-cloop_close:
- close(s->fd);
- return -1;
- }
- if(read(s->fd,&s->block_size,4)<4)
- goto cloop_close;
- s->block_size=be32_to_cpu(s->block_size);
- if(read(s->fd,&s->n_blocks,4)<4)
- goto cloop_close;
- s->n_blocks=be32_to_cpu(s->n_blocks);
-
- /* read offsets */
- offsets_size=s->n_blocks*sizeof(uint64_t);
- if(!(s->offsets=(uint64_t*)malloc(offsets_size)))
- goto cloop_close;
- if(read(s->fd,s->offsets,offsets_size)<offsets_size)
- goto cloop_close;
- for(i=0;i<s->n_blocks;i++) {
- s->offsets[i]=be64_to_cpu(s->offsets[i]);
- if(i>0) {
- uint32_t size=s->offsets[i]-s->offsets[i-1];
- if(size>max_compressed_block_size)
- max_compressed_block_size=size;
- }
- }
-
- /* initialize zlib engine */
- if(!(s->compressed_block = malloc(max_compressed_block_size+1)))
- goto cloop_close;
- if(!(s->uncompressed_block = malloc(s->block_size)))
- goto cloop_close;
- if(inflateInit(&s->zstream) != Z_OK)
- goto cloop_close;
- s->current_block=s->n_blocks;
-
- s->sectors_per_block = s->block_size/512;
- bs->total_sectors = s->n_blocks*s->sectors_per_block;
- return 0;
-}
-
-static inline int cloop_read_block(BDRVCloopState *s,int block_num)
-{
- if(s->current_block != block_num) {
- int ret;
- uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
-
- lseek(s->fd, s->offsets[block_num], SEEK_SET);
- ret = read(s->fd, s->compressed_block, bytes);
- if (ret != bytes)
- return -1;
-
- s->zstream.next_in = s->compressed_block;
- s->zstream.avail_in = bytes;
- s->zstream.next_out = s->uncompressed_block;
- s->zstream.avail_out = s->block_size;
- ret = inflateReset(&s->zstream);
- if(ret != Z_OK)
- return -1;
- ret = inflate(&s->zstream, Z_FINISH);
- if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
- return -1;
-
- s->current_block = block_num;
- }
- return 0;
-}
-
-static int cloop_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVCloopState *s = bs->opaque;
- int i;
-
- for(i=0;i<nb_sectors;i++) {
- uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
- block_num=(sector_num+i)/s->sectors_per_block;
- if(cloop_read_block(s, block_num) != 0)
- return -1;
- memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
- }
- return 0;
-}
-
-static void cloop_close(BlockDriverState *bs)
-{
- 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);
-}
-
-BlockDriver bdrv_cloop = {
- "cloop",
- sizeof(BDRVCloopState),
- cloop_probe,
- cloop_open,
- cloop_read,
- NULL,
- cloop_close,
-};
-
-
diff --git a/tools/ioemu/block-cow.c b/tools/ioemu/block-cow.c
deleted file mode 100644
index eeee9a1cc4..0000000000
--- a/tools/ioemu/block-cow.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Block driver for the COW format
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef _WIN32
-#include "vl.h"
-#include "block_int.h"
-#include <sys/mman.h>
-
-/**************************************************************/
-/* COW block driver using file system holes */
-
-/* user mode linux compatible COW file */
-#define COW_MAGIC 0x4f4f4f4d /* MOOO */
-#define COW_VERSION 2
-
-struct cow_header_v2 {
- uint32_t magic;
- uint32_t version;
- char backing_file[1024];
- int32_t mtime;
- uint64_t size;
- uint32_t sectorsize;
-};
-
-typedef struct BDRVCowState {
- int fd;
- uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */
- uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */
- int cow_bitmap_size;
- int64_t cow_sectors_offset;
-} BDRVCowState;
-
-static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const struct cow_header_v2 *cow_header = (const void *)buf;
-
- 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
- return 0;
-}
-
-static int cow_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVCowState *s = bs->opaque;
- int fd;
- struct cow_header_v2 cow_header;
- int64_t size;
-
- 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;
- }
- s->fd = fd;
- /* see if it is a cow image */
- if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) {
- goto fail;
- }
-
- if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
- be32_to_cpu(cow_header.version) != COW_VERSION) {
- goto fail;
- }
-
- /* cow image found */
- size = be64_to_cpu(cow_header.size);
- bs->total_sectors = size / 512;
-
- pstrcpy(bs->backing_file, sizeof(bs->backing_file),
- cow_header.backing_file);
-
- /* mmap the bitmap */
- s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
- s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size),
- s->cow_bitmap_size,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, s->fd, 0);
- if (s->cow_bitmap_addr == MAP_FAILED)
- goto fail;
- s->cow_bitmap = s->cow_bitmap_addr + sizeof(cow_header);
- s->cow_sectors_offset = (s->cow_bitmap_size + 511) & ~511;
- return 0;
- fail:
- close(fd);
- return -1;
-}
-
-static inline void cow_set_bit(uint8_t *bitmap, int64_t bitnum)
-{
- bitmap[bitnum / 8] |= (1 << (bitnum%8));
-}
-
-static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum)
-{
- return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
-}
-
-
-/* Return true if first block has been changed (ie. current version is
- * in COW file). Set the number of continuous blocks for which that
- * is true. */
-static inline int is_changed(uint8_t *bitmap,
- int64_t sector_num, int nb_sectors,
- int *num_same)
-{
- int changed;
-
- if (!bitmap || nb_sectors == 0) {
- *num_same = nb_sectors;
- return 0;
- }
-
- changed = is_bit_set(bitmap, sector_num);
- for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
- if (is_bit_set(bitmap, sector_num + *num_same) != changed)
- break;
- }
-
- return changed;
-}
-
-static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVCowState *s = bs->opaque;
- return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
-}
-
-static int cow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVCowState *s = bs->opaque;
- int ret, n;
-
- while (nb_sectors > 0) {
- if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
- lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
- ret = read(s->fd, buf, n * 512);
- if (ret != n * 512)
- return -1;
- } else {
- if (bs->backing_hd) {
- /* read from the base image */
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
- if (ret < 0)
- return -1;
- } else {
- memset(buf, 0, n * 512);
- }
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int cow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVCowState *s = bs->opaque;
- int ret, i;
-
- lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
- ret = write(s->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
- return -1;
- for (i = 0; i < nb_sectors; i++)
- cow_set_bit(s->cow_bitmap, sector_num + i);
- return 0;
-}
-
-static void cow_close(BlockDriverState *bs)
-{
- BDRVCowState *s = bs->opaque;
- munmap(s->cow_bitmap_addr, s->cow_bitmap_size);
- close(s->fd);
-}
-
-static int cow_create(const char *filename, int64_t image_sectors,
- const char *image_filename, int flags)
-{
- int fd, cow_fd;
- struct cow_header_v2 cow_header;
- struct stat st;
-
- if (flags)
- return -ENOTSUP;
-
- cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- 0644);
- if (cow_fd < 0)
- return -1;
- memset(&cow_header, 0, sizeof(cow_header));
- cow_header.magic = cpu_to_be32(COW_MAGIC);
- cow_header.version = cpu_to_be32(COW_VERSION);
- if (image_filename) {
- /* Note: if no file, we put a dummy mtime */
- cow_header.mtime = cpu_to_be32(0);
-
- fd = open(image_filename, O_RDONLY | O_BINARY);
- if (fd < 0) {
- close(cow_fd);
- goto mtime_fail;
- }
- if (fstat(fd, &st) != 0) {
- close(fd);
- goto mtime_fail;
- }
- close(fd);
- cow_header.mtime = cpu_to_be32(st.st_mtime);
- mtime_fail:
- pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file),
- image_filename);
- }
- cow_header.sectorsize = cpu_to_be32(512);
- cow_header.size = cpu_to_be64(image_sectors * 512);
- write(cow_fd, &cow_header, sizeof(cow_header));
- /* resize to include at least all the bitmap */
- ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
- close(cow_fd);
- return 0;
-}
-
-static int cow_flush(BlockDriverState *bs)
-{
- BDRVCowState *s = bs->opaque;
- fsync(s->fd);
- return 0;
-}
-
-BlockDriver bdrv_cow = {
- "cow",
- sizeof(BDRVCowState),
- cow_probe,
- cow_open,
- cow_read,
- cow_write,
- cow_close,
- cow_create,
- cow_flush,
- cow_is_allocated,
-};
-#endif
diff --git a/tools/ioemu/block-dmg.c b/tools/ioemu/block-dmg.c
deleted file mode 100644
index a883a23f8e..0000000000
--- a/tools/ioemu/block-dmg.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * QEMU Block driver for DMG images
- *
- * Copyright (c) 2004 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include "bswap.h"
-#include <zlib.h>
-
-typedef struct BDRVDMGState {
- int fd;
-
- /* each chunk contains a certain number of sectors,
- * offsets[i] is the offset in the .dmg file,
- * lengths[i] is the length of the compressed chunk,
- * sectors[i] is the sector beginning at offsets[i],
- * sectorcounts[i] is the number of sectors in that chunk,
- * the sectors array is ordered
- * 0<=i<n_chunks */
-
- uint32_t n_chunks;
- uint32_t* types;
- uint64_t* offsets;
- uint64_t* lengths;
- uint64_t* sectors;
- uint64_t* sectorcounts;
- uint32_t current_chunk;
- uint8_t *compressed_chunk;
- uint8_t *uncompressed_chunk;
- z_stream zstream;
-} BDRVDMGState;
-
-static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- int len=strlen(filename);
- if(len>4 && !strcmp(filename+len-4,".dmg"))
- return 2;
- return 0;
-}
-
-static off_t read_off(int fd)
-{
- uint64_t buffer;
- if(read(fd,&buffer,8)<8)
- return 0;
- return be64_to_cpu(buffer);
-}
-
-static off_t read_uint32(int fd)
-{
- uint32_t buffer;
- if(read(fd,&buffer,4)<4)
- return 0;
- return be32_to_cpu(buffer);
-}
-
-static int dmg_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVDMGState *s = bs->opaque;
- off_t info_begin,info_end,last_in_offset,last_out_offset;
- uint32_t count;
- uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;
-
- s->fd = open(filename, O_RDONLY | O_BINARY);
- if (s->fd < 0)
- return -errno;
- bs->read_only = 1;
- s->n_chunks = 0;
- s->offsets = s->lengths = s->sectors = s->sectorcounts = 0;
-
- /* read offset of info blocks */
- if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
-dmg_close:
- close(s->fd);
- /* open raw instead */
- bs->drv=&bdrv_raw;
- return bs->drv->bdrv_open(bs, filename, flags);
- }
- info_begin=read_off(s->fd);
- if(info_begin==0)
- goto dmg_close;
- if(lseek(s->fd,info_begin,SEEK_SET)<0)
- goto dmg_close;
- if(read_uint32(s->fd)!=0x100)
- goto dmg_close;
- if((count = read_uint32(s->fd))==0)
- goto dmg_close;
- info_end = info_begin+count;
- if(lseek(s->fd,0xf8,SEEK_CUR)<0)
- goto dmg_close;
-
- /* read offsets */
- last_in_offset = last_out_offset = 0;
- while(lseek(s->fd,0,SEEK_CUR)<info_end) {
- uint32_t type;
-
- count = read_uint32(s->fd);
- if(count==0)
- goto dmg_close;
- type = read_uint32(s->fd);
- if(type!=0x6d697368 || count<244)
- lseek(s->fd,count-4,SEEK_CUR);
- else {
- int new_size, chunk_count;
- if(lseek(s->fd,200,SEEK_CUR)<0)
- goto dmg_close;
- chunk_count = (count-204)/40;
- new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
- s->types = realloc(s->types, new_size/2);
- s->offsets = realloc(s->offsets, new_size);
- s->lengths = realloc(s->lengths, new_size);
- s->sectors = realloc(s->sectors, new_size);
- s->sectorcounts = realloc(s->sectorcounts, new_size);
-
- for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {
- s->types[i] = read_uint32(s->fd);
- if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {
- if(s->types[i]==0xffffffff) {
- last_in_offset = s->offsets[i-1]+s->lengths[i-1];
- last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];
- }
- chunk_count--;
- i--;
- if(lseek(s->fd,36,SEEK_CUR)<0)
- goto dmg_close;
- continue;
- }
- read_uint32(s->fd);
- s->sectors[i] = last_out_offset+read_off(s->fd);
- s->sectorcounts[i] = read_off(s->fd);
- s->offsets[i] = last_in_offset+read_off(s->fd);
- s->lengths[i] = read_off(s->fd);
- if(s->lengths[i]>max_compressed_size)
- max_compressed_size = s->lengths[i];
- if(s->sectorcounts[i]>max_sectors_per_chunk)
- max_sectors_per_chunk = s->sectorcounts[i];
- }
- s->n_chunks+=chunk_count;
- }
- }
-
- /* initialize zlib engine */
- if(!(s->compressed_chunk = malloc(max_compressed_size+1)))
- goto dmg_close;
- if(!(s->uncompressed_chunk = malloc(512*max_sectors_per_chunk)))
- goto dmg_close;
- if(inflateInit(&s->zstream) != Z_OK)
- goto dmg_close;
-
- s->current_chunk = s->n_chunks;
-
- return 0;
-}
-
-static inline int is_sector_in_chunk(BDRVDMGState* s,
- uint32_t chunk_num,int sector_num)
-{
- if(chunk_num>=s->n_chunks || s->sectors[chunk_num]>sector_num ||
- s->sectors[chunk_num]+s->sectorcounts[chunk_num]<=sector_num)
- return 0;
- else
- return -1;
-}
-
-static inline uint32_t search_chunk(BDRVDMGState* s,int sector_num)
-{
- /* binary search */
- uint32_t chunk1=0,chunk2=s->n_chunks,chunk3;
- while(chunk1!=chunk2) {
- chunk3 = (chunk1+chunk2)/2;
- if(s->sectors[chunk3]>sector_num)
- chunk2 = chunk3;
- else if(s->sectors[chunk3]+s->sectorcounts[chunk3]>sector_num)
- return chunk3;
- else
- chunk1 = chunk3;
- }
- return s->n_chunks; /* error */
-}
-
-static inline int dmg_read_chunk(BDRVDMGState *s,int sector_num)
-{
- if(!is_sector_in_chunk(s,s->current_chunk,sector_num)) {
- int ret;
- uint32_t chunk = search_chunk(s,sector_num);
-
- if(chunk>=s->n_chunks)
- return -1;
-
- s->current_chunk = s->n_chunks;
- switch(s->types[chunk]) {
- case 0x80000005: { /* zlib compressed */
- int i;
-
- ret = lseek(s->fd, s->offsets[chunk], SEEK_SET);
- if(ret<0)
- return -1;
-
- /* we need to buffer, because only the chunk as whole can be
- * inflated. */
- i=0;
- do {
- ret = read(s->fd, s->compressed_chunk+i, s->lengths[chunk]-i);
- if(ret<0 && errno==EINTR)
- ret=0;
- i+=ret;
- } while(ret>=0 && ret+i<s->lengths[chunk]);
-
- if (ret != s->lengths[chunk])
- return -1;
-
- s->zstream.next_in = s->compressed_chunk;
- s->zstream.avail_in = s->lengths[chunk];
- s->zstream.next_out = s->uncompressed_chunk;
- s->zstream.avail_out = 512*s->sectorcounts[chunk];
- ret = inflateReset(&s->zstream);
- if(ret != Z_OK)
- return -1;
- ret = inflate(&s->zstream, Z_FINISH);
- if(ret != Z_STREAM_END || s->zstream.total_out != 512*s->sectorcounts[chunk])
- return -1;
- break; }
- case 1: /* copy */
- ret = read(s->fd, s->uncompressed_chunk, s->lengths[chunk]);
- if (ret != s->lengths[chunk])
- return -1;
- break;
- case 2: /* zero */
- memset(s->uncompressed_chunk, 0, 512*s->sectorcounts[chunk]);
- break;
- }
- s->current_chunk = chunk;
- }
- return 0;
-}
-
-static int dmg_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVDMGState *s = bs->opaque;
- int i;
-
- for(i=0;i<nb_sectors;i++) {
- uint32_t sector_offset_in_chunk;
- if(dmg_read_chunk(s, sector_num+i) != 0)
- return -1;
- sector_offset_in_chunk = sector_num+i-s->sectors[s->current_chunk];
- memcpy(buf+i*512,s->uncompressed_chunk+sector_offset_in_chunk*512,512);
- }
- return 0;
-}
-
-static void dmg_close(BlockDriverState *bs)
-{
- BDRVDMGState *s = bs->opaque;
- close(s->fd);
- if(s->n_chunks>0) {
- free(s->types);
- free(s->offsets);
- free(s->lengths);
- free(s->sectors);
- free(s->sectorcounts);
- }
- free(s->compressed_chunk);
- free(s->uncompressed_chunk);
- inflateEnd(&s->zstream);
-}
-
-BlockDriver bdrv_dmg = {
- "dmg",
- sizeof(BDRVDMGState),
- dmg_probe,
- dmg_open,
- dmg_read,
- NULL,
- dmg_close,
-};
-
diff --git a/tools/ioemu/block-qcow.c b/tools/ioemu/block-qcow.c
deleted file mode 100644
index d7dacc75be..0000000000
--- a/tools/ioemu/block-qcow.c
+++ /dev/null
@@ -1,971 +0,0 @@
-/*
- * Block driver for the QCOW format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include <zlib.h>
-#include "aes.h"
-
-/**************************************************************/
-/* QEMU COW block driver with compression and encryption support */
-
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-#define QCOW_VERSION 1
-
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
-
-#define QCOW_OFLAG_COMPRESSED (1LL << 63)
-
-#define XEN_MAGIC (('X' << 24) | ('E' << 16) | ('N' << 8) | 0xfb)
-
-#define EXTHDR_SPARSE_FILE 0x01
-#define EXTHDR_L1_BIG_ENDIAN 0x02
-
-typedef struct QCowHeader {
- uint32_t magic;
- uint32_t version;
- uint64_t backing_file_offset;
- uint32_t backing_file_size;
- uint32_t mtime;
- uint64_t size; /* in bytes */
- uint8_t cluster_bits;
- uint8_t l2_bits;
- uint32_t crypt_method;
- uint64_t l1_table_offset;
-} QCowHeader;
-
-/*Extended header for Xen enhancements*/
-typedef struct QCowHeader_ext {
- uint32_t xmagic;
- uint32_t cksum;
- uint32_t min_cluster_alloc;
- uint32_t flags;
-} QCowHeader_ext;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVQcowState {
- BlockDriverState *hd;
- int cluster_bits;
- int cluster_size;
- int cluster_sectors;
- int l2_bits;
- int l2_size;
- int l1_size;
- uint64_t cluster_offset_mask;
- uint64_t l1_table_offset;
- uint64_t *l1_table;
- uint64_t *l2_cache;
- uint64_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
- uint8_t *cluster_cache;
- uint8_t *cluster_data;
- uint64_t cluster_cache_offset;
- uint32_t crypt_method; /* current crypt method, 0 if no key yet */
- uint32_t crypt_method_header;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
-} BDRVQcowState;
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
-
-static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const QCowHeader *cow_header = (const void *)buf;
-
- if (buf_size >= sizeof(QCowHeader) &&
- be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVQcowState *s = bs->opaque;
- int len, i, shift, ret;
- QCowHeader header;
-
- ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
- if (ret < 0)
- return ret;
- if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
- goto fail;
- be32_to_cpus(&header.magic);
- be32_to_cpus(&header.version);
- be64_to_cpus(&header.backing_file_offset);
- be32_to_cpus(&header.backing_file_size);
- be32_to_cpus(&header.mtime);
- be64_to_cpus(&header.size);
- be32_to_cpus(&header.crypt_method);
- be64_to_cpus(&header.l1_table_offset);
-
- if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
- goto fail;
- if (header.size <= 1 || header.cluster_bits < 9)
- goto fail;
- if (header.crypt_method > QCOW_CRYPT_AES)
- goto fail;
- s->crypt_method_header = header.crypt_method;
- if (s->crypt_method_header)
- bs->encrypted = 1;
- s->cluster_bits = header.cluster_bits;
- s->cluster_size = 1 << s->cluster_bits;
- s->cluster_sectors = 1 << (s->cluster_bits - 9);
- s->l2_bits = header.l2_bits;
- s->l2_size = 1 << s->l2_bits;
- bs->total_sectors = header.size / 512;
- s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
-
- /* read the level 1 table */
- shift = s->cluster_bits + s->l2_bits;
- s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
-
- s->l1_table_offset = header.l1_table_offset;
- s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
- if (!s->l1_table)
- goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
- s->l1_size * sizeof(uint64_t))
- goto fail;
-
- /* Try to detect old tapdisk images. They have to be fixed because they
- * don't use big endian but native endianess for the L1 table */
- if (header.backing_file_offset == 0 && s->l1_table_offset % 4096 == 0) {
-
- QCowHeader_ext exthdr;
- uint64_t l1_bytes = s->l1_size * sizeof(uint64_t);
-
- if (bdrv_pread(s->hd, sizeof(header), &exthdr, sizeof(exthdr))
- != sizeof(exthdr))
- goto end_xenhdr;
-
- be32_to_cpus(&exthdr.xmagic);
- if (exthdr.xmagic != XEN_MAGIC)
- goto end_xenhdr;
-
- be32_to_cpus(&exthdr.flags);
- if (exthdr.flags & EXTHDR_L1_BIG_ENDIAN)
- goto end_xenhdr;
-
- /* The image is broken. Fix it. */
- fprintf(stderr, "qcow: Converting image to big endian L1 table\n");
-
- for(i = 0;i < s->l1_size; i++) {
- cpu_to_be64s(&s->l1_table[i]);
- }
-
- if (bdrv_pwrite(s->hd, s->l1_table_offset, s->l1_table,
- l1_bytes) != l1_bytes) {
- fprintf(stderr, "qcow: Failed to write new L1 table\n");
- goto fail;
- }
-
- exthdr.flags |= EXTHDR_L1_BIG_ENDIAN;
- cpu_to_be32s(&exthdr.flags);
-
- if (bdrv_pwrite(s->hd, sizeof(header), &exthdr, sizeof(exthdr))
- != sizeof(exthdr)) {
- fprintf(stderr, "qcow: Failed to write extended header\n");
- goto fail;
- }
- }
-end_xenhdr:
-
- /* L1 table is big endian now */
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
- /* alloc L2 cache */
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- if (!s->l2_cache)
- goto fail;
- s->cluster_cache = qemu_malloc(s->cluster_size);
- if (!s->cluster_cache)
- goto fail;
- s->cluster_data = qemu_malloc(s->cluster_size);
- if (!s->cluster_data)
- goto fail;
- s->cluster_cache_offset = -1;
-
- /* read the backing file name */
- if (header.backing_file_offset != 0) {
- len = header.backing_file_size;
- if (len > 1023)
- len = 1023;
- if (bdrv_pread(s->hd, header.backing_file_offset, bs->backing_file, len) != len)
- goto fail;
- bs->backing_file[len] = '\0';
- }
- return 0;
-
- fail:
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- bdrv_delete(s->hd);
- return -1;
-}
-
-static int qcow_set_key(BlockDriverState *bs, const char *key)
-{
- BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
-
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
- s->crypt_method = s->crypt_method_header;
-
- if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
- return -1;
- if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
- return -1;
-#if 0
- /* test */
- {
- uint8_t in[16];
- uint8_t out[16];
- uint8_t tmp[16];
- for(i=0;i<16;i++)
- in[i] = i;
- AES_encrypt(in, tmp, &s->aes_encrypt_key);
- AES_decrypt(tmp, out, &s->aes_decrypt_key);
- for(i = 0; i < 16; i++)
- printf(" %02x", tmp[i]);
- printf("\n");
- for(i = 0; i < 16; i++)
- printf(" %02x", out[i]);
- printf("\n");
- }
-#endif
- return 0;
-}
-
-/* The crypt function is compatible with the linux cryptoloop
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
- supported */
-static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key)
-{
- union {
- uint64_t ll[2];
- uint8_t b[16];
- } ivec;
- int i;
-
- for(i = 0; i < nb_sectors; i++) {
- ivec.ll[0] = cpu_to_le64(sector_num);
- ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
- ivec.b, enc);
- sector_num++;
- in_buf += 512;
- out_buf += 512;
- }
-}
-
-/* 'allocate' is:
- *
- * 0 to not allocate.
- *
- * 1 to allocate a normal cluster (for sector indexes 'n_start' to
- * 'n_end')
- *
- * 2 to allocate a compressed cluster of size
- * 'compressed_size'. 'compressed_size' must be > 0 and <
- * cluster_size
- *
- * return 0 if not allocated.
- */
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset, int allocate,
- int compressed_size,
- int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- int min_index, i, j, l1_index, l2_index;
- uint64_t l2_offset, *l2_table, cluster_offset, tmp;
- uint32_t min_count;
- int new_l2_table;
-
- l1_index = offset >> (s->l2_bits + s->cluster_bits);
- l2_offset = s->l1_table[l1_index];
- new_l2_table = 0;
- if (!l2_offset) {
- if (!allocate)
- return 0;
- /* allocate a new l2 entry */
- l2_offset = bdrv_getlength(s->hd);
- /* round to cluster size */
- l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
- /* update the L1 entry */
- s->l1_table[l1_index] = l2_offset;
- tmp = cpu_to_be64(l2_offset);
- if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
- &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- new_l2_table = 1;
- }
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i << s->l2_bits);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- l2_table = s->l2_cache + (min_index << s->l2_bits);
- if (new_l2_table) {
- memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- if (bdrv_pwrite(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- } else {
- if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- }
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (!cluster_offset ||
- ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
- if (!allocate)
- return 0;
- /* allocate a new cluster */
- if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
- (n_end - n_start) < s->cluster_sectors) {
- /* if the cluster is already compressed, we must
- decompress it in the case it is not completely
- overwritten */
- if (decompress_cluster(s, cluster_offset) < 0)
- return 0;
- cluster_offset = bdrv_getlength(s->hd);
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- /* write the cluster content */
- if (bdrv_pwrite(s->hd, cluster_offset, s->cluster_cache, s->cluster_size) !=
- s->cluster_size)
- return -1;
- } else {
- cluster_offset = bdrv_getlength(s->hd);
- if (allocate == 1) {
- /* round to cluster size */
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- bdrv_truncate(s->hd, cluster_offset + s->cluster_size);
- /* if encrypted, we must initialize the cluster
- content which won't be written */
- if (s->crypt_method &&
- (n_end - n_start) < s->cluster_sectors) {
- uint64_t start_sect;
- start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
- memset(s->cluster_data + 512, 0x00, 512);
- for(i = 0; i < s->cluster_sectors; i++) {
- if (i < n_start || i >= n_end) {
- encrypt_sectors(s, start_sect + i,
- s->cluster_data,
- s->cluster_data + 512, 1, 1,
- &s->aes_encrypt_key);
- if (bdrv_pwrite(s->hd, cluster_offset + i * 512,
- s->cluster_data, 512) != 512)
- return -1;
- }
- }
- }
- } else {
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
- (uint64_t)compressed_size << (63 - s->cluster_bits);
- }
- }
- /* update L2 table */
- tmp = cpu_to_be64(cluster_offset);
- l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd,
- l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- }
- return cluster_offset;
-}
-
-static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
- const uint8_t *buf, int buf_size)
-{
- z_stream strm1, *strm = &strm1;
- int ret, out_len;
-
- memset(strm, 0, sizeof(*strm));
-
- strm->next_in = (uint8_t *)buf;
- strm->avail_in = buf_size;
- strm->next_out = out_buf;
- strm->avail_out = out_buf_size;
-
- ret = inflateInit2(strm, -12);
- if (ret != Z_OK)
- return -1;
- ret = inflate(strm, Z_FINISH);
- out_len = strm->next_out - out_buf;
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
- out_len != out_buf_size) {
- inflateEnd(strm);
- return -1;
- }
- inflateEnd(strm);
- return 0;
-}
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
-{
- int ret, csize;
- uint64_t coffset;
-
- coffset = cluster_offset & s->cluster_offset_mask;
- if (s->cluster_cache_offset != coffset) {
- csize = cluster_offset >> (63 - s->cluster_bits);
- csize &= (s->cluster_size - 1);
- ret = bdrv_pread(s->hd, coffset, s->cluster_data, csize);
- if (ret != csize)
- return -1;
- if (decompress_buffer(s->cluster_cache, s->cluster_size,
- s->cluster_data, csize) < 0) {
- return -1;
- }
- s->cluster_cache_offset = coffset;
- }
- return 0;
-}
-
-#if 0
-
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- if (!cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
- if (ret < 0)
- return -1;
- } else {
- memset(buf, 0, 512 * n);
- }
- } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- if (decompress_cluster(s, cluster_offset) < 0)
- return -1;
- memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
- } else {
- ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- if (ret != n * 512)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf, n, 0,
- &s->aes_decrypt_key);
- }
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-#endif
-
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *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, 0,
- index_in_cluster,
- index_in_cluster + n);
- if (!cluster_offset)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
- &s->aes_encrypt_key);
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
- s->cluster_data, n * 512);
- } else {
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- }
- if (ret != n * 512)
- return -1;
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- s->cluster_cache_offset = -1; /* disable compressed cache */
- return 0;
-}
-
-typedef struct QCowAIOCB {
- BlockDriverAIOCB common;
- int64_t sector_num;
- uint8_t *buf;
- int nb_sectors;
- int n;
- uint64_t cluster_offset;
- uint8_t *cluster_data;
- BlockDriverAIOCB *hd_aiocb;
-} QCowAIOCB;
-
-static void qcow_aio_read_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
-
- acb->hd_aiocb = NULL;
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- redo:
- /* post process the read buffer */
- if (!acb->cluster_offset) {
- /* nothing to do */
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* nothing to do */
- } else {
- if (s->crypt_method) {
- encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
- acb->n, 0,
- &s->aes_decrypt_key);
- }
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- /* prepare next AIO request */
- acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
- 0, 0, 0, 0);
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
- acb->n = s->cluster_sectors - index_in_cluster;
- if (acb->n > acb->nb_sectors)
- acb->n = acb->nb_sectors;
-
- if (!acb->cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- acb->hd_aiocb = bdrv_aio_read(bs->backing_hd,
- acb->sector_num, acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- } else {
- /* Note: in this case, no need to wait */
- memset(acb->buf, 0, 512 * acb->n);
- goto redo;
- }
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* add AIO support for compressed blocks ? */
- if (decompress_cluster(s, acb->cluster_offset) < 0)
- goto fail;
- memcpy(acb->buf,
- s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
- goto redo;
- } else {
- if ((acb->cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- acb->hd_aiocb = bdrv_aio_read(s->hd,
- (acb->cluster_offset >> 9) + index_in_cluster,
- acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- }
-}
-
-static BlockDriverAIOCB *qcow_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QCowAIOCB *acb;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->hd_aiocb = NULL;
- acb->sector_num = sector_num;
- acb->buf = buf;
- acb->nb_sectors = nb_sectors;
- acb->n = 0;
- acb->cluster_offset = 0;
-
- qcow_aio_read_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_write_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
- uint64_t cluster_offset;
- const uint8_t *src_buf;
-
- acb->hd_aiocb = NULL;
-
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
- acb->n = s->cluster_sectors - index_in_cluster;
- if (acb->n > acb->nb_sectors)
- acb->n = acb->nb_sectors;
- cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
- index_in_cluster,
- index_in_cluster + acb->n);
- if (!cluster_offset || (cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- if (s->crypt_method) {
- if (!acb->cluster_data) {
- acb->cluster_data = qemu_mallocz(s->cluster_size);
- if (!acb->cluster_data) {
- ret = -ENOMEM;
- goto fail;
- }
- }
- encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
- acb->n, 1, &s->aes_encrypt_key);
- src_buf = acb->cluster_data;
- } else {
- src_buf = acb->buf;
- }
- acb->hd_aiocb = bdrv_aio_write(s->hd,
- (cluster_offset >> 9) + index_in_cluster,
- src_buf, acb->n,
- qcow_aio_write_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
-}
-
-static BlockDriverAIOCB *qcow_aio_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVQcowState *s = bs->opaque;
- QCowAIOCB *acb;
-
- s->cluster_cache_offset = -1; /* disable compressed cache */
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->hd_aiocb = NULL;
- acb->sector_num = sector_num;
- acb->buf = (uint8_t *)buf;
- acb->nb_sectors = nb_sectors;
- acb->n = 0;
-
- qcow_aio_write_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- QCowAIOCB *acb = (QCowAIOCB *)blockacb;
- if (acb->hd_aiocb)
- bdrv_aio_cancel(acb->hd_aiocb);
- qemu_aio_release(acb);
-}
-
-static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVQcowState *s = bs->opaque;
- return bdrv_aio_flush(s->hd, cb, opaque);
-}
-
-static void qcow_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- bdrv_delete(s->hd);
-}
-
-static int qcow_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd, header_size, backing_filename_len, l1_size, i, shift;
- QCowHeader header;
- uint64_t tmp;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
- if (fd < 0)
- return -1;
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(QCOW_VERSION);
- header.size = cpu_to_be64(total_size * 512);
- header_size = sizeof(header);
- backing_filename_len = 0;
- if (backing_file) {
- header.backing_file_offset = cpu_to_be64(header_size);
- backing_filename_len = strlen(backing_file);
- header.backing_file_size = cpu_to_be32(backing_filename_len);
- header_size += backing_filename_len;
- header.mtime = cpu_to_be32(0);
- header.cluster_bits = 9; /* 512 byte cluster to avoid copying
- unmodifyed sectors */
- header.l2_bits = 12; /* 32 KB L2 tables */
- } else {
- header.cluster_bits = 12; /* 4 KB clusters */
- header.l2_bits = 9; /* 4 KB L2 tables */
- }
- header_size = (header_size + 7) & ~7;
- shift = header.cluster_bits + header.l2_bits;
- l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
-
- header.l1_table_offset = cpu_to_be64(header_size);
- if (flags) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
- } else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
- }
-
- /* write all the data */
- write(fd, &header, sizeof(header));
- if (backing_file) {
- write(fd, backing_file, backing_filename_len);
- }
- lseek(fd, header_size, SEEK_SET);
- tmp = 0;
- for(i = 0;i < l1_size; i++) {
- write(fd, &tmp, sizeof(tmp));
- }
- close(fd);
- return 0;
-}
-
-static int qcow_make_empty(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- uint32_t l1_length = s->l1_size * sizeof(uint64_t);
- int ret;
-
- memset(s->l1_table, 0, l1_length);
- if (bdrv_pwrite(s->hd, s->l1_table_offset, s->l1_table, l1_length) < 0)
- return -1;
- ret = bdrv_truncate(s->hd, s->l1_table_offset + l1_length);
- if (ret < 0)
- return ret;
-
- 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;
-}
-
-/* XXX: put compressed sectors first, then all the cluster aligned
- tables to avoid losing bytes in alignment */
-static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- z_stream strm;
- int ret, out_len;
- uint8_t *out_buf;
- uint64_t cluster_offset;
-
- if (nb_sectors != s->cluster_sectors)
- return -EINVAL;
-
- out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
- if (!out_buf)
- return -1;
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != 0) {
- qemu_free(out_buf);
- return -1;
- }
-
- strm.avail_in = s->cluster_size;
- strm.next_in = (uint8_t *)buf;
- strm.avail_out = s->cluster_size;
- strm.next_out = out_buf;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- qemu_free(out_buf);
- deflateEnd(&strm);
- return -1;
- }
- out_len = strm.next_out - out_buf;
-
- deflateEnd(&strm);
-
- if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
- /* could not compress: write normal cluster */
- qcow_write(bs, sector_num, buf, s->cluster_sectors);
- } else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
- out_len, 0, 0);
- cluster_offset &= s->cluster_offset_mask;
- if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
- qemu_free(out_buf);
- return -1;
- }
- }
-
- qemu_free(out_buf);
- return 0;
-}
-
-static int qcow_flush(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- return bdrv_flush(s->hd);
-}
-
-static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BDRVQcowState *s = bs->opaque;
- bdi->cluster_size = s->cluster_size;
- return 0;
-}
-
-BlockDriver bdrv_qcow = {
- "qcow",
- sizeof(BDRVQcowState),
- qcow_probe,
- qcow_open,
- NULL,
- NULL,
- qcow_close,
- qcow_create,
- qcow_flush,
- qcow_is_allocated,
- qcow_set_key,
- qcow_make_empty,
-
- .bdrv_aio_read = qcow_aio_read,
- .bdrv_aio_write = qcow_aio_write,
- .bdrv_aio_cancel = qcow_aio_cancel,
- .bdrv_aio_flush = qcow_aio_flush,
- .aiocb_size = sizeof(QCowAIOCB),
- .bdrv_write_compressed = qcow_write_compressed,
- .bdrv_get_info = qcow_get_info,
-};
diff --git a/tools/ioemu/block-qcow2.c b/tools/ioemu/block-qcow2.c
deleted file mode 100644
index 606716bdc1..0000000000
--- a/tools/ioemu/block-qcow2.c
+++ /dev/null
@@ -1,2260 +0,0 @@
-/*
- * Block driver for the QCOW version 2 format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include <zlib.h>
-#include "aes.h"
-#include <assert.h>
-
-/*
- Differences with QCOW:
-
- - Support for multiple incremental snapshots.
- - Memory management by reference counts.
- - Clusters which have a reference count of one have the bit
- QCOW_OFLAG_COPIED to optimize write performance.
- - Size of compressed clusters is stored in sectors to reduce bit usage
- in the cluster offsets.
- - Support for storing additional data (such as the VM state) in the
- snapshots.
- - If a backing store is used, the cluster size is not constrained
- (could be backported to QCOW).
- - L2 tables have always a size of one cluster.
-*/
-
-//#define DEBUG_ALLOC
-//#define DEBUG_ALLOC2
-
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-#define QCOW_VERSION 2
-
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
-
-/* indicate that the refcount of the referenced cluster is exactly one. */
-#define QCOW_OFLAG_COPIED (1LL << 63)
-/* indicate that the cluster is compressed (they never have the copied flag) */
-#define QCOW_OFLAG_COMPRESSED (1LL << 62)
-
-#define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
-
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-typedef struct QCowHeader {
- uint32_t magic;
- uint32_t version;
- uint64_t backing_file_offset;
- uint32_t backing_file_size;
- uint32_t cluster_bits;
- uint64_t size; /* in bytes */
- uint32_t crypt_method;
- uint32_t l1_size; /* XXX: save number of clusters instead ? */
- uint64_t l1_table_offset;
- uint64_t refcount_table_offset;
- uint32_t refcount_table_clusters;
- uint32_t nb_snapshots;
- uint64_t snapshots_offset;
-} QCowHeader;
-
-typedef struct __attribute__((packed)) QCowSnapshotHeader {
- /* header is 8 byte aligned */
- uint64_t l1_table_offset;
-
- uint32_t l1_size;
- uint16_t id_str_size;
- uint16_t name_size;
-
- uint32_t date_sec;
- uint32_t date_nsec;
-
- uint64_t vm_clock_nsec;
-
- uint32_t vm_state_size;
- uint32_t extra_data_size; /* for extension */
- /* extra data follows */
- /* id_str follows */
- /* name follows */
-} QCowSnapshotHeader;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct QCowSnapshot {
- uint64_t l1_table_offset;
- uint32_t l1_size;
- char *id_str;
- char *name;
- uint32_t vm_state_size;
- uint32_t date_sec;
- uint32_t date_nsec;
- uint64_t vm_clock_nsec;
-} QCowSnapshot;
-
-typedef struct BDRVQcowState {
- BlockDriverState *hd;
- int cluster_bits;
- int cluster_size;
- int cluster_sectors;
- int l2_bits;
- int l2_size;
- int l1_size;
- int l1_vm_state_index;
- int csize_shift;
- int csize_mask;
- uint64_t cluster_offset_mask;
- uint64_t l1_table_offset;
- uint64_t *l1_table;
- uint64_t *l2_cache;
- uint64_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
- uint8_t *cluster_cache;
- uint8_t *cluster_data;
- uint64_t cluster_cache_offset;
-
- uint64_t *refcount_table;
- uint64_t refcount_table_offset;
- uint32_t refcount_table_size;
- uint64_t refcount_block_cache_offset;
- uint16_t *refcount_block_cache;
- int64_t free_cluster_index;
- int64_t free_byte_offset;
-
- uint32_t crypt_method; /* current crypt method, 0 if no key yet */
- uint32_t crypt_method_header;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
- uint64_t snapshots_offset;
- int snapshots_size;
- int nb_snapshots;
- QCowSnapshot *snapshots;
-} BDRVQcowState;
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-static int qcow_read_snapshots(BlockDriverState *bs);
-static void qcow_free_snapshots(BlockDriverState *bs);
-static int refcount_init(BlockDriverState *bs);
-static void refcount_close(BlockDriverState *bs);
-static int get_refcount(BlockDriverState *bs, int64_t cluster_index);
-static int update_cluster_refcount(BlockDriverState *bs,
- int64_t cluster_index,
- int addend);
-static void update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
- int addend);
-static int64_t alloc_clusters(BlockDriverState *bs, int64_t size);
-static int64_t alloc_bytes(BlockDriverState *bs, int size);
-static void free_clusters(BlockDriverState *bs,
- int64_t offset, int64_t size);
-#ifdef DEBUG_ALLOC
-static void check_refcounts(BlockDriverState *bs);
-#endif
-
-static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const QCowHeader *cow_header = (const void *)buf;
-
- if (buf_size >= sizeof(QCowHeader) &&
- be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVQcowState *s = bs->opaque;
- int len, i, shift, ret;
- QCowHeader header;
-
- ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
- if (ret < 0)
- return ret;
- if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
- goto fail;
- be32_to_cpus(&header.magic);
- be32_to_cpus(&header.version);
- be64_to_cpus(&header.backing_file_offset);
- be32_to_cpus(&header.backing_file_size);
- be64_to_cpus(&header.size);
- be32_to_cpus(&header.cluster_bits);
- be32_to_cpus(&header.crypt_method);
- be64_to_cpus(&header.l1_table_offset);
- be32_to_cpus(&header.l1_size);
- be64_to_cpus(&header.refcount_table_offset);
- be32_to_cpus(&header.refcount_table_clusters);
- be64_to_cpus(&header.snapshots_offset);
- be32_to_cpus(&header.nb_snapshots);
-
- if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
- goto fail;
- if (header.size <= 1 ||
- header.cluster_bits < 9 ||
- header.cluster_bits > 16)
- goto fail;
- if (header.crypt_method > QCOW_CRYPT_AES)
- goto fail;
- s->crypt_method_header = header.crypt_method;
- if (s->crypt_method_header)
- bs->encrypted = 1;
- s->cluster_bits = header.cluster_bits;
- s->cluster_size = 1 << s->cluster_bits;
- s->cluster_sectors = 1 << (s->cluster_bits - 9);
- s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */
- s->l2_size = 1 << s->l2_bits;
- bs->total_sectors = header.size / 512;
- s->csize_shift = (62 - (s->cluster_bits - 8));
- s->csize_mask = (1 << (s->cluster_bits - 8)) - 1;
- s->cluster_offset_mask = (1LL << s->csize_shift) - 1;
- s->refcount_table_offset = header.refcount_table_offset;
- s->refcount_table_size =
- header.refcount_table_clusters << (s->cluster_bits - 3);
-
- s->snapshots_offset = header.snapshots_offset;
- s->nb_snapshots = header.nb_snapshots;
-
- /* read the level 1 table */
- s->l1_size = header.l1_size;
- shift = s->cluster_bits + s->l2_bits;
- s->l1_vm_state_index = (header.size + (1LL << shift) - 1) >> shift;
- /* the L1 table must contain at least enough entries to put
- header.size bytes */
- if (s->l1_size < s->l1_vm_state_index)
- goto fail;
- s->l1_table_offset = header.l1_table_offset;
- s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
- if (!s->l1_table)
- goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
- s->l1_size * sizeof(uint64_t))
- goto fail;
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
- /* alloc L2 cache */
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- if (!s->l2_cache)
- goto fail;
- s->cluster_cache = qemu_malloc(s->cluster_size);
- if (!s->cluster_cache)
- goto fail;
- /* one more sector for decompressed data alignment */
- s->cluster_data = qemu_malloc(s->cluster_size + 512);
- if (!s->cluster_data)
- goto fail;
- s->cluster_cache_offset = -1;
-
- if (refcount_init(bs) < 0)
- goto fail;
-
- /* read the backing file name */
- if (header.backing_file_offset != 0) {
- len = header.backing_file_size;
- if (len > 1023)
- len = 1023;
- if (bdrv_pread(s->hd, header.backing_file_offset, bs->backing_file, len) != len)
- goto fail;
- bs->backing_file[len] = '\0';
- }
- if (qcow_read_snapshots(bs) < 0)
- goto fail;
-
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
-
- fail:
- qcow_free_snapshots(bs);
- refcount_close(bs);
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- bdrv_delete(s->hd);
- return -1;
-}
-
-static int qcow_set_key(BlockDriverState *bs, const char *key)
-{
- BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
-
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
- s->crypt_method = s->crypt_method_header;
-
- if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
- return -1;
- if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
- return -1;
-#if 0
- /* test */
- {
- uint8_t in[16];
- uint8_t out[16];
- uint8_t tmp[16];
- for(i=0;i<16;i++)
- in[i] = i;
- AES_encrypt(in, tmp, &s->aes_encrypt_key);
- AES_decrypt(tmp, out, &s->aes_decrypt_key);
- for(i = 0; i < 16; i++)
- printf(" %02x", tmp[i]);
- printf("\n");
- for(i = 0; i < 16; i++)
- printf(" %02x", out[i]);
- printf("\n");
- }
-#endif
- return 0;
-}
-
-/* The crypt function is compatible with the linux cryptoloop
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
- supported */
-static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key)
-{
- union {
- uint64_t ll[2];
- uint8_t b[16];
- } ivec;
- int i;
-
- for(i = 0; i < nb_sectors; i++) {
- ivec.ll[0] = cpu_to_le64(sector_num);
- ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
- ivec.b, enc);
- sector_num++;
- in_buf += 512;
- out_buf += 512;
- }
-}
-
-static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
- uint64_t cluster_offset, int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- int n, ret;
-
- n = n_end - n_start;
- if (n <= 0)
- return 0;
- ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n);
- if (ret < 0)
- return ret;
- if (s->crypt_method) {
- encrypt_sectors(s, start_sect + n_start,
- s->cluster_data,
- s->cluster_data, n, 1,
- &s->aes_encrypt_key);
- }
- ret = bdrv_write(s->hd, (cluster_offset >> 9) + n_start,
- s->cluster_data, n);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static void l2_cache_reset(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
-
- 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));
-}
-
-static inline int l2_cache_new_entry(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- uint32_t min_count;
- int min_index, i;
-
- /* find a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- return min_index;
-}
-
-static int64_t align_offset(int64_t offset, int n)
-{
- offset = (offset + n - 1) & ~(n - 1);
- return offset;
-}
-
-static int grow_l1_table(BlockDriverState *bs, int min_size)
-{
- BDRVQcowState *s = bs->opaque;
- int new_l1_size, new_l1_size2, ret, i;
- uint64_t *new_l1_table;
- uint64_t new_l1_table_offset;
- uint64_t data64;
- uint32_t data32;
-
- new_l1_size = s->l1_size;
- if (min_size <= new_l1_size)
- return 0;
- while (min_size > new_l1_size) {
- new_l1_size = (new_l1_size * 3 + 1) / 2;
- }
-#ifdef DEBUG_ALLOC2
- printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
-#endif
-
- new_l1_size2 = sizeof(uint64_t) * new_l1_size;
- new_l1_table = qemu_mallocz(new_l1_size2);
- if (!new_l1_table)
- return -ENOMEM;
- memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
-
- /* write new table (align to cluster) */
- new_l1_table_offset = alloc_clusters(bs, new_l1_size2);
-
- for(i = 0; i < s->l1_size; i++)
- new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
- ret = bdrv_pwrite(s->hd, new_l1_table_offset, new_l1_table, new_l1_size2);
- if (ret != new_l1_size2)
- goto fail;
- for(i = 0; i < s->l1_size; i++)
- new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
-
- /* set new table */
- data64 = cpu_to_be64(new_l1_table_offset);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_table_offset),
- &data64, sizeof(data64)) != sizeof(data64))
- goto fail;
- data32 = cpu_to_be32(new_l1_size);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size),
- &data32, sizeof(data32)) != sizeof(data32))
- goto fail;
- qemu_free(s->l1_table);
- free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
- s->l1_table_offset = new_l1_table_offset;
- s->l1_table = new_l1_table;
- s->l1_size = new_l1_size;
- return 0;
- fail:
- qemu_free(s->l1_table);
- return -EIO;
-}
-
-/* 'allocate' is:
- *
- * 0 not to allocate.
- *
- * 1 to allocate a normal cluster (for sector indexes 'n_start' to
- * 'n_end')
- *
- * 2 to allocate a compressed cluster of size
- * 'compressed_size'. 'compressed_size' must be > 0 and <
- * cluster_size
- *
- * return 0 if not allocated.
- */
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset, int allocate,
- int compressed_size,
- int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- int min_index, i, j, l1_index, l2_index, ret;
- uint64_t l2_offset, *l2_table, cluster_offset, tmp, old_l2_offset;
-
- l1_index = offset >> (s->l2_bits + s->cluster_bits);
- if (l1_index >= s->l1_size) {
- /* outside l1 table is allowed: we grow the table if needed */
- if (!allocate)
- return 0;
- if (grow_l1_table(bs, l1_index + 1) < 0)
- return 0;
- }
- l2_offset = s->l1_table[l1_index];
- if (!l2_offset) {
- if (!allocate)
- return 0;
- l2_allocate:
- old_l2_offset = l2_offset;
- /* allocate a new l2 entry */
- l2_offset = alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
- /* update the L1 entry */
- s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
- tmp = cpu_to_be64(l2_offset | QCOW_OFLAG_COPIED);
- if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
- &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- min_index = l2_cache_new_entry(bs);
- l2_table = s->l2_cache + (min_index << s->l2_bits);
-
- if (old_l2_offset == 0) {
- memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- } else {
- if (bdrv_pread(s->hd, old_l2_offset,
- l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- }
- if (bdrv_pwrite(s->hd, l2_offset,
- l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- } else {
- if (!(l2_offset & QCOW_OFLAG_COPIED)) {
- if (allocate) {
- free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
- goto l2_allocate;
- }
- } else {
- l2_offset &= ~QCOW_OFLAG_COPIED;
- }
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i << s->l2_bits);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = l2_cache_new_entry(bs);
- l2_table = s->l2_cache + (min_index << s->l2_bits);
- if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- }
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (!cluster_offset) {
- if (!allocate)
- return cluster_offset;
- } else if (!(cluster_offset & QCOW_OFLAG_COPIED)) {
- if (!allocate)
- return cluster_offset;
- /* free the cluster */
- if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- int nb_csectors;
- nb_csectors = ((cluster_offset >> s->csize_shift) &
- s->csize_mask) + 1;
- free_clusters(bs, (cluster_offset & s->cluster_offset_mask) & ~511,
- nb_csectors * 512);
- } else {
- free_clusters(bs, cluster_offset, s->cluster_size);
- }
- } else {
- cluster_offset &= ~QCOW_OFLAG_COPIED;
- return cluster_offset;
- }
- if (allocate == 1) {
- /* allocate a new cluster */
- cluster_offset = alloc_clusters(bs, s->cluster_size);
-
- /* we must initialize the cluster content which won't be
- written */
- if ((n_end - n_start) < s->cluster_sectors) {
- uint64_t start_sect;
-
- start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
- ret = copy_sectors(bs, start_sect,
- cluster_offset, 0, n_start);
- if (ret < 0)
- return 0;
- ret = copy_sectors(bs, start_sect,
- cluster_offset, n_end, s->cluster_sectors);
- if (ret < 0)
- return 0;
- }
- tmp = cpu_to_be64(cluster_offset | QCOW_OFLAG_COPIED);
- } else {
- int nb_csectors;
- cluster_offset = alloc_bytes(bs, compressed_size);
- nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
- (cluster_offset >> 9);
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
- ((uint64_t)nb_csectors << s->csize_shift);
- /* compressed clusters never have the copied flag */
- tmp = cpu_to_be64(cluster_offset);
- }
- /* update L2 table */
- l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd,
- l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- return cluster_offset;
-}
-
-static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
- const uint8_t *buf, int buf_size)
-{
- z_stream strm1, *strm = &strm1;
- int ret, out_len;
-
- memset(strm, 0, sizeof(*strm));
-
- strm->next_in = (uint8_t *)buf;
- strm->avail_in = buf_size;
- strm->next_out = out_buf;
- strm->avail_out = out_buf_size;
-
- ret = inflateInit2(strm, -12);
- if (ret != Z_OK)
- return -1;
- ret = inflate(strm, Z_FINISH);
- out_len = strm->next_out - out_buf;
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
- out_len != out_buf_size) {
- inflateEnd(strm);
- return -1;
- }
- inflateEnd(strm);
- return 0;
-}
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
-{
- int ret, csize, nb_csectors, sector_offset;
- uint64_t coffset;
-
- coffset = cluster_offset & s->cluster_offset_mask;
- if (s->cluster_cache_offset != coffset) {
- nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
- sector_offset = coffset & 511;
- csize = nb_csectors * 512 - sector_offset;
- ret = bdrv_read(s->hd, coffset >> 9, s->cluster_data, nb_csectors);
- if (ret < 0) {
- return -1;
- }
- if (decompress_buffer(s->cluster_cache, s->cluster_size,
- s->cluster_data + sector_offset, csize) < 0) {
- return -1;
- }
- s->cluster_cache_offset = coffset;
- }
- return 0;
-}
-
-/* handle reading after the end of the backing file */
-static int backing_read1(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors)
-{
- int n1;
- if ((sector_num + nb_sectors) <= bs->total_sectors)
- return nb_sectors;
- if (sector_num >= bs->total_sectors)
- n1 = 0;
- else
- n1 = bs->total_sectors - sector_num;
- memset(buf + n1 * 512, 0, 512 * (nb_sectors - n1));
- return n1;
-}
-
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n, n1;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- if (!cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- n1 = backing_read1(bs->backing_hd, sector_num, buf, n);
- if (n1 > 0) {
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
- if (ret < 0)
- return -1;
- }
- } else {
- memset(buf, 0, 512 * n);
- }
- } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- if (decompress_cluster(s, cluster_offset) < 0)
- return -1;
- memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
- } else {
- ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- if (ret != n * 512)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf, n, 0,
- &s->aes_decrypt_key);
- }
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *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, 0,
- index_in_cluster,
- index_in_cluster + n);
- if (!cluster_offset)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
- &s->aes_encrypt_key);
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
- s->cluster_data, n * 512);
- } else {
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- }
- if (ret != n * 512)
- return -1;
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- s->cluster_cache_offset = -1; /* disable compressed cache */
- return 0;
-}
-
-typedef struct QCowAIOCB {
- BlockDriverAIOCB common;
- int64_t sector_num;
- uint8_t *buf;
- int nb_sectors;
- int n;
- uint64_t cluster_offset;
- uint8_t *cluster_data;
- BlockDriverAIOCB *hd_aiocb;
-} QCowAIOCB;
-
-static void qcow_aio_read_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n1;
-
- acb->hd_aiocb = NULL;
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- redo:
- /* post process the read buffer */
- if (!acb->cluster_offset) {
- /* nothing to do */
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* nothing to do */
- } else {
- if (s->crypt_method) {
- encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
- acb->n, 0,
- &s->aes_decrypt_key);
- }
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- /* prepare next AIO request */
- acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
- 0, 0, 0, 0);
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
- acb->n = s->cluster_sectors - index_in_cluster;
- if (acb->n > acb->nb_sectors)
- acb->n = acb->nb_sectors;
-
- if (!acb->cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- n1 = backing_read1(bs->backing_hd, acb->sector_num,
- acb->buf, acb->n);
- if (n1 > 0) {
- acb->hd_aiocb = bdrv_aio_read(bs->backing_hd, acb->sector_num,
- acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- } else {
- goto redo;
- }
- } else {
- /* Note: in this case, no need to wait */
- memset(acb->buf, 0, 512 * acb->n);
- goto redo;
- }
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* add AIO support for compressed blocks ? */
- if (decompress_cluster(s, acb->cluster_offset) < 0)
- goto fail;
- memcpy(acb->buf,
- s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
- goto redo;
- } else {
- if ((acb->cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- acb->hd_aiocb = bdrv_aio_read(s->hd,
- (acb->cluster_offset >> 9) + index_in_cluster,
- acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- }
-}
-
-static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QCowAIOCB *acb;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->hd_aiocb = NULL;
- acb->sector_num = sector_num;
- acb->buf = buf;
- acb->nb_sectors = nb_sectors;
- acb->n = 0;
- acb->cluster_offset = 0;
- return acb;
-}
-
-static BlockDriverAIOCB *qcow_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QCowAIOCB *acb;
-
- acb = qcow_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
-
- qcow_aio_read_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_write_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
- uint64_t cluster_offset;
- const uint8_t *src_buf;
-
- acb->hd_aiocb = NULL;
-
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
- acb->n = s->cluster_sectors - index_in_cluster;
- if (acb->n > acb->nb_sectors)
- acb->n = acb->nb_sectors;
- cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
- index_in_cluster,
- index_in_cluster + acb->n);
- if (!cluster_offset || (cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- if (s->crypt_method) {
- if (!acb->cluster_data) {
- acb->cluster_data = qemu_mallocz(s->cluster_size);
- if (!acb->cluster_data) {
- ret = -ENOMEM;
- goto fail;
- }
- }
- encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
- acb->n, 1, &s->aes_encrypt_key);
- src_buf = acb->cluster_data;
- } else {
- src_buf = acb->buf;
- }
- acb->hd_aiocb = bdrv_aio_write(s->hd,
- (cluster_offset >> 9) + index_in_cluster,
- src_buf, acb->n,
- qcow_aio_write_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
-}
-
-static BlockDriverAIOCB *qcow_aio_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVQcowState *s = bs->opaque;
- QCowAIOCB *acb;
-
- s->cluster_cache_offset = -1; /* disable compressed cache */
-
- acb = qcow_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
-
- qcow_aio_write_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- QCowAIOCB *acb = (QCowAIOCB *)blockacb;
- if (acb->hd_aiocb)
- bdrv_aio_cancel(acb->hd_aiocb);
- qemu_aio_release(acb);
-}
-
-static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVQcowState *s = bs->opaque;
- return bdrv_aio_flush(s->hd, cb, opaque);
-}
-
-static void qcow_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- refcount_close(bs);
- bdrv_delete(s->hd);
-}
-
-/* XXX: use std qcow open function ? */
-typedef struct QCowCreateState {
- int cluster_size;
- int cluster_bits;
- uint16_t *refcount_block;
- uint64_t *refcount_table;
- int64_t l1_table_offset;
- int64_t refcount_table_offset;
- int64_t refcount_block_offset;
-} QCowCreateState;
-
-static void create_refcount_update(QCowCreateState *s,
- int64_t offset, int64_t size)
-{
- int refcount;
- int64_t start, last, cluster_offset;
- uint16_t *p;
-
- start = offset & ~(s->cluster_size - 1);
- last = (offset + size - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size) {
- p = &s->refcount_block[cluster_offset >> s->cluster_bits];
- refcount = be16_to_cpu(*p);
- refcount++;
- *p = cpu_to_be16(refcount);
- }
-}
-
-static int qcow_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
- QCowHeader header;
- uint64_t tmp, offset;
- QCowCreateState s1, *s = &s1;
-
- memset(s, 0, sizeof(*s));
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
- if (fd < 0)
- return -1;
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(QCOW_VERSION);
- header.size = cpu_to_be64(total_size * 512);
- header_size = sizeof(header);
- backing_filename_len = 0;
- if (backing_file) {
- header.backing_file_offset = cpu_to_be64(header_size);
- backing_filename_len = strlen(backing_file);
- header.backing_file_size = cpu_to_be32(backing_filename_len);
- header_size += backing_filename_len;
- }
- s->cluster_bits = 12; /* 4 KB clusters */
- s->cluster_size = 1 << s->cluster_bits;
- header.cluster_bits = cpu_to_be32(s->cluster_bits);
- header_size = (header_size + 7) & ~7;
- if (flags) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
- } else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
- }
- l2_bits = s->cluster_bits - 3;
- shift = s->cluster_bits + l2_bits;
- l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift);
- offset = align_offset(header_size, s->cluster_size);
- s->l1_table_offset = offset;
- header.l1_table_offset = cpu_to_be64(s->l1_table_offset);
- header.l1_size = cpu_to_be32(l1_size);
- offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
-
- s->refcount_table = qemu_mallocz(s->cluster_size);
- if (!s->refcount_table)
- goto fail;
- s->refcount_block = qemu_mallocz(s->cluster_size);
- if (!s->refcount_block)
- goto fail;
-
- s->refcount_table_offset = offset;
- header.refcount_table_offset = cpu_to_be64(offset);
- header.refcount_table_clusters = cpu_to_be32(1);
- offset += s->cluster_size;
-
- s->refcount_table[0] = cpu_to_be64(offset);
- s->refcount_block_offset = offset;
- offset += s->cluster_size;
-
- /* update refcounts */
- create_refcount_update(s, 0, header_size);
- create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));
- create_refcount_update(s, s->refcount_table_offset, s->cluster_size);
- create_refcount_update(s, s->refcount_block_offset, s->cluster_size);
-
- /* write all the data */
- write(fd, &header, sizeof(header));
- if (backing_file) {
- write(fd, backing_file, backing_filename_len);
- }
- lseek(fd, s->l1_table_offset, SEEK_SET);
- tmp = 0;
- for(i = 0;i < l1_size; i++) {
- write(fd, &tmp, sizeof(tmp));
- }
- lseek(fd, s->refcount_table_offset, SEEK_SET);
- write(fd, s->refcount_table, s->cluster_size);
-
- lseek(fd, s->refcount_block_offset, SEEK_SET);
- write(fd, s->refcount_block, s->cluster_size);
-
- qemu_free(s->refcount_table);
- qemu_free(s->refcount_block);
- close(fd);
- return 0;
- fail:
- qemu_free(s->refcount_table);
- qemu_free(s->refcount_block);
- close(fd);
- return -ENOMEM;
-}
-
-static int qcow_make_empty(BlockDriverState *bs)
-{
-#if 0
- /* XXX: not correct */
- BDRVQcowState *s = bs->opaque;
- uint32_t l1_length = s->l1_size * sizeof(uint64_t);
- int ret;
-
- memset(s->l1_table, 0, l1_length);
- if (bdrv_pwrite(s->hd, s->l1_table_offset, s->l1_table, l1_length) < 0)
- return -1;
- ret = bdrv_truncate(s->hd, s->l1_table_offset + l1_length);
- if (ret < 0)
- return ret;
-
- l2_cache_reset(bs);
-#endif
- return 0;
-}
-
-/* XXX: put compressed sectors first, then all the cluster aligned
- tables to avoid losing bytes in alignment */
-static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- z_stream strm;
- int ret, out_len;
- uint8_t *out_buf;
- uint64_t cluster_offset;
-
- if (nb_sectors == 0) {
- /* align end of file to a sector boundary to ease reading with
- sector based I/Os */
- cluster_offset = bdrv_getlength(s->hd);
- cluster_offset = (cluster_offset + 511) & ~511;
- bdrv_truncate(s->hd, cluster_offset);
- return 0;
- }
-
- if (nb_sectors != s->cluster_sectors)
- return -EINVAL;
-
- out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
- if (!out_buf)
- return -ENOMEM;
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != 0) {
- qemu_free(out_buf);
- return -1;
- }
-
- strm.avail_in = s->cluster_size;
- strm.next_in = (uint8_t *)buf;
- strm.avail_out = s->cluster_size;
- strm.next_out = out_buf;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- qemu_free(out_buf);
- deflateEnd(&strm);
- return -1;
- }
- out_len = strm.next_out - out_buf;
-
- deflateEnd(&strm);
-
- if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
- /* could not compress: write normal cluster */
- qcow_write(bs, sector_num, buf, s->cluster_sectors);
- } else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
- out_len, 0, 0);
- cluster_offset &= s->cluster_offset_mask;
- if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
- qemu_free(out_buf);
- return -1;
- }
- }
-
- qemu_free(out_buf);
- return 0;
-}
-
-static int qcow_flush(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- return bdrv_flush(s->hd);
-}
-
-static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BDRVQcowState *s = bs->opaque;
- bdi->cluster_size = s->cluster_size;
- bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
- (s->cluster_bits + s->l2_bits);
- return 0;
-}
-
-/*********************************************************/
-/* snapshot support */
-
-/* update the refcounts of snapshots and the copied flag */
-static int update_snapshot_refcount(BlockDriverState *bs,
- int64_t l1_table_offset,
- int l1_size,
- int addend)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated;
- int64_t old_offset, old_l2_offset;
- int l2_size, i, j, l1_modified, l2_modified, nb_csectors, refcount;
-
- l2_cache_reset(bs);
-
- l2_table = NULL;
- l1_table = NULL;
- l1_size2 = l1_size * sizeof(uint64_t);
- l1_allocated = 0;
- if (l1_table_offset != s->l1_table_offset) {
- l1_table = qemu_malloc(l1_size2);
- if (!l1_table)
- goto fail;
- l1_allocated = 1;
- if (bdrv_pread(s->hd, l1_table_offset,
- l1_table, l1_size2) != l1_size2)
- goto fail;
- for(i = 0;i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
- } else {
- assert(l1_size == s->l1_size);
- l1_table = s->l1_table;
- l1_allocated = 0;
- }
-
- l2_size = s->l2_size * sizeof(uint64_t);
- l2_table = qemu_malloc(l2_size);
- if (!l2_table)
- goto fail;
- l1_modified = 0;
- for(i = 0; i < l1_size; i++) {
- l2_offset = l1_table[i];
- if (l2_offset) {
- old_l2_offset = l2_offset;
- l2_offset &= ~QCOW_OFLAG_COPIED;
- l2_modified = 0;
- if (bdrv_pread(s->hd, l2_offset, l2_table, l2_size) != l2_size)
- goto fail;
- for(j = 0; j < s->l2_size; j++) {
- offset = be64_to_cpu(l2_table[j]);
- if (offset != 0) {
- old_offset = offset;
- offset &= ~QCOW_OFLAG_COPIED;
- if (offset & QCOW_OFLAG_COMPRESSED) {
- nb_csectors = ((offset >> s->csize_shift) &
- s->csize_mask) + 1;
- if (addend != 0)
- update_refcount(bs, (offset & s->cluster_offset_mask) & ~511,
- nb_csectors * 512, addend);
- /* compressed clusters are never modified */
- refcount = 2;
- } else {
- if (addend != 0) {
- refcount = update_cluster_refcount(bs, offset >> s->cluster_bits, addend);
- } else {
- refcount = get_refcount(bs, offset >> s->cluster_bits);
- }
- }
-
- if (refcount == 1) {
- offset |= QCOW_OFLAG_COPIED;
- }
- if (offset != old_offset) {
- l2_table[j] = cpu_to_be64(offset);
- l2_modified = 1;
- }
- }
- }
- if (l2_modified) {
- if (bdrv_pwrite(s->hd,
- l2_offset, l2_table, l2_size) != l2_size)
- goto fail;
- }
-
- if (addend != 0) {
- refcount = update_cluster_refcount(bs, l2_offset >> s->cluster_bits, addend);
- } else {
- refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
- }
- if (refcount == 1) {
- l2_offset |= QCOW_OFLAG_COPIED;
- }
- if (l2_offset != old_l2_offset) {
- l1_table[i] = l2_offset;
- l1_modified = 1;
- }
- }
- }
- if (l1_modified) {
- for(i = 0; i < l1_size; i++)
- cpu_to_be64s(&l1_table[i]);
- if (bdrv_pwrite(s->hd, l1_table_offset, l1_table,
- l1_size2) != l1_size2)
- goto fail;
- for(i = 0; i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
- }
- if (l1_allocated)
- qemu_free(l1_table);
- qemu_free(l2_table);
- return 0;
- fail:
- if (l1_allocated)
- qemu_free(l1_table);
- qemu_free(l2_table);
- return -EIO;
-}
-
-static void qcow_free_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int i;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- qemu_free(s->snapshots[i].name);
- qemu_free(s->snapshots[i].id_str);
- }
- qemu_free(s->snapshots);
- s->snapshots = NULL;
- s->nb_snapshots = 0;
-}
-
-static int qcow_read_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshotHeader h;
- QCowSnapshot *sn;
- int i, id_str_size, name_size;
- int64_t offset;
- uint32_t extra_data_size;
-
- offset = s->snapshots_offset;
- s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot));
- if (!s->snapshots)
- goto fail;
- for(i = 0; i < s->nb_snapshots; i++) {
- offset = align_offset(offset, 8);
- if (bdrv_pread(s->hd, offset, &h, sizeof(h)) != sizeof(h))
- goto fail;
- offset += sizeof(h);
- sn = s->snapshots + i;
- sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
- sn->l1_size = be32_to_cpu(h.l1_size);
- sn->vm_state_size = be32_to_cpu(h.vm_state_size);
- sn->date_sec = be32_to_cpu(h.date_sec);
- sn->date_nsec = be32_to_cpu(h.date_nsec);
- sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);
- extra_data_size = be32_to_cpu(h.extra_data_size);
-
- id_str_size = be16_to_cpu(h.id_str_size);
- name_size = be16_to_cpu(h.name_size);
-
- offset += extra_data_size;
-
- sn->id_str = qemu_malloc(id_str_size + 1);
- if (!sn->id_str)
- goto fail;
- if (bdrv_pread(s->hd, offset, sn->id_str, id_str_size) != id_str_size)
- goto fail;
- offset += id_str_size;
- sn->id_str[id_str_size] = '\0';
-
- sn->name = qemu_malloc(name_size + 1);
- if (!sn->name)
- goto fail;
- if (bdrv_pread(s->hd, offset, sn->name, name_size) != name_size)
- goto fail;
- offset += name_size;
- sn->name[name_size] = '\0';
- }
- s->snapshots_size = offset - s->snapshots_offset;
- return 0;
- fail:
- qcow_free_snapshots(bs);
- return -1;
-}
-
-/* add at the end of the file a new list of snapshots */
-static int qcow_write_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- QCowSnapshotHeader h;
- int i, name_size, id_str_size, snapshots_size;
- uint64_t data64;
- uint32_t data32;
- int64_t offset, snapshots_offset;
-
- /* compute the size of the snapshots */
- offset = 0;
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- offset = align_offset(offset, 8);
- offset += sizeof(h);
- offset += strlen(sn->id_str);
- offset += strlen(sn->name);
- }
- snapshots_size = offset;
-
- snapshots_offset = alloc_clusters(bs, snapshots_size);
- offset = snapshots_offset;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- memset(&h, 0, sizeof(h));
- h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);
- h.l1_size = cpu_to_be32(sn->l1_size);
- h.vm_state_size = cpu_to_be32(sn->vm_state_size);
- h.date_sec = cpu_to_be32(sn->date_sec);
- h.date_nsec = cpu_to_be32(sn->date_nsec);
- h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
-
- id_str_size = strlen(sn->id_str);
- name_size = strlen(sn->name);
- h.id_str_size = cpu_to_be16(id_str_size);
- h.name_size = cpu_to_be16(name_size);
- offset = align_offset(offset, 8);
- if (bdrv_pwrite(s->hd, offset, &h, sizeof(h)) != sizeof(h))
- goto fail;
- offset += sizeof(h);
- if (bdrv_pwrite(s->hd, offset, sn->id_str, id_str_size) != id_str_size)
- goto fail;
- offset += id_str_size;
- if (bdrv_pwrite(s->hd, offset, sn->name, name_size) != name_size)
- goto fail;
- offset += name_size;
- }
-
- /* update the various header fields */
- data64 = cpu_to_be64(snapshots_offset);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, snapshots_offset),
- &data64, sizeof(data64)) != sizeof(data64))
- goto fail;
- data32 = cpu_to_be32(s->nb_snapshots);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, nb_snapshots),
- &data32, sizeof(data32)) != sizeof(data32))
- goto fail;
-
- /* free the old snapshot table */
- free_clusters(bs, s->snapshots_offset, s->snapshots_size);
- s->snapshots_offset = snapshots_offset;
- s->snapshots_size = snapshots_size;
- return 0;
- fail:
- return -1;
-}
-
-static void find_new_snapshot_id(BlockDriverState *bs,
- char *id_str, int id_str_size)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int i, id, id_max = 0;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- id = strtoul(sn->id_str, NULL, 10);
- if (id > id_max)
- id_max = id;
- }
- snprintf(id_str, id_str_size, "%d", id_max + 1);
-}
-
-static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str)
-{
- BDRVQcowState *s = bs->opaque;
- int i;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- if (!strcmp(s->snapshots[i].id_str, id_str))
- return i;
- }
- return -1;
-}
-
-static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name)
-{
- BDRVQcowState *s = bs->opaque;
- int i, ret;
-
- ret = find_snapshot_by_id(bs, name);
- if (ret >= 0)
- return ret;
- for(i = 0; i < s->nb_snapshots; i++) {
- if (!strcmp(s->snapshots[i].name, name))
- return i;
- }
- return -1;
-}
-
-/* if no id is provided, a new one is constructed */
-static int qcow_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *snapshots1, sn1, *sn = &sn1;
- int i, ret;
- uint64_t *l1_table = NULL;
-
- memset(sn, 0, sizeof(*sn));
-
- if (sn_info->id_str[0] == '\0') {
- /* compute a new id */
- find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));
- }
-
- /* check that the ID is unique */
- if (find_snapshot_by_id(bs, sn_info->id_str) >= 0)
- return -ENOENT;
-
- sn->id_str = qemu_strdup(sn_info->id_str);
- if (!sn->id_str)
- goto fail;
- sn->name = qemu_strdup(sn_info->name);
- if (!sn->name)
- goto fail;
- sn->vm_state_size = sn_info->vm_state_size;
- sn->date_sec = sn_info->date_sec;
- sn->date_nsec = sn_info->date_nsec;
- sn->vm_clock_nsec = sn_info->vm_clock_nsec;
-
- ret = update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1);
- if (ret < 0)
- goto fail;
-
- /* create the L1 table of the snapshot */
- sn->l1_table_offset = alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
- sn->l1_size = s->l1_size;
-
- l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
- if (!l1_table)
- goto fail;
- for(i = 0; i < s->l1_size; i++) {
- l1_table[i] = cpu_to_be64(s->l1_table[i]);
- }
- if (bdrv_pwrite(s->hd, sn->l1_table_offset,
- l1_table, s->l1_size * sizeof(uint64_t)) !=
- (s->l1_size * sizeof(uint64_t)))
- goto fail;
- qemu_free(l1_table);
- l1_table = NULL;
-
- snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
- if (!snapshots1)
- goto fail;
- memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot));
- s->snapshots = snapshots1;
- s->snapshots[s->nb_snapshots++] = *sn;
-
- if (qcow_write_snapshots(bs) < 0)
- goto fail;
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
- fail:
- qemu_free(sn->name);
- qemu_free(l1_table);
- return -1;
-}
-
-/* copy the snapshot 'snapshot_name' into the current disk image */
-static int qcow_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int i, snapshot_index, l1_size2;
-
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
- if (snapshot_index < 0)
- return -ENOENT;
- sn = &s->snapshots[snapshot_index];
-
- if (update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0)
- goto fail;
-
- if (grow_l1_table(bs, sn->l1_size) < 0)
- goto fail;
-
- s->l1_size = sn->l1_size;
- l1_size2 = s->l1_size * sizeof(uint64_t);
- /* copy the snapshot l1 table to the current l1 table */
- if (bdrv_pread(s->hd, sn->l1_table_offset,
- s->l1_table, l1_size2) != l1_size2)
- goto fail;
- if (bdrv_pwrite(s->hd, s->l1_table_offset,
- s->l1_table, l1_size2) != l1_size2)
- goto fail;
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
-
- if (update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1) < 0)
- goto fail;
-
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
- fail:
- return -EIO;
-}
-
-static int qcow_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int snapshot_index, ret;
-
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
- if (snapshot_index < 0)
- return -ENOENT;
- sn = &s->snapshots[snapshot_index];
-
- ret = update_snapshot_refcount(bs, sn->l1_table_offset, sn->l1_size, -1);
- if (ret < 0)
- return ret;
- /* must update the copied flag on the current cluster offsets */
- ret = update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
- if (ret < 0)
- return ret;
- free_clusters(bs, sn->l1_table_offset, sn->l1_size * sizeof(uint64_t));
-
- qemu_free(sn->id_str);
- qemu_free(sn->name);
- memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn));
- s->nb_snapshots--;
- ret = qcow_write_snapshots(bs);
- if (ret < 0) {
- /* XXX: restore snapshot if error ? */
- return ret;
- }
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
-}
-
-static int qcow_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_tab)
-{
- BDRVQcowState *s = bs->opaque;
- QEMUSnapshotInfo *sn_tab, *sn_info;
- QCowSnapshot *sn;
- int i;
-
- sn_tab = qemu_mallocz(s->nb_snapshots * sizeof(QEMUSnapshotInfo));
- if (!sn_tab)
- goto fail;
- for(i = 0; i < s->nb_snapshots; i++) {
- sn_info = sn_tab + i;
- sn = s->snapshots + i;
- pstrcpy(sn_info->id_str, sizeof(sn_info->id_str),
- sn->id_str);
- pstrcpy(sn_info->name, sizeof(sn_info->name),
- sn->name);
- sn_info->vm_state_size = sn->vm_state_size;
- sn_info->date_sec = sn->date_sec;
- sn_info->date_nsec = sn->date_nsec;
- sn_info->vm_clock_nsec = sn->vm_clock_nsec;
- }
- *psn_tab = sn_tab;
- return s->nb_snapshots;
- fail:
- qemu_free(sn_tab);
- *psn_tab = NULL;
- return -ENOMEM;
-}
-
-/*********************************************************/
-/* refcount handling */
-
-static int refcount_init(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, refcount_table_size2, i;
-
- s->refcount_block_cache = qemu_malloc(s->cluster_size);
- if (!s->refcount_block_cache)
- goto fail;
- refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t);
- s->refcount_table = qemu_malloc(refcount_table_size2);
- if (!s->refcount_table)
- goto fail;
- if (s->refcount_table_size > 0) {
- ret = bdrv_pread(s->hd, s->refcount_table_offset,
- s->refcount_table, refcount_table_size2);
- if (ret != refcount_table_size2)
- goto fail;
- for(i = 0; i < s->refcount_table_size; i++)
- be64_to_cpus(&s->refcount_table[i]);
- }
- return 0;
- fail:
- return -ENOMEM;
-}
-
-static void refcount_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- qemu_free(s->refcount_block_cache);
- qemu_free(s->refcount_table);
-}
-
-
-static int load_refcount_block(BlockDriverState *bs,
- int64_t refcount_block_offset)
-{
- BDRVQcowState *s = bs->opaque;
- int ret;
- ret = bdrv_pread(s->hd, refcount_block_offset, s->refcount_block_cache,
- s->cluster_size);
- if (ret != s->cluster_size)
- return -EIO;
- s->refcount_block_cache_offset = refcount_block_offset;
- return 0;
-}
-
-static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
-{
- BDRVQcowState *s = bs->opaque;
- int refcount_table_index, block_index;
- int64_t refcount_block_offset;
-
- refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
- if (refcount_table_index >= s->refcount_table_size)
- return 0;
- refcount_block_offset = s->refcount_table[refcount_table_index];
- if (!refcount_block_offset)
- return 0;
- if (refcount_block_offset != s->refcount_block_cache_offset) {
- /* better than nothing: return allocated if read error */
- if (load_refcount_block(bs, refcount_block_offset) < 0)
- return 1;
- }
- block_index = cluster_index &
- ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
- return be16_to_cpu(s->refcount_block_cache[block_index]);
-}
-
-/* return < 0 if error */
-static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
-{
- BDRVQcowState *s = bs->opaque;
- int i, nb_clusters;
-
- nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits;
- for(;;) {
- if (get_refcount(bs, s->free_cluster_index) == 0) {
- s->free_cluster_index++;
- for(i = 1; i < nb_clusters; i++) {
- if (get_refcount(bs, s->free_cluster_index) != 0)
- goto not_found;
- s->free_cluster_index++;
- }
-#ifdef DEBUG_ALLOC2
- printf("alloc_clusters: size=%lld -> %lld\n",
- size,
- (s->free_cluster_index - nb_clusters) << s->cluster_bits);
-#endif
- return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
- } else {
- not_found:
- s->free_cluster_index++;
- }
- }
-}
-
-static int64_t alloc_clusters(BlockDriverState *bs, int64_t size)
-{
- int64_t offset;
-
- offset = alloc_clusters_noref(bs, size);
- update_refcount(bs, offset, size, 1);
- return offset;
-}
-
-/* only used to allocate compressed sectors. We try to allocate
- contiguous sectors. size must be <= cluster_size */
-static int64_t alloc_bytes(BlockDriverState *bs, int size)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t offset, cluster_offset;
- int free_in_cluster;
-
- assert(size > 0 && size <= s->cluster_size);
- if (s->free_byte_offset == 0) {
- s->free_byte_offset = alloc_clusters(bs, s->cluster_size);
- }
- redo:
- free_in_cluster = s->cluster_size -
- (s->free_byte_offset & (s->cluster_size - 1));
- if (size <= free_in_cluster) {
- /* enough space in current cluster */
- offset = s->free_byte_offset;
- s->free_byte_offset += size;
- free_in_cluster -= size;
- if (free_in_cluster == 0)
- s->free_byte_offset = 0;
- if ((offset & (s->cluster_size - 1)) != 0)
- update_cluster_refcount(bs, offset >> s->cluster_bits, 1);
- } else {
- offset = alloc_clusters(bs, s->cluster_size);
- cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1);
- if ((cluster_offset + s->cluster_size) == offset) {
- /* we are lucky: contiguous data */
- offset = s->free_byte_offset;
- update_cluster_refcount(bs, offset >> s->cluster_bits, 1);
- s->free_byte_offset += size;
- } else {
- s->free_byte_offset = offset;
- goto redo;
- }
- }
- return offset;
-}
-
-static void free_clusters(BlockDriverState *bs,
- int64_t offset, int64_t size)
-{
- update_refcount(bs, offset, size, -1);
-}
-
-static int grow_refcount_table(BlockDriverState *bs, int min_size)
-{
- BDRVQcowState *s = bs->opaque;
- int new_table_size, new_table_size2, refcount_table_clusters, i, ret;
- uint64_t *new_table;
- int64_t table_offset;
- uint64_t data64;
- uint32_t data32;
- int old_table_size;
- int64_t old_table_offset;
-
- if (min_size <= s->refcount_table_size)
- return 0;
- /* compute new table size */
- refcount_table_clusters = s->refcount_table_size >> (s->cluster_bits - 3);
- for(;;) {
- if (refcount_table_clusters == 0) {
- refcount_table_clusters = 1;
- } else {
- refcount_table_clusters = (refcount_table_clusters * 3 + 1) / 2;
- }
- new_table_size = refcount_table_clusters << (s->cluster_bits - 3);
- if (min_size <= new_table_size)
- break;
- }
-#ifdef DEBUG_ALLOC2
- printf("grow_refcount_table from %d to %d\n",
- s->refcount_table_size,
- new_table_size);
-#endif
- new_table_size2 = new_table_size * sizeof(uint64_t);
- new_table = qemu_mallocz(new_table_size2);
- if (!new_table)
- return -ENOMEM;
- memcpy(new_table, s->refcount_table,
- s->refcount_table_size * sizeof(uint64_t));
- for(i = 0; i < s->refcount_table_size; i++)
- cpu_to_be64s(&new_table[i]);
- /* Note: we cannot update the refcount now to avoid recursion */
- table_offset = alloc_clusters_noref(bs, new_table_size2);
- ret = bdrv_pwrite(s->hd, table_offset, new_table, new_table_size2);
- if (ret != new_table_size2)
- goto fail;
- for(i = 0; i < s->refcount_table_size; i++)
- be64_to_cpus(&new_table[i]);
-
- data64 = cpu_to_be64(table_offset);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
- &data64, sizeof(data64)) != sizeof(data64))
- goto fail;
- data32 = cpu_to_be32(refcount_table_clusters);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_clusters),
- &data32, sizeof(data32)) != sizeof(data32))
- goto fail;
- qemu_free(s->refcount_table);
- old_table_offset = s->refcount_table_offset;
- old_table_size = s->refcount_table_size;
- s->refcount_table = new_table;
- s->refcount_table_size = new_table_size;
- s->refcount_table_offset = table_offset;
-
- update_refcount(bs, table_offset, new_table_size2, 1);
- free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t));
- return 0;
- fail:
- free_clusters(bs, table_offset, new_table_size2);
- qemu_free(new_table);
- return -EIO;
-}
-
-/* addend must be 1 or -1 */
-/* XXX: cache several refcount block clusters ? */
-static int update_cluster_refcount(BlockDriverState *bs,
- int64_t cluster_index,
- int addend)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t offset, refcount_block_offset;
- int ret, refcount_table_index, block_index, refcount;
- uint64_t data64;
-
- refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
- if (refcount_table_index >= s->refcount_table_size) {
- if (addend < 0)
- return -EINVAL;
- ret = grow_refcount_table(bs, refcount_table_index + 1);
- if (ret < 0)
- return ret;
- }
- refcount_block_offset = s->refcount_table[refcount_table_index];
- if (!refcount_block_offset) {
- if (addend < 0)
- return -EINVAL;
- /* create a new refcount block */
- /* Note: we cannot update the refcount now to avoid recursion */
- offset = alloc_clusters_noref(bs, s->cluster_size);
- memset(s->refcount_block_cache, 0, s->cluster_size);
- ret = bdrv_pwrite(s->hd, offset, s->refcount_block_cache, s->cluster_size);
- if (ret != s->cluster_size)
- return -EINVAL;
- s->refcount_table[refcount_table_index] = offset;
- data64 = cpu_to_be64(offset);
- ret = bdrv_pwrite(s->hd, s->refcount_table_offset +
- refcount_table_index * sizeof(uint64_t),
- &data64, sizeof(data64));
- if (ret != sizeof(data64))
- return -EINVAL;
-
- refcount_block_offset = offset;
- s->refcount_block_cache_offset = offset;
- update_refcount(bs, offset, s->cluster_size, 1);
- } else {
- if (refcount_block_offset != s->refcount_block_cache_offset) {
- if (load_refcount_block(bs, refcount_block_offset) < 0)
- return -EIO;
- }
- }
- /* we can update the count and save it */
- block_index = cluster_index &
- ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
- refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
- refcount += addend;
- if (refcount < 0 || refcount > 0xffff)
- return -EINVAL;
- if (refcount == 0 && cluster_index < s->free_cluster_index) {
- s->free_cluster_index = cluster_index;
- }
- s->refcount_block_cache[block_index] = cpu_to_be16(refcount);
- if (bdrv_pwrite(s->hd,
- refcount_block_offset + (block_index << REFCOUNT_SHIFT),
- &s->refcount_block_cache[block_index], 2) != 2)
- return -EIO;
- return refcount;
-}
-
-static void update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
- int addend)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t start, last, cluster_offset;
-
-#ifdef DEBUG_ALLOC2
- printf("update_refcount: offset=%lld size=%lld addend=%d\n",
- offset, length, addend);
-#endif
- if (length <= 0)
- return;
- start = offset & ~(s->cluster_size - 1);
- last = (offset + length - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size) {
- update_cluster_refcount(bs, cluster_offset >> s->cluster_bits, addend);
- }
-}
-
-#ifdef DEBUG_ALLOC
-static void inc_refcounts(BlockDriverState *bs,
- uint16_t *refcount_table,
- int refcount_table_size,
- int64_t offset, int64_t size)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t start, last, cluster_offset;
- int k;
-
- if (size <= 0)
- return;
-
- start = offset & ~(s->cluster_size - 1);
- last = (offset + size - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size) {
- k = cluster_offset >> s->cluster_bits;
- if (k < 0 || k >= refcount_table_size) {
- printf("ERROR: invalid cluster offset=0x%llx\n", cluster_offset);
- } else {
- if (++refcount_table[k] == 0) {
- printf("ERROR: overflow cluster offset=0x%llx\n", cluster_offset);
- }
- }
- }
-}
-
-static int check_refcounts_l1(BlockDriverState *bs,
- uint16_t *refcount_table,
- int refcount_table_size,
- int64_t l1_table_offset, int l1_size,
- int check_copied)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2;
- int l2_size, i, j, nb_csectors, refcount;
-
- l2_table = NULL;
- l1_size2 = l1_size * sizeof(uint64_t);
-
- inc_refcounts(bs, refcount_table, refcount_table_size,
- l1_table_offset, l1_size2);
-
- l1_table = qemu_malloc(l1_size2);
- if (!l1_table)
- goto fail;
- if (bdrv_pread(s->hd, l1_table_offset,
- l1_table, l1_size2) != l1_size2)
- goto fail;
- for(i = 0;i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
-
- l2_size = s->l2_size * sizeof(uint64_t);
- l2_table = qemu_malloc(l2_size);
- if (!l2_table)
- goto fail;
- for(i = 0; i < l1_size; i++) {
- l2_offset = l1_table[i];
- if (l2_offset) {
- if (check_copied) {
- refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED) >> s->cluster_bits);
- if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {
- printf("ERROR OFLAG_COPIED: l2_offset=%llx refcount=%d\n",
- l2_offset, refcount);
- }
- }
- l2_offset &= ~QCOW_OFLAG_COPIED;
- if (bdrv_pread(s->hd, l2_offset, l2_table, l2_size) != l2_size)
- goto fail;
- for(j = 0; j < s->l2_size; j++) {
- offset = be64_to_cpu(l2_table[j]);
- if (offset != 0) {
- if (offset & QCOW_OFLAG_COMPRESSED) {
- if (offset & QCOW_OFLAG_COPIED) {
- printf("ERROR: cluster %lld: copied flag must never be set for compressed clusters\n",
- offset >> s->cluster_bits);
- offset &= ~QCOW_OFLAG_COPIED;
- }
- nb_csectors = ((offset >> s->csize_shift) &
- s->csize_mask) + 1;
- offset &= s->cluster_offset_mask;
- inc_refcounts(bs, refcount_table,
- refcount_table_size,
- offset & ~511, nb_csectors * 512);
- } else {
- if (check_copied) {
- refcount = get_refcount(bs, (offset & ~QCOW_OFLAG_COPIED) >> s->cluster_bits);
- if ((refcount == 1) != ((offset & QCOW_OFLAG_COPIED) != 0)) {
- printf("ERROR OFLAG_COPIED: offset=%llx refcount=%d\n",
- offset, refcount);
- }
- }
- offset &= ~QCOW_OFLAG_COPIED;
- inc_refcounts(bs, refcount_table,
- refcount_table_size,
- offset, s->cluster_size);
- }
- }
- }
- inc_refcounts(bs, refcount_table,
- refcount_table_size,
- l2_offset,
- s->cluster_size);
- }
- }
- qemu_free(l1_table);
- qemu_free(l2_table);
- return 0;
- fail:
- printf("ERROR: I/O error in check_refcounts_l1\n");
- qemu_free(l1_table);
- qemu_free(l2_table);
- return -EIO;
-}
-
-static void check_refcounts(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t size;
- int nb_clusters, refcount1, refcount2, i;
- QCowSnapshot *sn;
- uint16_t *refcount_table;
-
- size = bdrv_getlength(s->hd);
- nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits;
- refcount_table = qemu_mallocz(nb_clusters * sizeof(uint16_t));
-
- /* header */
- inc_refcounts(bs, refcount_table, nb_clusters,
- 0, s->cluster_size);
-
- check_refcounts_l1(bs, refcount_table, nb_clusters,
- s->l1_table_offset, s->l1_size, 1);
-
- /* snapshots */
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- check_refcounts_l1(bs, refcount_table, nb_clusters,
- sn->l1_table_offset, sn->l1_size, 0);
- }
- inc_refcounts(bs, refcount_table, nb_clusters,
- s->snapshots_offset, s->snapshots_size);
-
- /* refcount data */
- inc_refcounts(bs, refcount_table, nb_clusters,
- s->refcount_table_offset,
- s->refcount_table_size * sizeof(uint64_t));
- for(i = 0; i < s->refcount_table_size; i++) {
- int64_t offset;
- offset = s->refcount_table[i];
- if (offset != 0) {
- inc_refcounts(bs, refcount_table, nb_clusters,
- offset, s->cluster_size);
- }
- }
-
- /* compare ref counts */
- for(i = 0; i < nb_clusters; i++) {
- refcount1 = get_refcount(bs, i);
- refcount2 = refcount_table[i];
- if (refcount1 != refcount2)
- printf("ERROR cluster %d refcount=%d reference=%d\n",
- i, refcount1, refcount2);
- }
-
- qemu_free(refcount_table);
-}
-
-#if 0
-static void dump_refcounts(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t nb_clusters, k, k1, size;
- int refcount;
-
- size = bdrv_getlength(s->hd);
- nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits;
- for(k = 0; k < nb_clusters;) {
- k1 = k;
- refcount = get_refcount(bs, k);
- k++;
- while (k < nb_clusters && get_refcount(bs, k) == refcount)
- k++;
- printf("%lld: refcount=%d nb=%lld\n", k, refcount, k - k1);
- }
-}
-#endif
-#endif
-
-BlockDriver bdrv_qcow2 = {
- "qcow2",
- sizeof(BDRVQcowState),
- qcow_probe,
- qcow_open,
- NULL,
- NULL,
- qcow_close,
- qcow_create,
- qcow_flush,
- qcow_is_allocated,
- qcow_set_key,
- qcow_make_empty,
-
- .bdrv_aio_read = qcow_aio_read,
- .bdrv_aio_write = qcow_aio_write,
- .bdrv_aio_cancel = qcow_aio_cancel,
- .bdrv_aio_flush = qcow_aio_flush,
- .aiocb_size = sizeof(QCowAIOCB),
- .bdrv_write_compressed = qcow_write_compressed,
-
- .bdrv_snapshot_create = qcow_snapshot_create,
- .bdrv_snapshot_goto = qcow_snapshot_goto,
- .bdrv_snapshot_delete = qcow_snapshot_delete,
- .bdrv_snapshot_list = qcow_snapshot_list,
- .bdrv_get_info = qcow_get_info,
-};
diff --git a/tools/ioemu/block-raw.c b/tools/ioemu/block-raw.c
deleted file mode 100644
index cbc049f64e..0000000000
--- a/tools/ioemu/block-raw.c
+++ /dev/null
@@ -1,1512 +0,0 @@
-/*
- * Block driver for RAW files
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include <assert.h>
-#ifndef _WIN32
-#ifndef NO_AIO
-#include <aio.h>
-#endif
-
-#ifndef QEMU_TOOL
-#include "exec-all.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__
-#define _POSIX_PTHREAD_SEMANTICS 1
-#include <signal.h>
-#include <sys/dkio.h>
-#endif
-#ifdef __linux__
-#include <sys/ioctl.h>
-#include <linux/cdrom.h>
-#include <linux/fd.h>
-#endif
-#if defined(__FreeBSD__)
-#include <sys/disk.h>
-#endif
-#if defined(__OpenBSD__)
-#include <sys/ioctl.h>
-#include <sys/disklabel.h>
-#include <sys/dkio.h>
-#endif
-
-//#define DEBUG_FLOPPY
-
-#define DEBUG_BLOCK
-#ifdef DEBUG_BLOCK
-#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile )
-#else
-#define DEBUG_BLOCK_PRINT( formatCstr, args... )
-#endif
-
-#define FTYPE_FILE 0
-#define FTYPE_CD 1
-#define FTYPE_FD 2
-
-/* if the FD is not accessed during that time (in ms), we try to
- reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT 1000
-
-typedef struct BDRVRawState {
- int fd;
- int type;
- unsigned int lseek_err_cnt;
-#if defined(__linux__)
- /* linux floppy specific */
- int fd_open_flags;
- int64_t fd_open_time;
- int64_t fd_error_time;
- int fd_got_error;
- int fd_media_changed;
-#endif
-} BDRVRawState;
-
-static int fd_open(BlockDriverState *bs);
-
-static int raw_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int fd, open_flags, ret;
-
- s->lseek_err_cnt = 0;
-
- open_flags = O_BINARY;
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- open_flags |= O_RDWR;
- } else {
- open_flags |= O_RDONLY;
- bs->read_only = 1;
- }
- if (flags & BDRV_O_CREAT)
- open_flags |= O_CREAT | O_TRUNC;
-
- s->type = FTYPE_FILE;
-
- fd = open(filename, open_flags, 0644);
- if (fd < 0) {
- ret = -errno;
- if (ret == -EROFS)
- ret = -EACCES;
- return ret;
- }
- s->fd = fd;
- return 0;
-}
-
-/* XXX: use host sector size if necessary with:
-#ifdef DIOCGSECTORSIZE
- {
- unsigned int sectorsize = 512;
- if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
- sectorsize > bufsize)
- bufsize = sectorsize;
- }
-#endif
-#ifdef CONFIG_COCOA
- u_int32_t blockSize = 512;
- if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
- bufsize = blockSize;
- }
-#endif
-*/
-
-static int raw_pread(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- ret = fd_open(bs);
- if (ret < 0)
- return ret;
-
- if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
- ++(s->lseek_err_cnt);
- if(s->lseek_err_cnt <= 10) {
- DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] lseek failed : %d = %s\n",
- s->fd,
- bs->filename,
- offset,
- buf,
- count,
- bs->total_sectors, errno, strerror(errno) );
- }
- return -1;
- }
- s->lseek_err_cnt=0;
-
- uint64_t done;
- for (done = 0; done < count; done += ret) {
- ret = read(s->fd, buf + done, count - done);
- if (ret == -1)
- goto label__raw_read__error;
- }
- ret = count;
- goto label__raw_read__success;
-
-label__raw_read__error:
- DEBUG_BLOCK_PRINT("raw_read(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] read failed %d : %d = %s\n",
- s->fd,
- bs->filename,
- offset,
- buf,
- count,
- bs->total_sectors,
- ret, errno, strerror(errno) );
-
- if (bs->type == BDRV_TYPE_CDROM) { // Try harder for CDrom
- lseek(s->fd, offset, SEEK_SET);
- ret = read(s->fd, buf, count);
- if (ret == count)
- goto label__raw_read__success;
- lseek(s->fd, offset, SEEK_SET);
- ret = read(s->fd, buf, count);
- if (ret == count)
- goto label__raw_read__success;
-
- DEBUG_BLOCK_PRINT("raw_read(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] retry read failed %d : %d = %s\n",
- s->fd,
- bs->filename,
- offset,
- buf,
- count,
- bs->total_sectors,
- ret, errno, strerror(errno) );
- }
-
- return -1;
-
-label__raw_read__success:
-
- return ret;
-}
-
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- ret = fd_open(bs);
- if (ret < 0)
- return ret;
-
- if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
- ++(s->lseek_err_cnt);
- if(s->lseek_err_cnt) {
- DEBUG_BLOCK_PRINT("raw_write(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] lseek failed : %d = %s\n",
- s->fd,
- bs->filename,
- offset,
- buf,
- count,
- bs->total_sectors, errno, strerror(errno) );
- }
- return -1;
- }
- s->lseek_err_cnt = 0;
-
- uint64_t done;
- for (done = 0; done < count; done += ret) {
- ret = write(s->fd, buf + done, count - done);
- if (ret == -1)
- goto label__raw_write__error;
- }
- ret = count;
- goto label__raw_write__success;
-
-label__raw_write__error:
-
- DEBUG_BLOCK_PRINT("raw_write(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] write failed %d : %d = %s\n",
- s->fd,
- bs->filename,
- offset,
- buf,
- count,
- bs->total_sectors,
- ret, errno, strerror(errno) );
-
- return -1;
-
-label__raw_write__success:
-
- return ret;
-}
-
-/***********************************************************/
-/* Unix AIO using POSIX AIO */
-
-#ifndef NO_AIO
-typedef struct RawAIOCB {
- BlockDriverAIOCB common;
- struct aiocb aiocb;
- struct RawAIOCB *next;
-} RawAIOCB;
-
-const int aio_sig_num = SIGUSR2;
-static RawAIOCB *first_aio; /* AIO issued */
-static int aio_initialized = 0;
-
-static void aio_signal_handler(int signum)
-{
-#ifndef QEMU_TOOL
- CPUState *env = cpu_single_env;
- if (env) {
- /* stop the currently executing cpu because a timer occured */
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_cpu_interrupt(env);
- }
-#endif
- }
-#endif
-}
-
-void qemu_aio_init(void)
-{
- struct sigaction act;
- sigset_t set;
-
- aio_initialized = 1;
-
- /* Ensure aio_sig_num is not blocked */
- sigemptyset(&set);
- sigaddset(&set, aio_sig_num);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
-
- sigfillset(&act.sa_mask);
- act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
- act.sa_handler = aio_signal_handler;
- sigaction(aio_sig_num, &act, NULL);
-
-#if defined(__GLIBC__) && defined(__linux__)
- {
- /* XXX: aio thread exit seems to hang on RedHat 9 and this init
- seems to fix the problem. */
- struct aioinit ai;
- memset(&ai, 0, sizeof(ai));
- ai.aio_threads = 1;
- ai.aio_num = 1;
- ai.aio_idle_time = 365 * 100000;
- aio_init(&ai);
- }
-#endif
-}
-
-void qemu_aio_poll(void)
-{
- RawAIOCB *acb, **pacb;
- int ret;
-
- for(;;) {
- pacb = &first_aio;
- for(;;) {
- acb = *pacb;
- if (!acb)
- goto the_end;
- ret = aio_error(&acb->aiocb);
- if (ret == ECANCELED) {
- /* remove the request */
- *pacb = acb->next;
- qemu_aio_release(acb);
- } else if (ret != EINPROGRESS) {
- /* end of aio */
- if (ret == 0) {
- ret = aio_return(&acb->aiocb);
- if (ret == acb->aiocb.aio_nbytes)
- ret = 0;
- else
- ret = -EINVAL;
- } else {
- ret = -ret;
- }
- /* remove the request */
- *pacb = acb->next;
- /* call the callback */
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- break;
- } else {
- pacb = &acb->next;
- }
- }
- }
- the_end: ;
-}
-
-/* Wait for all IO requests to complete. */
-void qemu_aio_flush(void)
-{
- qemu_aio_wait_start();
- qemu_aio_poll();
- while (first_aio) {
- qemu_aio_wait();
- }
- qemu_aio_wait_end();
-}
-
-/* wait until at least one AIO was handled */
-static sigset_t wait_oset;
-
-void qemu_aio_wait_start(void)
-{
- sigset_t set;
-
- if (!aio_initialized)
- qemu_aio_init();
- sigemptyset(&set);
- sigaddset(&set, aio_sig_num);
- sigprocmask(SIG_BLOCK, &set, &wait_oset);
-}
-
-void qemu_aio_wait(void)
-{
- sigset_t set;
- int nb_sigs;
-
-#ifndef QEMU_TOOL
- if (qemu_bh_poll())
- return;
-#endif
- sigemptyset(&set);
- sigaddset(&set, aio_sig_num);
- sigwait(&set, &nb_sigs);
- qemu_aio_poll();
-}
-
-void qemu_aio_wait_end(void)
-{
- sigprocmask(SIG_SETMASK, &wait_oset, NULL);
-}
-
-static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVRawState *s = bs->opaque;
- RawAIOCB *acb;
-
- if (fd_open(bs) < 0)
- return NULL;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->aiocb.aio_fildes = s->fd;
- acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
- acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- acb->aiocb.aio_buf = buf;
- acb->aiocb.aio_nbytes = nb_sectors * 512;
- acb->aiocb.aio_offset = sector_num * 512;
- acb->next = first_aio;
- first_aio = acb;
- return acb;
-}
-
-static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- RawAIOCB *acb;
-
- acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- if (aio_read(&acb->aiocb) < 0) {
- qemu_aio_release(acb);
- return NULL;
- }
- return &acb->common;
-}
-
-static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- RawAIOCB *acb;
-
- acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- if (aio_write(&acb->aiocb) < 0) {
- qemu_aio_release(acb);
- return NULL;
- }
- return &acb->common;
-}
-
-static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- int ret;
- RawAIOCB *acb = (RawAIOCB *)blockacb;
- RawAIOCB **pacb;
-
- ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
- if (ret == AIO_NOTCANCELED) {
- /* fail safe: if the aio could not be canceled, we wait for
- it */
- while (aio_error(&acb->aiocb) == EINPROGRESS);
- }
-
- /* remove the callback from the queue */
- pacb = &first_aio;
- for(;;) {
- if (*pacb == NULL) {
- break;
- } else if (*pacb == acb) {
- *pacb = acb->next;
- qemu_aio_release(acb);
- break;
- }
- pacb = &acb->next;
- }
-}
-
-static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- RawAIOCB *acb;
-
- acb = raw_aio_setup(bs, 0, NULL, 0, cb, opaque);
- if (!acb)
- return NULL;
- if (aio_fsync(O_SYNC, &acb->aiocb) < 0) {
- qemu_aio_release(acb);
- return NULL;
- }
- return &acb->common;
-}
-#endif
-
-static void raw_close(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- bs->total_sectors = 0;
- if (s->fd >= 0) {
- close(s->fd);
- s->fd = -1;
- }
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
- BDRVRawState *s = bs->opaque;
- if (s->type != FTYPE_FILE)
- return -ENOTSUP;
- if (ftruncate(s->fd, offset) < 0)
- return -errno;
- return 0;
-}
-
-#ifdef __OpenBSD__
-static int64_t raw_getlength(BlockDriverState *bs)
-{
- int fd = ((BDRVRawState*)bs->opaque)->fd;
- struct stat st;
- if(fstat(fd, &st))
- return -1;
- if(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)){
- struct disklabel dl;
- if(ioctl(fd, DIOCGDINFO, &dl))
- return -1;
- return (uint64_t)dl.d_secsize *
- dl.d_partitions[DISKPART(st.st_rdev)].p_size;
- }else
- return st.st_size;
-}
-#else /* !__OpenBSD__ */
-static int64_t raw_getlength(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int fd = s->fd;
- int64_t size;
-#ifdef _BSD
- struct stat sb;
-#endif
-#ifdef __sun__
- struct dk_minfo minfo;
- int rv;
-#endif
- int ret;
-
- ret = fd_open(bs);
- if (ret < 0)
- return ret;
-
-#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);
- }
- return size;
-}
-#endif
-
-static int raw_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd;
-
- if (flags || backing_file)
- return -ENOTSUP;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- 0644);
- if (fd < 0)
- return -EIO;
- ftruncate(fd, total_size * 512);
- close(fd);
- return 0;
-}
-
-static int raw_flush(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- if (fsync(s->fd))
- return errno;
- return 0;
-}
-
-BlockDriver bdrv_raw = {
- "raw",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- raw_open,
- NULL,
- NULL,
- raw_close,
- raw_create,
- raw_flush,
-
-#ifndef NO_AIO
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .bdrv_aio_flush = raw_aio_flush,
- .aiocb_size = sizeof(RawAIOCB),
-#endif
- .protocol_name = "file",
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_truncate = raw_truncate,
- .bdrv_getlength = raw_getlength,
-};
-
-/***********************************************/
-/* host device */
-
-#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
-
-static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int fd, open_flags, ret;
-
-#ifdef CONFIG_COCOA
- if (strstart(filename, "/dev/cdrom", NULL)) {
- 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
- open_flags = O_BINARY;
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- open_flags |= O_RDWR;
- } else {
- open_flags |= O_RDONLY;
- bs->read_only = 1;
- }
-
- s->type = FTYPE_FILE;
-#if defined(__linux__)
- if (strstart(filename, "/dev/cd", NULL)) {
- /* open will not fail even if no CD is inserted */
- open_flags |= O_NONBLOCK;
- s->type = FTYPE_CD;
- } else if (strstart(filename, "/dev/fd", NULL)) {
- s->type = FTYPE_FD;
- s->fd_open_flags = open_flags;
- /* open will not fail even if no floppy is inserted */
- open_flags |= O_NONBLOCK;
- }
-#endif
- fd = open(filename, open_flags, 0644);
- if (fd < 0) {
- ret = -errno;
- if (ret == -EROFS)
- ret = -EACCES;
- return ret;
- }
- s->fd = fd;
-#if defined(__linux__)
- /* close fd so that we can reopen it as needed */
- if (s->type == FTYPE_FD) {
- close(s->fd);
- s->fd = -1;
- s->fd_media_changed = 1;
- }
-#endif
- return 0;
-}
-
-#if defined(__linux__) && !defined(QEMU_TOOL)
-
-/* Note: we do not have a reliable method to detect if the floppy is
- present. The current method is to try to open the floppy at every
- I/O and to keep it opened during a few hundreds of ms. */
-static int fd_open(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int last_media_present;
-
- if (s->type != FTYPE_FD)
- return 0;
- last_media_present = (s->fd >= 0);
- if (s->fd >= 0 &&
- (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
- close(s->fd);
- s->fd = -1;
-#ifdef DEBUG_FLOPPY
- printf("Floppy closed\n");
-#endif
- }
- if (s->fd < 0) {
- if (s->fd_got_error &&
- (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
-#ifdef DEBUG_FLOPPY
- printf("No floppy (open delayed)\n");
-#endif
- return -EIO;
- }
- s->fd = open(bs->filename, s->fd_open_flags);
- if (s->fd < 0) {
- s->fd_error_time = qemu_get_clock(rt_clock);
- s->fd_got_error = 1;
- if (last_media_present)
- s->fd_media_changed = 1;
-#ifdef DEBUG_FLOPPY
- printf("No floppy\n");
-#endif
- return -EIO;
- }
-#ifdef DEBUG_FLOPPY
- printf("Floppy opened\n");
-#endif
- }
- if (!last_media_present)
- s->fd_media_changed = 1;
- s->fd_open_time = qemu_get_clock(rt_clock);
- s->fd_got_error = 0;
- return 0;
-}
-#else
-static int fd_open(BlockDriverState *bs)
-{
- return 0;
-}
-#endif
-
-#if defined(__linux__)
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- switch(s->type) {
- case FTYPE_CD:
- ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
- if (ret == CDS_DISC_OK)
- return 1;
- else
- return 0;
- break;
- case FTYPE_FD:
- ret = fd_open(bs);
- return (ret >= 0);
- default:
- return 1;
- }
-}
-
-/* currently only used by fdc.c, but a CD version would be good too */
-static int raw_media_changed(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
-
- switch(s->type) {
- case FTYPE_FD:
- {
- int ret;
- /* XXX: we do not have a true media changed indication. It
- does not work if the floppy is changed without trying
- to read it */
- fd_open(bs);
- ret = s->fd_media_changed;
- s->fd_media_changed = 0;
-#ifdef DEBUG_FLOPPY
- printf("Floppy changed=%d\n", ret);
-#endif
- return ret;
- }
- default:
- return -ENOTSUP;
- }
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
- BDRVRawState *s = bs->opaque;
-
- switch(s->type) {
- case FTYPE_CD:
- if (eject_flag) {
- if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
- perror("CDROMEJECT");
- } else {
- if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
- perror("CDROMEJECT");
- }
- break;
- case FTYPE_FD:
- {
- int fd;
- if (s->fd >= 0) {
- close(s->fd);
- s->fd = -1;
- }
- fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
- if (fd >= 0) {
- if (ioctl(fd, FDEJECT, 0) < 0)
- perror("FDEJECT");
- close(fd);
- }
- }
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
- BDRVRawState *s = bs->opaque;
-
- switch(s->type) {
- case FTYPE_CD:
- if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
- /* Note: an error can happen if the distribution automatically
- mounts the CD-ROM */
- // perror("CDROM_LOCKDOOR");
- }
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-#else
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
- return 1;
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
- return -ENOTSUP;
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
- return -ENOTSUP;
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
- return -ENOTSUP;
-}
-
-#endif /* !linux */
-
-BlockDriver bdrv_host_device = {
- "host_device",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- hdev_open,
- NULL,
- NULL,
- raw_close,
- NULL,
- raw_flush,
-
-#ifndef NO_AIO
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .bdrv_aio_flush = raw_aio_flush,
- .aiocb_size = sizeof(RawAIOCB),
-#endif
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_getlength = raw_getlength,
-
- /* removable device support */
- .bdrv_is_inserted = raw_is_inserted,
- .bdrv_media_changed = raw_media_changed,
- .bdrv_eject = raw_eject,
- .bdrv_set_locked = raw_set_locked,
-};
-
-#else /* _WIN32 */
-
-/* XXX: use another file ? */
-#include <winioctl.h>
-
-#define FTYPE_FILE 0
-#define FTYPE_CD 1
-#define FTYPE_HARDDISK 2
-
-typedef struct BDRVRawState {
- HANDLE hfile;
- int type;
- char drive_path[16]; /* format: "d:\" */
-} BDRVRawState;
-
-typedef struct RawAIOCB {
- BlockDriverAIOCB common;
- HANDLE hEvent;
- OVERLAPPED ov;
- int count;
-} RawAIOCB;
-
-int qemu_ftruncate64(int fd, int64_t length)
-{
- LARGE_INTEGER li;
- LONG high;
- HANDLE h;
- BOOL res;
-
- if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
- return -1;
-
- h = (HANDLE)_get_osfhandle(fd);
-
- /* get current position, ftruncate do not change position */
- li.HighPart = 0;
- li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
- if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
- return -1;
-
- high = length >> 32;
- if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
- return -1;
- res = SetEndOfFile(h);
-
- /* back to old position */
- SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
- return res ? 0 : -1;
-}
-
-static int set_sparse(int fd)
-{
- DWORD returned;
- return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
- NULL, 0, NULL, 0, &returned, NULL);
-}
-
-static int raw_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int access_flags, create_flags;
- DWORD overlapped;
-
- s->type = FTYPE_FILE;
-
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- access_flags = GENERIC_READ | GENERIC_WRITE;
- } else {
- access_flags = GENERIC_READ;
- }
- if (flags & BDRV_O_CREAT) {
- create_flags = CREATE_ALWAYS;
- } else {
- create_flags = OPEN_EXISTING;
- }
-#ifdef QEMU_TOOL
- overlapped = FILE_ATTRIBUTE_NORMAL;
-#else
- overlapped = FILE_FLAG_OVERLAPPED;
-#endif
- s->hfile = CreateFile(filename, access_flags,
- FILE_SHARE_READ, NULL,
- create_flags, overlapped, NULL);
- if (s->hfile == INVALID_HANDLE_VALUE) {
- int err = GetLastError();
-
- if (err == ERROR_ACCESS_DENIED)
- return -EACCES;
- return -1;
- }
- return 0;
-}
-
-static int raw_pread(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- OVERLAPPED ov;
- DWORD ret_count;
- int ret;
-
- memset(&ov, 0, sizeof(ov));
- ov.Offset = offset;
- ov.OffsetHigh = offset >> 32;
- ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
- if (!ret) {
- ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
- if (!ret)
- return -EIO;
- else
- return ret_count;
- }
- return ret_count;
-}
-
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- OVERLAPPED ov;
- DWORD ret_count;
- int ret;
-
- memset(&ov, 0, sizeof(ov));
- ov.Offset = offset;
- ov.OffsetHigh = offset >> 32;
- ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
- if (!ret) {
- ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
- if (!ret)
- return -EIO;
- else
- return ret_count;
- }
- return ret_count;
-}
-
-#if 0
-#ifndef QEMU_TOOL
-static void raw_aio_cb(void *opaque)
-{
- RawAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVRawState *s = bs->opaque;
- DWORD ret_count;
- int ret;
-
- ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
- if (!ret || ret_count != acb->count) {
- acb->common.cb(acb->common.opaque, -EIO);
- } else {
- acb->common.cb(acb->common.opaque, 0);
- }
-}
-#endif
-
-static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- RawAIOCB *acb;
- int64_t offset;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (acb->hEvent) {
- acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!acb->hEvent) {
- qemu_aio_release(acb);
- return NULL;
- }
- }
- memset(&acb->ov, 0, sizeof(acb->ov));
- offset = sector_num * 512;
- acb->ov.Offset = offset;
- acb->ov.OffsetHigh = offset >> 32;
- acb->ov.hEvent = acb->hEvent;
- acb->count = nb_sectors * 512;
-#ifndef QEMU_TOOL
- qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
-#endif
- return acb;
-}
-
-static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVRawState *s = bs->opaque;
- RawAIOCB *acb;
- int ret;
-
- acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
- if (!ret) {
- qemu_aio_release(acb);
- return NULL;
- }
-#ifdef QEMU_TOOL
- qemu_aio_release(acb);
-#endif
- return (BlockDriverAIOCB *)acb;
-}
-
-static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVRawState *s = bs->opaque;
- RawAIOCB *acb;
- int ret;
-
- acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
- if (!ret) {
- qemu_aio_release(acb);
- return NULL;
- }
-#ifdef QEMU_TOOL
- qemu_aio_release(acb);
-#endif
- return (BlockDriverAIOCB *)acb;
-}
-
-static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-#ifndef QEMU_TOOL
- RawAIOCB *acb = (RawAIOCB *)blockacb;
- BlockDriverState *bs = acb->common.bs;
- BDRVRawState *s = bs->opaque;
-
- qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
- /* XXX: if more than one async I/O it is not correct */
- CancelIo(s->hfile);
- qemu_aio_release(acb);
-#endif
-}
-#endif /* #if 0 */
-
-static void raw_flush(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- FlushFileBuffers(s->hfile);
-}
-
-static void raw_close(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- CloseHandle(s->hfile);
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
- BDRVRawState *s = bs->opaque;
- DWORD low, high;
-
- low = offset;
- high = offset >> 32;
- if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
- return -EIO;
- if (!SetEndOfFile(s->hfile))
- return -EIO;
- return 0;
-}
-
-static int64_t raw_getlength(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- LARGE_INTEGER l;
- ULARGE_INTEGER available, total, total_free;
- DISK_GEOMETRY dg;
- DWORD count;
- BOOL status;
-
- switch(s->type) {
- case FTYPE_FILE:
- l.LowPart = GetFileSize(s->hfile, &l.HighPart);
- if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
- return -EIO;
- break;
- case FTYPE_CD:
- if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
- return -EIO;
- l.QuadPart = total.QuadPart;
- break;
- case FTYPE_HARDDISK:
- status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL, 0, &dg, sizeof(dg), &count, NULL);
- if (status != FALSE) {
- l.QuadPart = dg.Cylinders.QuadPart * dg.TracksPerCylinder
- * dg.SectorsPerTrack * dg.BytesPerSector;
- }
- break;
- default:
- return -EIO;
- }
- return l.QuadPart;
-}
-
-static int raw_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd;
-
- if (flags || backing_file)
- return -ENOTSUP;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- 0644);
- if (fd < 0)
- return -EIO;
- set_sparse(fd);
- ftruncate(fd, total_size * 512);
- close(fd);
- return 0;
-}
-
-void qemu_aio_init(void)
-{
-}
-
-void qemu_aio_poll(void)
-{
-}
-
-void qemu_aio_flush(void)
-{
-}
-
-void qemu_aio_wait_start(void)
-{
-}
-
-void qemu_aio_wait(void)
-{
-#ifndef QEMU_TOOL
- qemu_bh_poll();
-#endif
-}
-
-void qemu_aio_wait_end(void)
-{
-}
-
-BlockDriver bdrv_raw = {
- "raw",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- raw_open,
- NULL,
- NULL,
- raw_close,
- raw_create,
- raw_flush,
-
-#if 0
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .aiocb_size = sizeof(RawAIOCB);
-#endif
- .protocol_name = "file",
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_truncate = raw_truncate,
- .bdrv_getlength = raw_getlength,
-};
-
-/***********************************************/
-/* host device */
-
-static int find_cdrom(char *cdrom_name, int cdrom_name_size)
-{
- char drives[256], *pdrv = drives;
- UINT type;
-
- memset(drives, 0, sizeof(drives));
- GetLogicalDriveStrings(sizeof(drives), drives);
- while(pdrv[0] != '\0') {
- type = GetDriveType(pdrv);
- switch(type) {
- case DRIVE_CDROM:
- snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
- return 0;
- break;
- }
- pdrv += lstrlen(pdrv) + 1;
- }
- return -1;
-}
-
-static int find_device_type(BlockDriverState *bs, const char *filename)
-{
- BDRVRawState *s = bs->opaque;
- UINT type;
- const char *p;
-
- if (strstart(filename, "\\\\.\\", &p) ||
- strstart(filename, "//./", &p)) {
- if (stristart(p, "PhysicalDrive", NULL))
- return FTYPE_HARDDISK;
- snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
- type = GetDriveType(s->drive_path);
- if (type == DRIVE_CDROM)
- return FTYPE_CD;
- else
- return FTYPE_FILE;
- } else {
- return FTYPE_FILE;
- }
-}
-
-static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int access_flags, create_flags;
- DWORD overlapped;
- char device_name[64];
-
- if (strstart(filename, "/dev/cdrom", NULL)) {
- if (find_cdrom(device_name, sizeof(device_name)) < 0)
- return -ENOENT;
- filename = device_name;
- } else {
- /* transform drive letters into device name */
- if (((filename[0] >= 'a' && filename[0] <= 'z') ||
- (filename[0] >= 'A' && filename[0] <= 'Z')) &&
- filename[1] == ':' && filename[2] == '\0') {
- snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
- filename = device_name;
- }
- }
- s->type = find_device_type(bs, filename);
-
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- access_flags = GENERIC_READ | GENERIC_WRITE;
- } else {
- access_flags = GENERIC_READ;
- }
- create_flags = OPEN_EXISTING;
-
-#ifdef QEMU_TOOL
- overlapped = FILE_ATTRIBUTE_NORMAL;
-#else
- overlapped = FILE_FLAG_OVERLAPPED;
-#endif
- s->hfile = CreateFile(filename, access_flags,
- FILE_SHARE_READ, NULL,
- create_flags, overlapped, NULL);
- if (s->hfile == INVALID_HANDLE_VALUE) {
- int err = GetLastError();
-
- if (err == ERROR_ACCESS_DENIED)
- return -EACCES;
- return -1;
- }
- return 0;
-}
-
-#if 0
-/***********************************************/
-/* removable device additionnal commands */
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
- return 1;
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
- return -ENOTSUP;
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
- DWORD ret_count;
-
- if (s->type == FTYPE_FILE)
- return -ENOTSUP;
- if (eject_flag) {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
- NULL, 0, NULL, 0, &lpBytesReturned, NULL);
- } else {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
- NULL, 0, NULL, 0, &lpBytesReturned, NULL);
- }
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
- return -ENOTSUP;
-}
-#endif
-
-BlockDriver bdrv_host_device = {
- "host_device",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- hdev_open,
- NULL,
- NULL,
- raw_close,
- NULL,
- raw_flush,
-
-#if 0
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .aiocb_size = sizeof(RawAIOCB);
-#endif
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_getlength = raw_getlength,
-};
-#endif /* _WIN32 */
diff --git a/tools/ioemu/block-vbd.c b/tools/ioemu/block-vbd.c
deleted file mode 100644
index 10f7a21f53..0000000000
--- a/tools/ioemu/block-vbd.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Block driver for Mini-os PV devices
- * Based on block-raw.c
- *
- * Copyright (c) 2006 Fabrice Bellard, 2007 Samuel Thibault
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include <assert.h>
-#include <xenbus.h>
-#include <blkfront.h>
-#include <malloc.h>
-
-#define SECTOR_SIZE 512
-
-#ifndef QEMU_TOOL
-#include "exec-all.h"
-#endif
-
-#define DEBUG_BLOCK
-#ifdef DEBUG_BLOCK
-#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile )
-#else
-#define DEBUG_BLOCK_PRINT( formatCstr, args... )
-#endif
-
-#define FTYPE_FILE 0
-#define FTYPE_CD 1
-#define FTYPE_FD 2
-
-typedef struct BDRVVbdState {
- struct blkfront_dev *dev;
- int fd;
- struct blkfront_info info;
- LIST_ENTRY(BDRVVbdState) list;
-} BDRVVbdState;
-
-LIST_HEAD(, BDRVVbdState) vbds;
-
-static int vbd_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- char *value;
- if (xenbus_read(XBT_NIL, filename, &value))
- return 0;
- free(value);
- return 100;
-}
-
-static void vbd_io_completed(void *opaque)
-{
- BDRVVbdState *s = opaque;
- blkfront_aio_poll(s->dev);
-}
-
-static int vbd_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVVbdState *s = bs->opaque;
-
- //handy to test posix access
- //return -EIO;
-
- s->dev = init_blkfront((char *) filename, &s->info);
-
- if (!s->dev)
- return -EIO;
-
- if (SECTOR_SIZE % s->info.sector_size) {
- printf("sector size is %d, we only support sector sizes that divide %d\n", s->info.sector_size, SECTOR_SIZE);
- return -EIO;
- }
-
- s->fd = blkfront_open(s->dev);
- qemu_set_fd_handler(s->fd, vbd_io_completed, NULL, s);
-
- LIST_INSERT_HEAD(&vbds, s, list);
-
- return 0;
-}
-
-typedef struct VbdAIOCB {
- BlockDriverAIOCB common;
- struct blkfront_aiocb aiocb;
-} VbdAIOCB;
-
-void qemu_aio_init(void)
-{
-}
-
-void qemu_aio_poll(void)
-{
-}
-
-/* Wait for all IO requests to complete. */
-void qemu_aio_flush(void)
-{
- BDRVVbdState *s;
- for (s = vbds.lh_first; s; s = s->list.le_next)
- blkfront_sync(s->dev);
-}
-
-void qemu_aio_wait_start(void)
-{
-}
-
-void qemu_aio_wait(void)
-{
- int some = 0;
- DEFINE_WAIT(w);
- while (1) {
- BDRVVbdState *s;
- add_waiter(w, blkfront_queue);
- for (s = vbds.lh_first; s; s = s->list.le_next)
- if (blkfront_aio_poll(s->dev))
- some = 1;
- if (some)
- break;
- schedule();
- }
- remove_waiter(w);
-}
-
-void qemu_aio_wait_end(void)
-{
-}
-
-static void vbd_aio_callback(struct blkfront_aiocb *aiocbp, int ret) {
- VbdAIOCB *acb = aiocbp->data;
-
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
-}
-
-static VbdAIOCB *vbd_aio_setup(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVVbdState *s = bs->opaque;
- VbdAIOCB *acb;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->aiocb.aio_dev = s->dev;
- acb->aiocb.aio_buf = buf;
- acb->aiocb.aio_nbytes = nb_sectors * SECTOR_SIZE;
- acb->aiocb.aio_offset = sector_num * SECTOR_SIZE;
- acb->aiocb.aio_cb = vbd_aio_callback;
- acb->aiocb.data = acb;
-
- return acb;
-}
-
-static BlockDriverAIOCB *vbd_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- VbdAIOCB *acb;
-
- acb = vbd_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- blkfront_aio(&acb->aiocb, 0);
- return &acb->common;
-}
-
-static BlockDriverAIOCB *vbd_aio_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- VbdAIOCB *acb;
-
- acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- blkfront_aio(&acb->aiocb, 1);
- return &acb->common;
-}
-
-static void vbd_cb(void *data, int ret) {
- int *result = data;
- result[0] = 1;
- result[1] = ret;
-}
-
-static int vbd_aligned_io(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors, int write)
-{
- VbdAIOCB *acb;
- int result[2];
- result[0] = 0;
- qemu_aio_wait_start();
- acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, vbd_cb, &result);
- blkfront_aio(&acb->aiocb, write);
- while (!result[0])
- qemu_aio_wait();
- qemu_aio_wait_end();
- return result[1];
-}
-
-static int vbd_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors)
-{
- uint8_t *iobuf;
- int ret;
- /* page alignment would be a bit better, but that's still fine compared to
- * copying */
- if (!((uintptr_t)buf & (SECTOR_SIZE-1)))
- return vbd_aligned_io(bs, sector_num, buf, nb_sectors, 0);
- iobuf = qemu_memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE);
- ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 0);
- memcpy(buf, iobuf, nb_sectors * SECTOR_SIZE);
- free(iobuf);
- if (ret < 0)
- return ret;
- else if (ret != nb_sectors * SECTOR_SIZE)
- return -EINVAL;
- else
- return 0;
-}
-
-static int vbd_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors)
-{
- uint8_t *iobuf;
- int ret;
- if (!((uintptr_t)buf & (SECTOR_SIZE-1)))
- return vbd_aligned_io(bs, sector_num, (uint8_t*) buf, nb_sectors, 1);
- iobuf = qemu_memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE);
- memcpy(iobuf, buf, nb_sectors * SECTOR_SIZE);
- ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 1);
- free(iobuf);
- if (ret < 0)
- return ret;
- else if (ret != nb_sectors * SECTOR_SIZE)
- return -EINVAL;
- else
- return 0;
-}
-
-static void vbd_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- /* TODO */
- //VbdAIOCB *acb = (VbdAIOCB *)blockacb;
-
- // Try to cancel. If can't, wait for it, drop the callback and call qemu_aio_release(acb)
-}
-
-static void vbd_nop_cb(void *opaque, int ret)
-{
-}
-
-static BlockDriverAIOCB *vbd_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVVbdState *s = bs->opaque;
- VbdAIOCB *acb = NULL;
-
- if (s->info.mode == O_RDONLY) {
- cb(opaque, 0);
- return NULL;
- }
- if (s->info.barrier == 1) {
- acb = vbd_aio_setup(bs, 0, NULL, 0,
- s->info.flush == 1 ? vbd_nop_cb : cb, opaque);
- if (!acb)
- return NULL;
- blkfront_aio_push_operation(&acb->aiocb, BLKIF_OP_WRITE_BARRIER);
- }
- if (s->info.flush == 1) {
- acb = vbd_aio_setup(bs, 0, NULL, 0, cb, opaque);
- if (!acb)
- return NULL;
- blkfront_aio_push_operation(&acb->aiocb, BLKIF_OP_FLUSH_DISKCACHE);
- }
- return &acb->common;
-}
-
-static void vbd_close(BlockDriverState *bs)
-{
- BDRVVbdState *s = bs->opaque;
- bs->total_sectors = 0;
- if (s->fd >= 0) {
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
- close(s->fd);
- s->fd = -1;
- }
- LIST_REMOVE(s, list);
-}
-
-static int64_t vbd_getlength(BlockDriverState *bs)
-{
- BDRVVbdState *s = bs->opaque;
- return s->info.sectors * s->info.sector_size;
-}
-
-static int vbd_flush(BlockDriverState *bs)
-{
- BDRVVbdState *s = bs->opaque;
- blkfront_sync(s->dev);
- return 0;
-}
-
-/***********************************************/
-/* host device */
-
-static int vbd_is_inserted(BlockDriverState *bs)
-{
- /* TODO: monitor the backend */
- return 1;
-}
-
-/* currently only used by fdc.c, but a CD version would be good too */
-static int vbd_media_changed(BlockDriverState *bs)
-{
- /* TODO: monitor the backend */
- return -ENOTSUP;
-}
-
-static int vbd_eject(BlockDriverState *bs, int eject_flag)
-{
- /* TODO: Xen support needed */
- return -ENOTSUP;
-}
-
-static int vbd_set_locked(BlockDriverState *bs, int locked)
-{
- /* TODO: Xen support needed */
- return -ENOTSUP;
-}
-
-BlockDriver bdrv_vbd = {
- "vbd",
- sizeof(BDRVVbdState),
- vbd_probe,
- vbd_open,
- NULL,
- NULL,
- vbd_close,
- NULL,
- vbd_flush,
-
- .bdrv_aio_read = vbd_aio_read,
- .bdrv_aio_write = vbd_aio_write,
- .bdrv_aio_cancel = vbd_aio_cancel,
- .bdrv_aio_flush = vbd_aio_flush,
- .aiocb_size = sizeof(VbdAIOCB),
- .bdrv_read = vbd_read,
- .bdrv_write = vbd_write,
- .bdrv_getlength = vbd_getlength,
-
- /* removable device support */
- .bdrv_is_inserted = vbd_is_inserted,
- .bdrv_media_changed = vbd_media_changed,
- .bdrv_eject = vbd_eject,
- .bdrv_set_locked = vbd_set_locked,
-};
-
diff --git a/tools/ioemu/block-vmdk.c b/tools/ioemu/block-vmdk.c
deleted file mode 100644
index a8b8a35153..0000000000
--- a/tools/ioemu/block-vmdk.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * 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
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-#include "block_int.h"
-
-#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
-#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
-
-typedef struct {
- uint32_t version;
- uint32_t flags;
- uint32_t disk_sectors;
- uint32_t granularity;
- uint32_t l1dir_offset;
- uint32_t l1dir_size;
- uint32_t file_sectors;
- uint32_t cylinders;
- uint32_t heads;
- uint32_t sectors_per_track;
-} VMDK3Header;
-
-typedef struct {
- uint32_t version;
- uint32_t flags;
- int64_t capacity;
- int64_t granularity;
- int64_t desc_offset;
- int64_t desc_size;
- int32_t num_gtes_per_gte;
- int64_t rgd_offset;
- int64_t gd_offset;
- int64_t grain_offset;
- char filler[1];
- char check_bytes[4];
-} __attribute__((packed)) VMDK4Header;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVVmdkState {
- BlockDriverState *hd;
- 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;
-
- unsigned int l2_size;
- uint32_t *l2_cache;
- uint32_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
-
- unsigned int cluster_sectors;
- uint32_t parent_cid;
-} BDRVVmdkState;
-
-static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- uint32_t magic;
-
- if (buf_size < 4)
- return 0;
- magic = be32_to_cpu(*(uint32_t *)buf);
- if (magic == VMDK3_MAGIC ||
- magic == VMDK4_MAGIC)
- return 100;
- else
- return 0;
-}
-
-#define CHECK_CID 1
-
-#define SECTOR_SIZE 512
-#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each
-#define HEADER_SIZE 512 // first sector of 512 bytes
-
-static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
-{
- BDRVVmdkState *s = bs->opaque;
- char desc[DESC_SIZE];
- uint32_t cid;
- char *p_name, *cid_str;
- size_t cid_str_size;
-
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return 0;
-
- if (parent) {
- cid_str = "parentCID";
- cid_str_size = sizeof("parentCID");
- } else {
- cid_str = "CID";
- cid_str_size = sizeof("CID");
- }
-
- if ((p_name = strstr(desc,cid_str)) != 0) {
- p_name += cid_str_size;
- sscanf(p_name,"%x",&cid);
- }
-
- return cid;
-}
-
-static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
-{
- BDRVVmdkState *s = bs->opaque;
- char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
- char *p_name, *tmp_str;
-
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return -1;
-
- tmp_str = strstr(desc,"parentCID");
- strcpy(tmp_desc, tmp_str);
- if ((p_name = strstr(desc,"CID")) != 0) {
- p_name += sizeof("CID");
- sprintf(p_name,"%x\n",cid);
- strcat(desc,tmp_desc);
- }
-
- if (bdrv_pwrite(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return -1;
- return 0;
-}
-
-static int vmdk_is_cid_valid(BlockDriverState *bs)
-{
-#ifdef CHECK_CID
- BDRVVmdkState *s = bs->opaque;
- BlockDriverState *p_bs = s->hd->backing_hd;
- uint32_t cur_pcid;
-
- if (p_bs) {
- cur_pcid = vmdk_read_cid(p_bs,0);
- if (s->parent_cid != cur_pcid)
- // CID not valid
- return 0;
- }
-#endif
- // CID valid
- return 1;
-}
-
-static int vmdk_snapshot_create(const char *filename, const char *backing_file)
-{
- int snp_fd, p_fd;
- uint32_t p_cid;
- char *p_name, *gd_buf, *rgd_buf;
- const char *real_filename, *temp_str;
- VMDK4Header header;
- uint32_t gde_entries, gd_size;
- int64_t gd_offset, rgd_offset, capacity, gt_size;
- char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];
- char *desc_template =
- "# Disk DescriptorFile\n"
- "version=1\n"
- "CID=%x\n"
- "parentCID=%x\n"
- "createType=\"monolithicSparse\"\n"
- "parentFileNameHint=\"%s\"\n"
- "\n"
- "# Extent description\n"
- "RW %lu SPARSE \"%s\"\n"
- "\n"
- "# The Disk Data Base \n"
- "#DDB\n"
- "\n";
-
- snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);
- if (snp_fd < 0)
- return -1;
- p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (p_fd < 0) {
- close(snp_fd);
- return -1;
- }
-
- /* read the header */
- if (lseek(p_fd, 0x0, SEEK_SET) == -1)
- goto fail;
- if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE)
- goto fail;
-
- /* write the header */
- if (lseek(snp_fd, 0x0, SEEK_SET) == -1)
- goto fail;
- if (write(snp_fd, hdr, HEADER_SIZE) == -1)
- goto fail;
-
- memset(&header, 0, sizeof(header));
- memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
-
- ftruncate(snp_fd, header.grain_offset << 9);
- /* the descriptor offset = 0x200 */
- if (lseek(p_fd, 0x200, SEEK_SET) == -1)
- goto fail;
- if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE)
- goto fail;
-
- if ((p_name = strstr(p_desc,"CID")) != 0) {
- p_name += sizeof("CID");
- sscanf(p_name,"%x",&p_cid);
- }
-
- 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(s_desc, desc_template, p_cid, p_cid, backing_file
- , (uint32_t)header.capacity, real_filename);
-
- /* write the descriptor */
- if (lseek(snp_fd, 0x200, SEEK_SET) == -1)
- goto fail;
- if (write(snp_fd, s_desc, strlen(s_desc)) == -1)
- goto fail;
-
- gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table
- rgd_offset = header.rgd_offset * SECTOR_SIZE; // offset of RGD table
- capacity = header.capacity * SECTOR_SIZE; // Extent size
- /*
- * Each GDE span 32M disk, means:
- * 512 GTE per GT, each GTE points to grain
- */
- gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;
- if (!gt_size)
- goto fail;
- gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde
- gd_size = gde_entries * sizeof(uint32_t);
-
- /* write RGD */
- rgd_buf = qemu_malloc(gd_size);
- if (!rgd_buf)
- goto fail;
- if (lseek(p_fd, rgd_offset, SEEK_SET) == -1)
- goto fail_rgd;
- if (read(p_fd, rgd_buf, gd_size) != gd_size)
- goto fail_rgd;
- if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1)
- goto fail_rgd;
- if (write(snp_fd, rgd_buf, gd_size) == -1)
- goto fail_rgd;
- qemu_free(rgd_buf);
-
- /* write GD */
- gd_buf = qemu_malloc(gd_size);
- if (!gd_buf)
- goto fail_rgd;
- if (lseek(p_fd, gd_offset, SEEK_SET) == -1)
- goto fail_gd;
- if (read(p_fd, gd_buf, gd_size) != gd_size)
- goto fail_gd;
- if (lseek(snp_fd, gd_offset, SEEK_SET) == -1)
- goto fail_gd;
- if (write(snp_fd, gd_buf, gd_size) == -1)
- goto fail_gd;
- qemu_free(gd_buf);
-
- close(p_fd);
- close(snp_fd);
- return 0;
-
- fail_gd:
- qemu_free(gd_buf);
- fail_rgd:
- qemu_free(rgd_buf);
- fail:
- close(p_fd);
- close(snp_fd);
- return -1;
-}
-
-static void vmdk_parent_close(BlockDriverState *bs)
-{
- if (bs->backing_hd)
- bdrv_close(bs->backing_hd);
-}
-
-
-static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
-{
- BDRVVmdkState *s = bs->opaque;
- char *p_name;
- char desc[DESC_SIZE];
- char parent_img_name[1024];
-
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return -1;
-
- if ((p_name = strstr(desc,"parentFileNameHint")) != 0) {
- char *end_name;
- struct stat file_buf;
-
- p_name += sizeof("parentFileNameHint") + 1;
- if ((end_name = strchr(p_name,'\"')) == 0)
- return -1;
-
- strncpy(s->hd->backing_file, p_name, end_name - p_name);
- if (stat(s->hd->backing_file, &file_buf) != 0) {
- path_combine(parent_img_name, sizeof(parent_img_name),
- filename, s->hd->backing_file);
- } else {
- strcpy(parent_img_name, s->hd->backing_file);
- }
-
- s->hd->backing_hd = bdrv_new("");
- if (!s->hd->backing_hd) {
- failure:
- bdrv_close(s->hd);
- return -1;
- }
- if (bdrv_open(s->hd->backing_hd, parent_img_name, 0) < 0)
- goto failure;
- }
-
- return 0;
-}
-
-static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVVmdkState *s = bs->opaque;
- uint32_t magic;
- int l1_size, i, ret;
-
- ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
- if (ret < 0)
- return ret;
- if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))
- goto fail;
-
- magic = be32_to_cpu(magic);
- if (magic == VMDK3_MAGIC) {
- VMDK3Header header;
-
- if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))
- goto fail;
- s->cluster_sectors = le32_to_cpu(header.granularity);
- 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) << 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 (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))
- goto fail;
- 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) << 9;
- s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
-
- // try to open parent images, if exist
- if (vmdk_parent_open(bs, filename) != 0)
- goto fail;
- // write the CID once after the image creation
- s->parent_cid = vmdk_read_cid(bs,1);
- } else {
- goto fail;
- }
-
- /* read the L1 table */
- l1_size = s->l1_size * sizeof(uint32_t);
- s->l1_table = qemu_malloc(l1_size);
- if (!s->l1_table)
- goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, l1_size) != l1_size)
- goto fail;
- for(i = 0; i < s->l1_size; i++) {
- 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 (bdrv_pread(s->hd, s->l1_backup_table_offset, 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;
- return 0;
- fail:
- qemu_free(s->l1_backup_table);
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- bdrv_delete(s->hd);
- return -1;
-}
-
-static uint64_t get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate);
-
-static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
- uint64_t offset, int allocate)
-{
- uint64_t parent_cluster_offset;
- BDRVVmdkState *s = bs->opaque;
- uint8_t whole_grain[s->cluster_sectors*512]; // 128 sectors * 512 bytes each = grain size 64KB
-
- // we will be here if it's first write on non-exist grain(cluster).
- // try to read from parent image, if exist
- if (s->hd->backing_hd) {
- BDRVVmdkState *ps = s->hd->backing_hd->opaque;
-
- if (!vmdk_is_cid_valid(bs))
- return -1;
- parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, offset, allocate);
- if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) !=
- ps->cluster_sectors*512)
- return -1;
-
- if (bdrv_pwrite(s->hd, cluster_offset << 9, whole_grain, sizeof(whole_grain)) !=
- sizeof(whole_grain))
- return -1;
- }
- return 0;
-}
-
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- 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, tmp;
- uint64_t cluster_offset;
-
- l1_index = (offset >> 9) / s->l1_entry_sectors;
- if (l1_index >= s->l1_size)
- return 0;
- 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 */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i * s->l2_size);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- l2_table = s->l2_cache + (min_index * s->l2_size);
- if (bdrv_pread(s->hd, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
- s->l2_size * sizeof(uint32_t))
- return 0;
-
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
- cluster_offset = le32_to_cpu(l2_table[l2_index]);
- if (!cluster_offset) {
- struct stat file_buf;
-
- if (!allocate)
- return 0;
- stat(s->hd->filename, &file_buf);
- cluster_offset = file_buf.st_size;
- bdrv_truncate(s->hd, cluster_offset + (s->cluster_sectors << 9));
-
- cluster_offset >>= 9;
- /* update L2 table */
- tmp = cpu_to_le32(cluster_offset);
- l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
- &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];
- if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
- &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- }
-
- if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
- return 0;
- }
- cluster_offset <<= 9;
- return cluster_offset;
-}
-
-static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- 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)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n, ret;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- 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)
- n = nb_sectors;
- if (!cluster_offset) {
- // try to read from parent image, if exist
- if (s->hd->backing_hd) {
- if (!vmdk_is_cid_valid(bs))
- return -1;
- ret = bdrv_read(s->hd->backing_hd, sector_num, buf, n);
- if (ret < 0)
- return -1;
- } else {
- memset(buf, 0, 512 * n);
- }
- } else {
- if(bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
- return -1;
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
- static int cid_update = 0;
-
- 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;
- if (bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
- return -1;
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
-
- // update CID on the first write every time the virtual disk is opened
- if (!cid_update) {
- vmdk_write_cid(bs, time(NULL));
- cid_update++;
- }
- }
- 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 = \"4\"\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 */
- if (backing_file) {
- return vmdk_snapshot_create(filename, 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)
-{
- BDRVVmdkState *s = bs->opaque;
-
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- bdrv_delete(s->hd);
- // try to close parent image, if exist
- vmdk_parent_close(s->hd);
-}
-
-static int vmdk_flush(BlockDriverState *bs)
-{
- BDRVVmdkState *s = bs->opaque;
- return bdrv_flush(s->hd);
-}
-
-BlockDriver bdrv_vmdk = {
- "vmdk",
- sizeof(BDRVVmdkState),
- vmdk_probe,
- vmdk_open,
- vmdk_read,
- vmdk_write,
- vmdk_close,
- vmdk_create,
- vmdk_flush,
- vmdk_is_allocated,
-};
diff --git a/tools/ioemu/block-vpc.c b/tools/ioemu/block-vpc.c
deleted file mode 100644
index 4d228c5b62..0000000000
--- a/tools/ioemu/block-vpc.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Block driver for Conectix/Microsoft Virtual PC images
- *
- * Copyright (c) 2005 Alex Beregszaszi
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-
-/**************************************************************/
-
-#define HEADER_SIZE 512
-
-//#define CACHE
-
-// always big-endian
-struct vpc_subheader {
- char magic[8]; // "conectix" / "cxsparse"
- union {
- struct {
- uint32_t unk1[2];
- uint32_t unk2; // always zero?
- uint32_t subheader_offset;
- uint32_t unk3; // some size?
- char creator[4]; // "vpc "
- uint16_t major;
- uint16_t minor;
- char guest[4]; // "Wi2k"
- uint32_t unk4[7];
- uint8_t vnet_id[16]; // virtual network id, purpose unknown
- // next 16 longs are used, but dunno the purpose
- // next 6 longs unknown, following 7 long maybe a serial
- char padding[HEADER_SIZE - 84];
- } main;
- struct {
- uint32_t unk1[2]; // all bits set
- uint32_t unk2; // always zero?
- uint32_t pagetable_offset;
- uint32_t unk3;
- uint32_t pagetable_entries; // 32bit/entry
- uint32_t pageentry_size; // 512*8*512
- uint32_t nb_sectors;
- char padding[HEADER_SIZE - 40];
- } sparse;
- char padding[HEADER_SIZE - 8];
- } type;
-};
-
-typedef struct BDRVVPCState {
- int fd;
-
- int pagetable_entries;
- uint32_t *pagetable;
-
- uint32_t pageentry_size;
-#ifdef CACHE
- uint8_t *pageentry_u8;
- uint32_t *pageentry_u32;
- uint16_t *pageentry_u16;
-
- uint64_t last_bitmap;
-#endif
-} BDRVVPCState;
-
-static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- if (buf_size >= 8 && !strncmp(buf, "conectix", 8))
- return 100;
- return 0;
-}
-
-static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVVPCState *s = bs->opaque;
- int fd, i;
- struct vpc_subheader header;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
-
- bs->read_only = 1; // no write support yet
-
- s->fd = fd;
-
- if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE)
- goto fail;
-
- if (strncmp(header.magic, "conectix", 8))
- goto fail;
- lseek(s->fd, be32_to_cpu(header.type.main.subheader_offset), SEEK_SET);
-
- if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE)
- goto fail;
-
- if (strncmp(header.magic, "cxsparse", 8))
- goto fail;
-
- bs->total_sectors = ((uint64_t)be32_to_cpu(header.type.sparse.pagetable_entries) *
- be32_to_cpu(header.type.sparse.pageentry_size)) / 512;
-
- lseek(s->fd, be32_to_cpu(header.type.sparse.pagetable_offset), SEEK_SET);
-
- s->pagetable_entries = be32_to_cpu(header.type.sparse.pagetable_entries);
- s->pagetable = qemu_malloc(s->pagetable_entries * 4);
- if (!s->pagetable)
- goto fail;
- if (read(s->fd, s->pagetable, s->pagetable_entries * 4) !=
- s->pagetable_entries * 4)
- goto fail;
- for (i = 0; i < s->pagetable_entries; i++)
- be32_to_cpus(&s->pagetable[i]);
-
- s->pageentry_size = be32_to_cpu(header.type.sparse.pageentry_size);
-#ifdef CACHE
- s->pageentry_u8 = qemu_malloc(512);
- if (!s->pageentry_u8)
- goto fail;
- s->pageentry_u32 = s->pageentry_u8;
- s->pageentry_u16 = s->pageentry_u8;
- s->last_pagetable = -1;
-#endif
-
- return 0;
- fail:
- close(fd);
- return -1;
-}
-
-static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
-{
- BDRVVPCState *s = bs->opaque;
- uint64_t offset = sector_num * 512;
- uint64_t bitmap_offset, block_offset;
- uint32_t pagetable_index, pageentry_index;
-
- pagetable_index = offset / s->pageentry_size;
- pageentry_index = (offset % s->pageentry_size) / 512;
-
- if (pagetable_index > s->pagetable_entries || s->pagetable[pagetable_index] == 0xffffffff)
- return -1; // not allocated
-
- bitmap_offset = 512 * s->pagetable[pagetable_index];
- block_offset = bitmap_offset + 512 + (512 * pageentry_index);
-
-// printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
-// sector_num, pagetable_index, pageentry_index,
-// bitmap_offset, block_offset);
-
-// disabled by reason
-#if 0
-#ifdef CACHE
- if (bitmap_offset != s->last_bitmap)
- {
- lseek(s->fd, bitmap_offset, SEEK_SET);
-
- s->last_bitmap = bitmap_offset;
-
- // Scary! Bitmap is stored as big endian 32bit entries,
- // while we used to look it up byte by byte
- read(s->fd, s->pageentry_u8, 512);
- for (i = 0; i < 128; i++)
- be32_to_cpus(&s->pageentry_u32[i]);
- }
-
- if ((s->pageentry_u8[pageentry_index / 8] >> (pageentry_index % 8)) & 1)
- return -1;
-#else
- lseek(s->fd, bitmap_offset + (pageentry_index / 8), SEEK_SET);
-
- read(s->fd, &bitmap_entry, 1);
-
- if ((bitmap_entry >> (pageentry_index % 8)) & 1)
- return -1; // not allocated
-#endif
-#endif
- lseek(s->fd, block_offset, SEEK_SET);
-
- return 0;
-}
-
-static int vpc_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVVPCState *s = bs->opaque;
- int ret;
-
- while (nb_sectors > 0) {
- if (!seek_to_sector(bs, sector_num))
- {
- ret = read(s->fd, buf, 512);
- if (ret != 512)
- return -1;
- }
- else
- memset(buf, 0, 512);
- nb_sectors--;
- sector_num++;
- buf += 512;
- }
- return 0;
-}
-
-static void vpc_close(BlockDriverState *bs)
-{
- BDRVVPCState *s = bs->opaque;
- qemu_free(s->pagetable);
-#ifdef CACHE
- qemu_free(s->pageentry_u8);
-#endif
- close(s->fd);
-}
-
-BlockDriver bdrv_vpc = {
- "vpc",
- sizeof(BDRVVPCState),
- vpc_probe,
- vpc_open,
- vpc_read,
- NULL,
- vpc_close,
-};
diff --git a/tools/ioemu/block-vvfat.c b/tools/ioemu/block-vvfat.c
deleted file mode 100644
index faa53a5ac2..0000000000
--- a/tools/ioemu/block-vvfat.c
+++ /dev/null
@@ -1,2804 +0,0 @@
-/* vim:set shiftwidth=4 ts=8: */
-/*
- * QEMU Block driver for virtual VFAT (shadows a local directory)
- *
- * Copyright (c) 2004,2005 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <sys/stat.h>
-#include <dirent.h>
-#include <assert.h>
-#include "vl.h"
-#include "block_int.h"
-
-#ifndef S_IWGRP
-#define S_IWGRP 0
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 0
-#endif
-
-/* TODO: add ":bootsector=blabla.img:" */
-/* LATER TODO: add automatic boot sector generation from
- BOOTEASY.ASM and Ranish Partition Manager
- Note that DOS assumes the system files to be the first files in the
- file system (test if the boot sector still relies on that fact)! */
-/* MAYBE TODO: write block-visofs.c */
-/* TODO: call try_commit() only after a timeout */
-
-/* #define DEBUG */
-
-#ifdef DEBUG
-
-#define DLOG(a) a
-
-#undef stderr
-#define stderr STDERR
-FILE* stderr = NULL;
-
-static void checkpoint();
-
-#ifdef __MINGW32__
-void nonono(const char* file, int line, const char* msg) {
- fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
- exit(-5);
-}
-#undef assert
-#define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
-#endif
-
-#else
-
-#define DLOG(a)
-
-#endif
-
-/* dynamic array functions */
-typedef struct array_t {
- char* pointer;
- unsigned int size,next,item_size;
-} array_t;
-
-static inline void array_init(array_t* array,unsigned int item_size)
-{
- array->pointer=0;
- array->size=0;
- array->next=0;
- array->item_size=item_size;
-}
-
-static inline void array_free(array_t* array)
-{
- if(array->pointer)
- free(array->pointer);
- array->size=array->next=0;
-}
-
-/* does not automatically grow */
-static inline void* array_get(array_t* array,unsigned int index) {
- assert(index >= 0);
- assert(index < array->next);
- return array->pointer + index * array->item_size;
-}
-
-static inline int array_ensure_allocated(array_t* array, int index)
-{
- if((index + 1) * array->item_size > array->size) {
- int new_size = (index + 32) * array->item_size;
- array->pointer = realloc(array->pointer, new_size);
- if (!array->pointer)
- return -1;
- array->size = new_size;
- array->next = index + 1;
- }
-
- return 0;
-}
-
-static inline void* array_get_next(array_t* array) {
- unsigned int next = array->next;
- void* result;
-
- if (array_ensure_allocated(array, next) < 0)
- return NULL;
-
- array->next = next + 1;
- result = array_get(array, next);
-
- return result;
-}
-
-static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
- if((array->next+count)*array->item_size>array->size) {
- int increment=count*array->item_size;
- array->pointer=realloc(array->pointer,array->size+increment);
- if(!array->pointer)
- return 0;
- array->size+=increment;
- }
- memmove(array->pointer+(index+count)*array->item_size,
- array->pointer+index*array->item_size,
- (array->next-index)*array->item_size);
- array->next+=count;
- return array->pointer+index*array->item_size;
-}
-
-/* this performs a "roll", so that the element which was at index_from becomes
- * index_to, but the order of all other elements is preserved. */
-static inline int array_roll(array_t* array,int index_to,int index_from,int count)
-{
- char* buf;
- char* from;
- char* to;
- int is;
-
- if(!array ||
- index_to<0 || index_to>=array->next ||
- index_from<0 || index_from>=array->next)
- return -1;
-
- if(index_to==index_from)
- return 0;
-
- is=array->item_size;
- from=array->pointer+index_from*is;
- to=array->pointer+index_to*is;
- buf=malloc(is*count);
- memcpy(buf,from,is*count);
-
- if(index_to<index_from)
- memmove(to+is*count,to,from-to);
- else
- memmove(from,from+is*count,to-from);
-
- memcpy(to,buf,is*count);
-
- free(buf);
-
- return 0;
-}
-
-inline int array_remove_slice(array_t* array,int index, int count)
-{
- assert(index >=0);
- assert(count > 0);
- assert(index + count <= array->next);
- if(array_roll(array,array->next-1,index,count))
- return -1;
- array->next -= count;
- return 0;
-}
-
-int array_remove(array_t* array,int index)
-{
- return array_remove_slice(array, index, 1);
-}
-
-/* return the index for a given member */
-int array_index(array_t* array, void* pointer)
-{
- size_t offset = (char*)pointer - array->pointer;
- assert(offset >= 0);
- assert((offset % array->item_size) == 0);
- assert(offset/array->item_size < array->next);
- return offset/array->item_size;
-}
-
-/* These structures are used to fake a disk and the VFAT filesystem.
- * For this reason we need to use __attribute__((packed)). */
-
-typedef struct bootsector_t {
- uint8_t jump[3];
- uint8_t name[8];
- uint16_t sector_size;
- uint8_t sectors_per_cluster;
- uint16_t reserved_sectors;
- uint8_t number_of_fats;
- uint16_t root_entries;
- uint16_t total_sectors16;
- uint8_t media_type;
- uint16_t sectors_per_fat;
- uint16_t sectors_per_track;
- uint16_t number_of_heads;
- uint32_t hidden_sectors;
- uint32_t total_sectors;
- union {
- struct {
- uint8_t drive_number;
- uint8_t current_head;
- uint8_t signature;
- uint32_t id;
- uint8_t volume_label[11];
- } __attribute__((packed)) fat16;
- struct {
- uint32_t sectors_per_fat;
- uint16_t flags;
- uint8_t major,minor;
- uint32_t first_cluster_of_root_directory;
- uint16_t info_sector;
- uint16_t backup_boot_sector;
- uint16_t ignored;
- } __attribute__((packed)) fat32;
- } u;
- uint8_t fat_type[8];
- uint8_t ignored[0x1c0];
- uint8_t magic[2];
-} __attribute__((packed)) bootsector_t;
-
-typedef struct partition_t {
- uint8_t attributes; /* 0x80 = bootable */
- uint8_t start_head;
- uint8_t start_sector;
- uint8_t start_cylinder;
- uint8_t fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xb = FAT32 */
- uint8_t end_head;
- uint8_t end_sector;
- uint8_t end_cylinder;
- uint32_t start_sector_long;
- uint32_t end_sector_long;
-} __attribute__((packed)) partition_t;
-
-typedef struct mbr_t {
- uint8_t ignored[0x1be];
- partition_t partition[4];
- uint8_t magic[2];
-} __attribute__((packed)) mbr_t;
-
-typedef struct direntry_t {
- uint8_t name[8];
- uint8_t extension[3];
- uint8_t attributes;
- uint8_t reserved[2];
- uint16_t ctime;
- uint16_t cdate;
- uint16_t adate;
- uint16_t begin_hi;
- uint16_t mtime;
- uint16_t mdate;
- uint16_t begin;
- uint32_t size;
-} __attribute__((packed)) direntry_t;
-
-/* this structure are used to transparently access the files */
-
-typedef struct mapping_t {
- /* begin is the first cluster, end is the last+1 */
- uint32_t begin,end;
- /* as s->directory is growable, no pointer may be used here */
- unsigned int dir_index;
- /* the clusters of a file may be in any order; this points to the first */
- int first_mapping_index;
- union {
- /* offset is
- * - the offset in the file (in clusters) for a file, or
- * - the next cluster of the directory for a directory, and
- * - the address of the buffer for a faked entry
- */
- struct {
- uint32_t offset;
- } file;
- struct {
- int parent_mapping_index;
- int first_dir_index;
- } dir;
- } info;
- /* path contains the full path, i.e. it always starts with s->path */
- char* path;
-
- enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
- MODE_DIRECTORY = 4, MODE_FAKED = 8,
- MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
- int read_only;
-} mapping_t;
-
-#ifdef DEBUG
-static void print_direntry(const struct direntry_t*);
-static void print_mapping(const struct mapping_t* mapping);
-#endif
-
-/* here begins the real VVFAT driver */
-
-typedef struct BDRVVVFATState {
- BlockDriverState* bs; /* pointer to parent */
- unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
- unsigned char first_sectors[0x40*0x200];
-
- int fat_type; /* 16 or 32 */
- array_t fat,directory,mapping;
-
- unsigned int cluster_size;
- unsigned int sectors_per_cluster;
- unsigned int sectors_per_fat;
- unsigned int sectors_of_root_directory;
- uint32_t last_cluster_of_root_directory;
- unsigned int faked_sectors; /* how many sectors are faked before file data */
- uint32_t sector_count; /* total number of sectors of the partition */
- uint32_t cluster_count; /* total number of clusters of this partition */
- uint32_t max_fat_value;
-
- int current_fd;
- mapping_t* current_mapping;
- unsigned char* cluster; /* points to current cluster */
- unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
- unsigned int current_cluster;
-
- /* write support */
- BlockDriverState* write_target;
- char* qcow_filename;
- BlockDriverState* qcow;
- void* fat2;
- char* used_clusters;
- array_t commits;
- const char* path;
- int downcase_short_names;
-} BDRVVVFATState;
-
-
-static void init_mbr(BDRVVVFATState* s)
-{
- /* TODO: if the files mbr.img and bootsect.img exist, use them */
- mbr_t* real_mbr=(mbr_t*)s->first_sectors;
- partition_t* partition=&(real_mbr->partition[0]);
-
- memset(s->first_sectors,0,512);
-
- partition->attributes=0x80; /* bootable */
- partition->start_head=1;
- partition->start_sector=1;
- partition->start_cylinder=0;
- /* FAT12/FAT16/FAT32 */
- partition->fs_type=(s->fat_type==12?0x1:s->fat_type==16?0x6:0xb);
- partition->end_head=s->bs->heads-1;
- partition->end_sector=0xff; /* end sector & upper 2 bits of cylinder */;
- partition->end_cylinder=0xff; /* lower 8 bits of end cylinder */;
- partition->start_sector_long=cpu_to_le32(s->bs->secs);
- partition->end_sector_long=cpu_to_le32(s->sector_count);
-
- real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
-}
-
-/* direntry functions */
-
-/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
-static inline int short2long_name(unsigned char* dest,const char* src)
-{
- int i;
- for(i=0;i<129 && src[i];i++) {
- dest[2*i]=src[i];
- dest[2*i+1]=0;
- }
- dest[2*i]=dest[2*i+1]=0;
- for(i=2*i+2;(i%26);i++)
- dest[i]=0xff;
- return i;
-}
-
-static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
-{
- char buffer[258];
- int length=short2long_name(buffer,filename),
- number_of_entries=(length+25)/26,i;
- direntry_t* entry;
-
- for(i=0;i<number_of_entries;i++) {
- entry=array_get_next(&(s->directory));
- entry->attributes=0xf;
- entry->reserved[0]=0;
- entry->begin=0;
- entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
- }
- for(i=0;i<length;i++) {
- int offset=(i%26);
- if(offset<10) offset=1+offset;
- else if(offset<22) offset=14+offset-10;
- else offset=28+offset-22;
- entry=array_get(&(s->directory),s->directory.next-1-(i/26));
- entry->name[offset]=buffer[i];
- }
- return array_get(&(s->directory),s->directory.next-number_of_entries);
-}
-
-static char is_free(const direntry_t* direntry)
-{
- /* return direntry->name[0]==0 ; */
- return direntry->attributes == 0 || direntry->name[0]==0xe5;
-}
-
-static char is_volume_label(const direntry_t* direntry)
-{
- return direntry->attributes == 0x28;
-}
-
-static char is_long_name(const direntry_t* direntry)
-{
- return direntry->attributes == 0xf;
-}
-
-static char is_short_name(const direntry_t* direntry)
-{
- return !is_volume_label(direntry) && !is_long_name(direntry)
- && !is_free(direntry);
-}
-
-static char is_directory(const direntry_t* direntry)
-{
- return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
-}
-
-static inline char is_dot(const direntry_t* direntry)
-{
- return is_short_name(direntry) && direntry->name[0] == '.';
-}
-
-static char is_file(const direntry_t* direntry)
-{
- return is_short_name(direntry) && !is_directory(direntry);
-}
-
-static inline uint32_t begin_of_direntry(const direntry_t* direntry)
-{
- return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
-}
-
-static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
-{
- return le32_to_cpu(direntry->size);
-}
-
-static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
-{
- direntry->begin = cpu_to_le16(begin & 0xffff);
- direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
-}
-
-/* fat functions */
-
-static inline uint8_t fat_chksum(const direntry_t* entry)
-{
- uint8_t chksum=0;
- int i;
-
- for(i=0;i<11;i++)
- chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0))
- +(unsigned char)entry->name[i];
-
- return chksum;
-}
-
-/* if return_time==0, this returns the fat_date, else the fat_time */
-static uint16_t fat_datetime(time_t time,int return_time) {
- struct tm* t;
-#ifdef _WIN32
- t=localtime(&time); /* this is not thread safe */
-#else
- struct tm t1;
- t=&t1;
- localtime_r(&time,t);
-#endif
- if(return_time)
- return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
- return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
-}
-
-static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
-{
- if(s->fat_type==32) {
- uint32_t* entry=array_get(&(s->fat),cluster);
- *entry=cpu_to_le32(value);
- } else if(s->fat_type==16) {
- uint16_t* entry=array_get(&(s->fat),cluster);
- *entry=cpu_to_le16(value&0xffff);
- } else {
- int offset = (cluster*3/2);
- unsigned char* p = array_get(&(s->fat), offset);
- switch (cluster&1) {
- case 0:
- p[0] = value&0xff;
- p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
- break;
- case 1:
- p[0] = (p[0]&0xf) | ((value&0xf)<<4);
- p[1] = (value>>4);
- break;
- }
- }
-}
-
-static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
-{
- if(s->fat_type==32) {
- uint32_t* entry=array_get(&(s->fat),cluster);
- return le32_to_cpu(*entry);
- } else if(s->fat_type==16) {
- uint16_t* entry=array_get(&(s->fat),cluster);
- return le16_to_cpu(*entry);
- } else {
- const uint8_t* x=s->fat.pointer+cluster*3/2;
- return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
- }
-}
-
-static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
-{
- if(fat_entry>s->max_fat_value-8)
- return -1;
- return 0;
-}
-
-static inline void init_fat(BDRVVVFATState* s)
-{
- if (s->fat_type == 12) {
- array_init(&(s->fat),1);
- array_ensure_allocated(&(s->fat),
- s->sectors_per_fat * 0x200 * 3 / 2 - 1);
- } else {
- array_init(&(s->fat),(s->fat_type==32?4:2));
- array_ensure_allocated(&(s->fat),
- s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
- }
- memset(s->fat.pointer,0,s->fat.size);
-
- switch(s->fat_type) {
- case 12: s->max_fat_value=0xfff; break;
- case 16: s->max_fat_value=0xffff; break;
- case 32: s->max_fat_value=0x0fffffff; break;
- default: s->max_fat_value=0; /* error... */
- }
-
-}
-
-/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
-/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
-static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
- unsigned int directory_start, const char* filename, int is_dot)
-{
- int i,j,long_index=s->directory.next;
- direntry_t* entry=0;
- direntry_t* entry_long=0;
-
- if(is_dot) {
- entry=array_get_next(&(s->directory));
- memset(entry->name,0x20,11);
- memcpy(entry->name,filename,strlen(filename));
- return entry;
- }
-
- entry_long=create_long_filename(s,filename);
-
- i = strlen(filename);
- for(j = i - 1; j>0 && filename[j]!='.';j--);
- if (j > 0)
- i = (j > 8 ? 8 : j);
- else if (i > 8)
- i = 8;
-
- entry=array_get_next(&(s->directory));
- memset(entry->name,0x20,11);
- strncpy(entry->name,filename,i);
-
- if(j > 0)
- for (i = 0; i < 3 && filename[j+1+i]; i++)
- entry->extension[i] = filename[j+1+i];
-
- /* upcase & remove unwanted characters */
- for(i=10;i>=0;i--) {
- if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
- if(entry->name[i]<=' ' || entry->name[i]>0x7f
- || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
- entry->name[i]='_';
- else if(entry->name[i]>='a' && entry->name[i]<='z')
- entry->name[i]+='A'-'a';
- }
-
- /* mangle duplicates */
- while(1) {
- direntry_t* entry1=array_get(&(s->directory),directory_start);
- int j;
-
- for(;entry1<entry;entry1++)
- if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
- break; /* found dupe */
- if(entry1==entry) /* no dupe found */
- break;
-
- /* use all 8 characters of name */
- if(entry->name[7]==' ') {
- int j;
- for(j=6;j>0 && entry->name[j]==' ';j--)
- entry->name[j]='~';
- }
-
- /* increment number */
- for(j=7;j>0 && entry->name[j]=='9';j--)
- entry->name[j]='0';
- if(j>0) {
- if(entry->name[j]<'0' || entry->name[j]>'9')
- entry->name[j]='0';
- else
- entry->name[j]++;
- }
- }
-
- /* calculate checksum; propagate to long name */
- if(entry_long) {
- uint8_t chksum=fat_chksum(entry);
-
- /* calculate anew, because realloc could have taken place */
- entry_long=array_get(&(s->directory),long_index);
- while(entry_long<entry && is_long_name(entry_long)) {
- entry_long->reserved[1]=chksum;
- entry_long++;
- }
- }
-
- return entry;
-}
-
-/*
- * Read a directory. (the index of the corresponding mapping must be passed).
- */
-static int read_directory(BDRVVVFATState* s, int mapping_index)
-{
- mapping_t* mapping = array_get(&(s->mapping), mapping_index);
- direntry_t* direntry;
- const char* dirname = mapping->path;
- int first_cluster = mapping->begin;
- int parent_index = mapping->info.dir.parent_mapping_index;
- mapping_t* parent_mapping = (mapping_t*)
- (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : 0);
- int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;
-
- DIR* dir=opendir(dirname);
- struct dirent* entry;
- int i;
-
- assert(mapping->mode & MODE_DIRECTORY);
-
- if(!dir) {
- mapping->end = mapping->begin;
- return -1;
- }
-
- i = mapping->info.dir.first_dir_index =
- first_cluster == 0 ? 0 : s->directory.next;
-
- /* actually read the directory, and allocate the mappings */
- while((entry=readdir(dir))) {
- unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
- char* buffer;
- direntry_t* direntry;
- struct stat st;
- int is_dot=!strcmp(entry->d_name,".");
- int is_dotdot=!strcmp(entry->d_name,"..");
-
- if(first_cluster == 0 && (is_dotdot || is_dot))
- continue;
-
- buffer=(char*)malloc(length);
- assert(buffer);
- snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
-
- if(stat(buffer,&st)<0) {
- free(buffer);
- continue;
- }
-
- /* create directory entry for this file */
- direntry=create_short_and_long_name(s, i, entry->d_name,
- is_dot || is_dotdot);
- direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
- direntry->reserved[0]=direntry->reserved[1]=0;
- direntry->ctime=fat_datetime(st.st_ctime,1);
- direntry->cdate=fat_datetime(st.st_ctime,0);
- direntry->adate=fat_datetime(st.st_atime,0);
- direntry->begin_hi=0;
- direntry->mtime=fat_datetime(st.st_mtime,1);
- direntry->mdate=fat_datetime(st.st_mtime,0);
- if(is_dotdot)
- set_begin_of_direntry(direntry, first_cluster_of_parent);
- else if(is_dot)
- set_begin_of_direntry(direntry, first_cluster);
- else
- direntry->begin=0; /* do that later */
- if (st.st_size > 0x7fffffff) {
- fprintf(stderr, "File %s is larger than 2GB\n", buffer);
- free(buffer);
- return -2;
- }
- direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
-
- /* create mapping for this file */
- if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
- s->current_mapping=(mapping_t*)array_get_next(&(s->mapping));
- s->current_mapping->begin=0;
- s->current_mapping->end=st.st_size;
- /*
- * we get the direntry of the most recent direntry, which
- * contains the short name and all the relevant information.
- */
- s->current_mapping->dir_index=s->directory.next-1;
- s->current_mapping->first_mapping_index = -1;
- if (S_ISDIR(st.st_mode)) {
- s->current_mapping->mode = MODE_DIRECTORY;
- s->current_mapping->info.dir.parent_mapping_index =
- mapping_index;
- } else {
- s->current_mapping->mode = MODE_UNDEFINED;
- s->current_mapping->info.file.offset = 0;
- }
- s->current_mapping->path=buffer;
- s->current_mapping->read_only =
- (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
- }
- }
- closedir(dir);
-
- /* fill with zeroes up to the end of the cluster */
- while(s->directory.next%(0x10*s->sectors_per_cluster)) {
- direntry_t* direntry=array_get_next(&(s->directory));
- memset(direntry,0,sizeof(direntry_t));
- }
-
-/* TODO: if there are more entries, bootsector has to be adjusted! */
-#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
- if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
- /* root directory */
- int cur = s->directory.next;
- array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
- memset(array_get(&(s->directory), cur), 0,
- (ROOT_ENTRIES - cur) * sizeof(direntry_t));
- }
-
- /* reget the mapping, since s->mapping was possibly realloc()ed */
- mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
- first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
- * 0x20 / s->cluster_size;
- mapping->end = first_cluster;
-
- direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
- set_begin_of_direntry(direntry, mapping->begin);
-
- return 0;
-}
-
-static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
-{
- return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
-}
-
-static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
-{
- return s->faked_sectors + s->sectors_per_cluster * cluster_num;
-}
-
-static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num)
-{
- return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster;
-}
-
-#ifdef DBG
-static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping)
-{
- if(mapping->mode==MODE_UNDEFINED)
- return 0;
- return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index);
-}
-#endif
-
-static int init_directories(BDRVVVFATState* s,
- const char* dirname)
-{
- bootsector_t* bootsector;
- mapping_t* mapping;
- unsigned int i;
- unsigned int cluster;
-
- memset(&(s->first_sectors[0]),0,0x40*0x200);
-
- s->cluster_size=s->sectors_per_cluster*0x200;
- s->cluster_buffer=malloc(s->cluster_size);
- assert(s->cluster_buffer);
-
- /*
- * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
- * where sc is sector_count,
- * spf is sectors_per_fat,
- * spc is sectors_per_clusters, and
- * fat_type = 12, 16 or 32.
- */
- i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
- s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
-
- array_init(&(s->mapping),sizeof(mapping_t));
- array_init(&(s->directory),sizeof(direntry_t));
-
- /* add volume label */
- {
- direntry_t* entry=array_get_next(&(s->directory));
- entry->attributes=0x28; /* archive | volume label */
- snprintf(entry->name,11,"QEMU VVFAT");
- }
-
- /* Now build FAT, and write back information into directory */
- init_fat(s);
-
- s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
- s->cluster_count=sector2cluster(s, s->sector_count);
-
- mapping = array_get_next(&(s->mapping));
- mapping->begin = 0;
- mapping->dir_index = 0;
- mapping->info.dir.parent_mapping_index = -1;
- mapping->first_mapping_index = -1;
- mapping->path = strdup(dirname);
- i = strlen(mapping->path);
- if (i > 0 && mapping->path[i - 1] == '/')
- mapping->path[i - 1] = '\0';
- mapping->mode = MODE_DIRECTORY;
- mapping->read_only = 0;
- s->path = mapping->path;
-
- for (i = 0, cluster = 0; i < s->mapping.next; i++) {
- int j;
- /* MS-DOS expects the FAT to be 0 for the root directory
- * (except for the media byte). */
- /* LATER TODO: still true for FAT32? */
- int fix_fat = (i != 0);
- mapping = array_get(&(s->mapping), i);
-
- if (mapping->mode & MODE_DIRECTORY) {
- mapping->begin = cluster;
- if(read_directory(s, i)) {
- fprintf(stderr, "Could not read directory %s\n",
- mapping->path);
- return -1;
- }
- mapping = array_get(&(s->mapping), i);
- } else {
- assert(mapping->mode == MODE_UNDEFINED);
- mapping->mode=MODE_NORMAL;
- mapping->begin = cluster;
- if (mapping->end > 0) {
- direntry_t* direntry = array_get(&(s->directory),
- mapping->dir_index);
-
- mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
- set_begin_of_direntry(direntry, mapping->begin);
- } else {
- mapping->end = cluster + 1;
- fix_fat = 0;
- }
- }
-
- assert(mapping->begin < mapping->end);
-
- /* fix fat for entry */
- if (fix_fat) {
- for(j = mapping->begin; j < mapping->end - 1; j++)
- fat_set(s, j, j+1);
- fat_set(s, mapping->end - 1, s->max_fat_value);
- }
-
- /* next free cluster */
- cluster = mapping->end;
-
- if(cluster > s->cluster_count) {
- fprintf(stderr,"Directory does not fit in FAT%d\n",s->fat_type);
- return -1;
- }
- }
-
- mapping = array_get(&(s->mapping), 0);
- s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
- s->last_cluster_of_root_directory = mapping->end;
-
- /* the FAT signature */
- fat_set(s,0,s->max_fat_value);
- fat_set(s,1,s->max_fat_value);
-
- s->current_mapping = NULL;
-
- bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
- bootsector->jump[0]=0xeb;
- bootsector->jump[1]=0x3e;
- bootsector->jump[2]=0x90;
- memcpy(bootsector->name,"QEMU ",8);
- bootsector->sector_size=cpu_to_le16(0x200);
- bootsector->sectors_per_cluster=s->sectors_per_cluster;
- bootsector->reserved_sectors=cpu_to_le16(1);
- bootsector->number_of_fats=0x2; /* number of FATs */
- bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
- bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
- bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */
- s->fat.pointer[0] = bootsector->media_type;
- bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
- bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
- bootsector->number_of_heads=cpu_to_le16(s->bs->heads);
- bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
- bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
-
- /* LATER TODO: if FAT32, this is wrong */
- bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */
- bootsector->u.fat16.current_head=0;
- bootsector->u.fat16.signature=0x29;
- bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
-
- memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);
- memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12 ":s->fat_type==16?"FAT16 ":"FAT32 "),8);
- bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
-
- return 0;
-}
-
-#ifdef DEBUG
-static BDRVVVFATState *vvv = NULL;
-#endif
-
-static int enable_write_target(BDRVVVFATState *s);
-static int is_consistent(BDRVVVFATState *s);
-
-static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
-{
- BDRVVVFATState *s = bs->opaque;
- int floppy = 0;
- int i;
-
-#ifdef DEBUG
- vvv = s;
-#endif
-
-DLOG(if (stderr == NULL) {
- stderr = fopen("vvfat.log", "a");
- setbuf(stderr, NULL);
-})
-
- s->bs = bs;
-
- s->fat_type=16;
- /* LATER TODO: if FAT32, adjust */
- s->sector_count=0xec04f;
- s->sectors_per_cluster=0x10;
- /* LATER TODO: this could be wrong for FAT32 */
- bs->cyls=1023; bs->heads=15; bs->secs=63;
-
- s->current_cluster=0xffffffff;
-
- s->first_sectors_number=0x40;
- /* read only is the default for safety */
- bs->read_only = 1;
- s->qcow = s->write_target = NULL;
- s->qcow_filename = NULL;
- s->fat2 = NULL;
- s->downcase_short_names = 1;
-
- if (!strstart(dirname, "fat:", NULL))
- return -1;
-
- if (strstr(dirname, ":rw:")) {
- if (enable_write_target(s))
- return -1;
- bs->read_only = 0;
- }
-
- if (strstr(dirname, ":floppy:")) {
- floppy = 1;
- s->fat_type = 12;
- s->first_sectors_number = 1;
- s->sectors_per_cluster=2;
- bs->cyls = 80; bs->heads = 2; bs->secs = 36;
- }
-
- if (strstr(dirname, ":32:")) {
- fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
- s->fat_type = 32;
- } else if (strstr(dirname, ":16:")) {
- s->fat_type = 16;
- } else if (strstr(dirname, ":12:")) {
- s->fat_type = 12;
- s->sector_count=2880;
- }
-
- i = strrchr(dirname, ':') - dirname;
- assert(i >= 3);
- if (dirname[i-2] == ':' && isalpha((uint8_t)dirname[i-1]))
- /* workaround for DOS drive names */
- dirname += i-1;
- else
- dirname += i+1;
-
- bs->total_sectors=bs->cyls*bs->heads*bs->secs;
- if (s->sector_count > bs->total_sectors)
- s->sector_count = bs->total_sectors;
- if(init_directories(s, dirname))
- return -1;
-
- if(s->first_sectors_number==0x40)
- init_mbr(s);
-
- /* for some reason or other, MS-DOS does not like to know about CHS... */
- if (floppy)
- bs->heads = bs->cyls = bs->secs = 0;
-
- // assert(is_consistent(s));
- return 0;
-}
-
-static inline void vvfat_close_current_file(BDRVVVFATState *s)
-{
- if(s->current_mapping) {
- s->current_mapping = NULL;
- if (s->current_fd) {
- close(s->current_fd);
- s->current_fd = 0;
- }
- }
- s->current_cluster = -1;
-}
-
-/* mappings between index1 and index2-1 are supposed to be ordered
- * return value is the index of the last mapping for which end>cluster_num
- */
-static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
-{
- int index3=index1+1;
- while(1) {
- mapping_t* mapping;
- index3=(index1+index2)/2;
- mapping=array_get(&(s->mapping),index3);
- assert(mapping->begin < mapping->end);
- if(mapping->begin>=cluster_num) {
- assert(index2!=index3 || index2==0);
- if(index2==index3)
- return index1;
- index2=index3;
- } else {
- if(index1==index3)
- return mapping->end<=cluster_num ? index2 : index1;
- index1=index3;
- }
- assert(index1<=index2);
- DLOG(mapping=array_get(&(s->mapping),index1);
- assert(mapping->begin<=cluster_num);
- assert(index2 >= s->mapping.next ||
- ((mapping = array_get(&(s->mapping),index2)) &&
- mapping->end>cluster_num)));
- }
-}
-
-static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
-{
- int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
- mapping_t* mapping;
- if(index>=s->mapping.next)
- return 0;
- mapping=array_get(&(s->mapping),index);
- if(mapping->begin>cluster_num)
- return 0;
- assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
- return mapping;
-}
-
-/*
- * This function simply compares path == mapping->path. Since the mappings
- * are sorted by cluster, this is expensive: O(n).
- */
-static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s,
- const char* path)
-{
- int i;
-
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->first_mapping_index < 0 &&
- !strcmp(path, mapping->path))
- return mapping;
- }
-
- return NULL;
-}
-
-static int open_file(BDRVVVFATState* s,mapping_t* mapping)
-{
- if(!mapping)
- return -1;
- if(!s->current_mapping ||
- strcmp(s->current_mapping->path,mapping->path)) {
- /* open file */
- int fd = open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
- if(fd<0)
- return -1;
- vvfat_close_current_file(s);
- s->current_fd = fd;
- s->current_mapping = mapping;
- }
- return 0;
-}
-
-static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
-{
- if(s->current_cluster != cluster_num) {
- int result=0;
- off_t offset;
- assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
- if(!s->current_mapping
- || s->current_mapping->begin>cluster_num
- || s->current_mapping->end<=cluster_num) {
- /* binary search of mappings for file */
- mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
-
- assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
-
- if (mapping && mapping->mode & MODE_DIRECTORY) {
- vvfat_close_current_file(s);
- s->current_mapping = mapping;
-read_cluster_directory:
- offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
- s->cluster = s->directory.pointer+offset
- + 0x20*s->current_mapping->info.dir.first_dir_index;
- assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
- assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
- s->current_cluster = cluster_num;
- return 0;
- }
-
- if(open_file(s,mapping))
- return -2;
- } else if (s->current_mapping->mode & MODE_DIRECTORY)
- goto read_cluster_directory;
-
- assert(s->current_fd);
-
- offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
- if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
- return -3;
- s->cluster=s->cluster_buffer;
- result=read(s->current_fd,s->cluster,s->cluster_size);
- if(result<0) {
- s->current_cluster = -1;
- return -1;
- }
- s->current_cluster = cluster_num;
- }
- return 0;
-}
-
-#ifdef DEBUG
-static void hexdump(const void* address, uint32_t len)
-{
- const unsigned char* p = address;
- int i, j;
-
- for (i = 0; i < len; i += 16) {
- for (j = 0; j < 16 && i + j < len; j++)
- fprintf(stderr, "%02x ", p[i + j]);
- for (; j < 16; j++)
- fprintf(stderr, " ");
- fprintf(stderr, " ");
- for (j = 0; j < 16 && i + j < len; j++)
- fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
- fprintf(stderr, "\n");
- }
-}
-
-static void print_direntry(const direntry_t* direntry)
-{
- int j = 0;
- char buffer[1024];
-
- fprintf(stderr, "direntry 0x%x: ", (int)direntry);
- if(!direntry)
- return;
- if(is_long_name(direntry)) {
- unsigned char* c=(unsigned char*)direntry;
- int i;
- for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
-#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = '°'; j++;}
- ADD_CHAR(c[i]);
- for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
- ADD_CHAR(c[i]);
- for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
- ADD_CHAR(c[i]);
- buffer[j] = 0;
- fprintf(stderr, "%s\n", buffer);
- } else {
- int i;
- for(i=0;i<11;i++)
- ADD_CHAR(direntry->name[i]);
- buffer[j] = 0;
- fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
- buffer,
- direntry->attributes,
- begin_of_direntry(direntry),le32_to_cpu(direntry->size));
- }
-}
-
-static void print_mapping(const mapping_t* mapping)
-{
- fprintf(stderr, "mapping (0x%x): begin, end = %d, %d, dir_index = %d, first_mapping_index = %d, name = %s, mode = 0x%x, " , (int)mapping, mapping->begin, mapping->end, mapping->dir_index, mapping->first_mapping_index, mapping->path, mapping->mode);
- if (mapping->mode & MODE_DIRECTORY)
- fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
- else
- fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
-}
-#endif
-
-static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVVVFATState *s = bs->opaque;
- int i;
-
- for(i=0;i<nb_sectors;i++,sector_num++) {
- if (sector_num >= s->sector_count)
- return -1;
- if (s->qcow) {
- int n;
- if (s->qcow->drv->bdrv_is_allocated(s->qcow,
- sector_num, nb_sectors-i, &n)) {
-DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
- if (s->qcow->drv->bdrv_read(s->qcow, sector_num, buf+i*0x200, n))
- return -1;
- i += n - 1;
- sector_num += n - 1;
- continue;
- }
-DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
- }
- if(sector_num<s->faked_sectors) {
- if(sector_num<s->first_sectors_number)
- memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
- else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
- memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
- else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
- memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
- } else {
- uint32_t sector=sector_num-s->faked_sectors,
- sector_offset_in_cluster=(sector%s->sectors_per_cluster),
- cluster_num=sector/s->sectors_per_cluster;
- if(read_cluster(s, cluster_num) != 0) {
- /* LATER TODO: strict: return -1; */
- memset(buf+i*0x200,0,0x200);
- continue;
- }
- memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
- }
- }
- return 0;
-}
-
-/* LATER TODO: statify all functions */
-
-/*
- * Idea of the write support (use snapshot):
- *
- * 1. check if all data is consistent, recording renames, modifications,
- * new files and directories (in s->commits).
- *
- * 2. if the data is not consistent, stop committing
- *
- * 3. handle renames, and create new files and directories (do not yet
- * write their contents)
- *
- * 4. walk the directories, fixing the mapping and direntries, and marking
- * the handled mappings as not deleted
- *
- * 5. commit the contents of the files
- *
- * 6. handle deleted files and directories
- *
- */
-
-typedef struct commit_t {
- char* path;
- union {
- struct { uint32_t cluster; } rename;
- struct { int dir_index; uint32_t modified_offset; } writeout;
- struct { uint32_t first_cluster; } new_file;
- struct { uint32_t cluster; } mkdir;
- } param;
- /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
- enum {
- ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
- } action;
-} commit_t;
-
-static void clear_commits(BDRVVVFATState* s)
-{
- int i;
-DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
- for (i = 0; i < s->commits.next; i++) {
- commit_t* commit = array_get(&(s->commits), i);
- assert(commit->path || commit->action == ACTION_WRITEOUT);
- if (commit->action != ACTION_WRITEOUT) {
- assert(commit->path);
- free(commit->path);
- } else
- assert(commit->path == NULL);
- }
- s->commits.next = 0;
-}
-
-static void schedule_rename(BDRVVVFATState* s,
- uint32_t cluster, char* new_path)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = new_path;
- commit->param.rename.cluster = cluster;
- commit->action = ACTION_RENAME;
-}
-
-static void schedule_writeout(BDRVVVFATState* s,
- int dir_index, uint32_t modified_offset)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = NULL;
- commit->param.writeout.dir_index = dir_index;
- commit->param.writeout.modified_offset = modified_offset;
- commit->action = ACTION_WRITEOUT;
-}
-
-static void schedule_new_file(BDRVVVFATState* s,
- char* path, uint32_t first_cluster)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = path;
- commit->param.new_file.first_cluster = first_cluster;
- commit->action = ACTION_NEW_FILE;
-}
-
-static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = path;
- commit->param.mkdir.cluster = cluster;
- commit->action = ACTION_MKDIR;
-}
-
-typedef struct {
- unsigned char name[1024];
- int checksum, len;
- int sequence_number;
-} long_file_name;
-
-static void lfn_init(long_file_name* lfn)
-{
- lfn->sequence_number = lfn->len = 0;
- lfn->checksum = 0x100;
-}
-
-/* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
-static int parse_long_name(long_file_name* lfn,
- const direntry_t* direntry)
-{
- int i, j, offset;
- const unsigned char* pointer = (const unsigned char*)direntry;
-
- if (!is_long_name(direntry))
- return 1;
-
- if (pointer[0] & 0x40) {
- lfn->sequence_number = pointer[0] & 0x3f;
- lfn->checksum = pointer[13];
- lfn->name[0] = 0;
- } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
- return -1;
- else if (pointer[13] != lfn->checksum)
- return -2;
- else if (pointer[12] || pointer[26] || pointer[27])
- return -3;
-
- offset = 13 * (lfn->sequence_number - 1);
- for (i = 0, j = 1; i < 13; i++, j+=2) {
- if (j == 11)
- j = 14;
- else if (j == 26)
- j = 28;
-
- if (pointer[j+1] == 0)
- lfn->name[offset + i] = pointer[j];
- else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
- return -4;
- else
- lfn->name[offset + i] = 0;
- }
-
- if (pointer[0] & 0x40)
- lfn->len = offset + strlen(lfn->name + offset);
-
- return 0;
-}
-
-/* returns 0 if successful, >0 if no short_name, and <0 on error */
-static int parse_short_name(BDRVVVFATState* s,
- long_file_name* lfn, direntry_t* direntry)
-{
- int i, j;
-
- if (!is_short_name(direntry))
- return 1;
-
- for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
- for (i = 0; i <= j; i++) {
- if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
- return -1;
- else if (s->downcase_short_names)
- lfn->name[i] = tolower(direntry->name[i]);
- else
- lfn->name[i] = direntry->name[i];
- }
-
- for (j = 2; j >= 0 && direntry->extension[j] == ' '; j--);
- if (j >= 0) {
- lfn->name[i++] = '.';
- lfn->name[i + j + 1] = '\0';
- for (;j >= 0; j--) {
- if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
- return -2;
- else if (s->downcase_short_names)
- lfn->name[i + j] = tolower(direntry->extension[j]);
- else
- lfn->name[i + j] = direntry->extension[j];
- }
- } else
- lfn->name[i + j + 1] = '\0';
-
- lfn->len = strlen(lfn->name);
-
- return 0;
-}
-
-static inline uint32_t modified_fat_get(BDRVVVFATState* s,
- unsigned int cluster)
-{
- if (cluster < s->last_cluster_of_root_directory) {
- if (cluster + 1 == s->last_cluster_of_root_directory)
- return s->max_fat_value;
- else
- return cluster + 1;
- }
-
- if (s->fat_type==32) {
- uint32_t* entry=((uint32_t*)s->fat2)+cluster;
- return le32_to_cpu(*entry);
- } else if (s->fat_type==16) {
- uint16_t* entry=((uint16_t*)s->fat2)+cluster;
- return le16_to_cpu(*entry);
- } else {
- const uint8_t* x=s->fat2+cluster*3/2;
- return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
- }
-}
-
-static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
-{
- int was_modified = 0;
- int i, dummy;
-
- if (s->qcow == NULL)
- return 0;
-
- for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
- was_modified = s->qcow->drv->bdrv_is_allocated(s->qcow,
- cluster2sector(s, cluster_num) + i, 1, &dummy);
-
- return was_modified;
-}
-
-static const char* get_basename(const char* path)
-{
- char* basename = strrchr(path, '/');
- if (basename == NULL)
- return path;
- else
- return basename + 1; /* strip '/' */
-}
-
-/*
- * The array s->used_clusters holds the states of the clusters. If it is
- * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
- * was modified, bit 3 is set.
- * If any cluster is allocated, but not part of a file or directory, this
- * driver refuses to commit.
- */
-typedef enum {
- USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
-} used_t;
-
-/*
- * get_cluster_count_for_direntry() not only determines how many clusters
- * are occupied by direntry, but also if it was renamed or modified.
- *
- * A file is thought to be renamed *only* if there already was a file with
- * exactly the same first cluster, but a different name.
- *
- * Further, the files/directories handled by this function are
- * assumed to be *not* deleted (and *only* those).
- */
-static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
- direntry_t* direntry, const char* path)
-{
- /*
- * This is a little bit tricky:
- * IF the guest OS just inserts a cluster into the file chain,
- * and leaves the rest alone, (i.e. the original file had clusters
- * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
- *
- * - do_commit will write the cluster into the file at the given
- * offset, but
- *
- * - the cluster which is overwritten should be moved to a later
- * position in the file.
- *
- * I am not aware that any OS does something as braindead, but this
- * situation could happen anyway when not committing for a long time.
- * Just to be sure that this does not bite us, detect it, and copy the
- * contents of the clusters to-be-overwritten into the qcow.
- */
- int copy_it = 0;
- int was_modified = 0;
- int32_t ret = 0;
-
- uint32_t cluster_num = begin_of_direntry(direntry);
- uint32_t offset = 0;
- int first_mapping_index = -1;
- mapping_t* mapping = NULL;
- const char* basename2 = NULL;
-
- vvfat_close_current_file(s);
-
- /* the root directory */
- if (cluster_num == 0)
- return 0;
-
- /* write support */
- if (s->qcow) {
- basename2 = get_basename(path);
-
- mapping = find_mapping_for_cluster(s, cluster_num);
-
- if (mapping) {
- const char* basename;
-
- assert(mapping->mode & MODE_DELETED);
- mapping->mode &= ~MODE_DELETED;
-
- basename = get_basename(mapping->path);
-
- assert(mapping->mode & MODE_NORMAL);
-
- /* rename */
- if (strcmp(basename, basename2))
- schedule_rename(s, cluster_num, strdup(path));
- } else if (is_file(direntry))
- /* new file */
- schedule_new_file(s, strdup(path), cluster_num);
- else {
- assert(0);
- return 0;
- }
- }
-
- while(1) {
- if (s->qcow) {
- if (!copy_it && cluster_was_modified(s, cluster_num)) {
- if (mapping == NULL ||
- mapping->begin > cluster_num ||
- mapping->end <= cluster_num)
- mapping = find_mapping_for_cluster(s, cluster_num);
-
-
- if (mapping &&
- (mapping->mode & MODE_DIRECTORY) == 0) {
-
- /* was modified in qcow */
- if (offset != mapping->info.file.offset + s->cluster_size
- * (cluster_num - mapping->begin)) {
- /* offset of this cluster in file chain has changed */
- assert(0);
- copy_it = 1;
- } else if (offset == 0) {
- const char* basename = get_basename(mapping->path);
-
- if (strcmp(basename, basename2))
- copy_it = 1;
- first_mapping_index = array_index(&(s->mapping), mapping);
- }
-
- if (mapping->first_mapping_index != first_mapping_index
- && mapping->info.file.offset > 0) {
- assert(0);
- copy_it = 1;
- }
-
- /* need to write out? */
- if (!was_modified && is_file(direntry)) {
- was_modified = 1;
- schedule_writeout(s, mapping->dir_index, offset);
- }
- }
- }
-
- if (copy_it) {
- int i, dummy;
- /*
- * This is horribly inefficient, but that is okay, since
- * it is rarely executed, if at all.
- */
- int64_t offset = cluster2sector(s, cluster_num);
-
- vvfat_close_current_file(s);
- for (i = 0; i < s->sectors_per_cluster; i++)
- if (!s->qcow->drv->bdrv_is_allocated(s->qcow,
- offset + i, 1, &dummy)) {
- if (vvfat_read(s->bs,
- offset, s->cluster_buffer, 1))
- return -1;
- if (s->qcow->drv->bdrv_write(s->qcow,
- offset, s->cluster_buffer, 1))
- return -2;
- }
- }
- }
-
- ret++;
- if (s->used_clusters[cluster_num] & USED_ANY)
- return 0;
- s->used_clusters[cluster_num] = USED_FILE;
-
- cluster_num = modified_fat_get(s, cluster_num);
-
- if (fat_eof(s, cluster_num))
- return ret;
- else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
- return -1;
-
- offset += s->cluster_size;
- }
-}
-
-/*
- * This function looks at the modified data (qcow).
- * It returns 0 upon inconsistency or error, and the number of clusters
- * used by the directory, its subdirectories and their files.
- */
-static int check_directory_consistency(BDRVVVFATState *s,
- int cluster_num, const char* path)
-{
- int ret = 0;
- unsigned char* cluster = malloc(s->cluster_size);
- direntry_t* direntries = (direntry_t*)cluster;
- mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
-
- long_file_name lfn;
- int path_len = strlen(path);
- char path2[PATH_MAX];
-
- assert(path_len < PATH_MAX); /* len was tested before! */
- strcpy(path2, path);
- path2[path_len] = '/';
- path2[path_len + 1] = '\0';
-
- if (mapping) {
- const char* basename = get_basename(mapping->path);
- const char* basename2 = get_basename(path);
-
- assert(mapping->mode & MODE_DIRECTORY);
-
- assert(mapping->mode & MODE_DELETED);
- mapping->mode &= ~MODE_DELETED;
-
- if (strcmp(basename, basename2))
- schedule_rename(s, cluster_num, strdup(path));
- } else
- /* new directory */
- schedule_mkdir(s, cluster_num, strdup(path));
-
- lfn_init(&lfn);
- do {
- int i;
- int subret = 0;
-
- ret++;
-
- if (s->used_clusters[cluster_num] & USED_ANY) {
- fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
- return 0;
- }
- s->used_clusters[cluster_num] = USED_DIRECTORY;
-
-DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
- subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
- s->sectors_per_cluster);
- if (subret) {
- fprintf(stderr, "Error fetching direntries\n");
- fail:
- free(cluster);
- return 0;
- }
-
- for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
- int cluster_count;
-
-DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i));
- if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
- is_free(direntries + i))
- continue;
-
- subret = parse_long_name(&lfn, direntries + i);
- if (subret < 0) {
- fprintf(stderr, "Error in long name\n");
- goto fail;
- }
- if (subret == 0 || is_free(direntries + i))
- continue;
-
- if (fat_chksum(direntries+i) != lfn.checksum) {
- subret = parse_short_name(s, &lfn, direntries + i);
- if (subret < 0) {
- fprintf(stderr, "Error in short name (%d)\n", subret);
- goto fail;
- }
- if (subret > 0 || !strcmp(lfn.name, ".")
- || !strcmp(lfn.name, ".."))
- continue;
- }
- lfn.checksum = 0x100; /* cannot use long name twice */
-
- if (path_len + 1 + lfn.len >= PATH_MAX) {
- fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
- goto fail;
- }
- strcpy(path2 + path_len + 1, lfn.name);
-
- if (is_directory(direntries + i)) {
- if (begin_of_direntry(direntries + i) == 0) {
- DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
- goto fail;
- }
- cluster_count = check_directory_consistency(s,
- begin_of_direntry(direntries + i), path2);
- if (cluster_count == 0) {
- DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
- goto fail;
- }
- } else if (is_file(direntries + i)) {
- /* check file size with FAT */
- cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
- if (cluster_count !=
- (le32_to_cpu(direntries[i].size) + s->cluster_size
- - 1) / s->cluster_size) {
- DLOG(fprintf(stderr, "Cluster count mismatch\n"));
- goto fail;
- }
- } else
- assert(0); /* cluster_count = 0; */
-
- ret += cluster_count;
- }
-
- cluster_num = modified_fat_get(s, cluster_num);
- } while(!fat_eof(s, cluster_num));
-
- free(cluster);
- return ret;
-}
-
-/* returns 1 on success */
-static int is_consistent(BDRVVVFATState* s)
-{
- int i, check;
- int used_clusters_count = 0;
-
-DLOG(checkpoint());
- /*
- * - get modified FAT
- * - compare the two FATs (TODO)
- * - get buffer for marking used clusters
- * - recurse direntries from root (using bs->bdrv_read to make
- * sure to get the new data)
- * - check that the FAT agrees with the size
- * - count the number of clusters occupied by this directory and
- * its files
- * - check that the cumulative used cluster count agrees with the
- * FAT
- * - if all is fine, return number of used clusters
- */
- if (s->fat2 == NULL) {
- int size = 0x200 * s->sectors_per_fat;
- s->fat2 = malloc(size);
- memcpy(s->fat2, s->fat.pointer, size);
- }
- check = vvfat_read(s->bs,
- s->first_sectors_number, s->fat2, s->sectors_per_fat);
- if (check) {
- fprintf(stderr, "Could not copy fat\n");
- return 0;
- }
- assert (s->used_clusters);
- for (i = 0; i < sector2cluster(s, s->sector_count); i++)
- s->used_clusters[i] &= ~USED_ANY;
-
- clear_commits(s);
-
- /* mark every mapped file/directory as deleted.
- * (check_directory_consistency() will unmark those still present). */
- if (s->qcow)
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->first_mapping_index < 0)
- mapping->mode |= MODE_DELETED;
- }
-
- used_clusters_count = check_directory_consistency(s, 0, s->path);
- if (used_clusters_count <= 0) {
- DLOG(fprintf(stderr, "problem in directory\n"));
- return 0;
- }
-
- check = s->last_cluster_of_root_directory;
- for (i = check; i < sector2cluster(s, s->sector_count); i++) {
- if (modified_fat_get(s, i)) {
- if(!s->used_clusters[i]) {
- DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
- return 0;
- }
- check++;
- }
-
- if (s->used_clusters[i] == USED_ALLOCATED) {
- /* allocated, but not used... */
- DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
- return 0;
- }
- }
-
- if (check != used_clusters_count)
- return 0;
-
- return used_clusters_count;
-}
-
-static inline void adjust_mapping_indices(BDRVVVFATState* s,
- int offset, int adjust)
-{
- int i;
-
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
-
-#define ADJUST_MAPPING_INDEX(name) \
- if (mapping->name >= offset) \
- mapping->name += adjust
-
- ADJUST_MAPPING_INDEX(first_mapping_index);
- if (mapping->mode & MODE_DIRECTORY)
- ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
- }
-}
-
-/* insert or update mapping */
-static mapping_t* insert_mapping(BDRVVVFATState* s,
- uint32_t begin, uint32_t end)
-{
- /*
- * - find mapping where mapping->begin >= begin,
- * - if mapping->begin > begin: insert
- * - adjust all references to mappings!
- * - else: adjust
- * - replace name
- */
- int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
- mapping_t* mapping = NULL;
- mapping_t* first_mapping = array_get(&(s->mapping), 0);
-
- if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
- && mapping->begin < begin) {
- mapping->end = begin;
- index++;
- mapping = array_get(&(s->mapping), index);
- }
- if (index >= s->mapping.next || mapping->begin > begin) {
- mapping = array_insert(&(s->mapping), index, 1);
- mapping->path = NULL;
- adjust_mapping_indices(s, index, +1);
- }
-
- mapping->begin = begin;
- mapping->end = end;
-
-DLOG(mapping_t* next_mapping;
-assert(index + 1 >= s->mapping.next ||
-((next_mapping = array_get(&(s->mapping), index + 1)) &&
- next_mapping->begin >= end)));
-
- if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
- s->current_mapping = array_get(&(s->mapping),
- s->current_mapping - first_mapping);
-
- return mapping;
-}
-
-static int remove_mapping(BDRVVVFATState* s, int mapping_index)
-{
- mapping_t* mapping = array_get(&(s->mapping), mapping_index);
- mapping_t* first_mapping = array_get(&(s->mapping), 0);
-
- /* free mapping */
- if (mapping->first_mapping_index < 0)
- free(mapping->path);
-
- /* remove from s->mapping */
- array_remove(&(s->mapping), mapping_index);
-
- /* adjust all references to mappings */
- adjust_mapping_indices(s, mapping_index, -1);
-
- if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
- s->current_mapping = array_get(&(s->mapping),
- s->current_mapping - first_mapping);
-
- return 0;
-}
-
-static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
-{
- int i;
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->dir_index >= offset)
- mapping->dir_index += adjust;
- if ((mapping->mode & MODE_DIRECTORY) &&
- mapping->info.dir.first_dir_index >= offset)
- mapping->info.dir.first_dir_index += adjust;
- }
-}
-
-static direntry_t* insert_direntries(BDRVVVFATState* s,
- int dir_index, int count)
-{
- /*
- * make room in s->directory,
- * adjust_dirindices
- */
- direntry_t* result = array_insert(&(s->directory), dir_index, count);
- if (result == NULL)
- return NULL;
- adjust_dirindices(s, dir_index, count);
- return result;
-}
-
-static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
-{
- int ret = array_remove_slice(&(s->directory), dir_index, count);
- if (ret)
- return ret;
- adjust_dirindices(s, dir_index, -count);
- return 0;
-}
-
-/*
- * Adapt the mappings of the cluster chain starting at first cluster
- * (i.e. if a file starts at first_cluster, the chain is followed according
- * to the modified fat, and the corresponding entries in s->mapping are
- * adjusted)
- */
-static int commit_mappings(BDRVVVFATState* s,
- uint32_t first_cluster, int dir_index)
-{
- mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
- direntry_t* direntry = array_get(&(s->directory), dir_index);
- uint32_t cluster = first_cluster;
-
- vvfat_close_current_file(s);
-
- assert(mapping);
- assert(mapping->begin == first_cluster);
- mapping->first_mapping_index = -1;
- mapping->dir_index = dir_index;
- mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
- MODE_DIRECTORY : MODE_NORMAL;
-
- while (!fat_eof(s, cluster)) {
- uint32_t c, c1;
-
- for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
- c = c1, c1 = modified_fat_get(s, c1));
-
- c++;
- if (c > mapping->end) {
- int index = array_index(&(s->mapping), mapping);
- int i, max_i = s->mapping.next - index;
- for (i = 1; i < max_i && mapping[i].begin < c; i++);
- while (--i > 0)
- remove_mapping(s, index + 1);
- }
- assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
- || mapping[1].begin >= c);
- mapping->end = c;
-
- if (!fat_eof(s, c1)) {
- int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
- mapping_t* next_mapping = i >= s->mapping.next ? NULL :
- array_get(&(s->mapping), i);
-
- if (next_mapping == NULL || next_mapping->begin > c1) {
- int i1 = array_index(&(s->mapping), mapping);
-
- next_mapping = insert_mapping(s, c1, c1+1);
-
- if (c1 < c)
- i1++;
- mapping = array_get(&(s->mapping), i1);
- }
-
- next_mapping->dir_index = mapping->dir_index;
- next_mapping->first_mapping_index =
- mapping->first_mapping_index < 0 ?
- array_index(&(s->mapping), mapping) :
- mapping->first_mapping_index;
- next_mapping->path = mapping->path;
- next_mapping->mode = mapping->mode;
- next_mapping->read_only = mapping->read_only;
- if (mapping->mode & MODE_DIRECTORY) {
- next_mapping->info.dir.parent_mapping_index =
- mapping->info.dir.parent_mapping_index;
- next_mapping->info.dir.first_dir_index =
- mapping->info.dir.first_dir_index +
- 0x10 * s->sectors_per_cluster *
- (mapping->end - mapping->begin);
- } else
- next_mapping->info.file.offset = mapping->info.file.offset +
- mapping->end - mapping->begin;
-
- mapping = next_mapping;
- }
-
- cluster = c1;
- }
-
- return 0;
-}
-
-static int commit_direntries(BDRVVVFATState* s,
- int dir_index, int parent_mapping_index)
-{
- direntry_t* direntry = array_get(&(s->directory), dir_index);
- uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
- mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
-
- int factor = 0x10 * s->sectors_per_cluster;
- int old_cluster_count, new_cluster_count;
- int current_dir_index = mapping->info.dir.first_dir_index;
- int first_dir_index = current_dir_index;
- int ret, i;
- uint32_t c;
-
-DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));
-
- assert(direntry);
- assert(mapping);
- assert(mapping->begin == first_cluster);
- assert(mapping->info.dir.first_dir_index < s->directory.next);
- assert(mapping->mode & MODE_DIRECTORY);
- assert(dir_index == 0 || is_directory(direntry));
-
- mapping->info.dir.parent_mapping_index = parent_mapping_index;
-
- if (first_cluster == 0) {
- old_cluster_count = new_cluster_count =
- s->last_cluster_of_root_directory;
- } else {
- for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
- c = fat_get(s, c))
- old_cluster_count++;
-
- for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
- c = modified_fat_get(s, c))
- new_cluster_count++;
- }
-
- if (new_cluster_count > old_cluster_count) {
- if (insert_direntries(s,
- current_dir_index + factor * old_cluster_count,
- factor * (new_cluster_count - old_cluster_count)) == NULL)
- return -1;
- } else if (new_cluster_count < old_cluster_count)
- remove_direntries(s,
- current_dir_index + factor * new_cluster_count,
- factor * (old_cluster_count - new_cluster_count));
-
- for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
- void* direntry = array_get(&(s->directory), current_dir_index);
- int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
- s->sectors_per_cluster);
- if (ret)
- return ret;
- assert(!strncmp(s->directory.pointer, "QEMU", 4));
- current_dir_index += factor;
- }
-
- ret = commit_mappings(s, first_cluster, dir_index);
- if (ret)
- return ret;
-
- /* recurse */
- for (i = 0; i < factor * new_cluster_count; i++) {
- direntry = array_get(&(s->directory), first_dir_index + i);
- if (is_directory(direntry) && !is_dot(direntry)) {
- mapping = find_mapping_for_cluster(s, first_cluster);
- assert(mapping->mode & MODE_DIRECTORY);
- ret = commit_direntries(s, first_dir_index + i,
- array_index(&(s->mapping), mapping));
- if (ret)
- return ret;
- }
- }
-
- return 0;
-}
-
-/* commit one file (adjust contents, adjust mapping),
- return first_mapping_index */
-static int commit_one_file(BDRVVVFATState* s,
- int dir_index, uint32_t offset)
-{
- direntry_t* direntry = array_get(&(s->directory), dir_index);
- uint32_t c = begin_of_direntry(direntry);
- uint32_t first_cluster = c;
- mapping_t* mapping = find_mapping_for_cluster(s, c);
- uint32_t size = filesize_of_direntry(direntry);
- char* cluster = malloc(s->cluster_size);
- uint32_t i;
- int fd = 0;
-
- assert(offset < size);
- assert((offset % s->cluster_size) == 0);
-
- for (i = s->cluster_size; i < offset; i += s->cluster_size)
- c = modified_fat_get(s, c);
-
- fd = open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
- if (fd < 0) {
- fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
- strerror(errno), errno);
- return fd;
- }
- if (offset > 0)
- if (lseek(fd, offset, SEEK_SET) != offset)
- return -3;
-
- while (offset < size) {
- uint32_t c1;
- int rest_size = (size - offset > s->cluster_size ?
- s->cluster_size : size - offset);
- int ret;
-
- c1 = modified_fat_get(s, c);
-
- assert((size - offset == 0 && fat_eof(s, c)) ||
- (size > offset && c >=2 && !fat_eof(s, c)));
- assert(size >= 0);
-
- ret = vvfat_read(s->bs, cluster2sector(s, c),
- cluster, (rest_size + 0x1ff) / 0x200);
-
- if (ret < 0)
- return ret;
-
- if (write(fd, cluster, rest_size) < 0)
- return -2;
-
- offset += rest_size;
- c = c1;
- }
-
- ftruncate(fd, size);
- close(fd);
-
- return commit_mappings(s, first_cluster, dir_index);
-}
-
-#ifdef DEBUG
-/* test, if all mappings point to valid direntries */
-static void check1(BDRVVVFATState* s)
-{
- int i;
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->mode & MODE_DELETED) {
- fprintf(stderr, "deleted\n");
- continue;
- }
- assert(mapping->dir_index >= 0);
- assert(mapping->dir_index < s->directory.next);
- direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
- assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
- if (mapping->mode & MODE_DIRECTORY) {
- assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
- assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
- }
- }
-}
-
-/* test, if all direntries have mappings */
-static void check2(BDRVVVFATState* s)
-{
- int i;
- int first_mapping = -1;
-
- for (i = 0; i < s->directory.next; i++) {
- direntry_t* direntry = array_get(&(s->directory), i);
-
- if (is_short_name(direntry) && begin_of_direntry(direntry)) {
- mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
- assert(mapping);
- assert(mapping->dir_index == i || is_dot(direntry));
- assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
- }
-
- if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
- /* cluster start */
- int j, count = 0;
-
- for (j = 0; j < s->mapping.next; j++) {
- mapping_t* mapping = array_get(&(s->mapping), j);
- if (mapping->mode & MODE_DELETED)
- continue;
- if (mapping->mode & MODE_DIRECTORY) {
- if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
- assert(++count == 1);
- if (mapping->first_mapping_index == -1)
- first_mapping = array_index(&(s->mapping), mapping);
- else
- assert(first_mapping == mapping->first_mapping_index);
- if (mapping->info.dir.parent_mapping_index < 0)
- assert(j == 0);
- else {
- mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
- assert(parent->mode & MODE_DIRECTORY);
- assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
- }
- }
- }
- }
- if (count == 0)
- first_mapping = -1;
- }
- }
-}
-#endif
-
-static int handle_renames_and_mkdirs(BDRVVVFATState* s)
-{
- int i;
-
-#ifdef DEBUG
- fprintf(stderr, "handle_renames\n");
- for (i = 0; i < s->commits.next; i++) {
- commit_t* commit = array_get(&(s->commits), i);
- fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
- }
-#endif
-
- for (i = 0; i < s->commits.next;) {
- commit_t* commit = array_get(&(s->commits), i);
- if (commit->action == ACTION_RENAME) {
- mapping_t* mapping = find_mapping_for_cluster(s,
- commit->param.rename.cluster);
- char* old_path = mapping->path;
-
- assert(commit->path);
- mapping->path = commit->path;
- if (rename(old_path, mapping->path))
- return -2;
-
- if (mapping->mode & MODE_DIRECTORY) {
- int l1 = strlen(mapping->path);
- int l2 = strlen(old_path);
- int diff = l1 - l2;
- direntry_t* direntry = array_get(&(s->directory),
- mapping->info.dir.first_dir_index);
- uint32_t c = mapping->begin;
- int i = 0;
-
- /* recurse */
- while (!fat_eof(s, c)) {
- do {
- direntry_t* d = direntry + i;
-
- if (is_file(d) || (is_directory(d) && !is_dot(d))) {
- mapping_t* m = find_mapping_for_cluster(s,
- begin_of_direntry(d));
- int l = strlen(m->path);
- char* new_path = malloc(l + diff + 1);
-
- assert(!strncmp(m->path, mapping->path, l2));
-
- strcpy(new_path, mapping->path);
- strcpy(new_path + l1, m->path + l2);
-
- schedule_rename(s, m->begin, new_path);
- }
- i++;
- } while((i % (0x10 * s->sectors_per_cluster)) != 0);
- c = fat_get(s, c);
- }
- }
-
- free(old_path);
- array_remove(&(s->commits), i);
- continue;
- } else if (commit->action == ACTION_MKDIR) {
- mapping_t* mapping;
- int j, parent_path_len;
-
-#ifdef __MINGW32__
- if (mkdir(commit->path))
- return -5;
-#else
- if (mkdir(commit->path, 0755))
- return -5;
-#endif
-
- mapping = insert_mapping(s, commit->param.mkdir.cluster,
- commit->param.mkdir.cluster + 1);
- if (mapping == NULL)
- return -6;
-
- mapping->mode = MODE_DIRECTORY;
- mapping->read_only = 0;
- mapping->path = commit->path;
- j = s->directory.next;
- assert(j);
- insert_direntries(s, s->directory.next,
- 0x10 * s->sectors_per_cluster);
- mapping->info.dir.first_dir_index = j;
-
- parent_path_len = strlen(commit->path)
- - strlen(get_basename(commit->path)) - 1;
- for (j = 0; j < s->mapping.next; j++) {
- mapping_t* m = array_get(&(s->mapping), j);
- if (m->first_mapping_index < 0 && m != mapping &&
- !strncmp(m->path, mapping->path, parent_path_len) &&
- strlen(m->path) == parent_path_len)
- break;
- }
- assert(j < s->mapping.next);
- mapping->info.dir.parent_mapping_index = j;
-
- array_remove(&(s->commits), i);
- continue;
- }
-
- i++;
- }
- return 0;
-}
-
-/*
- * TODO: make sure that the short name is not matching *another* file
- */
-static int handle_commits(BDRVVVFATState* s)
-{
- int i, fail = 0;
-
- vvfat_close_current_file(s);
-
- for (i = 0; !fail && i < s->commits.next; i++) {
- commit_t* commit = array_get(&(s->commits), i);
- switch(commit->action) {
- case ACTION_RENAME: case ACTION_MKDIR:
- assert(0);
- fail = -2;
- break;
- case ACTION_WRITEOUT: {
- direntry_t* entry = array_get(&(s->directory),
- commit->param.writeout.dir_index);
- uint32_t begin = begin_of_direntry(entry);
- mapping_t* mapping = find_mapping_for_cluster(s, begin);
-
- assert(mapping);
- assert(mapping->begin == begin);
- assert(commit->path == NULL);
-
- if (commit_one_file(s, commit->param.writeout.dir_index,
- commit->param.writeout.modified_offset))
- fail = -3;
-
- break;
- }
- case ACTION_NEW_FILE: {
- int begin = commit->param.new_file.first_cluster;
- mapping_t* mapping = find_mapping_for_cluster(s, begin);
- direntry_t* entry;
- int i;
-
- /* find direntry */
- for (i = 0; i < s->directory.next; i++) {
- entry = array_get(&(s->directory), i);
- if (is_file(entry) && begin_of_direntry(entry) == begin)
- break;
- }
-
- if (i >= s->directory.next) {
- fail = -6;
- continue;
- }
-
- /* make sure there exists an initial mapping */
- if (mapping && mapping->begin != begin) {
- mapping->end = begin;
- mapping = NULL;
- }
- if (mapping == NULL) {
- mapping = insert_mapping(s, begin, begin+1);
- }
- /* most members will be fixed in commit_mappings() */
- assert(commit->path);
- mapping->path = commit->path;
- mapping->read_only = 0;
- mapping->mode = MODE_NORMAL;
- mapping->info.file.offset = 0;
-
- if (commit_one_file(s, i, 0))
- fail = -7;
-
- break;
- }
- default:
- assert(0);
- }
- }
- if (i > 0 && array_remove_slice(&(s->commits), 0, i))
- return -1;
- return fail;
-}
-
-static int handle_deletes(BDRVVVFATState* s)
-{
- int i, deferred = 1, deleted = 1;
-
- /* delete files corresponding to mappings marked as deleted */
- /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
- while (deferred && deleted) {
- deferred = 0;
- deleted = 0;
-
- for (i = 1; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->mode & MODE_DELETED) {
- direntry_t* entry = array_get(&(s->directory),
- mapping->dir_index);
-
- if (is_free(entry)) {
- /* remove file/directory */
- if (mapping->mode & MODE_DIRECTORY) {
- int j, next_dir_index = s->directory.next,
- first_dir_index = mapping->info.dir.first_dir_index;
-
- if (rmdir(mapping->path) < 0) {
- if (errno == ENOTEMPTY) {
- deferred++;
- continue;
- } else
- return -5;
- }
-
- for (j = 1; j < s->mapping.next; j++) {
- mapping_t* m = array_get(&(s->mapping), j);
- if (m->mode & MODE_DIRECTORY &&
- m->info.dir.first_dir_index >
- first_dir_index &&
- m->info.dir.first_dir_index <
- next_dir_index)
- next_dir_index =
- m->info.dir.first_dir_index;
- }
- remove_direntries(s, first_dir_index,
- next_dir_index - first_dir_index);
-
- deleted++;
- }
- } else {
- if (unlink(mapping->path))
- return -4;
- deleted++;
- }
- DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
- remove_mapping(s, i);
- }
- }
- }
-
- return 0;
-}
-
-/*
- * synchronize mapping with new state:
- *
- * - copy FAT (with bdrv_read)
- * - mark all filenames corresponding to mappings as deleted
- * - recurse direntries from root (using bs->bdrv_read)
- * - delete files corresponding to mappings marked as deleted
- */
-static int do_commit(BDRVVVFATState* s)
-{
- int ret = 0;
-
- /* the real meat are the commits. Nothing to do? Move along! */
- if (s->commits.next == 0)
- return 0;
-
- vvfat_close_current_file(s);
-
- ret = handle_renames_and_mkdirs(s);
- if (ret) {
- fprintf(stderr, "Error handling renames (%d)\n", ret);
- assert(0);
- return ret;
- }
-
- /* copy FAT (with bdrv_read) */
- memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
-
- /* recurse direntries from root (using bs->bdrv_read) */
- ret = commit_direntries(s, 0, -1);
- if (ret) {
- fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
- assert(0);
- return ret;
- }
-
- ret = handle_commits(s);
- if (ret) {
- fprintf(stderr, "Error handling commits (%d)\n", ret);
- assert(0);
- return ret;
- }
-
- ret = handle_deletes(s);
- if (ret) {
- fprintf(stderr, "Error deleting\n");
- assert(0);
- return ret;
- }
-
- s->qcow->drv->bdrv_make_empty(s->qcow);
-
- memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
-
-DLOG(checkpoint());
- return 0;
-}
-
-static int try_commit(BDRVVVFATState* s)
-{
- vvfat_close_current_file(s);
-DLOG(checkpoint());
- if(!is_consistent(s))
- return -1;
- return do_commit(s);
-}
-
-static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVVVFATState *s = bs->opaque;
- int i, ret;
-
-DLOG(checkpoint());
-
- vvfat_close_current_file(s);
-
- /*
- * Some sanity checks:
- * - do not allow writing to the boot sector
- * - do not allow to write non-ASCII filenames
- */
-
- if (sector_num < s->first_sectors_number)
- return -1;
-
- for (i = sector2cluster(s, sector_num);
- i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
- mapping_t* mapping = find_mapping_for_cluster(s, i);
- if (mapping) {
- if (mapping->read_only) {
- fprintf(stderr, "Tried to write to write-protected file %s\n",
- mapping->path);
- return -1;
- }
-
- if (mapping->mode & MODE_DIRECTORY) {
- int begin = cluster2sector(s, i);
- int end = begin + s->sectors_per_cluster, k;
- int dir_index;
- const direntry_t* direntries;
- long_file_name lfn;
-
- lfn_init(&lfn);
-
- if (begin < sector_num)
- begin = sector_num;
- if (end > sector_num + nb_sectors)
- end = sector_num + nb_sectors;
- dir_index = mapping->dir_index +
- 0x10 * (begin - mapping->begin * s->sectors_per_cluster);
- direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
-
- for (k = 0; k < (end - begin) * 0x10; k++) {
- /* do not allow non-ASCII filenames */
- if (parse_long_name(&lfn, direntries + k) < 0) {
- fprintf(stderr, "Warning: non-ASCII filename\n");
- return -1;
- }
- /* no access to the direntry of a read-only file */
- else if (is_short_name(direntries+k) &&
- (direntries[k].attributes & 1)) {
- if (memcmp(direntries + k,
- array_get(&(s->directory), dir_index + k),
- sizeof(direntry_t))) {
- fprintf(stderr, "Warning: tried to write to write-protected file\n");
- return -1;
- }
- }
- }
- }
- i = mapping->end;
- } else
- i++;
- }
-
- /*
- * Use qcow backend. Commit later.
- */
-DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
- ret = s->qcow->drv->bdrv_write(s->qcow, sector_num, buf, nb_sectors);
- if (ret < 0) {
- fprintf(stderr, "Error writing to qcow backend\n");
- return ret;
- }
-
- for (i = sector2cluster(s, sector_num);
- i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
- if (i >= 0)
- s->used_clusters[i] |= USED_ALLOCATED;
-
-DLOG(checkpoint());
- /* TODO: add timeout */
- try_commit(s);
-
-DLOG(checkpoint());
- return 0;
-}
-
-static int vvfat_is_allocated(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, int* n)
-{
- BDRVVVFATState* s = bs->opaque;
- *n = s->sector_count - sector_num;
- if (*n > nb_sectors)
- *n = nb_sectors;
- else if (*n < 0)
- return 0;
- return 1;
-}
-
-static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
- const uint8_t* buffer, int nb_sectors) {
- BDRVVVFATState* s = bs->opaque;
- return try_commit(s);
-}
-
-static void write_target_close(BlockDriverState *bs) {
- BDRVVVFATState* s = bs->opaque;
- bdrv_delete(s->qcow);
- free(s->qcow_filename);
-}
-
-static BlockDriver vvfat_write_target = {
- "vvfat_write_target", 0, NULL, NULL, NULL,
- write_target_commit,
- write_target_close,
- NULL, NULL, NULL
-};
-
-static int enable_write_target(BDRVVVFATState *s)
-{
- int size = sector2cluster(s, s->sector_count);
- s->used_clusters = calloc(size, 1);
-
- array_init(&(s->commits), sizeof(commit_t));
-
- s->qcow_filename = malloc(1024);
- get_tmp_filename(s->qcow_filename, 1024);
- if (bdrv_create(&bdrv_qcow,
- s->qcow_filename, s->sector_count, "fat:", 0) < 0)
- return -1;
- s->qcow = bdrv_new("");
- if (s->qcow == NULL || bdrv_open(s->qcow, s->qcow_filename, 0) < 0)
- return -1;
-
-#ifndef _WIN32
- unlink(s->qcow_filename);
-#endif
-
- s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
- s->bs->backing_hd->drv = &vvfat_write_target;
- s->bs->backing_hd->opaque = s;
-
- return 0;
-}
-
-static void vvfat_close(BlockDriverState *bs)
-{
- BDRVVVFATState *s = bs->opaque;
-
- vvfat_close_current_file(s);
- array_free(&(s->fat));
- array_free(&(s->directory));
- array_free(&(s->mapping));
- if(s->cluster_buffer)
- free(s->cluster_buffer);
-}
-
-BlockDriver bdrv_vvfat = {
- "vvfat",
- sizeof(BDRVVVFATState),
- NULL, /* no probe for protocols */
- vvfat_open,
- vvfat_read,
- vvfat_write,
- vvfat_close,
- NULL, /* ??? Not sure if we can do any meaningful flushing. */
- NULL,
- vvfat_is_allocated,
- .protocol_name = "fat",
-};
-
-#ifdef DEBUG
-static void checkpoint() {
- assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
- check1(vvv);
- check2(vvv);
- assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
-#if 0
- if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
- fprintf(stderr, "Nonono!\n");
- mapping_t* mapping;
- direntry_t* direntry;
- assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
- assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
- if (vvv->mapping.next<47)
- return;
- assert((mapping = array_get(&(vvv->mapping), 47)));
- assert(mapping->dir_index < vvv->directory.next);
- direntry = array_get(&(vvv->directory), mapping->dir_index);
- assert(!memcmp(direntry->name, "USB H ", 11) || direntry->name[0]==0);
-#endif
- return;
- /* avoid compiler warnings: */
- hexdump(NULL, 100);
- remove_mapping(vvv, NULL);
- print_mapping(NULL);
- print_direntry(NULL);
-}
-#endif
-
diff --git a/tools/ioemu/block.c b/tools/ioemu/block.c
deleted file mode 100644
index e61ba2637e..0000000000
--- a/tools/ioemu/block.c
+++ /dev/null
@@ -1,1437 +0,0 @@
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#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
-
-#define SECTOR_BITS 9
-#define SECTOR_SIZE (1 << SECTOR_BITS)
-
-typedef struct BlockDriverAIOCBSync {
- BlockDriverAIOCB common;
- QEMUBH *bh;
- int ret;
-} BlockDriverAIOCBSync;
-
-static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
-static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque);
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-
-static BlockDriverState *bdrv_first;
-static BlockDriver *first_drv;
-
-int path_is_absolute(const char *path)
-{
- const char *p;
-#ifdef _WIN32
- /* specific case for names like: "\\.\d:" */
- if (*path == '/' || *path == '\\')
- return 1;
-#endif
- p = strchr(path, ':');
- if (p)
- p++;
- else
- p = path;
-#ifdef _WIN32
- return (*p == '/' || *p == '\\');
-#else
- return (*p == '/');
-#endif
-}
-
-/* if filename is absolute, just copy it to dest. Otherwise, build a
- path to it by considering it is relative to base_path. URL are
- supported. */
-void path_combine(char *dest, int dest_size,
- const char *base_path,
- const char *filename)
-{
- const char *p, *p1;
- int len;
-
- if (dest_size <= 0)
- return;
- if (path_is_absolute(filename)) {
- pstrcpy(dest, dest_size, filename);
- } else {
- p = strchr(base_path, ':');
- if (p)
- p++;
- else
- p = base_path;
- p1 = strrchr(base_path, '/');
-#ifdef _WIN32
- {
- const char *p2;
- p2 = strrchr(base_path, '\\');
- if (!p1 || p2 > p1)
- p1 = p2;
- }
-#endif
- if (p1)
- p1++;
- else
- p1 = base_path;
- if (p1 > p)
- p = p1;
- len = p - base_path;
- if (len > dest_size - 1)
- len = dest_size - 1;
- memcpy(dest, base_path, len);
- dest[len] = '\0';
- pstrcat(dest, dest_size, filename);
- }
-}
-
-static int bdrv_rw_badreq_sectors(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors)
-{
- return (
- nb_sectors < 0 ||
- nb_sectors > bs->total_sectors ||
- sector_num > bs->total_sectors - nb_sectors
- ) && !bs->extendable;
-}
-
-static int bdrv_rw_badreq_bytes(BlockDriverState *bs,
- int64_t offset, int count)
-{
- int64_t size = bs->total_sectors << SECTOR_BITS;
- return (
- count < 0 ||
- count > size ||
- offset > size - count
- ) && !bs->extendable;
-
-}
-
-void bdrv_register(BlockDriver *bdrv)
-{
- if (!bdrv->bdrv_aio_read) {
- /* add AIO emulation layer */
- bdrv->bdrv_aio_read = bdrv_aio_read_em;
- bdrv->bdrv_aio_write = bdrv_aio_write_em;
- bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
- bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
- } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
- /* add synchronous IO emulation layer */
- bdrv->bdrv_read = bdrv_read_em;
- bdrv->bdrv_write = bdrv_write_em;
- }
- if (!bdrv->bdrv_aio_flush)
- bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
- bdrv->next = first_drv;
- first_drv = bdrv;
-}
-
-/* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new(const char *device_name)
-{
- BlockDriverState **pbs, *bs;
-
- bs = qemu_mallocz(sizeof(BlockDriverState));
- if(!bs)
- return NULL;
- pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
- if (device_name[0] != '\0') {
- /* insert at the end */
- pbs = &bdrv_first;
- while (*pbs != NULL)
- pbs = &(*pbs)->next;
- *pbs = bs;
- }
- return bs;
-}
-
-BlockDriver *bdrv_find_format(const char *format_name)
-{
- BlockDriver *drv1;
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (!strcmp(drv1->format_name, format_name))
- return drv1;
- }
- return NULL;
-}
-
-int bdrv_create(BlockDriver *drv,
- const char *filename, int64_t size_in_sectors,
- const char *backing_file, int flags)
-{
- if (!drv->bdrv_create)
- return -ENOTSUP;
- return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
-}
-
-#ifdef _WIN32
-void get_tmp_filename(char *filename, int size)
-{
- char temp_dir[MAX_PATH];
-
- GetTempPath(MAX_PATH, temp_dir);
- GetTempFileName(temp_dir, "qem", 0, filename);
-}
-#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
-
-#ifdef _WIN32
-static int is_windows_drive_prefix(const char *filename)
-{
- return (((filename[0] >= 'a' && filename[0] <= 'z') ||
- (filename[0] >= 'A' && filename[0] <= 'Z')) &&
- filename[1] == ':');
-}
-
-static int is_windows_drive(const char *filename)
-{
- if (is_windows_drive_prefix(filename) &&
- filename[2] == '\0')
- return 1;
- if (strstart(filename, "\\\\.\\", NULL) ||
- strstart(filename, "//./", NULL))
- return 1;
- return 0;
-}
-#endif
-
-static int bdrv_invalid_protocol_open(BlockDriverState *bs,
- const char *filename, int flags) {
- return -ENOENT;
-}
-
-static BlockDriver bdrv_invalid_protocol = {
- "invalid_protocol",
- .bdrv_open = bdrv_invalid_protocol_open,
-};
-
-static BlockDriver *find_protocol(const char *filename)
-{
- /* Return values:
- * &bdrv_xxx
- * filename specifies protocol xxx
- * caller should use that
- * NULL filename does not specify any protocol
- * caller may apply their own default
- * &bdrv_invalid_protocol filename speciies an unknown protocol
- * caller should return -ENOENT; or may just try to open with
- * that bdrv, which always fails that way.
- */
- BlockDriver *drv1;
- char protocol[128];
- int len;
- const char *p;
-
-#ifdef _WIN32
- if (is_windows_drive(filename) ||
- is_windows_drive_prefix(filename))
- return &bdrv_raw;
-#endif
- p = strchr(filename, ':');
- if (!p)
- return NULL;
- len = p - filename;
- if (len > sizeof(protocol) - 1)
- len = sizeof(protocol) - 1;
- memcpy(protocol, filename, len);
- protocol[len] = '\0';
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (drv1->protocol_name &&
- !strcmp(drv1->protocol_name, protocol))
- return drv1;
- }
- return &bdrv_invalid_protocol;
-}
-
-/* XXX: force raw format if block or character device ? It would
- simplify the BSD case */
-static BlockDriver *find_image_format(const char *filename)
-{
- int ret, score, score_max;
- BlockDriver *drv1, *drv;
- uint8_t buf[2048];
- BlockDriverState *bs;
-
- /* detect host devices. By convention, /dev/cdrom[N] is always
- recognized as a host CDROM */
- if (strstart(filename, "/dev/cdrom", NULL))
- return &bdrv_host_device;
-#ifdef _WIN32
- if (is_windows_drive(filename))
- return &bdrv_host_device;
-#else
- {
- struct stat st;
- if (stat(filename, &st) >= 0 &&
- (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
- return &bdrv_host_device;
- }
- }
-#endif
-
- drv = find_protocol(filename);
- /* no need to test disk image format if the filename told us */
- if (drv != NULL)
- return drv;
-
- ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
- if (ret < 0)
- return NULL;
- ret = bdrv_pread(bs, 0, buf, sizeof(buf));
- bdrv_delete(bs);
- if (ret < 0) {
- return NULL;
- }
-
- score_max = 0;
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (drv1->bdrv_probe) {
- score = drv1->bdrv_probe(buf, ret, filename);
- if (score > score_max) {
- score_max = score;
- drv = drv1;
- }
- }
- }
- return drv;
-}
-
-int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
-{
- BlockDriverState *bs;
- int ret;
-
- bs = bdrv_new("");
- if (!bs)
- return -ENOMEM;
- ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
- if (ret < 0) {
- bdrv_delete(bs);
- return ret;
- }
- *pbs = bs;
- return 0;
-}
-
-int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
-{
- return bdrv_open2(bs, filename, flags, NULL);
-}
-
-int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
- BlockDriver *drv)
-{
- int ret, open_flags;
- char tmp_filename[PATH_MAX];
- char backing_filename[PATH_MAX];
-
- bs->read_only = 0;
- bs->is_temporary = 0;
- bs->encrypted = 0;
-
- if (flags & BDRV_O_EXTENDABLE)
- bs->extendable = 1;
-
- if (flags & BDRV_O_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 -ENOMEM;
- }
- if (bdrv_open(bs1, filename, 0) < 0) {
- bdrv_delete(bs1);
- return -1;
- }
- total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
- bdrv_delete(bs1);
-
- get_tmp_filename(tmp_filename, sizeof(tmp_filename));
- realpath(filename, backing_filename);
- if (bdrv_create(&bdrv_qcow2, tmp_filename,
- total_size, backing_filename, 0) < 0) {
- return -1;
- }
- filename = tmp_filename;
- bs->is_temporary = 1;
- }
-
- pstrcpy(bs->filename, sizeof(bs->filename), filename);
- if (flags & BDRV_O_FILE) {
- drv = find_protocol(filename);
- if (!drv)
- drv = &bdrv_raw;
- } else {
- if (!drv) {
- drv = find_image_format(filename);
- if (!drv)
- return -1;
- }
- }
- bs->drv = drv;
- bs->opaque = qemu_mallocz(drv->instance_size);
- bs->total_sectors = 0; /* driver will set if it does not do getlength */
- if (bs->opaque == NULL && drv->instance_size > 0)
- return -1;
- /* Note: for compatibility, we open disk image files as RDWR, and
- RDONLY as fallback */
- if (!(flags & BDRV_O_FILE))
- open_flags = BDRV_O_RDWR;
- else
- open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
- ret = drv->bdrv_open(bs, filename, open_flags);
- if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
- ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
- bs->read_only = 1;
- }
- if (ret < 0) {
- qemu_free(bs->opaque);
- bs->opaque = NULL;
- bs->drv = NULL;
- return ret;
- }
- if (drv->bdrv_getlength) {
- bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
- }
-#ifndef _WIN32
- if (bs->is_temporary) {
- unlink(filename);
- }
-#endif
- if (bs->backing_file[0] != '\0') {
- /* if there is a backing file, use it */
- bs->backing_hd = bdrv_new("");
- if (!bs->backing_hd) {
- fail:
- bdrv_close(bs);
- return -ENOMEM;
- }
- path_combine(backing_filename, sizeof(backing_filename),
- filename, bs->backing_file);
- if (bdrv_open2(bs->backing_hd, backing_filename, 0, &bdrv_raw) < 0)
- goto fail;
- }
-
- /* call the change callback */
- bs->media_changed = 1;
- if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
-
- return 0;
-}
-
-void bdrv_close(BlockDriverState *bs)
-{
- if (bs->drv) {
- if (bs->backing_hd)
- bdrv_delete(bs->backing_hd);
- bs->drv->bdrv_close(bs);
- qemu_free(bs->opaque);
-#ifdef _WIN32
- if (bs->is_temporary) {
- unlink(bs->filename);
- }
-#endif
- bs->opaque = NULL;
- bs->drv = NULL;
-
- /* call the change callback */
- bs->total_sectors = 0;
- bs->media_changed = 1;
- if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
- }
-}
-
-void bdrv_delete(BlockDriverState *bs)
-{
- /* XXX: remove the driver list */
- bdrv_close(bs);
- qemu_free(bs);
-}
-
-/* commit COW file into the raw image */
-int bdrv_commit(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- int64_t i, total_sectors;
- int n, j;
- unsigned char sector[512];
-
- if (!drv)
- return -ENOMEDIUM;
-
- if (bs->read_only) {
- return -EACCES;
- }
-
- if (!bs->backing_hd) {
- return -ENOTSUP;
- }
-
- total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
- for (i = 0; i < total_sectors;) {
- if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
- for(j = 0; j < n; j++) {
- if (bdrv_read(bs, i, sector, 1) != 0) {
- return -EIO;
- }
-
- if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
- return -EIO;
- }
- i++;
- }
- } else {
- i += n;
- }
- }
-
- if (drv->bdrv_make_empty)
- return drv->bdrv_make_empty(bs);
-
- return 0;
-}
-
-/* return < 0 if error. See bdrv_write() for the return codes */
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return -ENOMEDIUM;
-
- if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
- return -EDOM;
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(buf, bs->boot_sector_data, 512);
- sector_num++;
- nb_sectors--;
- buf += 512;
- if (nb_sectors == 0)
- return 0;
- }
- if (drv->bdrv_pread) {
- int ret, len;
- len = nb_sectors * 512;
- ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EINVAL;
- else
- return 0;
- } else {
- return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
- }
-}
-
-/* Return < 0 if error. Important errors are:
- -EIO generic I/O error (may happen for all errors)
- -ENOMEDIUM No media inserted.
- -EINVAL Invalid sector number or nb_sectors
- -EACCES Trying to write a read-only device
-*/
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
- if (!bs->drv)
- return -ENOMEDIUM;
- if (bs->read_only)
- return -EACCES;
- if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
- return -EDOM;
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(bs->boot_sector_data, buf, 512);
- }
- if (drv->bdrv_pwrite) {
- int ret, len;
- len = nb_sectors * 512;
- ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EIO;
- else
- return 0;
- } else {
- return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
- }
-}
-
-static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count1)
-{
- uint8_t tmp_buf[SECTOR_SIZE];
- int len, nb_sectors, count;
- int64_t sector_num;
-
- count = count1;
- /* first read to align to sector start */
- len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
- if (len > count)
- len = count;
- sector_num = offset >> SECTOR_BITS;
- if (len > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
- count -= len;
- if (count == 0)
- return count1;
- sector_num++;
- buf += len;
- }
-
- /* read the sectors "in place" */
- nb_sectors = count >> SECTOR_BITS;
- if (nb_sectors > 0) {
- if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
- return -EIO;
- sector_num += nb_sectors;
- len = nb_sectors << SECTOR_BITS;
- buf += len;
- count -= len;
- }
-
- /* add data from the last sector */
- if (count > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(buf, tmp_buf, count);
- }
- return count1;
-}
-
-static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count1)
-{
- uint8_t tmp_buf[SECTOR_SIZE];
- int len, nb_sectors, count;
- int64_t sector_num;
-
- count = count1;
- /* first write to align to sector start */
- len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
- if (len > count)
- len = count;
- sector_num = offset >> SECTOR_BITS;
- if (len > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
- if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- count -= len;
- if (count == 0)
- return count1;
- sector_num++;
- buf += len;
- }
-
- /* write the sectors "in place" */
- nb_sectors = count >> SECTOR_BITS;
- if (nb_sectors > 0) {
- if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
- return -EIO;
- sector_num += nb_sectors;
- len = nb_sectors << SECTOR_BITS;
- buf += len;
- count -= len;
- }
-
- /* add data from the last sector */
- if (count > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(tmp_buf, buf, count);
- if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- }
- return count1;
-}
-
-/**
- * Read with byte offsets (needed only for file protocols)
- */
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
- void *buf1, int count1)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_pread)
- return bdrv_pread_em(bs, offset, buf1, count1);
- if (bdrv_rw_badreq_bytes(bs, offset, count1))
- return -EDOM;
- return drv->bdrv_pread(bs, offset, buf1, count1);
-}
-
-/**
- * Write with byte offsets (needed only for file protocols)
- */
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
- const void *buf1, int count1)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_pwrite)
- return bdrv_pwrite_em(bs, offset, buf1, count1);
- if (bdrv_rw_badreq_bytes(bs, offset, count1))
- return -EDOM;
- return drv->bdrv_pwrite(bs, offset, buf1, count1);
-}
-
-/**
- * Truncate file to 'offset' bytes (needed only for file protocols)
- */
-int bdrv_truncate(BlockDriverState *bs, int64_t offset)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_truncate)
- return -ENOTSUP;
- return drv->bdrv_truncate(bs, offset);
-}
-
-/**
- * Length of a file in bytes. Return < 0 if error or unknown.
- */
-int64_t bdrv_getlength(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_getlength) {
- /* legacy mode */
- return bs->total_sectors * SECTOR_SIZE;
- }
- return drv->bdrv_getlength(bs);
-}
-
-/* return 0 as number of sectors if no device present or error */
-void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
-{
- int64_t length;
- length = bdrv_getlength(bs);
- if (length < 0)
- length = 0;
- else
- length = length >> SECTOR_BITS;
- *nb_sectors_ptr = length;
-}
-
-/* force a given boot sector. */
-void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
-{
- bs->boot_sector_enabled = 1;
- if (size > 512)
- size = 512;
- memcpy(bs->boot_sector_data, data, size);
- memset(bs->boot_sector_data + size, 0, 512 - size);
-}
-
-void bdrv_set_geometry_hint(BlockDriverState *bs,
- int cyls, int heads, int secs)
-{
- bs->cyls = cyls;
- bs->heads = heads;
- bs->secs = secs;
-}
-
-void bdrv_set_type_hint(BlockDriverState *bs, int type)
-{
- bs->type = type;
- bs->removable = ((type == BDRV_TYPE_CDROM ||
- 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)
-{
- *pcyls = bs->cyls;
- *pheads = bs->heads;
- *psecs = bs->secs;
-}
-
-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)
-{
- return bs->removable;
-}
-
-int bdrv_is_read_only(BlockDriverState *bs)
-{
- return bs->read_only;
-}
-
-/* XXX: no longer used */
-void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque)
-{
- bs->change_cb = change_cb;
- bs->change_opaque = opaque;
-}
-
-int bdrv_is_encrypted(BlockDriverState *bs)
-{
- if (bs->backing_hd && bs->backing_hd->encrypted)
- return 1;
- return bs->encrypted;
-}
-
-int bdrv_set_key(BlockDriverState *bs, const char *key)
-{
- int ret;
- if (bs->backing_hd && bs->backing_hd->encrypted) {
- ret = bdrv_set_key(bs->backing_hd, key);
- if (ret < 0)
- return ret;
- if (!bs->encrypted)
- return 0;
- }
- if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
- return -1;
- return bs->drv->bdrv_set_key(bs, key);
-}
-
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
-{
- if (!bs->drv) {
- buf[0] = '\0';
- } else {
- pstrcpy(buf, buf_size, bs->drv->format_name);
- }
-}
-
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque)
-{
- BlockDriver *drv;
-
- for (drv = first_drv; drv != NULL; drv = drv->next) {
- it(opaque, drv->format_name);
- }
-}
-
-BlockDriverState *bdrv_find(const char *name)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- if (!strcmp(name, bs->device_name))
- return bs;
- }
- return NULL;
-}
-
-void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- it(opaque, bs->device_name);
- }
-}
-
-const char *bdrv_get_device_name(BlockDriverState *bs)
-{
- return bs->device_name;
-}
-
-int bdrv_flush(BlockDriverState *bs)
-{
- int ret = 0;
- if (bs->drv->bdrv_flush)
- ret = bs->drv->bdrv_flush(bs);
- if (!ret && bs->backing_hd)
- ret = bdrv_flush(bs->backing_hd);
- return ret;
-}
-
-void bdrv_info(void)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- term_printf("%s:", bs->device_name);
- term_printf(" type=");
- switch(bs->type) {
- case BDRV_TYPE_HD:
- term_printf("hd");
- break;
- case BDRV_TYPE_CDROM:
- term_printf("cdrom");
- break;
- case BDRV_TYPE_FLOPPY:
- term_printf("floppy");
- break;
- }
- term_printf(" removable=%d", bs->removable);
- if (bs->removable) {
- term_printf(" locked=%d", bs->locked);
- }
- if (bs->drv) {
- term_printf(" file=");
- term_print_filename(bs->filename);
- if (bs->backing_file[0] != '\0') {
- term_printf(" backing_file=");
- term_print_filename(bs->backing_file);
- }
- term_printf(" ro=%d", bs->read_only);
- term_printf(" drv=%s", bs->drv->format_name);
- if (bs->encrypted)
- term_printf(" encrypted");
- } else {
- term_printf(" [not inserted]");
- }
- term_printf("\n");
- }
-}
-
-void bdrv_get_backing_filename(BlockDriverState *bs,
- char *filename, int filename_size)
-{
- if (!bs->backing_hd) {
- pstrcpy(filename, filename_size, "");
- } else {
- pstrcpy(filename, filename_size, bs->backing_file);
- }
-}
-
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_write_compressed)
- return -ENOTSUP;
- if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
- return -EDOM;
- return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
-}
-
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_get_info)
- return -ENOTSUP;
- memset(bdi, 0, sizeof(*bdi));
- return drv->bdrv_get_info(bs, bdi);
-}
-
-/**************************************************************/
-/* handling of snapshots */
-
-int bdrv_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_create)
- return -ENOTSUP;
- return drv->bdrv_snapshot_create(bs, sn_info);
-}
-
-int bdrv_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_goto)
- return -ENOTSUP;
- return drv->bdrv_snapshot_goto(bs, snapshot_id);
-}
-
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_delete)
- return -ENOTSUP;
- return drv->bdrv_snapshot_delete(bs, snapshot_id);
-}
-
-int bdrv_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_list)
- return -ENOTSUP;
- return drv->bdrv_snapshot_list(bs, psn_info);
-}
-
-#define NB_SUFFIXES 4
-
-char *get_human_readable_size(char *buf, int buf_size, int64_t size)
-{
- static const char suffixes[NB_SUFFIXES] = "KMGT";
- int64_t base;
- int i;
-
- if (size <= 999) {
- snprintf(buf, buf_size, "%" PRId64, size);
- } else {
- base = 1024;
- for(i = 0; i < NB_SUFFIXES; i++) {
- if (size < (10 * base)) {
- snprintf(buf, buf_size, "%0.1f%c",
- (double)size / base,
- suffixes[i]);
- break;
- } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
- snprintf(buf, buf_size, "%" PRId64 "%c",
- ((size + (base >> 1)) / base),
- suffixes[i]);
- break;
- }
- base = base * 1024;
- }
- }
- return buf;
-}
-
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
-{
- char buf1[128], date_buf[128], clock_buf[128];
-#ifdef _WIN32
- struct tm *ptm;
-#else
- struct tm tm;
-#endif
- time_t ti;
- int64_t secs;
-
- if (!sn) {
- snprintf(buf, buf_size,
- "%-10s%-20s%7s%20s%15s",
- "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
- } else {
- ti = sn->date_sec;
-#ifdef _WIN32
- ptm = localtime(&ti);
- strftime(date_buf, sizeof(date_buf),
- "%Y-%m-%d %H:%M:%S", ptm);
-#else
- localtime_r(&ti, &tm);
- strftime(date_buf, sizeof(date_buf),
- "%Y-%m-%d %H:%M:%S", &tm);
-#endif
- secs = sn->vm_clock_nsec / 1000000000;
- snprintf(clock_buf, sizeof(clock_buf),
- "%02d:%02d:%02d.%03d",
- (int)(secs / 3600),
- (int)((secs / 60) % 60),
- (int)(secs % 60),
- (int)((sn->vm_clock_nsec / 1000000) % 1000));
- snprintf(buf, buf_size,
- "%-10s%-20s%7s%20s%15s",
- sn->id_str, sn->name,
- get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
- date_buf,
- clock_buf);
- }
- return buf;
-}
-
-
-/**************************************************************/
-/* async I/Os */
-
-BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return NULL;
- if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
- return NULL;
-
- /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(buf, bs->boot_sector_data, 512);
- sector_num++;
- nb_sectors--;
- buf += 512;
- }
-
- return drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
-}
-
-BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return NULL;
- if (bs->read_only)
- return NULL;
- if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
- return NULL;
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(bs->boot_sector_data, buf, 512);
- }
-
- return drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
-}
-
-void bdrv_aio_cancel(BlockDriverAIOCB *acb)
-{
- BlockDriver *drv = acb->bs->drv;
-
- drv->bdrv_aio_cancel(acb);
-}
-
-BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return NULL;
-
- return drv->bdrv_aio_flush(bs, cb, opaque);
-}
-
-
-/**************************************************************/
-/* async block device emulation */
-
-#ifdef QEMU_TOOL
-static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- int ret;
- ret = bdrv_read(bs, sector_num, buf, nb_sectors);
- cb(opaque, ret);
- return NULL;
-}
-
-static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- int ret;
- ret = bdrv_write(bs, sector_num, buf, nb_sectors);
- cb(opaque, ret);
- return NULL;
-}
-
-static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
-{
-}
-#else
-static void bdrv_aio_bh_cb(void *opaque)
-{
- BlockDriverAIOCBSync *acb = opaque;
- acb->common.cb(acb->common.opaque, acb->ret);
- qemu_aio_release(acb);
-}
-
-static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriverAIOCBSync *acb;
- int ret;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb->bh)
- acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
- ret = bdrv_read(bs, sector_num, buf, nb_sectors);
- acb->ret = ret;
- qemu_bh_schedule(acb->bh);
- return &acb->common;
-}
-
-static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriverAIOCBSync *acb;
- int ret;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb->bh)
- acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
- ret = bdrv_write(bs, sector_num, buf, nb_sectors);
- acb->ret = ret;
- qemu_bh_schedule(acb->bh);
- return &acb->common;
-}
-
-static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
-{
- BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
- qemu_bh_cancel(acb->bh);
- qemu_aio_release(acb);
-}
-#endif /* !QEMU_TOOL */
-
-static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- int ret;
- ret = bdrv_flush(bs);
- cb(opaque, ret);
- return NULL;
-}
-
-/**************************************************************/
-/* sync block device emulation */
-
-static void bdrv_rw_em_cb(void *opaque, int ret)
-{
- *(int *)opaque = ret;
-}
-
-#define NOT_DONE 0x7fffffff
-
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- int async_ret;
- BlockDriverAIOCB *acb;
-
- async_ret = NOT_DONE;
- qemu_aio_wait_start();
- acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
- bdrv_rw_em_cb, &async_ret);
- if (acb == NULL) {
- qemu_aio_wait_end();
- return -1;
- }
- while (async_ret == NOT_DONE) {
- qemu_aio_wait();
- }
- qemu_aio_wait_end();
- return async_ret;
-}
-
-static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- int async_ret;
- BlockDriverAIOCB *acb;
-
- async_ret = NOT_DONE;
- qemu_aio_wait_start();
- acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
- bdrv_rw_em_cb, &async_ret);
- if (acb == NULL) {
- qemu_aio_wait_end();
- return -1;
- }
- while (async_ret == NOT_DONE) {
- qemu_aio_wait();
- }
- qemu_aio_wait_end();
- return async_ret;
-}
-
-void bdrv_init(void)
-{
- bdrv_register(&bdrv_raw);
- bdrv_register(&bdrv_host_device);
-#ifdef CONFIG_STUBDOM
- bdrv_register(&bdrv_vbd);
-#endif
-#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);
- bdrv_register(&bdrv_qcow2);
-}
-
-void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- BlockDriver *drv;
- BlockDriverAIOCB *acb;
-
- drv = bs->drv;
- if (drv->free_aiocb) {
- acb = drv->free_aiocb;
- drv->free_aiocb = acb->next;
- } else {
- acb = qemu_mallocz(drv->aiocb_size);
- if (!acb)
- return NULL;
- }
- acb->bs = bs;
- acb->cb = cb;
- acb->opaque = opaque;
- return acb;
-}
-
-void qemu_aio_release(void *p)
-{
- BlockDriverAIOCB *acb = p;
- BlockDriver *drv = acb->bs->drv;
- acb->next = drv->free_aiocb;
- drv->free_aiocb = acb;
-}
-
-/**************************************************************/
-/* removable device support */
-
-/**
- * Return TRUE if the media is present
- */
-int bdrv_is_inserted(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- int ret;
- if (!drv)
- return 0;
- if (!drv->bdrv_is_inserted)
- return 1;
- ret = drv->bdrv_is_inserted(bs);
- return ret;
-}
-
-/**
- * Return TRUE if the media changed since the last call to this
- * function. It is currently only used for floppy disks
- */
-int bdrv_media_changed(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- int ret;
-
- if (!drv || !drv->bdrv_media_changed)
- ret = -ENOTSUP;
- else
- ret = drv->bdrv_media_changed(bs);
- if (ret == -ENOTSUP)
- ret = bs->media_changed;
- bs->media_changed = 0;
- return ret;
-}
-
-/**
- * If eject_flag is TRUE, eject the media. Otherwise, close the tray
- */
-void bdrv_eject(BlockDriverState *bs, int eject_flag)
-{
- BlockDriver *drv = bs->drv;
- int ret;
-
- if (!drv || !drv->bdrv_eject) {
- ret = -ENOTSUP;
- } else {
- ret = drv->bdrv_eject(bs, eject_flag);
- }
- if (ret == -ENOTSUP) {
- if (eject_flag)
- bdrv_close(bs);
- }
-}
-
-int bdrv_is_locked(BlockDriverState *bs)
-{
- return bs->locked;
-}
-
-/**
- * Lock or unlock the media (if it is locked, the user won't be able
- * to eject it manually).
- */
-void bdrv_set_locked(BlockDriverState *bs, int locked)
-{
- BlockDriver *drv = bs->drv;
-
- bs->locked = locked;
- if (drv && drv->bdrv_set_locked) {
- drv->bdrv_set_locked(bs, locked);
- }
-}
diff --git a/tools/ioemu/block_int.h b/tools/ioemu/block_int.h
deleted file mode 100644
index 8c0318e795..0000000000
--- a/tools/ioemu/block_int.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef BLOCK_INT_H
-#define BLOCK_INT_H
-
-struct BlockDriver {
- const char *format_name;
- int instance_size;
- int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
- int (*bdrv_open)(BlockDriverState *bs, const char *filename, int flags);
- int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
- int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
- void (*bdrv_close)(BlockDriverState *bs);
- int (*bdrv_create)(const char *filename, int64_t total_sectors,
- const char *backing_file, int flags);
- int (*bdrv_flush)(BlockDriverState *bs);
- int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum);
- int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
- int (*bdrv_make_empty)(BlockDriverState *bs);
- /* aio */
- BlockDriverAIOCB *(*bdrv_aio_read)(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
- BlockDriverAIOCB *(*bdrv_aio_write)(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
- void (*bdrv_aio_cancel)(BlockDriverAIOCB *acb);
- BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque);
- int aiocb_size;
-
- const char *protocol_name;
- int (*bdrv_pread)(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count);
- int (*bdrv_pwrite)(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count);
- int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
- int64_t (*bdrv_getlength)(BlockDriverState *bs);
- int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-
- int (*bdrv_snapshot_create)(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info);
- int (*bdrv_snapshot_goto)(BlockDriverState *bs,
- const char *snapshot_id);
- int (*bdrv_snapshot_delete)(BlockDriverState *bs, const char *snapshot_id);
- int (*bdrv_snapshot_list)(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info);
- int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
-
- /* removable device specific */
- int (*bdrv_is_inserted)(BlockDriverState *bs);
- int (*bdrv_media_changed)(BlockDriverState *bs);
- int (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
- int (*bdrv_set_locked)(BlockDriverState *bs, int locked);
-
- BlockDriverAIOCB *free_aiocb;
- struct BlockDriver *next;
-};
-
-struct BlockDriverState {
- int64_t total_sectors; /* if we are reading a disk image, give its
- size in sectors */
- int read_only; /* if true, the media is read only */
- int removable; /* if true, the media can be removed */
- int locked; /* if true, the media cannot temporarily be ejected */
- int encrypted; /* if true, the media is encrypted */
- int extendable;/* if true, we may write out of original range */
- /* event callback when inserting/removing */
- void (*change_cb)(void *opaque);
- void *change_opaque;
-
- BlockDriver *drv; /* NULL means no media */
- void *opaque;
-
- int boot_sector_enabled;
- uint8_t boot_sector_data[512];
-
- char filename[1024];
- char backing_file[1024]; /* if non zero, the image is a diff of
- this file image */
- int is_temporary;
- int media_changed;
-
- BlockDriverState *backing_hd;
- /* async read/write emulation */
-
- void *sync_aiocb;
-
- /* NOTE: the following infos are only hints for real hardware
- drivers. They are not used by the block driver */
- int cyls, heads, secs, translation;
- int type;
- char device_name[32];
- BlockDriverState *next;
-};
-
-struct BlockDriverAIOCB {
- BlockDriverState *bs;
- BlockDriverCompletionFunc *cb;
- void *opaque;
- BlockDriverAIOCB *next;
-};
-
-void get_tmp_filename(char *filename, int size);
-
-void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
- void *opaque);
-void qemu_aio_release(void *p);
-
-#endif /* BLOCK_INT_H */
diff --git a/tools/ioemu/bswap.h b/tools/ioemu/bswap.h
deleted file mode 100644
index f0d77f591c..0000000000
--- a/tools/ioemu/bswap.h
+++ /dev/null
@@ -1,209 +0,0 @@
-#ifndef BSWAP_H
-#define BSWAP_H
-
-#include "config-host.h"
-
-#include <inttypes.h>
-
-#ifdef _BSD
-#include <sys/endian.h>
-#include <sys/types.h>
-#else
-
-#ifdef HAVE_BYTESWAP_H
-#include <byteswap.h>
-#else
-
-#define bswap_16(x) \
-({ \
- uint16_t __x = (x); \
- ((uint16_t)( \
- (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
- (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
-})
-
-#define bswap_32(x) \
-({ \
- uint32_t __x = (x); \
- ((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
-})
-
-#define bswap_64(x) \
-({ \
- uint64_t __x = (x); \
- ((uint64_t)( \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
-})
-
-#endif /* !HAVE_BYTESWAP_H */
-
-static inline uint16_t bswap16(uint16_t x)
-{
- return bswap_16(x);
-}
-
-static inline uint32_t bswap32(uint32_t x)
-{
- return bswap_32(x);
-}
-
-static inline uint64_t bswap64(uint64_t x)
-{
- return bswap_64(x);
-}
-
-static inline void bswap16s(uint16_t *s)
-{
- *s = bswap16(*s);
-}
-
-static inline void bswap32s(uint32_t *s)
-{
- *s = bswap32(*s);
-}
-
-static inline void bswap64s(uint64_t *s)
-{
- *s = bswap64(*s);
-}
-
-#endif /* _BSD */
-
-#if defined(WORDS_BIGENDIAN)
-#define be_bswap(v, size) (v)
-#define le_bswap(v, size) bswap ## size(v)
-#define be_bswaps(v, size)
-#define le_bswaps(p, size) *p = bswap ## size(*p);
-#else
-#define le_bswap(v, size) (v)
-#define be_bswap(v, size) bswap ## size(v)
-#define le_bswaps(v, size)
-#define be_bswaps(p, size) *p = bswap ## size(*p);
-#endif
-
-#define CPU_CONVERT(endian, size, type)\
-static inline type endian ## size ## _to_cpu(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-static inline type cpu_to_ ## endian ## size(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-static inline void endian ## size ## _to_cpus(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## s(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-static inline type endian ## size ## _to_cpup(const type *p)\
-{\
- return endian ## size ## _to_cpu(*p);\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
-{\
- *p = cpu_to_ ## endian ## size(v);\
-}
-
-CPU_CONVERT(be, 16, uint16_t)
-CPU_CONVERT(be, 32, uint32_t)
-CPU_CONVERT(be, 64, uint64_t)
-
-CPU_CONVERT(le, 16, uint16_t)
-CPU_CONVERT(le, 32, uint32_t)
-CPU_CONVERT(le, 64, uint64_t)
-
-/* unaligned versions (optimized for frequent unaligned accesses)*/
-
-#if defined(__i386__) || defined(__powerpc__)
-
-#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
-#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
-#define le16_to_cpupu(p) le16_to_cpup(p)
-#define le32_to_cpupu(p) le32_to_cpup(p)
-
-#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
-#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
-
-#else
-
-static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v;
- p1[1] = v >> 8;
-}
-
-static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v;
- p1[1] = v >> 8;
- p1[2] = v >> 16;
- p1[3] = v >> 24;
-}
-
-static inline uint16_t le16_to_cpupu(const uint16_t *p)
-{
- const uint8_t *p1 = (const uint8_t *)p;
- return p1[0] | (p1[1] << 8);
-}
-
-static inline uint32_t le32_to_cpupu(const uint32_t *p)
-{
- const uint8_t *p1 = (const uint8_t *)p;
- return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
-}
-
-static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v >> 8;
- p1[1] = v;
-}
-
-static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v >> 24;
- p1[1] = v >> 16;
- p1[2] = v >> 8;
- p1[3] = v;
-}
-
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define cpu_to_32wu cpu_to_be32wu
-#else
-#define cpu_to_32wu cpu_to_le32wu
-#endif
-
-#undef le_bswap
-#undef be_bswap
-#undef le_bswaps
-#undef be_bswaps
-
-#endif /* BSWAP_H */
diff --git a/tools/ioemu/check_ops.sh b/tools/ioemu/check_ops.sh
deleted file mode 100755
index b1f2f8500c..0000000000
--- a/tools/ioemu/check_ops.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /bin/sh
-# Script to check for duplicate function prologues in op.o
-# Typically this indicates missing FORCE_RET();
-# This script does not detect other errors that may be present.
-
-# Usage: check_ops.sh [-m machine] [op.o]
-# machine and op.o are guessed if not specified.
-
-if [ "x$1" = "x-m" ]; then
- machine=$2
- shift 2
-else
- machine=`uname -m`
-fi
-if [ -z "$1" ]; then
- for f in `find . -name op.o`; do
- /bin/sh "$0" -m $machine $f
- done
- exit 0
-fi
-
-case $machine in
- i?86)
- ret='\tret'
- ;;
- x86_64)
- ret='\tretq'
- ;;
- arm)
- ret='\tldm.*pc'
- ;;
- ppc* | powerpc*)
- ret='\tblr'
- ;;
- mips*)
- ret='\tjr.*ra'
- ;;
- *)
- echo "Unknown machine `uname -m`"
- ;;
-esac
-echo $1
-# op_exit_tb causes false positives on some hosts.
-${CROSS}objdump -dr $1 | \
- sed -e '/>:$\|'"$ret"'/!d' -e 's/.*<\(.*\)>:/~\1:/' -e 's/.*'"$ret"'.*/!/' | \
- sed -e ':1;N;s/\n//;t1' | sed -e 's/~/\n/g' | grep -v '^op_exit_tb' | \
- grep '^op_.*!!'
diff --git a/tools/ioemu/cocoa.m b/tools/ioemu/cocoa.m
deleted file mode 100644
index 9551affa34..0000000000
--- a/tools/ioemu/cocoa.m
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
- * QEMU Cocoa display driver
- *
- * Copyright (c) 2005 Pierre d'Herbemont
- * many code/inspiration from SDL 1.2 code (LGPL)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- Todo : x miniaturize window
- x center the window
- - save window position
- - handle keyboard event
- - handle mouse event
- - non 32 bpp support
- - full screen
- - mouse focus
- x simple graphical prompt to demo
- - better graphical prompt
-*/
-
-#import <Cocoa/Cocoa.h>
-
-#include "vl.h"
-
-NSWindow *window = NULL;
-NSQuickDrawView *qd_view = NULL;
-
-
-int gArgc;
-char **gArgv;
-DisplayState current_ds;
-
-int grab = 0;
-int modifiers_state[256];
-
-/* main defined in qemu/vl.c */
-int qemu_main(int argc, char **argv);
-
-/* To deal with miniaturization */
-@interface QemuWindow : NSWindow
-{ }
-@end
-
-
-/*
- ------------------------------------------------------
- Qemu Video Driver
- ------------------------------------------------------
-*/
-
-/*
- ------------------------------------------------------
- cocoa_update
- ------------------------------------------------------
-*/
-static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
-{
- //printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
-
- /* Use QDFlushPortBuffer() to flush content to display */
- RgnHandle dirty = NewRgn ();
- RgnHandle temp = NewRgn ();
-
- SetEmptyRgn (dirty);
-
- /* Build the region of dirty rectangles */
- MacSetRectRgn (temp, x, y,
- x + w, y + h);
- MacUnionRgn (dirty, temp, dirty);
-
- /* Flush the dirty region */
- QDFlushPortBuffer ( [ qd_view qdPort ], dirty );
- DisposeRgn (dirty);
- DisposeRgn (temp);
-}
-
-/*
- ------------------------------------------------------
- cocoa_resize
- ------------------------------------------------------
-*/
-static void cocoa_resize(DisplayState *ds, int w, int h)
-{
- const int device_bpp = 32;
- static void *screen_pixels;
- static int screen_pitch;
- NSRect contentRect;
-
- //printf("resizing to %d %d\n", w, h);
-
- contentRect = NSMakeRect (0, 0, w, h);
- if(window)
- {
- [window close];
- [window release];
- }
- window = [ [ QemuWindow alloc ] initWithContentRect:contentRect
- styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
- backing:NSBackingStoreBuffered defer:NO];
- if(!window)
- {
- fprintf(stderr, "(cocoa) can't create window\n");
- exit(1);
- }
-
- if(qd_view)
- [qd_view release];
-
- qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
-
- if(!qd_view)
- {
- fprintf(stderr, "(cocoa) can't create qd_view\n");
- exit(1);
- }
-
- [ window setAcceptsMouseMovedEvents:YES ];
- [ window setTitle:@"Qemu" ];
- [ window setReleasedWhenClosed:NO ];
-
- /* Set screen to black */
- [ window setBackgroundColor: [NSColor blackColor] ];
-
- /* set window position */
- [ window center ];
-
- [ qd_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
- [ [ window contentView ] addSubview:qd_view ];
- [ qd_view release ];
- [ window makeKeyAndOrderFront:nil ];
-
- /* Careful here, the window seems to have to be onscreen to do that */
- LockPortBits ( [ qd_view qdPort ] );
- screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort ] ) );
- screen_pitch = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort ] ) );
- UnlockPortBits ( [ qd_view qdPort ] );
- {
- int vOffset = [ window frame ].size.height -
- [ qd_view frame ].size.height - [ qd_view frame ].origin.y;
-
- int hOffset = [ qd_view frame ].origin.x;
-
- screen_pixels += (vOffset * screen_pitch) + hOffset * (device_bpp/8);
- }
- ds->data = screen_pixels;
- ds->linesize = screen_pitch;
- ds->depth = device_bpp;
- ds->width = w;
- ds->height = h;
-
- current_ds = *ds;
-}
-
-/*
- ------------------------------------------------------
- keymap conversion
- ------------------------------------------------------
-*/
-
-int keymap[] =
-{
-// SdlI macI macH SdlH 104xtH 104xtC sdl
- 30, // 0 0x00 0x1e A QZ_a
- 31, // 1 0x01 0x1f S QZ_s
- 32, // 2 0x02 0x20 D QZ_d
- 33, // 3 0x03 0x21 F QZ_f
- 35, // 4 0x04 0x23 H QZ_h
- 34, // 5 0x05 0x22 G QZ_g
- 44, // 6 0x06 0x2c Z QZ_z
- 45, // 7 0x07 0x2d X QZ_x
- 46, // 8 0x08 0x2e C QZ_c
- 47, // 9 0x09 0x2f V QZ_v
- 0, // 10 0x0A Undefined
- 48, // 11 0x0B 0x30 B QZ_b
- 16, // 12 0x0C 0x10 Q QZ_q
- 17, // 13 0x0D 0x11 W QZ_w
- 18, // 14 0x0E 0x12 E QZ_e
- 19, // 15 0x0F 0x13 R QZ_r
- 21, // 16 0x10 0x15 Y QZ_y
- 20, // 17 0x11 0x14 T QZ_t
- 2, // 18 0x12 0x02 1 QZ_1
- 3, // 19 0x13 0x03 2 QZ_2
- 4, // 20 0x14 0x04 3 QZ_3
- 5, // 21 0x15 0x05 4 QZ_4
- 7, // 22 0x16 0x07 6 QZ_6
- 6, // 23 0x17 0x06 5 QZ_5
- 13, // 24 0x18 0x0d = QZ_EQUALS
- 10, // 25 0x19 0x0a 9 QZ_9
- 8, // 26 0x1A 0x08 7 QZ_7
- 12, // 27 0x1B 0x0c - QZ_MINUS
- 9, // 28 0x1C 0x09 8 QZ_8
- 11, // 29 0x1D 0x0b 0 QZ_0
- 27, // 30 0x1E 0x1b ] QZ_RIGHTBRACKET
- 24, // 31 0x1F 0x18 O QZ_o
- 22, // 32 0x20 0x16 U QZ_u
- 26, // 33 0x21 0x1a [ QZ_LEFTBRACKET
- 23, // 34 0x22 0x17 I QZ_i
- 25, // 35 0x23 0x19 P QZ_p
- 28, // 36 0x24 0x1c ENTER QZ_RETURN
- 38, // 37 0x25 0x26 L QZ_l
- 36, // 38 0x26 0x24 J QZ_j
- 40, // 39 0x27 0x28 ' QZ_QUOTE
- 37, // 40 0x28 0x25 K QZ_k
- 39, // 41 0x29 0x27 ; QZ_SEMICOLON
- 43, // 42 0x2A 0x2b \ QZ_BACKSLASH
- 51, // 43 0x2B 0x33 , QZ_COMMA
- 53, // 44 0x2C 0x35 / QZ_SLASH
- 49, // 45 0x2D 0x31 N QZ_n
- 50, // 46 0x2E 0x32 M QZ_m
- 52, // 47 0x2F 0x34 . QZ_PERIOD
- 15, // 48 0x30 0x0f TAB QZ_TAB
- 57, // 49 0x31 0x39 SPACE QZ_SPACE
- 41, // 50 0x32 0x29 ` QZ_BACKQUOTE
- 14, // 51 0x33 0x0e BKSP QZ_BACKSPACE
- 0, // 52 0x34 Undefined
- 1, // 53 0x35 0x01 ESC QZ_ESCAPE
- 0, // 54 0x36 QZ_RMETA
- 0, // 55 0x37 QZ_LMETA
- 42, // 56 0x38 0x2a L SHFT QZ_LSHIFT
- 58, // 57 0x39 0x3a CAPS QZ_CAPSLOCK
- 56, // 58 0x3A 0x38 L ALT QZ_LALT
- 29, // 59 0x3B 0x1d L CTRL QZ_LCTRL
- 54, // 60 0x3C 0x36 R SHFT QZ_RSHIFT
- 184,// 61 0x3D 0xb8 E0,38 R ALT QZ_RALT
- 157,// 62 0x3E 0x9d E0,1D R CTRL QZ_RCTRL
- 0, // 63 0x3F Undefined
- 0, // 64 0x40 Undefined
- 0, // 65 0x41 Undefined
- 0, // 66 0x42 Undefined
- 55, // 67 0x43 0x37 KP * QZ_KP_MULTIPLY
- 0, // 68 0x44 Undefined
- 78, // 69 0x45 0x4e KP + QZ_KP_PLUS
- 0, // 70 0x46 Undefined
- 69, // 71 0x47 0x45 NUM QZ_NUMLOCK
- 0, // 72 0x48 Undefined
- 0, // 73 0x49 Undefined
- 0, // 74 0x4A Undefined
- 181,// 75 0x4B 0xb5 E0,35 KP / QZ_KP_DIVIDE
- 152,// 76 0x4C 0x9c E0,1C KP EN QZ_KP_ENTER
- 0, // 77 0x4D undefined
- 74, // 78 0x4E 0x4a KP - QZ_KP_MINUS
- 0, // 79 0x4F Undefined
- 0, // 80 0x50 Undefined
- 0, // 81 0x51 QZ_KP_EQUALS
- 82, // 82 0x52 0x52 KP 0 QZ_KP0
- 79, // 83 0x53 0x4f KP 1 QZ_KP1
- 80, // 84 0x54 0x50 KP 2 QZ_KP2
- 81, // 85 0x55 0x51 KP 3 QZ_KP3
- 75, // 86 0x56 0x4b KP 4 QZ_KP4
- 76, // 87 0x57 0x4c KP 5 QZ_KP5
- 77, // 88 0x58 0x4d KP 6 QZ_KP6
- 71, // 89 0x59 0x47 KP 7 QZ_KP7
- 0, // 90 0x5A Undefined
- 72, // 91 0x5B 0x48 KP 8 QZ_KP8
- 73, // 92 0x5C 0x49 KP 9 QZ_KP9
- 0, // 93 0x5D Undefined
- 0, // 94 0x5E Undefined
- 0, // 95 0x5F Undefined
- 63, // 96 0x60 0x3f F5 QZ_F5
- 64, // 97 0x61 0x40 F6 QZ_F6
- 65, // 98 0x62 0x41 F7 QZ_F7
- 61, // 99 0x63 0x3d F3 QZ_F3
- 66, // 100 0x64 0x42 F8 QZ_F8
- 67, // 101 0x65 0x43 F9 QZ_F9
- 0, // 102 0x66 Undefined
- 87, // 103 0x67 0x57 F11 QZ_F11
- 0, // 104 0x68 Undefined
- 183,// 105 0x69 0xb7 QZ_PRINT
- 0, // 106 0x6A Undefined
- 70, // 107 0x6B 0x46 SCROLL QZ_SCROLLOCK
- 0, // 108 0x6C Undefined
- 68, // 109 0x6D 0x44 F10 QZ_F10
- 0, // 110 0x6E Undefined
- 88, // 111 0x6F 0x58 F12 QZ_F12
- 0, // 112 0x70 Undefined
- 110,// 113 0x71 0x0 QZ_PAUSE
- 210,// 114 0x72 0xd2 E0,52 INSERT QZ_INSERT
- 199,// 115 0x73 0xc7 E0,47 HOME QZ_HOME
- 201,// 116 0x74 0xc9 E0,49 PG UP QZ_PAGEUP
- 211,// 117 0x75 0xd3 E0,53 DELETE QZ_DELETE
- 62, // 118 0x76 0x3e F4 QZ_F4
- 207,// 119 0x77 0xcf E0,4f END QZ_END
- 60, // 120 0x78 0x3c F2 QZ_F2
- 209,// 121 0x79 0xd1 E0,51 PG DN QZ_PAGEDOWN
- 59, // 122 0x7A 0x3b F1 QZ_F1
- 203,// 123 0x7B 0xcb e0,4B L ARROW QZ_LEFT
- 205,// 124 0x7C 0xcd e0,4D R ARROW QZ_RIGHT
- 208,// 125 0x7D 0xd0 E0,50 D ARROW QZ_DOWN
- 200,// 126 0x7E 0xc8 E0,48 U ARROW QZ_UP
-/* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
-
-/* Aditional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */
-/*
- 219 // 0xdb e0,5b L GUI
- 220 // 0xdc e0,5c R GUI
- 221 // 0xdd e0,5d APPS
- // E0,2A,E0,37 PRNT SCRN
- // E1,1D,45,E1,9D,C5 PAUSE
- 83 // 0x53 0x53 KP .
-// ACPI Scan Codes
- 222 // 0xde E0, 5E Power
- 223 // 0xdf E0, 5F Sleep
- 227 // 0xe3 E0, 63 Wake
-// Windows Multimedia Scan Codes
- 153 // 0x99 E0, 19 Next Track
- 144 // 0x90 E0, 10 Previous Track
- 164 // 0xa4 E0, 24 Stop
- 162 // 0xa2 E0, 22 Play/Pause
- 160 // 0xa0 E0, 20 Mute
- 176 // 0xb0 E0, 30 Volume Up
- 174 // 0xae E0, 2E Volume Down
- 237 // 0xed E0, 6D Media Select
- 236 // 0xec E0, 6C E-Mail
- 161 // 0xa1 E0, 21 Calculator
- 235 // 0xeb E0, 6B My Computer
- 229 // 0xe5 E0, 65 WWW Search
- 178 // 0xb2 E0, 32 WWW Home
- 234 // 0xea E0, 6A WWW Back
- 233 // 0xe9 E0, 69 WWW Forward
- 232 // 0xe8 E0, 68 WWW Stop
- 231 // 0xe7 E0, 67 WWW Refresh
- 230 // 0xe6 E0, 66 WWW Favorites
-*/
-};
-
-int cocoa_keycode_to_qemu(int keycode)
-{
- if((sizeof(keymap)/sizeof(int)) <= keycode)
- {
- printf("(cocoa) warning unknow keycode 0x%x\n", keycode);
- return 0;
- }
- return keymap[keycode];
-}
-
-/*
- ------------------------------------------------------
- cocoa_refresh
- ------------------------------------------------------
-*/
-static void cocoa_refresh(DisplayState *ds)
-{
- //printf("cocoa_refresh \n");
- NSDate *distantPast;
- NSEvent *event;
- NSAutoreleasePool *pool;
-
- pool = [ [ NSAutoreleasePool alloc ] init ];
- distantPast = [ NSDate distantPast ];
-
- vga_hw_update();
-
- do {
- event = [ NSApp nextEventMatchingMask:NSAnyEventMask untilDate:distantPast
- inMode: NSDefaultRunLoopMode dequeue:YES ];
- if (event != nil) {
- switch ([event type]) {
- case NSFlagsChanged:
- {
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- if (keycode)
- {
- if (keycode == 58 || keycode == 69) {
- /* emulate caps lock and num lock keydown and keyup */
- kbd_put_keycode(keycode);
- kbd_put_keycode(keycode | 0x80);
- } else if (is_graphic_console()) {
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (modifiers_state[keycode] == 0) {
- /* keydown */
- kbd_put_keycode(keycode & 0x7f);
- modifiers_state[keycode] = 1;
- } else {
- /* keyup */
- kbd_put_keycode(keycode | 0x80);
- modifiers_state[keycode] = 0;
- }
- }
- }
-
- /* release Mouse grab when pressing ctrl+alt */
- if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask))
- {
- [window setTitle: @"QEMU"];
- [NSCursor unhide];
- CGAssociateMouseAndMouseCursorPosition ( TRUE );
- grab = 0;
- }
- }
- break;
-
- case NSKeyDown:
- {
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- /* handle command Key Combos */
- if ([event modifierFlags] & NSCommandKeyMask) {
- switch ([event keyCode]) {
- /* quit */
- case 12: /* q key */
- /* switch to windowed View */
- exit(0);
- return;
- }
- }
-
- /* handle control + alt Key Combos */
- if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
- switch (keycode) {
- /* toggle Monitor */
- case 0x02 ... 0x0a: /* '1' to '9' keys */
- console_select(keycode - 0x02);
- break;
- }
- } else {
- /* handle standard key events */
- if (is_graphic_console()) {
- if (keycode & 0x80) //check bit for e0 in front
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front
- /* handle monitor key events */
- } else {
- int keysym = 0;
-
- switch([event keyCode]) {
- case 115:
- keysym = QEMU_KEY_HOME;
- break;
- case 117:
- keysym = QEMU_KEY_DELETE;
- break;
- case 119:
- keysym = QEMU_KEY_END;
- break;
- case 123:
- keysym = QEMU_KEY_LEFT;
- break;
- case 124:
- keysym = QEMU_KEY_RIGHT;
- break;
- case 125:
- keysym = QEMU_KEY_DOWN;
- break;
- case 126:
- keysym = QEMU_KEY_UP;
- break;
- default:
- {
- NSString *ks = [event characters];
-
- if ([ks length] > 0)
- keysym = [ks characterAtIndex:0];
- }
- }
- if (keysym)
- kbd_put_keysym(keysym);
- }
- }
- }
- break;
-
- case NSKeyUp:
- {
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
- if (is_graphic_console()) {
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key
- }
- }
- break;
-
- case NSMouseMoved:
- if (grab) {
- int dx = [event deltaX];
- int dy = [event deltaY];
- int dz = [event deltaZ];
- int buttons = 0;
- kbd_mouse_event(dx, dy, dz, buttons);
- }
- break;
-
- case NSLeftMouseDown:
- if (grab) {
- int buttons = 0;
-
- /* leftclick+command simulates rightclick */
- if ([event modifierFlags] & NSCommandKeyMask) {
- buttons |= MOUSE_EVENT_RBUTTON;
- } else {
- buttons |= MOUSE_EVENT_LBUTTON;
- }
- kbd_mouse_event(0, 0, 0, buttons);
- } else {
- [NSApp sendEvent: event];
- }
- break;
-
- case NSLeftMouseDragged:
- if (grab) {
- int dx = [event deltaX];
- int dy = [event deltaY];
- int dz = [event deltaZ];
- int buttons = 0;
- if ([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) { //leftclick+command simulates rightclick
- buttons |= MOUSE_EVENT_RBUTTON;
- } else {
- buttons |= MOUSE_EVENT_LBUTTON;
- }
- kbd_mouse_event(dx, dy, dz, buttons);
- }
- break;
-
- case NSLeftMouseUp:
- if (grab) {
- kbd_mouse_event(0, 0, 0, 0);
- } else {
- [window setTitle: @"QEMU (Press ctrl + alt to release Mouse)"];
- [NSCursor hide];
- CGAssociateMouseAndMouseCursorPosition ( FALSE );
- grab = 1;
- //[NSApp sendEvent: event];
- }
- break;
-
- case NSRightMouseDown:
- if (grab) {
- int buttons = 0;
-
- buttons |= MOUSE_EVENT_RBUTTON;
- kbd_mouse_event(0, 0, 0, buttons);
- } else {
- [NSApp sendEvent: event];
- }
- break;
-
- case NSRightMouseDragged:
- if (grab) {
- int dx = [event deltaX];
- int dy = [event deltaY];
- int dz = [event deltaZ];
- int buttons = 0;
- buttons |= MOUSE_EVENT_RBUTTON;
- kbd_mouse_event(dx, dy, dz, buttons);
- }
- break;
-
- case NSRightMouseUp:
- if (grab) {
- kbd_mouse_event(0, 0, 0, 0);
- } else {
- [NSApp sendEvent: event];
- }
- break;
-
- case NSOtherMouseDragged:
- if (grab) {
- int dx = [event deltaX];
- int dy = [event deltaY];
- int dz = [event deltaZ];
- int buttons = 0;
- buttons |= MOUSE_EVENT_MBUTTON;
- kbd_mouse_event(dx, dy, dz, buttons);
- }
- break;
-
- case NSOtherMouseDown:
- if (grab) {
- int buttons = 0;
- buttons |= MOUSE_EVENT_MBUTTON;
- kbd_mouse_event(0, 0, 0, buttons);
- } else {
- [NSApp sendEvent:event];
- }
- break;
-
- case NSOtherMouseUp:
- if (grab) {
- kbd_mouse_event(0, 0, 0, 0);
- } else {
- [NSApp sendEvent: event];
- }
- break;
-
- case NSScrollWheel:
- if (grab) {
- int dz = [event deltaY];
- kbd_mouse_event(0, 0, -dz, 0);
- }
- break;
-
- default: [NSApp sendEvent:event];
- }
- }
- } while(event != nil);
-}
-
-/*
- ------------------------------------------------------
- cocoa_cleanup
- ------------------------------------------------------
-*/
-
-static void cocoa_cleanup(void)
-{
-
-}
-
-/*
- ------------------------------------------------------
- cocoa_display_init
- ------------------------------------------------------
-*/
-
-void cocoa_display_init(DisplayState *ds, int full_screen)
-{
- ds->dpy_update = cocoa_update;
- ds->dpy_resize = cocoa_resize;
- ds->dpy_refresh = cocoa_refresh;
-
- cocoa_resize(ds, 640, 400);
-
- atexit(cocoa_cleanup);
-}
-
-/*
- ------------------------------------------------------
- Interface with Cocoa
- ------------------------------------------------------
-*/
-
-
-/*
- ------------------------------------------------------
- QemuWindow
- Some trick from SDL to use miniwindow
- ------------------------------------------------------
-*/
-static void QZ_SetPortAlphaOpaque ()
-{
- /* Assume 32 bit if( bpp == 32 )*/
- if ( 1 ) {
-
- uint32_t *pixels = (uint32_t*) current_ds.data;
- uint32_t rowPixels = current_ds.linesize / 4;
- uint32_t i, j;
-
- for (i = 0; i < current_ds.height; i++)
- for (j = 0; j < current_ds.width; j++) {
-
- pixels[ (i * rowPixels) + j ] |= 0xFF000000;
- }
- }
-}
-
-@implementation QemuWindow
-- (void)miniaturize:(id)sender
-{
-
- /* make the alpha channel opaque so anim won't have holes in it */
- QZ_SetPortAlphaOpaque ();
-
- [ super miniaturize:sender ];
-
-}
-- (void)display
-{
- /*
- This method fires just before the window deminaturizes from the Dock.
-
- We'll save the current visible surface, let the window manager redraw any
- UI elements, and restore the SDL surface. This way, no expose event
- is required, and the deminiaturize works perfectly.
- */
-
- /* make sure pixels are fully opaque */
- QZ_SetPortAlphaOpaque ();
-
- /* save current visible SDL surface */
- [ self cacheImageInRect:[ qd_view frame ] ];
-
- /* let the window manager redraw controls, border, etc */
- [ super display ];
-
- /* restore visible SDL surface */
- [ self restoreCachedImage ];
-}
-
-@end
-
-
-/*
- ------------------------------------------------------
- QemuCocoaGUIController
- NSApp's delegate - indeed main object
- ------------------------------------------------------
-*/
-
-@interface QemuCocoaGUIController : NSObject
-{
-}
-- (void)applicationDidFinishLaunching: (NSNotification *) note;
-- (void)applicationWillTerminate:(NSNotification *)aNotification;
-
-- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;
-
-- (void)startEmulationWithArgc:(int)argc argv:(char**)argv;
-@end
-
-@implementation QemuCocoaGUIController
-/* Called when the internal event loop has just started running */
-- (void)applicationDidFinishLaunching: (NSNotification *) note
-{
-
- /* Display an open dialog box if no argument were passed or
- if qemu was launched from the finder ( the Finder passes "-psn" ) */
-
- if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0)
- {
- NSOpenPanel *op = [[NSOpenPanel alloc] init];
-
- cocoa_resize(&current_ds, 640, 400);
-
- [op setPrompt:@"Boot image"];
-
- [op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"];
-
- [op beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil]
- modalForWindow:window modalDelegate:self
- didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
- }
- else
- {
- /* or Launch Qemu, with the global args */
- [self startEmulationWithArgc:gArgc argv:gArgv];
- }
-}
-
-- (void)applicationWillTerminate:(NSNotification *)aNotification
-{
- printf("Application will terminate\n");
- qemu_system_shutdown_request();
- /* In order to avoid a crash */
- exit(0);
-}
-
-- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
-{
- if(returnCode == NSCancelButton)
- {
- exit(0);
- }
-
- if(returnCode == NSOKButton)
- {
- char *bin = "qemu";
- char *img = (char*)[ [ sheet filename ] cString];
-
- char **argv = (char**)malloc( sizeof(char*)*3 );
-
- asprintf(&argv[0], "%s", bin);
- asprintf(&argv[1], "-hda");
- asprintf(&argv[2], "%s", img);
-
- printf("Using argc %d argv %s -hda %s\n", 3, bin, img);
-
- [self startEmulationWithArgc:3 argv:(char**)argv];
- }
-}
-
-- (void)startEmulationWithArgc:(int)argc argv:(char**)argv
-{
- int status;
- /* Launch Qemu */
- printf("starting qemu...\n");
- status = qemu_main (argc, argv);
- exit(status);
-}
-@end
-
-/*
- ------------------------------------------------------
- Application Creation
- ------------------------------------------------------
-*/
-
-/* Dock Connection */
-typedef struct CPSProcessSerNum
-{
- UInt32 lo;
- UInt32 hi;
-} CPSProcessSerNum;
-
-extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
-extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
-
-/* Menu Creation */
-static void setApplicationMenu(void)
-{
- /* warning: this code is very odd */
- NSMenu *appleMenu;
- NSMenuItem *menuItem;
- NSString *title;
- NSString *appName;
-
- appName = @"Qemu";
- appleMenu = [[NSMenu alloc] initWithTitle:@""];
-
- /* Add menu items */
- title = [@"About " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Hide " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
-
- menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
-
- [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Quit " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
-
-
- /* Put menu into the menubar */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:appleMenu];
- [[NSApp mainMenu] addItem:menuItem];
-
- /* Tell the application object that this is now the application menu */
- [NSApp setAppleMenu:appleMenu];
-
- /* Finally give up our references to the objects */
- [appleMenu release];
- [menuItem release];
-}
-
-/* Create a window menu */
-static void setupWindowMenu(void)
-{
- NSMenu *windowMenu;
- NSMenuItem *windowMenuItem;
- NSMenuItem *menuItem;
-
- windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
- /* "Minimize" item */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
- [windowMenu addItem:menuItem];
- [menuItem release];
-
- /* Put menu into the menubar */
- windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
- [windowMenuItem setSubmenu:windowMenu];
- [[NSApp mainMenu] addItem:windowMenuItem];
-
- /* Tell the application object that this is now the window menu */
- [NSApp setWindowsMenu:windowMenu];
-
- /* Finally give up our references to the objects */
- [windowMenu release];
- [windowMenuItem release];
-}
-
-static void CustomApplicationMain(void)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- QemuCocoaGUIController *gui_controller;
- CPSProcessSerNum PSN;
-
- [NSApplication sharedApplication];
-
- if (!CPSGetCurrentProcess(&PSN))
- if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
- if (!CPSSetFrontProcess(&PSN))
- [NSApplication sharedApplication];
-
- /* Set up the menubar */
- [NSApp setMainMenu:[[NSMenu alloc] init]];
- setApplicationMenu();
- setupWindowMenu();
-
- /* Create SDLMain and make it the app delegate */
- gui_controller = [[QemuCocoaGUIController alloc] init];
- [NSApp setDelegate:gui_controller];
-
- /* Start the main event loop */
- [NSApp run];
-
- [gui_controller release];
- [pool release];
-}
-
-/* Real main of qemu-cocoa */
-int main(int argc, char **argv)
-{
- gArgc = argc;
- gArgv = argv;
-
- CustomApplicationMain();
-
- return 0;
-}
diff --git a/tools/ioemu/configure b/tools/ioemu/configure
deleted file mode 100755
index bf68c12365..0000000000
--- a/tools/ioemu/configure
+++ /dev/null
@@ -1,1057 +0,0 @@
-#!/bin/sh
-#
-# qemu configure script (c) 2003 Fabrice Bellard
-#
-# set temporary file name
-if test ! -z "$TMPDIR" ; then
- TMPDIR1="${TMPDIR}"
-elif test ! -z "$TEMPDIR" ; then
- TMPDIR1="${TEMPDIR}"
-else
- TMPDIR1="/tmp"
-fi
-
-TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c"
-TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
-TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}"
-TMPS="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.S"
-
-# default parameters
-prefix=""
-static="no"
-libdir="lib"
-cross_prefix=""
-cc="gcc"
-gcc3_search="yes"
-gcc3_list="gcc-3.4 gcc34 gcc-3.3 gcc33 gcc-3.2 gcc32"
-host_cc="gcc"
-ar="ar"
-make="make"
-install="install"
-strip="strip"
-target_list=""
-case "$XEN_TARGET_ARCH" in
- x86_32)
- cpu="i386"
- ;;
- powerpc)
- cpu="powerpc"
- ;;
- ia64)
- cpu="ia64"
- ;;
- x86_64)
- cpu="x86_64"
- [ `uname -s` = "Linux" ] && libdir="lib64"
- ;;
- *)
- cpu="unknown"
- ;;
-esac
-gprof="no"
-bigendian="no"
-mingw32="no"
-EXESUF=""
-gdbstub="no"
-slirp="no"
-adlib="no"
-oss="no"
-dsound="no"
-coreaudio="no"
-alsa="no"
-fmod="no"
-fmod_lib=""
-fmod_inc=""
-vnc_tls="yes"
-bsd="no"
-linux="no"
-kqemu="no"
-profiler="no"
-cocoa="no"
-check_gfx="yes"
-check_gcc="no"
-softmmu="yes"
-linux_user="no"
-darwin_user="no"
-build_docs="no"
-stubdom="no"
-uname_release=""
-
-# OS specific
-targetos=`uname -s`
-case $targetos in
-CYGWIN*)
-mingw32="yes"
-OS_CFLAGS="-mno-cygwin"
-;;
-MINGW32*)
-mingw32="yes"
-;;
-FreeBSD)
-bsd="yes"
-oss="yes"
-if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
- kqemu="yes"
-fi
-;;
-NetBSD)
-bsd="yes"
-oss="yes"
-;;
-OpenBSD)
-bsd="yes"
-oss="yes"
-;;
-Darwin)
-bsd="yes"
-darwin="yes"
-darwin_user="yes"
-cocoa="yes"
-coreaudio="yes"
-OS_CFLAGS="-mdynamic-no-pic"
-;;
-SunOS)
-solaris="yes"
-;;
-*)
-oss="yes"
-linux="yes"
-linux_user="yes"
-if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
- kqemu="yes"
-fi
-;;
-esac
-
-if [ "$bsd" = "yes" ] ; then
- if [ "$darwin" != "yes" ] ; then
- make="gmake"
- fi
-fi
-
-if [ "$solaris" = "yes" ] ; then
- make="gmake"
- install="ginstall"
- solarisrev=`uname -r | cut -f2 -d.`
- if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
- if test "$solarisrev" -gt 10 ; then
- kqemu="yes"
- fi
- fi
-fi
-
-# find source path
-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
- --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"
- gcc3_search="no"
- ;;
- --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"
- ;;
- --static) static="yes"
- ;;
- --disable-sdl) sdl="no"
- ;;
- --disable-opengl) opengl="no"
- ;;
- --enable-coreaudio) coreaudio="yes"
- ;;
- --enable-alsa) alsa="yes"
- ;;
- --enable-dsound) dsound="yes"
- ;;
- --enable-fmod) fmod="yes"
- ;;
- --fmod-lib=*) fmod_lib="$optarg"
- ;;
- --fmod-inc=*) fmod_inc="$optarg"
- ;;
- --disable-vnc-tls) vnc_tls="no"
- ;;
- --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" ; user="no"
- ;;
- --disable-slirp) slirp="no"
- ;;
- --enable-adlib) adlib="yes"
- ;;
- --disable-kqemu) kqemu="no"
- ;;
- --enable-profiler) profiler="yes"
- ;;
- --enable-cocoa) cocoa="yes" ; coreaudio="yes" ; sdl="no"
- ;;
- --disable-gcc-check) check_gcc="no"
- ;;
- --disable-system) softmmu="no"
- ;;
- --enable-system) softmmu="yes"
- ;;
- --disable-linux-user) linux_user="no"
- ;;
- --enable-linux-user) linux_user="yes"
- ;;
- --disable-darwin-user) darwin_user="no"
- ;;
- --enable-darwin-user) darwin_user="yes"
- ;;
- --enable-uname-release=*) uname_release="$optarg"
- ;;
- --enable-stubdom) stubdom="yes"
- ;;
- esac
-done
-
-# default flags for all hosts
-CFLAGS="$CFLAGS -Wall -O2 -g -fno-strict-aliasing"
-LDFLAGS="$LDFLAGS -g"
-
-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 ""
-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 " --disable-vnc-tls disable TLS encryption for VNC server"
-echo " --enable-system enable all system emulation targets"
-echo " --disable-system disable all system emulation targets"
-echo " --enable-linux-user enable all linux usermode emulation targets"
-echo " --disable-linux-user disable all linux usermode emulation targets"
-echo " --enable-darwin-user enable all darwin usermode emulation targets"
-echo " --disable-darwin-user disable all darwin usermode emulation targets"
-echo " --fmod-lib path to FMOD library"
-echo " --fmod-inc path to FMOD includes"
-echo " --enable-uname-release=R Return R for uname -r in usermode emulation"
-echo ""
-echo "NOTE: The object files are built at the place where configure is launched"
-exit 1
-fi
-
-cc="${cross_prefix}${cc}"
-ar="${cross_prefix}${ar}"
-strip="${cross_prefix}${strip}"
-
-# check that the C compiler works.
-cat > $TMPC <<EOF
-int main(void) {}
-EOF
-
-if $cc -c -o $TMPO $TMPC 2>/dev/null ; then
- : C compiler works ok
-else
- echo "ERROR: \"$cc\" either does not exist or does not work"
- exit 1
-fi
-
-if test "$mingw32" = "yes" ; then
- linux="no"
- EXESUF=".exe"
- oss="no"
- if [ "$cpu" = "i386" ] ; then
- kqemu="yes"
- fi
-fi
-
-# 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
- check_cc() {
- which "$1" >&/dev/null
- return $?
- }
-
- if "$cc" -o $TMPE $TMPC 2>/dev/null ; then
- echo "WARNING: \"$cc\" looks like gcc 4.x"
- found_compat_cc="no"
- if test "$gcc3_search" = "yes" ; then
- echo "Looking for gcc 3.x"
- for compat_cc in $gcc3_list ; do
- if check_cc "$compat_cc" ; then
- echo "Found \"$compat_cc\""
- cc="$compat_cc"
- found_compat_cc="yes"
- break
- fi
- done
- if test "$found_compat_cc" = "no" ; then
- echo "gcc 3.x not found!"
- fi
- fi
- if test "$found_compat_cc" = "no" ; then
- 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
-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
-
-##########################################
-
-# VNC TLS detection
-if test "$vnc_tls" = "yes" ; then
- `pkg-config gnutls` || vnc_tls="no"
-fi
-if test "$vnc_tls" = "yes" ; then
- vnc_tls_cflags=`pkg-config --cflags gnutls`
- vnc_tls_libs=`pkg-config --libs gnutls`
-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 [ "$linux_user" = "yes" ] ; then
- target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user ppc-linux-user mips-linux-user mipsel-linux-user m68k-linux-user $target_list"
- fi
-# the following are Darwin specific
- if [ "$darwin_user" = "yes" ] ; then
- target_list="i386-darwin-user ppc-darwin-user $target_list"
- fi
-# the i386-dm target
- if test "$stubdom" = "yes"; then
- target_list="i386-dm-stubdom"
- else
- target_list="i386-dm"
- fi
-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
-
-# ---
-# big/little endian test
-cat > $TMPC << EOF
-#include <inttypes.h>
-int main(int argc, char ** argv){
- volatile uint32_t i=0x01234567;
- return (*((uint8_t*)(&i))) == 0x67;
-}
-EOF
-
-if $cc -o $TMPE $TMPC 2>/dev/null ; then
-$TMPE && bigendian="yes"
-else
-echo big/little test failed
-fi
-
-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" -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
-cat > $TMPC <<EOF
-int main(void) {
-}
-EOF
-
-have_gcc3_options="no"
-if $cc -fno-reorder-blocks -fno-optimize-sibling-calls -o $TMPO $TMPC 2> /dev/null ; then
- have_gcc3_options="yes"
-fi
-
-##########################################
-# SDL probe
-
-sdl_too_old=no
-
-if test -z "$sdl" ; then
-
-sdl_config="sdl-config"
-sdl=no
-sdl_static=no
-
-if test "$mingw32" = "yes" -a ! -z "$cross_prefix" ; then
-# win32 cross compilation case
- sdl_config="i386-mingw32msvc-sdl-config"
- sdl=yes
-else
-# normal SDL probe
-cat > $TMPC << EOF
-#include <SDL.h>
-#undef main /* We don't want SDL to override our main() */
-int main( void ) { return SDL_Init (SDL_INIT_VIDEO); }
-EOF
-
-if $cc -o $TMPE `$sdl_config --cflags 2> /dev/null` $TMPC `$sdl_config --libs 2> /dev/null` 2> /dev/null ; then
-_sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'`
-if test "$_sdlversion" -lt 121 ; then
-sdl_too_old=yes
-else
- if test "$cocoa" = "no" ; then
- sdl=yes
- fi
-fi
-
-# static link with sdl ?
-if test "$sdl" = "yes" ; then
-aa="no"
-`$sdl_config --static-libs | grep \\\-laa > /dev/null` && aa="yes"
-sdl_static_libs=`$sdl_config --static-libs`
-if [ "$aa" = "yes" ] ; then
- sdl_static_libs="$sdl_static_libs `aalib-config --static-libs`"
-fi
-
-if $cc -o $TMPE `$sdl_config --cflags 2> /dev/null` $TMPC $sdl_static_libs 2> /dev/null; then
- sdl_static=yes
-fi
-
-fi # static link
-
-fi # sdl compile test
-
-fi # cross compilation
-
-else
- # Make sure to disable cocoa if sdl was set
- if test "$sdl" = "yes" ; then
- cocoa="no"
- coreaudio="no"
- fi
-fi # -z $sdl
-
-##########################################
-# OpenGL test
-
-if test -z "$opengl" && test "$sdl" = "yes"
-then
-cat > $TMPC << EOF
-#include <SDL_opengl.h>
-#ifndef GL_TEXTURE_RECTANGLE_ARB
-#error "Opengl doesn't support GL_TEXTURE_RECTANGLE_ARB"
-#endif
-int main( void ) { return (int) glGetString(GL_EXTENSIONS); }
-EOF
-if $cc -o $TMPE `$sdl_config --cflags --libs 2> /dev/null` -I/usr/include/GL $TMPC -lXext -lGL 2> /dev/null
-then
-opengl="yes"
-else
-opengl="no"
-fi
-fi
-
-##########################################
-# alsa sound support libraries
-
-if test "$alsa" = "yes" ; then
- cat > $TMPC << EOF
-#include <alsa/asoundlib.h>
-int main(void) { snd_pcm_t **handle; return snd_pcm_close(*handle); }
-EOF
- if $cc -o $TMPE $TMPC -lasound 2> /dev/null ; then
- :
- else
- echo
- echo "Error: Could not find alsa"
- echo "Make sure to have the alsa libs and headers installed."
- echo
- exit 1
- fi
-fi
-
-# 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"
-bindir="$prefix"
-configdir=""
-else
-if test -z "$prefix" ; then
- 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
-
-if test "$stubdom" = "yes"; then
- oss="no"
- sdl="no"
-fi
-
-echo "Install prefix $prefix"
-echo "BIOS directory $datadir"
-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"
-if test "$darwin" = "yes" ; then
- echo "Cocoa support $cocoa"
-fi
-echo "SDL support $sdl"
-if test "$sdl" != "no" ; then
- echo "SDL static link $sdl_static"
-fi
-echo "OpenGL support $opengl"
-echo "mingw32 support $mingw32"
-echo "Adlib support $adlib"
-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"
-[ ! -z "$uname_release" ] && \
-echo "uname -r $uname_release"
-
-if test $sdl_too_old = "yes"; then
-echo "-> Your SDL version is too old - please upgrade to have SDL support"
-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
-echo "bindir=$bindir" >> $config_mak
-echo "mandir=$mandir" >> $config_mak
-echo "datadir=$datadir" >> $config_mak
-echo "docdir=$docdir" >> $config_mak
-echo "configdir=$configdir" >> $config_mak
-echo "LIBDIR=$libdir" >> $config_mak
-echo "#define CONFIG_QEMU_SHAREDIR \"$datadir\"" >> $config_h
-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 "OS_CFLAGS=$OS_CFLAGS" >> $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
-elif test -f "/usr/include/byteswap.h" ; then
- echo "#define HAVE_BYTESWAP_H 1" >> $config_h
-fi
-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
-fi
-if test "$gprof" = "yes" ; then
- echo "TARGET_GPROF=yes" >> $config_mak
- echo "#define HAVE_GPROF 1" >> $config_h
-fi
-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
-fi
-if test "$adlib" = "yes" ; then
- echo "CONFIG_ADLIB=yes" >> $config_mak
- echo "#define CONFIG_ADLIB 1" >> $config_h
-fi
-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
- echo "CONFIG_FMOD_LIB=$fmod_lib" >> $config_mak
- echo "CONFIG_FMOD_INC=$fmod_inc" >> $config_mak
- echo "#define CONFIG_FMOD 1" >> $config_h
-fi
-if test "$vnc_tls" = "yes" ; then
- echo "CONFIG_VNC_TLS=yes" >> $config_mak
- echo "CONFIG_VNC_TLS_CFLAGS=$vnc_tls_cflags" >> $config_mak
- echo "CONFIG_VNC_TLS_LIBS=$vnc_tls_libs" >> $config_mak
- echo "#define CONFIG_VNC_TLS 1" >> $config_h
-fi
-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
- echo "#define O_LARGEFILE 0" >> $config_h
- echo "#define MAP_ANONYMOUS MAP_ANON" >> $config_h
- echo "#define _BSD 1" >> $config_h
-fi
-
-echo "#define CONFIG_UNAME_RELEASE \"$uname_release\"" >> $config_h
-
-for target in $target_list; do
-target_dir="$target"
-config_mak=$target_dir/config.mak
-config_h=$target_dir/config.h
-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_cpu" = "sh4eb" ] && target_bigendian=yes
-[ "$target_cpu" = "m68k" ] && target_bigendian=yes
-target_softmmu="no"
-if expr $target : '.*-softmmu' > /dev/null ; then
- target_softmmu="yes"
-fi
-#for support 256M guest
-target_softmmu="yes"
-target_user_only="no"
-if expr $target : '.*-user' > /dev/null ; then
- target_user_only="yes"
-fi
-
-target_linux_user="no"
-if expr $target : '.*-linux-user' > /dev/null ; then
- target_linux_user="yes"
-fi
-
-target_darwin_user="no"
-if expr $target : '.*-darwin-user' > /dev/null ; then
- target_darwin_user="yes"
-fi
-
-#echo "Creating $config_mak, $config_h and $target_dir/Makefile"
-
-mkdir -p $target_dir
-mkdir -p $target_dir/fpu
-if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" ; then
- mkdir -p $target_dir/nwfpe
-fi
-if test "$target_user_only" = "no" ; then
- mkdir -p $target_dir/slirp
-fi
-
-#
-# 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
-
-
-echo "include ../config-host.mak" >> $config_mak
-echo "#include \"../config-host.h\"" >> $config_h
-
-bflt="no"
-interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
-echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
-
-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
- bflt="yes"
-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
- echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
- echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
-elif test "$target_cpu" = "sh4" -o "$target_cpu" = "sh4eb" ; then
- echo "TARGET_ARCH=sh4" >> $config_mak
- echo "#define TARGET_ARCH \"sh4\"" >> $config_h
- echo "#define TARGET_SH4 1" >> $config_h
- bflt="yes"
-elif test "$target_cpu" = "m68k" ; then
- echo "TARGET_ARCH=m68k" >> $config_mak
- echo "#define TARGET_ARCH \"m68k\"" >> $config_h
- echo "#define TARGET_M68K 1" >> $config_h
- bflt="yes"
-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
-fi
-if test "$target_softmmu" = "yes" ; then
- echo "CONFIG_SOFTMMU=yes" >> $config_mak
- echo "#define CONFIG_SOFTMMU 1" >> $config_h
-fi
-if test "$target_user_only" = "yes" ; then
- echo "CONFIG_USER_ONLY=yes" >> $config_mak
- echo "#define CONFIG_USER_ONLY 1" >> $config_h
-fi
-if test "$target_linux_user" = "yes" ; then
- echo "CONFIG_LINUX_USER=yes" >> $config_mak
- echo "#define CONFIG_LINUX_USER 1" >> $config_h
-fi
-if test "$target_darwin_user" = "yes" ; then
- echo "CONFIG_DARWIN_USER=yes" >> $config_mak
- echo "#define CONFIG_DARWIN_USER 1" >> $config_h
-fi
-if expr $target : '.*-dm' > /dev/null ; then
- echo "#define CONFIG_DM 1" >> $config_h
-fi
-
-if test "$stubdom" = "yes" ; then
- echo "CONFIG_STUBDOM=yes" >> $config_mak
- echo "#define CONFIG_STUBDOM 1" >> $config_h
- echo "#define NO_UNIX_SOCKETS 1" >> $config_h
- echo "#define NO_DAEMONIZE 1" >> $config_h
- echo "#define NO_AIO 1" >> $config_h
-fi
-
-if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64" -o "$target_cpu" = "m68k"; then
- echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
- echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
-fi
-if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
- echo "TARGET_HAS_BFLT=yes" >> $config_mak
- echo "#define TARGET_HAS_BFLT 1" >> $config_h
-fi
-# sdl defines
-
-if test "$target_user_only" = "no"; then
- if test "$target_softmmu" = "no" -o "$static" = "yes"; then
- sdl1=$sdl_static
- else
- sdl1=$sdl
- fi
- if test "$sdl1" = "yes" ; then
- echo "#define CONFIG_SDL 1" >> $config_h
- echo "CONFIG_SDL=yes" >> $config_mak
- if test "$target_softmmu" = "no" -o "$static" = "yes"; then
- echo "SDL_LIBS=$sdl_static_libs" >> $config_mak
- else
- echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak
- fi
- if [ "${aa}" = "yes" ] ; then
- echo "SDL_CFLAGS=`$sdl_config --cflags` `aalib-config --cflags`" >> $config_mak
- else
- echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
- fi
- fi
-fi
-
-if test $opengl = "yes"
-then
- echo "#define CONFIG_OPENGL 1" >> $config_h
- echo "CONFIG_OPENGL=yes" >> $config_mak
- echo "SDL_CFLAGS+=-I/usr/include/GL" >> $config_mak
- echo "SDL_LIBS+=-lXext" >> $config_mak
- echo "SDL_LIBS+=-lGL" >> $config_mak
-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
-
-# build tree in object directory if source path is different from current one
-if test "$source_path_used" = "yes" ; then
- DIRS="tests"
- FILES="Makefile tests/Makefile"
- 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
- rm -f $f
- ln -s $source_path/$f $f
- done
-fi
-
-echo "VNC TLS support $vnc_tls"
-if test "$vnc_tls" = "yes" ; then
- echo " TLS CFLAGS $vnc_tls_cflags"
- echo " TLS LIBS $vnc_tls_libs"
-fi
-
-rm -f $TMPO $TMPC $TMPE $TMPS
diff --git a/tools/ioemu/console.c b/tools/ioemu/console.c
deleted file mode 100644
index dc904f6574..0000000000
--- a/tools/ioemu/console.c
+++ /dev/null
@@ -1,1217 +0,0 @@
-/*
- * QEMU graphical console
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_CONSOLE
-#define DEFAULT_BACKSCROLL 512
-#define MAX_CONSOLES 12
-
-#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
-
-typedef struct TextAttributes {
- uint8_t fgcol:4;
- 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;
- TextAttributes t_attrib;
-} TextCell;
-
-#define MAX_ESC_PARAMS 3
-
-enum TTYState {
- TTY_STATE_NORM,
- TTY_STATE_ESC,
- TTY_STATE_CSI,
-};
-
-typedef struct QEMUFIFO {
- uint8_t *buf;
- int buf_size;
- int count, wptr, rptr;
-} QEMUFIFO;
-
-int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
-{
- int l, len;
-
- l = f->buf_size - f->count;
- if (len1 > l)
- len1 = l;
- len = len1;
- while (len > 0) {
- l = f->buf_size - f->wptr;
- if (l > len)
- l = len;
- memcpy(f->buf + f->wptr, buf, l);
- f->wptr += l;
- if (f->wptr >= f->buf_size)
- f->wptr = 0;
- buf += l;
- len -= l;
- }
- f->count += len1;
- return len1;
-}
-
-int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
-{
- int l, len;
-
- if (len1 > f->count)
- len1 = f->count;
- len = len1;
- while (len > 0) {
- l = f->buf_size - f->rptr;
- if (l > len)
- l = len;
- memcpy(buf, f->buf + f->rptr, l);
- f->rptr += l;
- if (f->rptr >= f->buf_size)
- f->rptr = 0;
- buf += l;
- len -= l;
- }
- f->count -= len1;
- return len1;
-}
-
-/* ??? This is mis-named.
- It is used for both text and graphical consoles. */
-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 x, y;
- int x_saved, y_saved;
- 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;
- int esc_params[MAX_ESC_PARAMS];
- int nb_esc_params;
-
- CharDriverState *chr;
- /* fifo for key pressed */
- QEMUFIFO out_fifo;
- uint8_t out_fifo_buf[16];
- QEMUTimer *kbd_timer;
-};
-
-static TextConsole *active_console;
-static TextConsole *consoles[MAX_CONSOLES];
-static int nb_consoles = 0;
-
-void vga_hw_update(void)
-{
- if (active_console && 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)
-{
- unsigned int r, g, b, color;
-
- switch(ds->depth) {
- case 8:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = ((r >> 5) << 5 | (g >> 5) << 2 | (b >> 6));
- break;
- case 15:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
- break;
- case 16:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
- break;
- case 32:
- default:
- color = rgba;
- break;
- }
- return color;
-}
-
-static void vga_fill_rect (DisplayState *ds,
- int posx, int posy, int width, int height, uint32_t color)
-{
- uint8_t *d, *d1;
- int x, y, bpp;
-
- bpp = (ds->depth + 7) >> 3;
- d1 = ds->data +
- ds->linesize * posy + bpp * posx;
- for (y = 0; y < height; y++) {
- d = d1;
- switch(bpp) {
- case 1:
- for (x = 0; x < width; x++) {
- *((uint8_t *)d) = color;
- d++;
- }
- break;
- case 2:
- for (x = 0; x < width; x++) {
- *((uint16_t *)d) = color;
- d += 2;
- }
- break;
- case 4:
- for (x = 0; x < width; x++) {
- *((uint32_t *)d) = color;
- d += 4;
- }
- break;
- }
- d1 += ds->linesize;
- }
-}
-
-/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
-static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h)
-{
- const uint8_t *s;
- uint8_t *d;
- int wb, y, bpp;
-
- bpp = (ds->depth + 7) >> 3;
- wb = w * bpp;
- if (yd <= ys) {
- s = ds->data +
- ds->linesize * ys + bpp * xs;
- d = ds->data +
- ds->linesize * yd + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d += ds->linesize;
- s += ds->linesize;
- }
- } else {
- s = ds->data +
- ds->linesize * (ys + h - 1) + bpp * xs;
- d = ds->data +
- ds->linesize * (yd + h - 1) + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d -= ds->linesize;
- s -= ds->linesize;
- }
- }
-}
-
-/***********************************************************/
-/* basic char display */
-
-#define FONT_HEIGHT 16
-#define FONT_WIDTH 8
-
-#include "vgafont.h"
-
-#define cbswap_32(__x) \
-((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef WORDS_BIGENDIAN
-#define PAT(x) x
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static const uint32_t dmask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
- PAT(0x00000000),
- PAT(0x0000ffff),
- PAT(0xffff0000),
- PAT(0xffffffff),
-};
-
-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 */
- QEMU_RGB(0x00, 0x00, 0x00), /* black */
- QEMU_RGB(0xaa, 0x00, 0x00), /* red */
- QEMU_RGB(0x00, 0xaa, 0x00), /* green */
- QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */
- QEMU_RGB(0x00, 0x00, 0xaa), /* blue */
- QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */
- QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */
- QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */
- },
- { /* bright */
- QEMU_RGB(0x00, 0x00, 0x00), /* black */
- QEMU_RGB(0xff, 0x00, 0x00), /* red */
- QEMU_RGB(0x00, 0xff, 0x00), /* green */
- QEMU_RGB(0xff, 0xff, 0x00), /* yellow */
- QEMU_RGB(0x00, 0x00, 0xff), /* blue */
- QEMU_RGB(0xff, 0x00, 0xff), /* magenta */
- QEMU_RGB(0x00, 0xff, 0xff), /* cyan */
- QEMU_RGB(0xff, 0xff, 0xff), /* white */
- }
-};
-
-static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
-{
- switch(ds->depth) {
- case 8:
- col |= col << 8;
- col |= col << 16;
- break;
- case 15:
- case 16:
- col |= col << 16;
- break;
- default:
- break;
- }
-
- 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,
- 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 +
- ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
- linesize = ds->linesize;
- font_ptr = vgafont16 + FONT_HEIGHT * ch;
- xorcol = bgcol ^ fgcol;
- switch(ds->depth) {
- 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;
- }
- break;
- case 16:
- 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;
- ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- 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;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- }
-}
-
-static void text_console_resize(TextConsole *s)
-{
- TextCell *cells, *c, *c1;
- int w1, x, y, last_width;
-
- last_width = s->width;
- s->width = s->g_width / FONT_WIDTH;
- s->height = s->g_height / FONT_HEIGHT;
-
- w1 = last_width;
- if (s->width < w1)
- w1 = s->width;
-
- cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
- for(y = 0; y < s->total_height; y++) {
- c = &cells[y * s->width];
- if (w1 > 0) {
- c1 = &s->cells[y * last_width];
- for(x = 0; x < w1; x++) {
- *c++ = *c1++;
- }
- }
- for(x = w1; x < s->width; x++) {
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- }
- }
- qemu_free(s->cells);
- s->cells = cells;
-}
-
-static void update_xy(TextConsole *s, int x, int y)
-{
- TextCell *c;
- int y1, y2;
-
- if (s == active_console) {
- y1 = (s->y_base + y) % s->total_height;
- y2 = y1 - s->y_displayed;
- if (y2 < 0)
- y2 += s->total_height;
- if (y2 < s->height) {
- c = &s->cells[y1 * s->width + x];
- vga_putcharxy(s->ds, x, y2, c->ch,
- &(c->t_attrib));
- dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
- FONT_WIDTH, FONT_HEIGHT);
- }
- }
-}
-
-static void console_show_cursor(TextConsole *s, int show)
-{
- TextCell *c;
- int y, y1;
-
- if (s == active_console) {
- y1 = (s->y_base + s->y) % s->total_height;
- y = y1 - s->y_displayed;
- if (y < 0)
- y += s->total_height;
- if (y < s->height) {
- c = &s->cells[y1 * s->width + s->x];
- if (show) {
- TextAttributes t_attrib = s->t_attrib_default;
- t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
- vga_putcharxy(s->ds, s->x, y, c->ch, &t_attrib);
- } else {
- vga_putcharxy(s->ds, s->x, y, c->ch,
- &(c->t_attrib));
- }
- dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,
- FONT_WIDTH, FONT_HEIGHT);
- }
- }
-}
-
-static void console_refresh(TextConsole *s)
-{
- TextCell *c;
- int x, y, y1;
-
- if (s != active_console)
- return;
-
- vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
- color_table[0][COLOR_BLACK]);
- y1 = s->y_displayed;
- for(y = 0; y < s->height; y++) {
- c = s->cells + y1 * s->width;
- for(x = 0; x < s->width; x++) {
- vga_putcharxy(s->ds, x, y, c->ch,
- &(c->t_attrib));
- c++;
- }
- if (++y1 == s->total_height)
- y1 = 0;
- }
- dpy_update(s->ds, 0, 0, s->ds->width, s->ds->height);
- console_show_cursor(s, 1);
-}
-
-static void console_scroll(int ydelta)
-{
- TextConsole *s;
- int i, y1;
-
- s = active_console;
- if (!s || !s->text_console)
- return;
-
- if (ydelta > 0) {
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == s->y_base)
- break;
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- } else {
- ydelta = -ydelta;
- i = s->backscroll_height;
- if (i > s->total_height - s->height)
- i = s->total_height - s->height;
- y1 = s->y_base - i;
- if (y1 < 0)
- y1 += s->total_height;
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == y1)
- break;
- if (--s->y_displayed < 0)
- s->y_displayed = s->total_height - 1;
- }
- }
- console_refresh(s);
-}
-
-static void console_put_lf(TextConsole *s)
-{
- TextCell *c;
- int x, y1;
-
- s->y++;
- if (s->y >= s->height) {
- s->y = s->height - 1;
-
- if (s->y_displayed == s->y_base) {
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- if (++s->y_base == s->total_height)
- s->y_base = 0;
- if (s->backscroll_height < s->total_height)
- s->backscroll_height++;
- y1 = (s->y_base + s->height - 1) % s->total_height;
- c = &s->cells[y1 * s->width];
- for(x = 0; x < s->width; x++) {
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- }
- if (s == active_console && s->y_displayed == s->y_base) {
- vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
- s->width * FONT_WIDTH,
- (s->height - 1) * FONT_HEIGHT);
- vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
- s->width * FONT_WIDTH, FONT_HEIGHT,
- color_table[0][s->t_attrib_default.bgcol]);
- dpy_update(s->ds, 0, 0,
- s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
- }
- }
-}
-
-/* Set console attributes depending on the current escape codes.
- * NOTE: I know this code is not very efficient (checking every color for it
- * self) but it is more readable and better maintainable.
- */
-static void console_handle_escape(TextConsole *s)
-{
- int i;
-
- for (i=0; i<s->nb_esc_params; i++) {
- switch (s->esc_params[i]) {
- case 0: /* reset all console attributes to default */
- s->t_attrib = s->t_attrib_default;
- break;
- case 1:
- s->t_attrib.bold = 1;
- break;
- case 4:
- s->t_attrib.uline = 1;
- break;
- case 5:
- s->t_attrib.blink = 1;
- break;
- case 7:
- s->t_attrib.invers = 1;
- break;
- case 8:
- s->t_attrib.unvisible = 1;
- break;
- case 22:
- s->t_attrib.bold = 0;
- break;
- case 24:
- s->t_attrib.uline = 0;
- break;
- case 25:
- s->t_attrib.blink = 0;
- break;
- case 27:
- s->t_attrib.invers = 0;
- break;
- case 28:
- s->t_attrib.unvisible = 0;
- break;
- /* set foreground color */
- case 30:
- s->t_attrib.fgcol=COLOR_BLACK;
- break;
- case 31:
- s->t_attrib.fgcol=COLOR_RED;
- break;
- case 32:
- s->t_attrib.fgcol=COLOR_GREEN;
- break;
- case 33:
- s->t_attrib.fgcol=COLOR_YELLOW;
- break;
- case 34:
- s->t_attrib.fgcol=COLOR_BLUE;
- break;
- case 35:
- s->t_attrib.fgcol=COLOR_MAGENTA;
- break;
- case 36:
- s->t_attrib.fgcol=COLOR_CYAN;
- break;
- case 37:
- s->t_attrib.fgcol=COLOR_WHITE;
- break;
- /* set background color */
- case 40:
- s->t_attrib.bgcol=COLOR_BLACK;
- break;
- case 41:
- s->t_attrib.bgcol=COLOR_RED;
- break;
- case 42:
- s->t_attrib.bgcol=COLOR_GREEN;
- break;
- case 43:
- s->t_attrib.bgcol=COLOR_YELLOW;
- break;
- case 44:
- s->t_attrib.bgcol=COLOR_BLUE;
- break;
- case 45:
- s->t_attrib.bgcol=COLOR_MAGENTA;
- break;
- case 46:
- s->t_attrib.bgcol=COLOR_CYAN;
- break;
- case 47:
- s->t_attrib.bgcol=COLOR_WHITE;
- break;
- }
- }
-}
-
-static void console_clear_xy(TextConsole *s, int x, int y)
-{
- int y1 = (s->y_base + y) % s->total_height;
- TextCell *c = &s->cells[y1 * s->width + x];
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- update_xy(s, x, y);
-}
-
-static void console_putchar(TextConsole *s, int ch)
-{
- TextCell *c;
- int y1, i;
- int x, y;
-
- switch(s->state) {
- case TTY_STATE_NORM:
- switch(ch) {
- case '\r': /* carriage return */
- s->x = 0;
- break;
- case '\n': /* newline */
- console_put_lf(s);
- break;
- case '\b': /* backspace */
- if (s->x > 0)
- s->x--;
- break;
- case '\t': /* tabspace */
- if (s->x + (8 - (s->x % 8)) > s->width) {
- s->x = 0;
- console_put_lf(s);
- } else {
- s->x = s->x + (8 - (s->x % 8));
- }
- break;
- case '\a': /* alert aka. bell */
- /* TODO: has to be implemented */
- break;
- case 14:
- /* SI (shift in), character set 0 (ignored) */
- break;
- case 15:
- /* SO (shift out), character set 1 (ignored) */
- break;
- case 27: /* esc (introducing an escape sequence) */
- s->state = TTY_STATE_ESC;
- break;
- default:
- if (s->x >= s->width - 1) {
- break;
- }
- y1 = (s->y_base + s->y) % s->total_height;
- c = &s->cells[y1 * s->width + s->x];
- c->ch = ch;
- c->t_attrib = s->t_attrib;
- update_xy(s, s->x, s->y);
- s->x++;
-#if 0 /* line wrap disabled */
- if (s->x >= s->width) {
- s->x = 0;
- console_put_lf(s);
- }
-#endif
- break;
- }
- break;
- case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
- if (ch == '[') {
- for(i=0;i<MAX_ESC_PARAMS;i++)
- s->esc_params[i] = 0;
- s->nb_esc_params = 0;
- s->state = TTY_STATE_CSI;
- } else {
- s->state = TTY_STATE_NORM;
- }
- break;
- case TTY_STATE_CSI: /* handle escape sequence parameters */
- if (ch >= '0' && ch <= '9') {
- if (s->nb_esc_params < MAX_ESC_PARAMS) {
- s->esc_params[s->nb_esc_params] =
- s->esc_params[s->nb_esc_params] * 10 + ch - '0';
- }
- } else {
- s->nb_esc_params++;
- if (ch == ';')
- break;
-#ifdef DEBUG_CONSOLE
- fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
- s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
-#endif
- s->state = TTY_STATE_NORM;
- switch(ch) {
- case 'A':
- /* move cursor up */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->y -= s->esc_params[0];
- if (s->y < 0) {
- s->y = 0;
- }
- break;
- case 'B':
- /* move cursor down */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->y += s->esc_params[0];
- if (s->y >= s->height) {
- s->y = s->height - 1;
- }
- break;
- case 'C':
- /* move cursor right */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->x += s->esc_params[0];
- if (s->x >= s->width) {
- s->x = s->width - 1;
- }
- break;
- case 'D':
- /* move cursor left */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->x -= s->esc_params[0];
- if (s->x < 0) {
- s->x = 0;
- }
- break;
- case 'G':
- /* move cursor to column */
- s->x = s->esc_params[0] - 1;
- if (s->x < 0) {
- s->x = 0;
- }
- break;
- case 'f':
- case 'H':
- /* move cursor to row, column */
- s->x = s->esc_params[1] - 1;
- if (s->x < 0) {
- s->x = 0;
- }
- s->y = s->esc_params[0] - 1;
- if (s->y < 0) {
- s->y = 0;
- }
- break;
- case 'J':
- switch (s->esc_params[0]) {
- case 0:
- /* clear to end of screen */
- for (y = s->y; y < s->height; y++) {
- for (x = 0; x < s->width; x++) {
- if (y == s->y && x < s->x) {
- continue;
- }
- console_clear_xy(s, x, y);
- }
- }
- break;
- case 1:
- /* clear from beginning of screen */
- for (y = 0; y <= s->y; y++) {
- for (x = 0; x < s->width; x++) {
- if (y == s->y && x > s->x) {
- break;
- }
- console_clear_xy(s, x, y);
- }
- }
- break;
- case 2:
- /* clear entire screen */
- for (y = 0; y <= s->height; y++) {
- for (x = 0; x < s->width; x++) {
- console_clear_xy(s, x, y);
- }
- }
- break;
- }
- case 'K':
- switch (s->esc_params[0]) {
- case 0:
- /* clear to eol */
- for(x = s->x; x < s->width; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- case 1:
- /* clear from beginning of line */
- for (x = 0; x <= s->x; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- case 2:
- /* clear entire line */
- for(x = 0; x < s->width; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- }
- break;
- case 'm':
- console_handle_escape(s);
- break;
- case 'n':
- /* report cursor position */
- /* TODO: send ESC[row;colR */
- break;
- case 's':
- /* save cursor position */
- s->x_saved = s->x;
- s->y_saved = s->y;
- break;
- case 'u':
- /* restore cursor position */
- s->x = s->x_saved;
- s->y = s->y_saved;
- break;
- default:
-#ifdef DEBUG_CONSOLE
- fprintf(stderr, "unhandled escape character '%c'\n", ch);
-#endif
- break;
- }
- break;
- }
- }
-}
-
-void console_select(unsigned int index)
-{
- TextConsole *s;
-
- if (index >= MAX_CONSOLES)
- return;
- s = consoles[index];
- if (s) {
- active_console = s;
- if (s->text_console) {
- if (s->g_width != s->ds->width ||
- s->g_height != s->ds->height) {
- s->g_width = s->ds->width;
- s->g_height = s->ds->height;
- text_console_resize(s);
- }
- console_refresh(s);
- } else {
- vga_hw_invalidate();
- }
- }
-}
-
-static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
-{
- TextConsole *s = chr->opaque;
- int i;
-
- console_show_cursor(s, 0);
- for(i = 0; i < len; i++) {
- console_putchar(s, buf[i]);
- }
- console_show_cursor(s, 1);
- return len;
-}
-
-static void console_send_event(CharDriverState *chr, int event)
-{
- TextConsole *s = chr->opaque;
- int i;
-
- if (event == CHR_EVENT_FOCUS) {
- for(i = 0; i < nb_consoles; i++) {
- if (consoles[i] == s) {
- console_select(i);
- break;
- }
- }
- }
-}
-
-static void kbd_send_chars(void *opaque)
-{
- TextConsole *s = opaque;
- int len;
- uint8_t buf[16];
-
- len = qemu_chr_can_read(s->chr);
- if (len > s->out_fifo.count)
- len = s->out_fifo.count;
- if (len > 0) {
- if (len > sizeof(buf))
- len = sizeof(buf);
- qemu_fifo_read(&s->out_fifo, buf, len);
- qemu_chr_read(s->chr, buf, len);
- }
- /* characters are pending: we send them a bit later (XXX:
- horrible, should change char device API) */
- if (s->out_fifo.count > 0) {
- qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
- }
-}
-
-/* called when an ascii key is pressed */
-void kbd_put_keysym(int keysym)
-{
- TextConsole *s;
- uint8_t buf[16], *q;
- int c;
-
- s = active_console;
- if (!s || !s->text_console)
- return;
-
- switch(keysym) {
- case QEMU_KEY_CTRL_UP:
- console_scroll(-1);
- break;
- case QEMU_KEY_CTRL_DOWN:
- console_scroll(1);
- break;
- case QEMU_KEY_CTRL_PAGEUP:
- console_scroll(-10);
- break;
- case QEMU_KEY_CTRL_PAGEDOWN:
- console_scroll(10);
- break;
- default:
- /* convert the QEMU keysym to VT100 key string */
- q = buf;
- if (keysym >= 0xe100 && keysym <= 0xe11f) {
- *q++ = '\033';
- *q++ = '[';
- c = keysym - 0xe100;
- if (c >= 10)
- *q++ = '0' + (c / 10);
- *q++ = '0' + (c % 10);
- *q++ = '~';
- } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
- *q++ = '\033';
- *q++ = '[';
- *q++ = keysym & 0xff;
- } else {
- *q++ = keysym;
- }
- if (s->chr->chr_read) {
- qemu_fifo_write(&s->out_fifo, buf, q - buf);
- kbd_send_chars(s);
- }
- break;
- }
-}
-
-static TextConsole *new_console(DisplayState *ds, int text)
-{
- TextConsole *s;
- int i;
-
- if (nb_consoles >= MAX_CONSOLES)
- return NULL;
- s = qemu_mallocz(sizeof(TextConsole));
- if (!s) {
- return NULL;
- }
- if (!active_console || (active_console->text_console && !text))
- active_console = s;
- s->ds = ds;
- s->text_console = text;
- if (text) {
- consoles[nb_consoles++] = s;
- } else {
- /* HACK: Put graphical consoles before text consoles. */
- for (i = nb_consoles; i > 0; i--) {
- if (!consoles[i - 1]->text_console)
- break;
- consoles[i] = consoles[i - 1];
- }
- consoles[i] = s;
- }
- return s;
-}
-
-TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
- vga_hw_invalidate_ptr invalidate,
- vga_hw_screen_dump_ptr screen_dump,
- void *opaque)
-{
- TextConsole *s;
-
- s = new_console(ds, 0);
- if (!s)
- return NULL;
- s->hw_update = update;
- s->hw_invalidate = invalidate;
- s->hw_screen_dump = screen_dump;
- s->hw = opaque;
- return s;
-}
-
-int is_graphic_console(void)
-{
- return !active_console->text_console;
-}
-
-void set_color_table(DisplayState *ds)
-{
- int i, j;
- for(j = 0; j < 2; j++) {
- for(i = 0; i < 8; i++) {
- color_table[j][i] =
- col_expand(ds, vga_get_color(ds, color_table_rgb[j][i]));
- }
- }
-}
-
-CharDriverState *text_console_init(DisplayState *ds)
-{
- CharDriverState *chr;
- TextConsole *s;
- static int color_inited;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = new_console(ds, 1);
- if (!s) {
- free(chr);
- return NULL;
- }
- chr->opaque = s;
- chr->chr_write = console_puts;
- chr->chr_send_event = console_send_event;
-
- s->chr = chr;
- s->out_fifo.buf = s->out_fifo_buf;
- s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
- s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
-
- if (!color_inited) {
- color_inited = 1;
- set_color_table(ds);
- }
- s->y_displayed = 0;
- s->y_base = 0;
- s->total_height = DEFAULT_BACKSCROLL;
- s->x = 0;
- s->y = 0;
- s->g_width = s->ds->width;
- s->g_height = s->ds->height;
-
- /* Set text attribute defaults */
- s->t_attrib_default.bold = 0;
- s->t_attrib_default.uline = 0;
- s->t_attrib_default.blink = 0;
- s->t_attrib_default.invers = 0;
- s->t_attrib_default.unvisible = 0;
- s->t_attrib_default.fgcol = COLOR_WHITE;
- s->t_attrib_default.bgcol = COLOR_BLACK;
-
- /* set current text attributes to default */
- s->t_attrib = s->t_attrib_default;
- text_console_resize(s);
-
- qemu_chr_reset(chr);
-
- return chr;
-}
diff --git a/tools/ioemu/cpu-all.h b/tools/ioemu/cpu-all.h
deleted file mode 100644
index 9cc854ed7c..0000000000
--- a/tools/ioemu/cpu-all.h
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * defines common to all virtual CPUs
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_ALL_H
-#define CPU_ALL_H
-
-#if defined(__arm__) || defined(__sparc__)
-#define WORDS_ALIGNED
-#endif
-
-/* some important defines:
- *
- * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
- * memory accesses.
- *
- * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
- * otherwise little endian.
- *
- * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
- *
- * TARGET_WORDS_BIGENDIAN : same for target cpu
- */
-
-#include "bswap.h"
-
-#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
-#define BSWAP_NEEDED
-#endif
-
-#ifdef BSWAP_NEEDED
-
-static inline uint16_t tswap16(uint16_t s)
-{
- return bswap16(s);
-}
-
-static inline uint32_t tswap32(uint32_t s)
-{
- return bswap32(s);
-}
-
-static inline uint64_t tswap64(uint64_t s)
-{
- return bswap64(s);
-}
-
-static inline void tswap16s(uint16_t *s)
-{
- *s = bswap16(*s);
-}
-
-static inline void tswap32s(uint32_t *s)
-{
- *s = bswap32(*s);
-}
-
-static inline void tswap64s(uint64_t *s)
-{
- *s = bswap64(*s);
-}
-
-#else
-
-static inline uint16_t tswap16(uint16_t s)
-{
- return s;
-}
-
-static inline uint32_t tswap32(uint32_t s)
-{
- return s;
-}
-
-static inline uint64_t tswap64(uint64_t s)
-{
- return s;
-}
-
-static inline void tswap16s(uint16_t *s)
-{
-}
-
-static inline void tswap32s(uint32_t *s)
-{
-}
-
-static inline void tswap64s(uint64_t *s)
-{
-}
-
-#endif
-
-#if TARGET_LONG_SIZE == 4
-#define tswapl(s) tswap32(s)
-#define tswapls(s) tswap32s((uint32_t *)(s))
-#define bswaptls(s) bswap32s(s)
-#else
-#define tswapl(s) tswap64(s)
-#define tswapls(s) tswap64s((uint64_t *)(s))
-#define bswaptls(s) bswap64s(s)
-#endif
-
-#ifdef CONFIG_SOFTFLOAT
-/* NOTE: arm FPA is horrible as double 32 bit words are stored in big
- endian ! */
-typedef union {
- float64 d;
-#if defined(WORDS_BIGENDIAN) \
- || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
- struct {
- uint32_t upper;
- uint32_t lower;
- } l;
-#else
- struct {
- uint32_t lower;
- uint32_t upper;
- } l;
-#endif
- uint64_t ll;
-} CPU_DoubleU;
-#endif
-
-/* CPU memory access without any memory or io remapping */
-
-/*
- * the generic syntax for the memory accesses is:
- *
- * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
- *
- * store: st{type}{size}{endian}_{access_type}(ptr, val)
- *
- * type is:
- * (empty): integer access
- * f : float access
- *
- * sign is:
- * (empty): for floats or 32 bit size
- * u : unsigned
- * s : signed
- *
- * size is:
- * b: 8 bits
- * w: 16 bits
- * l: 32 bits
- * q: 64 bits
- *
- * endian is:
- * (empty): target cpu endianness or 8 bit access
- * r : reversed target cpu endianness (not implemented yet)
- * be : big endian (not implemented yet)
- * le : little endian (not implemented yet)
- *
- * access_type is:
- * raw : host memory access
- * user : user mode access using soft MMU
- * kernel : kernel mode access using soft MMU
- */
-static inline int ldub_p(void *ptr)
-{
- return *(uint8_t *)ptr;
-}
-
-static inline int ldsb_p(void *ptr)
-{
- return *(int8_t *)ptr;
-}
-
-static inline void stb_p(void *ptr, int v)
-{
- *(uint8_t *)ptr = v;
-}
-
-/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
- kernel handles unaligned load/stores may give better results, but
- it is a system wide setting : bad */
-#if defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
-/* conservative code for little endian unaligned accesses */
-static inline int lduw_le_p(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return val;
-#else
- uint8_t *p = ptr;
- return p[0] | (p[1] << 8);
-#endif
-}
-
-static inline int ldsw_le_p(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return (int16_t)val;
-#else
- uint8_t *p = ptr;
- return (int16_t)(p[0] | (p[1] << 8));
-#endif
-}
-
-static inline int ldl_le_p(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return val;
-#else
- uint8_t *p = ptr;
- return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-#endif
-}
-
-static inline uint64_t ldq_le_p(void *ptr)
-{
- uint8_t *p = ptr;
- uint32_t v1, v2;
- v1 = ldl_le_p(p);
- v2 = ldl_le_p(p + 4);
- return v1 | ((uint64_t)v2 << 32);
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
-#ifdef __powerpc__
- __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
-#else
- uint8_t *p = ptr;
- p[0] = v;
- p[1] = v >> 8;
-#endif
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
-#ifdef __powerpc__
- __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
-#else
- uint8_t *p = ptr;
- p[0] = v;
- p[1] = v >> 8;
- p[2] = v >> 16;
- p[3] = v >> 24;
-#endif
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
- uint8_t *p = ptr;
- stl_le_p(p, (uint32_t)v);
- stl_le_p(p + 4, v >> 32);
-}
-
-#ifdef CONFIG_SOFTFLOAT
-/* float access */
-
-static inline float32 ldfl_le_p(void *ptr)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = ldl_le_p(ptr);
- return u.f;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = v;
- stl_le_p(ptr, u.i);
-}
-
-static inline float64 ldfq_le_p(void *ptr)
-{
- CPU_DoubleU u;
- u.l.lower = ldl_le_p(ptr);
- u.l.upper = ldl_le_p(ptr + 4);
- return u.d;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
- CPU_DoubleU u;
- u.d = v;
- stl_le_p(ptr, u.l.lower);
- stl_le_p(ptr + 4, u.l.upper);
-}
-#endif
-
-#else
-
-static inline int lduw_le_p(void *ptr)
-{
- return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_le_p(void *ptr)
-{
- return *(int16_t *)ptr;
-}
-
-static inline int ldl_le_p(void *ptr)
-{
- return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_le_p(void *ptr)
-{
- return *(uint64_t *)ptr;
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
- *(uint16_t *)ptr = v;
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
- *(uint32_t *)ptr = v;
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
- *(uint64_t *)ptr = v;
-}
-
-#ifdef CONFIG_SOFTFLOAT
-/* float access */
-
-static inline float32 ldfl_le_p(void *ptr)
-{
- return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_le_p(void *ptr)
-{
- return *(float64 *)ptr;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
- *(float32 *)ptr = v;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
- *(float64 *)ptr = v;
-}
-#endif
-#endif
-
-#if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
-static inline int lduw_be_p(void *ptr)
-{
-#if defined(__i386__)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return ((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldsw_be_p(void *ptr)
-{
-#if defined(__i386__)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return (int16_t)val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (int16_t)((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldl_be_p(void *ptr)
-{
-#if defined(__i386__) || defined(__x86_64__)
- int val;
- asm volatile ("movl %1, %0\n"
- "bswap %0\n"
- : "=r" (val)
- : "m" (*(uint32_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-#endif
-}
-
-static inline uint64_t ldq_be_p(void *ptr)
-{
- uint32_t a,b;
- a = ldl_be_p(ptr);
- b = ldl_be_p(ptr+4);
- return (((uint64_t)a<<32)|b);
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
-#if defined(__i386__)
- asm volatile ("xchgb %b0, %h0\n"
- "movw %w0, %1\n"
- : "=q" (v)
- : "m" (*(uint16_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 8;
- d[1] = v;
-#endif
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
-#if defined(__i386__) || defined(__x86_64__)
- asm volatile ("bswap %0\n"
- "movl %0, %1\n"
- : "=r" (v)
- : "m" (*(uint32_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 24;
- d[1] = v >> 16;
- d[2] = v >> 8;
- d[3] = v;
-#endif
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
- stl_be_p(ptr, v >> 32);
- stl_be_p(ptr + 4, v);
-}
-
-#ifdef CONFIG_SOFTFLOAT
-/* float access */
-
-static inline float32 ldfl_be_p(void *ptr)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = ldl_be_p(ptr);
- return u.f;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = v;
- stl_be_p(ptr, u.i);
-}
-
-static inline float64 ldfq_be_p(void *ptr)
-{
- CPU_DoubleU u;
- u.l.upper = ldl_be_p(ptr);
- u.l.lower = ldl_be_p(ptr + 4);
- return u.d;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
- CPU_DoubleU u;
- u.d = v;
- stl_be_p(ptr, u.l.upper);
- stl_be_p(ptr + 4, u.l.lower);
-}
-#endif
-
-#else
-
-static inline int lduw_be_p(void *ptr)
-{
- return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_be_p(void *ptr)
-{
- return *(int16_t *)ptr;
-}
-
-static inline int ldl_be_p(void *ptr)
-{
- return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_be_p(void *ptr)
-{
- return *(uint64_t *)ptr;
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
- *(uint16_t *)ptr = v;
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
- *(uint32_t *)ptr = v;
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
- *(uint64_t *)ptr = v;
-}
-
-#ifdef CONFIG_SOFTFLOAT
-/* float access */
-
-static inline float32 ldfl_be_p(void *ptr)
-{
- return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_be_p(void *ptr)
-{
- return *(float64 *)ptr;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
- *(float32 *)ptr = v;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
- *(float64 *)ptr = v;
-}
-#endif
-
-#endif
-
-/* target CPU memory access functions */
-#if defined(TARGET_WORDS_BIGENDIAN)
-#define lduw_p(p) lduw_be_p(p)
-#define ldsw_p(p) ldsw_be_p(p)
-#define ldl_p(p) ldl_be_p(p)
-#define ldq_p(p) ldq_be_p(p)
-#define ldfl_p(p) ldfl_be_p(p)
-#define ldfq_p(p) ldfq_be_p(p)
-#define stw_p(p, v) stw_be_p(p, v)
-#define stl_p(p, v) stl_be_p(p, v)
-#define stq_p(p, v) stq_be_p(p, v)
-#define stfl_p(p, v) stfl_be_p(p, v)
-#define stfq_p(p, v) stfq_be_p(p, v)
-#else
-#define lduw_p(p) lduw_le_p(p)
-#define ldsw_p(p) ldsw_le_p(p)
-#define ldl_p(p) ldl_le_p(p)
-#define ldq_p(p) ldq_le_p(p)
-#define ldfl_p(p) ldfl_le_p(p)
-#define ldfq_p(p) ldfq_le_p(p)
-#define stw_p(p, v) stw_le_p(p, v)
-#define stl_p(p, v) stl_le_p(p, v)
-#define stq_p(p, v) stq_le_p(p, v)
-#define stfl_p(p, v) stfl_le_p(p, v)
-#define stfq_p(p, v) stfq_le_p(p, v)
-#endif
-
-/* MMU memory access macros */
-
-#if defined(CONFIG_USER_ONLY)
-/* On some host systems the guest address space is reserved on the host.
- * This allows the guest address space to be offset to a convenient location.
- */
-//#define GUEST_BASE 0x20000000
-#define GUEST_BASE 0
-
-/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
-#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
-#define h2g(x) ((target_ulong)(x - GUEST_BASE))
-
-#define saddr(x) g2h(x)
-#define laddr(x) g2h(x)
-
-#else /* !CONFIG_USER_ONLY */
-/* NOTE: we use double casts if pointers and target_ulong have
- different sizes */
-#define saddr(x) (uint8_t *)(long)(x)
-#define laddr(x) (uint8_t *)(long)(x)
-#endif
-
-#define ldub_raw(p) ldub_p(laddr((p)))
-#define ldsb_raw(p) ldsb_p(laddr((p)))
-#define lduw_raw(p) lduw_p(laddr((p)))
-#define ldsw_raw(p) ldsw_p(laddr((p)))
-#define ldl_raw(p) ldl_p(laddr((p)))
-#define ldq_raw(p) ldq_p(laddr((p)))
-#define ldfl_raw(p) ldfl_p(laddr((p)))
-#define ldfq_raw(p) ldfq_p(laddr((p)))
-#define stb_raw(p, v) stb_p(saddr((p)), v)
-#define stw_raw(p, v) stw_p(saddr((p)), v)
-#define stl_raw(p, v) stl_p(saddr((p)), v)
-#define stq_raw(p, v) stq_p(saddr((p)), v)
-#define stfl_raw(p, v) stfl_p(saddr((p)), v)
-#define stfq_raw(p, v) stfq_p(saddr((p)), v)
-
-
-#if defined(CONFIG_USER_ONLY)
-
-/* if user mode, no other memory access functions */
-#define ldub(p) ldub_raw(p)
-#define ldsb(p) ldsb_raw(p)
-#define lduw(p) lduw_raw(p)
-#define ldsw(p) ldsw_raw(p)
-#define ldl(p) ldl_raw(p)
-#define ldq(p) ldq_raw(p)
-#define ldfl(p) ldfl_raw(p)
-#define ldfq(p) ldfq_raw(p)
-#define stb(p, v) stb_raw(p, v)
-#define stw(p, v) stw_raw(p, v)
-#define stl(p, v) stl_raw(p, v)
-#define stq(p, v) stq_raw(p, v)
-#define stfl(p, v) stfl_raw(p, v)
-#define stfq(p, v) stfq_raw(p, v)
-
-#define ldub_code(p) ldub_raw(p)
-#define ldsb_code(p) ldsb_raw(p)
-#define lduw_code(p) lduw_raw(p)
-#define ldsw_code(p) ldsw_raw(p)
-#define ldl_code(p) ldl_raw(p)
-
-#define ldub_kernel(p) ldub_raw(p)
-#define ldsb_kernel(p) ldsb_raw(p)
-#define lduw_kernel(p) lduw_raw(p)
-#define ldsw_kernel(p) ldsw_raw(p)
-#define ldl_kernel(p) ldl_raw(p)
-#define ldfl_kernel(p) ldfl_raw(p)
-#define ldfq_kernel(p) ldfq_raw(p)
-#define stb_kernel(p, v) stb_raw(p, v)
-#define stw_kernel(p, v) stw_raw(p, v)
-#define stl_kernel(p, v) stl_raw(p, v)
-#define stq_kernel(p, v) stq_raw(p, v)
-#define stfl_kernel(p, v) stfl_raw(p, v)
-#define stfq_kernel(p, vt) stfq_raw(p, v)
-
-#endif /* defined(CONFIG_USER_ONLY) */
-
-/* page related stuff */
-
-#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
-#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
-#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
-
-/* ??? These should be the larger of unsigned long and target_ulong. */
-extern unsigned long qemu_real_host_page_size;
-extern unsigned long qemu_host_page_bits;
-extern unsigned long qemu_host_page_size;
-extern unsigned long qemu_host_page_mask;
-
-#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
-
-/* same as PROT_xxx */
-#define PAGE_READ 0x0001
-#define PAGE_WRITE 0x0002
-#define PAGE_EXEC 0x0004
-#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
-#define PAGE_VALID 0x0008
-/* original state of the write flag (used when tracking self-modifying
- code */
-#define PAGE_WRITE_ORG 0x0010
-
-void page_dump(FILE *f);
-int page_get_flags(target_ulong address);
-void page_set_flags(target_ulong start, target_ulong end, int flags);
-void page_unprotect_range(target_ulong data, target_ulong data_size);
-
-#ifdef CONFIG_DM
-#define SINGLE_CPU_DEFINES
-#endif
-#ifdef SINGLE_CPU_DEFINES
-
-#if defined(TARGET_I386)
-
-#define CPUState CPUX86State
-#define cpu_init cpu_x86_init
-#define cpu_exec cpu_x86_exec
-#define cpu_gen_code cpu_x86_gen_code
-#define cpu_signal_handler cpu_x86_signal_handler
-
-#elif defined(TARGET_ARM)
-
-#define CPUState CPUARMState
-#define cpu_init cpu_arm_init
-#define cpu_exec cpu_arm_exec
-#define cpu_gen_code cpu_arm_gen_code
-#define cpu_signal_handler cpu_arm_signal_handler
-
-#elif defined(TARGET_SPARC)
-
-#define CPUState CPUSPARCState
-#define cpu_init cpu_sparc_init
-#define cpu_exec cpu_sparc_exec
-#define cpu_gen_code cpu_sparc_gen_code
-#define cpu_signal_handler cpu_sparc_signal_handler
-
-#elif defined(TARGET_PPC)
-
-#define CPUState CPUPPCState
-#define cpu_init cpu_ppc_init
-#define cpu_exec cpu_ppc_exec
-#define cpu_gen_code cpu_ppc_gen_code
-#define cpu_signal_handler cpu_ppc_signal_handler
-
-#elif defined(TARGET_M68K)
-#define CPUState CPUM68KState
-#define cpu_init cpu_m68k_init
-#define cpu_exec cpu_m68k_exec
-#define cpu_gen_code cpu_m68k_gen_code
-#define cpu_signal_handler cpu_m68k_signal_handler
-
-#elif defined(TARGET_MIPS)
-#define CPUState CPUMIPSState
-#define cpu_init cpu_mips_init
-#define cpu_exec cpu_mips_exec
-#define cpu_gen_code cpu_mips_gen_code
-#define cpu_signal_handler cpu_mips_signal_handler
-
-#elif defined(TARGET_SH4)
-#define CPUState CPUSH4State
-#define cpu_init cpu_sh4_init
-#define cpu_exec cpu_sh4_exec
-#define cpu_gen_code cpu_sh4_gen_code
-#define cpu_signal_handler cpu_sh4_signal_handler
-
-#else
-
-#error unsupported target CPU
-
-#endif
-
-#else /* SINGLE_CPU_DEFINES */
-
-#define CPUState CPUX86State
-#define cpu_init cpu_x86_init
-int main_loop(void);
-
-#endif /* SINGLE_CPU_DEFINES */
-
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags);
-
-void cpu_abort(CPUState *env, const char *fmt, ...);
-extern CPUState *first_cpu;
-extern CPUState *cpu_single_env;
-extern int code_copy_enabled;
-
-#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
-#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
-#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
-#define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
-#define CPU_INTERRUPT_FIQ 0x10 /* Fast interrupt pending. */
-#define CPU_INTERRUPT_HALT 0x20 /* CPU halt wanted */
-#define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */
-
-void cpu_interrupt(CPUState *s, int mask);
-void cpu_reset_interrupt(CPUState *env, int mask);
-
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
-void cpu_single_step(CPUState *env, int enabled);
-void cpu_reset(CPUState *s);
-
-/* Return the physical page corresponding to a virtual one. Use it
- only for debugging because no protection checks are done. Return -1
- if no page found. */
-target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
-
-#define CPU_LOG_TB_OUT_ASM (1 << 0)
-#define CPU_LOG_TB_IN_ASM (1 << 1)
-#define CPU_LOG_TB_OP (1 << 2)
-#define CPU_LOG_TB_OP_OPT (1 << 3)
-#define CPU_LOG_INT (1 << 4)
-#define CPU_LOG_EXEC (1 << 5)
-#define CPU_LOG_PCALL (1 << 6)
-#define CPU_LOG_IOPORT (1 << 7)
-#define CPU_LOG_TB_CPU (1 << 8)
-
-/* define log items */
-typedef struct CPULogItem {
- int mask;
- const char *name;
- const char *help;
-} CPULogItem;
-
-extern CPULogItem cpu_log_items[];
-
-void cpu_set_log(int log_flags);
-void cpu_set_log_filename(const char *filename);
-int cpu_str_to_log_mask(const char *str);
-
-/* IO ports API */
-
-/* NOTE: as these functions may be even used when there is an isa
- brige on non x86 targets, we always defined them */
-#ifndef NO_CPU_IO_DEFS
-void cpu_outb(CPUState *env, int addr, int val);
-void cpu_outw(CPUState *env, int addr, int val);
-void cpu_outl(CPUState *env, int addr, int val);
-int cpu_inb(CPUState *env, int addr);
-int cpu_inw(CPUState *env, int addr);
-int cpu_inl(CPUState *env, int addr);
-#endif
-
-/* memory API */
-
-extern uint64_t phys_ram_size;
-extern int phys_ram_fd;
-extern uint8_t *phys_ram_base;
-extern uint8_t *phys_ram_dirty;
-
-/* physical memory access */
-#define TLB_INVALID_MASK (1 << 3)
-#define IO_MEM_SHIFT 4
-#define IO_MEM_NB_ENTRIES (1 << (TARGET_PAGE_BITS - IO_MEM_SHIFT))
-
-#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
-#define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */
-/* acts like a ROM when read and like a device when written. As an
- exception, the write memory callback gets the ram offset instead of
- the physical address */
-#define IO_MEM_ROMD (1)
-
-typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
-typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
-
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- unsigned long size,
- unsigned long phys_offset);
-uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr);
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque);
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
-
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write);
-static inline void cpu_physical_memory_read(target_phys_addr_t addr,
- uint8_t *buf, int len)
-{
- cpu_physical_memory_rw(addr, buf, len, 0);
-}
-static inline void cpu_physical_memory_write(target_phys_addr_t addr,
- const uint8_t *buf, int len)
-{
- cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
-}
-uint32_t ldub_phys(target_phys_addr_t addr);
-uint32_t lduw_phys(target_phys_addr_t addr);
-uint32_t ldl_phys(target_phys_addr_t addr);
-uint64_t ldq_phys(target_phys_addr_t addr);
-void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
-void stb_phys(target_phys_addr_t addr, uint32_t val);
-void stw_phys(target_phys_addr_t addr, uint32_t val);
-void stl_phys(target_phys_addr_t addr, uint32_t val);
-void stq_phys(target_phys_addr_t addr, uint64_t val);
-
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
- const uint8_t *buf, int len);
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write);
-
-#define VGA_DIRTY_FLAG 0x01
-#define CODE_DIRTY_FLAG 0x02
-
-/* read dirty bit (return 0 or 1) */
-static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
-{
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
-}
-
-static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
- int dirty_flags)
-{
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
-}
-
-static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
-{
- phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
-}
-
-void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
- int dirty_flags);
-void cpu_tlb_update_dirty(CPUState *env);
-
-void dump_exec_info(FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
-
-/*******************************************/
-/* host CPU ticks (if available) */
-
-#if defined(__powerpc__)
-
-static inline uint32_t get_tbl(void)
-{
- uint32_t tbl;
- asm volatile("mftb %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline uint32_t get_tbu(void)
-{
- uint32_t tbl;
- asm volatile("mftbu %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint32_t l, h, h1;
- /* NOTE: we test if wrapping has occurred */
- do {
- h = get_tbu();
- l = get_tbl();
- h1 = get_tbu();
- } while (h != h1);
- return ((int64_t)h << 32) | l;
-}
-
-#elif defined(__i386__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("rdtsc" : "=A" (val));
- return val;
-}
-
-#elif defined(__x86_64__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint32_t low,high;
- int64_t val;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- val = high;
- val <<= 32;
- val |= low;
- return val;
-}
-
-#elif defined(__ia64)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
- return val;
-}
-
-#elif defined(__s390__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
- return val;
-}
-
-#elif defined(__sparc_v9__)
-
-static inline int64_t cpu_get_real_ticks (void)
-{
-#if defined(_LP64)
- uint64_t rval;
- asm volatile("rd %%tick,%0" : "=r"(rval));
- return rval;
-#else
- union {
- uint64_t i64;
- struct {
- uint32_t high;
- uint32_t low;
- } i32;
- } rval;
- asm volatile("rd %%tick,%1; srlx %1,32,%0"
- : "=r"(rval.i32.high), "=r"(rval.i32.low));
- return rval.i64;
-#endif
-}
-#else
-/* The host CPU doesn't have an easily accessible cycle counter.
- Just return a monotonically increasing vlue. This will be totally wrong,
- but hopefully better than nothing. */
-static inline int64_t cpu_get_real_ticks (void)
-{
- static int64_t ticks = 0;
- return ticks++;
-}
-#endif
-
-/* profiling */
-#ifdef CONFIG_PROFILER
-static inline int64_t profile_getclock(void)
-{
- return cpu_get_real_ticks();
-}
-
-extern int64_t kqemu_time, kqemu_time_start;
-extern int64_t qemu_time, qemu_time_start;
-extern int64_t tlb_flush_time;
-extern int64_t kqemu_exec_count;
-extern int64_t dev_time;
-extern int64_t kqemu_ret_int_count;
-extern int64_t kqemu_ret_excp_count;
-extern int64_t kqemu_ret_intr_count;
-
-#endif
-
-#endif /* CPU_ALL_H */
diff --git a/tools/ioemu/cpu-defs.h b/tools/ioemu/cpu-defs.h
deleted file mode 100644
index 0b49c89913..0000000000
--- a/tools/ioemu/cpu-defs.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * common defines for all CPUs
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_DEFS_H
-#define CPU_DEFS_H
-
-#include "config.h"
-#include <setjmp.h>
-#include <inttypes.h>
-#include "osdep.h"
-
-#ifndef TARGET_LONG_BITS
-#error TARGET_LONG_BITS must be defined before including this header
-#endif
-
-#ifndef TARGET_PHYS_ADDR_BITS
-#if TARGET_LONG_BITS >= HOST_LONG_BITS
-#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
-#else
-#define TARGET_PHYS_ADDR_BITS HOST_LONG_BITS
-#endif
-#endif
-
-#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
-
-/* target_ulong is the type of a virtual address */
-#if TARGET_LONG_SIZE == 4
-typedef int32_t target_long;
-typedef uint32_t target_ulong;
-#define TARGET_FMT_lx "%08x"
-#elif TARGET_LONG_SIZE == 8
-typedef int64_t target_long;
-typedef uint64_t target_ulong;
-#define TARGET_FMT_lx "%016" PRIx64
-#else
-#error TARGET_LONG_SIZE undefined
-#endif
-
-/* target_phys_addr_t is the type of a physical address (its size can
- be different from 'target_ulong'). We have sizeof(target_phys_addr)
- = max(sizeof(unsigned long),
- sizeof(size_of_target_physical_address)) because we must pass a
- host pointer to memory operations in some cases */
-
-#if TARGET_PHYS_ADDR_BITS == 32
-typedef uint32_t target_phys_addr_t;
-#elif TARGET_PHYS_ADDR_BITS == 64
-typedef uint64_t target_phys_addr_t;
-#else
-#error TARGET_PHYS_ADDR_BITS undefined
-#endif
-
-/* address in the RAM (different from a physical address) */
-typedef unsigned long ram_addr_t;
-
-#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
-
-#define EXCP_INTERRUPT 0x10000 /* async interruption */
-#define EXCP_HLT 0x10001 /* hlt instruction reached */
-#define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */
-#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
-#define MAX_BREAKPOINTS 32
-
-#define TB_JMP_CACHE_BITS 12
-#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
-
-/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
- addresses on the same page. The top bits are the same. This allows
- TLB invalidation to quickly clear a subset of the hash table. */
-#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2)
-#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS)
-#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1)
-#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE)
-
-#define CPU_TLB_BITS 8
-#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
-
-typedef struct CPUTLBEntry {
- /* bit 31 to TARGET_PAGE_BITS : virtual address
- bit TARGET_PAGE_BITS-1..IO_MEM_SHIFT : if non zero, memory io
- zone number
- bit 3 : indicates that the entry is invalid
- bit 2..0 : zero
- */
- target_ulong addr_read;
- target_ulong addr_write;
- target_ulong addr_code;
- /* addend to virtual address to get physical address */
- target_phys_addr_t addend;
-} CPUTLBEntry;
-
-#define CPU_COMMON \
- struct TranslationBlock *current_tb; /* currently executing TB */ \
- /* soft mmu support */ \
- /* in order to avoid passing too many arguments to the memory \
- write helpers, we store some rarely used information in the CPU \
- context) */ \
- unsigned long mem_write_pc; /* host pc at which the memory was \
- written */ \
- target_ulong mem_write_vaddr; /* target virtual addr at which the \
- memory was written */ \
- /* 0 = kernel, 1 = user */ \
- CPUTLBEntry tlb_table[2][CPU_TLB_SIZE]; \
- struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
- \
- /* from this point: preserved by CPU reset */ \
- /* ice debug support */ \
- target_ulong breakpoints[MAX_BREAKPOINTS]; \
- int nb_breakpoints; \
- int singlestep_enabled; \
- \
- void *next_cpu; /* next CPU sharing TB cache */ \
- int cpu_index; /* CPU index (informative) */ \
- /* user data */ \
- void *opaque;
-
-#endif
diff --git a/tools/ioemu/cpu-exec.c b/tools/ioemu/cpu-exec.c
deleted file mode 100644
index 058688fc77..0000000000
--- a/tools/ioemu/cpu-exec.c
+++ /dev/null
@@ -1,1487 +0,0 @@
-/*
- * i386 emulator main execution loop
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#include "exec.h"
-#include "disas.h"
-
-#if !defined(CONFIG_SOFTMMU)
-#undef EAX
-#undef ECX
-#undef EDX
-#undef EBX
-#undef ESP
-#undef EBP
-#undef ESI
-#undef EDI
-#undef EIP
-#include <signal.h>
-#include <sys/ucontext.h>
-#endif
-
-int tb_invalidated_flag;
-
-//#define DEBUG_EXEC
-//#define DEBUG_SIGNAL
-
-#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_M68K)
-/* XXX: unify with i386 target */
-void cpu_loop_exit(void)
-{
- longjmp(env->jmp_env, 1);
-}
-#endif
-#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
-#define reg_T2
-#endif
-
-/* exit the current TB from a signal handler. The host registers are
- restored in a state compatible with the CPU emulator
- */
-void cpu_resume_from_signal(CPUState *env1, void *puc)
-{
-#if !defined(CONFIG_SOFTMMU)
- struct ucontext *uc = puc;
-#endif
-
- env = env1;
-
- /* XXX: restore cpu registers saved in host registers */
-
-#if !defined(CONFIG_SOFTMMU)
- if (puc) {
- /* XXX: use siglongjmp ? */
- sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
- }
-#endif
- longjmp(env->jmp_env, 1);
-}
-
-
-static TranslationBlock *tb_find_slow(target_ulong pc,
- target_ulong cs_base,
- unsigned int flags)
-{
- TranslationBlock *tb, **ptb1;
- int code_gen_size;
- unsigned int h;
- target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
- uint8_t *tc_ptr;
-
- spin_lock(&tb_lock);
-
- tb_invalidated_flag = 0;
-
- regs_to_env(); /* XXX: do it just before cpu_gen_code() */
-
- /* find translated block using physical mappings */
- phys_pc = get_phys_addr_code(env, pc);
- phys_page1 = phys_pc & TARGET_PAGE_MASK;
- phys_page2 = -1;
- h = tb_phys_hash_func(phys_pc);
- ptb1 = &tb_phys_hash[h];
- for(;;) {
- tb = *ptb1;
- if (!tb)
- goto not_found;
- if (tb->pc == pc &&
- tb->page_addr[0] == phys_page1 &&
- tb->cs_base == cs_base &&
- tb->flags == flags) {
- /* check next page if needed */
- if (tb->page_addr[1] != -1) {
- virt_page2 = (pc & TARGET_PAGE_MASK) +
- TARGET_PAGE_SIZE;
- phys_page2 = get_phys_addr_code(env, virt_page2);
- if (tb->page_addr[1] == phys_page2)
- goto found;
- } else {
- goto found;
- }
- }
- ptb1 = &tb->phys_hash_next;
- }
- not_found:
- /* if no translated code available, then translate it now */
- tb = tb_alloc(pc);
- if (!tb) {
- /* flush must be done */
- tb_flush(env);
- /* cannot fail at this point */
- tb = tb_alloc(pc);
- /* don't forget to invalidate previous TB info */
- tb_invalidated_flag = 1;
- }
- tc_ptr = code_gen_ptr;
- tb->tc_ptr = tc_ptr;
- tb->cs_base = cs_base;
- tb->flags = flags;
- cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
- code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-
- /* check next page if needed */
- virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
- phys_page2 = -1;
- if ((pc & TARGET_PAGE_MASK) != virt_page2) {
- phys_page2 = get_phys_addr_code(env, virt_page2);
- }
- tb_link_phys(tb, phys_pc, phys_page2);
-
- found:
- /* we add the TB in the virtual pc hash table */
- env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
- spin_unlock(&tb_lock);
- return tb;
-}
-
-static inline TranslationBlock *tb_find_fast(void)
-{
- TranslationBlock *tb;
- target_ulong cs_base, pc;
- unsigned int flags;
-
- /* we record a subset of the CPU state. It will
- always be the same before a given translated block
- is executed. */
-#if defined(TARGET_I386)
- flags = env->hflags;
- flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- cs_base = env->segs[R_CS].base;
- pc = cs_base + env->eip;
-#elif defined(TARGET_ARM)
- flags = env->thumb | (env->vfp.vec_len << 1)
- | (env->vfp.vec_stride << 4);
- if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
- flags |= (1 << 6);
- if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
- flags |= (1 << 7);
- cs_base = 0;
- pc = env->regs[15];
-#elif defined(TARGET_SPARC)
-#ifdef TARGET_SPARC64
- // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
- | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
-#else
- // FPU enable . MMU enabled . MMU no-fault . Supervisor
- flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
- | env->psrs;
-#endif
- cs_base = env->npc;
- pc = env->pc;
-#elif defined(TARGET_PPC)
- flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) |
- (msr_se << MSR_SE) | (msr_le << MSR_LE);
- cs_base = 0;
- pc = env->nip;
-#elif defined(TARGET_MIPS)
- flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
- cs_base = 0;
- pc = env->PC;
-#elif defined(TARGET_M68K)
- flags = env->fpcr & M68K_FPCR_PREC;
- cs_base = 0;
- pc = env->pc;
-#elif defined(TARGET_SH4)
- flags = env->sr & (SR_MD | SR_RB);
- cs_base = 0; /* XXXXX */
- pc = env->pc;
-#else
-#error unsupported CPU
-#endif
- tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
- if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base ||
- tb->flags != flags, 0)) {
- tb = tb_find_slow(pc, cs_base, flags);
- /* Note: we do it here to avoid a gcc bug on Mac OS X when
- doing it in tb_find_slow */
- if (tb_invalidated_flag) {
- /* as some TB could have been invalidated because
- of memory exceptions while generating the code, we
- must recompute the hash index here */
- T0 = 0;
- }
- }
- return tb;
-}
-
-
-/* main execution loop */
-
-int cpu_exec(CPUState *env1)
-{
-#define DECLARE_HOST_REGS 1
-#include "hostregs_helper.h"
-#if defined(TARGET_SPARC)
-#if defined(reg_REGWPTR)
- uint32_t *saved_regwptr;
-#endif
-#endif
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- int saved_i7;
- target_ulong tmp_T0;
-#endif
- int ret, interrupt_request;
- void (*gen_func)(void);
- TranslationBlock *tb;
- uint8_t *tc_ptr;
-
-#if defined(TARGET_I386)
- /* handle exit of HALTED state */
- if (env1->hflags & HF_HALTED_MASK) {
- /* disable halt condition */
- if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env1->eflags & IF_MASK)) {
- env1->hflags &= ~HF_HALTED_MASK;
- } else {
- return EXCP_HALTED;
- }
- }
-#elif defined(TARGET_PPC)
- if (env1->halted) {
- if (env1->msr[MSR_EE] &&
- (env1->interrupt_request &
- (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {
- env1->halted = 0;
- } else {
- return EXCP_HALTED;
- }
- }
-#elif defined(TARGET_SPARC)
- if (env1->halted) {
- if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env1->psret != 0)) {
- env1->halted = 0;
- } else {
- return EXCP_HALTED;
- }
- }
-#elif defined(TARGET_ARM)
- if (env1->halted) {
- /* An interrupt wakes the CPU even if the I and F CPSR bits are
- set. */
- if (env1->interrupt_request
- & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) {
- env1->halted = 0;
- } else {
- return EXCP_HALTED;
- }
- }
-#elif defined(TARGET_MIPS)
- if (env1->halted) {
- if (env1->interrupt_request &
- (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {
- env1->halted = 0;
- } else {
- return EXCP_HALTED;
- }
- }
-#endif
-
- cpu_single_env = env1;
-
- /* first we save global registers */
-#define SAVE_HOST_REGS 1
-#include "hostregs_helper.h"
- env = env1;
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- /* we also save i7 because longjmp may not restore it */
- asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
-#endif
-
-#if defined(TARGET_I386)
- env_to_regs();
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_ARM)
-#elif defined(TARGET_SPARC)
-#if defined(reg_REGWPTR)
- saved_regwptr = REGWPTR;
-#endif
-#elif defined(TARGET_PPC)
-#elif defined(TARGET_M68K)
- env->cc_op = CC_OP_FLAGS;
- env->cc_dest = env->sr & 0xf;
- env->cc_x = (env->sr >> 4) & 1;
-#elif defined(TARGET_MIPS)
-#elif defined(TARGET_SH4)
- /* XXXXX */
-#else
-#error unsupported target CPU
-#endif
- env->exception_index = -1;
-
- /* prepare setjmp context for exception handling */
- for(;;) {
- if (setjmp(env->jmp_env) == 0) {
- env->current_tb = NULL;
- /* if an exception is pending, we execute it here */
- if (env->exception_index >= 0) {
- if (env->exception_index >= EXCP_INTERRUPT) {
- /* exit request from the cpu execution loop */
- ret = env->exception_index;
- break;
- } else if (env->user_mode_only) {
- /* if user mode only, we simulate a fake exception
- which will be handled outside the cpu execution
- loop */
-#if defined(TARGET_I386)
- do_interrupt_user(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip);
-#endif
- ret = env->exception_index;
- break;
- } else {
-#if defined(TARGET_I386)
- /* simulate a real cpu exception. On i386, it can
- trigger new exceptions, but we do not handle
- double or triple faults yet. */
- do_interrupt(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip, 0);
-#elif defined(TARGET_PPC)
- do_interrupt(env);
-#elif defined(TARGET_MIPS)
- do_interrupt(env);
-#elif defined(TARGET_SPARC)
- do_interrupt(env->exception_index);
-#elif defined(TARGET_ARM)
- do_interrupt(env);
-#elif defined(TARGET_SH4)
- do_interrupt(env);
-#endif
- }
- env->exception_index = -1;
- }
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env) && env->interrupt_request == 0) {
- int ret;
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
- ret = kqemu_cpu_exec(env);
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- if (ret == 1) {
- /* exception */
- longjmp(env->jmp_env, 1);
- } else if (ret == 2) {
- /* softmmu execution needed */
- } else {
- if (env->interrupt_request != 0) {
- /* hardware interrupt will be executed just after */
- } else {
- /* otherwise, we restart */
- longjmp(env->jmp_env, 1);
- }
- }
- }
-#endif
-
- T0 = 0; /* force lookup of first TB */
- for(;;) {
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- /* g1 can be modified by some libc? functions */
- tmp_T0 = T0;
-#endif
- interrupt_request = env->interrupt_request;
- if (__builtin_expect(interrupt_request, 0)) {
-#if defined(TARGET_I386)
- if ((interrupt_request & CPU_INTERRUPT_SMI) &&
- !(env->hflags & HF_SMM_MASK)) {
- env->interrupt_request &= ~CPU_INTERRUPT_SMI;
- do_smm_enter();
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- tmp_T0 = 0;
-#else
- T0 = 0;
-#endif
- } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->eflags & IF_MASK) &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
- int intno;
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
- intno = cpu_get_pic_interrupt(env);
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
- }
- do_interrupt(intno, 0, 0, 0, 1);
- /* ensure that no TB jump will be modified as
- the program flow was changed */
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- tmp_T0 = 0;
-#else
- T0 = 0;
-#endif
- }
-#elif defined(TARGET_PPC)
-#if 0
- if ((interrupt_request & CPU_INTERRUPT_RESET)) {
- cpu_ppc_reset(env);
- }
-#endif
- if (msr_ee != 0) {
- if ((interrupt_request & CPU_INTERRUPT_HARD)) {
- /* Raise it */
- env->exception_index = EXCP_EXTERNAL;
- env->error_code = 0;
- do_interrupt(env);
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- tmp_T0 = 0;
-#else
- T0 = 0;
-#endif
- } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {
- /* Raise it */
- env->exception_index = EXCP_DECR;
- env->error_code = 0;
- do_interrupt(env);
- env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- tmp_T0 = 0;
-#else
- T0 = 0;
-#endif
- }
- }
-#elif defined(TARGET_MIPS)
- if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->CP0_Status & (1 << CP0St_IE)) &&
- (env->CP0_Status & env->CP0_Cause & 0x0000FF00) &&
- !(env->hflags & MIPS_HFLAG_EXL) &&
- !(env->hflags & MIPS_HFLAG_ERL) &&
- !(env->hflags & MIPS_HFLAG_DM)) {
- /* Raise it */
- env->exception_index = EXCP_EXT_INTERRUPT;
- env->error_code = 0;
- do_interrupt(env);
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- tmp_T0 = 0;
-#else
- T0 = 0;
-#endif
- }
-#elif defined(TARGET_SPARC)
- if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->psret != 0)) {
- int pil = env->interrupt_index & 15;
- int type = env->interrupt_index & 0xf0;
-
- if (((type == TT_EXTINT) &&
- (pil == 15 || pil > env->psrpil)) ||
- type != TT_EXTINT) {
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
- do_interrupt(env->interrupt_index);
- env->interrupt_index = 0;
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- tmp_T0 = 0;
-#else
- T0 = 0;
-#endif
- }
- } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
- //do_interrupt(0, 0, 0, 0, 0);
- env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
- } else if (interrupt_request & CPU_INTERRUPT_HALT) {
- env->interrupt_request &= ~CPU_INTERRUPT_HALT;
- env->halted = 1;
- env->exception_index = EXCP_HLT;
- cpu_loop_exit();
- }
-#elif defined(TARGET_ARM)
- if (interrupt_request & CPU_INTERRUPT_FIQ
- && !(env->uncached_cpsr & CPSR_F)) {
- env->exception_index = EXCP_FIQ;
- do_interrupt(env);
- }
- if (interrupt_request & CPU_INTERRUPT_HARD
- && !(env->uncached_cpsr & CPSR_I)) {
- env->exception_index = EXCP_IRQ;
- do_interrupt(env);
- }
-#elif defined(TARGET_SH4)
- /* XXXXX */
-#endif
- /* Don't use the cached interupt_request value,
- do_interrupt may have updated the EXITTB flag. */
- if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
- env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
- /* ensure that no TB jump will be modified as
- the program flow was changed */
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- tmp_T0 = 0;
-#else
- T0 = 0;
-#endif
- }
- if (interrupt_request & CPU_INTERRUPT_EXIT) {
- env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
- env->exception_index = EXCP_INTERRUPT;
- cpu_loop_exit();
- }
- }
-#ifdef DEBUG_EXEC
- if ((loglevel & CPU_LOG_TB_CPU)) {
-#if defined(TARGET_I386)
- /* restore flags in standard format */
-#ifdef reg_EAX
- env->regs[R_EAX] = EAX;
-#endif
-#ifdef reg_EBX
- env->regs[R_EBX] = EBX;
-#endif
-#ifdef reg_ECX
- env->regs[R_ECX] = ECX;
-#endif
-#ifdef reg_EDX
- env->regs[R_EDX] = EDX;
-#endif
-#ifdef reg_ESI
- env->regs[R_ESI] = ESI;
-#endif
-#ifdef reg_EDI
- env->regs[R_EDI] = EDI;
-#endif
-#ifdef reg_EBP
- env->regs[R_EBP] = EBP;
-#endif
-#ifdef reg_ESP
- env->regs[R_ESP] = ESP;
-#endif
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_ARM)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_SPARC)
- REGWPTR = env->regbase + (env->cwp * 16);
- env->regwptr = REGWPTR;
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_PPC)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_M68K)
- cpu_m68k_flush_flags(env, env->cc_op);
- env->cc_op = CC_OP_FLAGS;
- env->sr = (env->sr & 0xffe0)
- | env->cc_dest | (env->cc_x << 4);
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_MIPS)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_SH4)
- cpu_dump_state(env, logfile, fprintf, 0);
-#else
-#error unsupported target CPU
-#endif
- }
-#endif
- tb = tb_find_fast();
-#ifdef DEBUG_EXEC
- if ((loglevel & CPU_LOG_EXEC)) {
- fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
- (long)tb->tc_ptr, tb->pc,
- lookup_symbol(tb->pc));
- }
-#endif
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- T0 = tmp_T0;
-#endif
- /* see if we can patch the calling TB. When the TB
- spans two pages, we cannot safely do a direct
- jump. */
- {
- if (T0 != 0 &&
-#if USE_KQEMU
- (env->kqemu_enabled != 2) &&
-#endif
- tb->page_addr[1] == -1
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
- && (tb->cflags & CF_CODE_COPY) ==
- (((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)
-#endif
- ) {
- spin_lock(&tb_lock);
- tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);
-#if defined(USE_CODE_COPY)
- /* propagates the FP use info */
- ((TranslationBlock *)(T0 & ~3))->cflags |=
- (tb->cflags & CF_FP_USED);
-#endif
- spin_unlock(&tb_lock);
- }
- }
- tc_ptr = tb->tc_ptr;
- env->current_tb = tb;
- /* execute the generated code */
- gen_func = (void *)tc_ptr;
-#if defined(__sparc__)
- __asm__ __volatile__("call %0\n\t"
- "mov %%o7,%%i0"
- : /* no outputs */
- : "r" (gen_func)
- : "i0", "i1", "i2", "i3", "i4", "i5",
- "l0", "l1", "l2", "l3", "l4", "l5",
- "l6", "l7");
-#elif defined(__arm__)
- asm volatile ("mov pc, %0\n\t"
- ".global exec_loop\n\t"
- "exec_loop:\n\t"
- : /* no outputs */
- : "r" (gen_func)
- : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");
-#elif defined(TARGET_I386) && defined(USE_CODE_COPY)
-{
- if (!(tb->cflags & CF_CODE_COPY)) {
- if ((tb->cflags & CF_FP_USED) && env->native_fp_regs) {
- save_native_fp_state(env);
- }
- gen_func();
- } else {
- if ((tb->cflags & CF_FP_USED) && !env->native_fp_regs) {
- restore_native_fp_state(env);
- }
- /* we work with native eflags */
- CC_SRC = cc_table[CC_OP].compute_all();
- CC_OP = CC_OP_EFLAGS;
- asm(".globl exec_loop\n"
- "\n"
- "debug1:\n"
- " pushl %%ebp\n"
- " fs movl %10, %9\n"
- " fs movl %11, %%eax\n"
- " andl $0x400, %%eax\n"
- " fs orl %8, %%eax\n"
- " pushl %%eax\n"
- " popf\n"
- " fs movl %%esp, %12\n"
- " fs movl %0, %%eax\n"
- " fs movl %1, %%ecx\n"
- " fs movl %2, %%edx\n"
- " fs movl %3, %%ebx\n"
- " fs movl %4, %%esp\n"
- " fs movl %5, %%ebp\n"
- " fs movl %6, %%esi\n"
- " fs movl %7, %%edi\n"
- " fs jmp *%9\n"
- "exec_loop:\n"
- " fs movl %%esp, %4\n"
- " fs movl %12, %%esp\n"
- " fs movl %%eax, %0\n"
- " fs movl %%ecx, %1\n"
- " fs movl %%edx, %2\n"
- " fs movl %%ebx, %3\n"
- " fs movl %%ebp, %5\n"
- " fs movl %%esi, %6\n"
- " fs movl %%edi, %7\n"
- " pushf\n"
- " popl %%eax\n"
- " movl %%eax, %%ecx\n"
- " andl $0x400, %%ecx\n"
- " shrl $9, %%ecx\n"
- " andl $0x8d5, %%eax\n"
- " fs movl %%eax, %8\n"
- " movl $1, %%eax\n"
- " subl %%ecx, %%eax\n"
- " fs movl %%eax, %11\n"
- " fs movl %9, %%ebx\n" /* get T0 value */
- " popl %%ebp\n"
- :
- : "m" (*(uint8_t *)offsetof(CPUState, regs[0])),
- "m" (*(uint8_t *)offsetof(CPUState, regs[1])),
- "m" (*(uint8_t *)offsetof(CPUState, regs[2])),
- "m" (*(uint8_t *)offsetof(CPUState, regs[3])),
- "m" (*(uint8_t *)offsetof(CPUState, regs[4])),
- "m" (*(uint8_t *)offsetof(CPUState, regs[5])),
- "m" (*(uint8_t *)offsetof(CPUState, regs[6])),
- "m" (*(uint8_t *)offsetof(CPUState, regs[7])),
- "m" (*(uint8_t *)offsetof(CPUState, cc_src)),
- "m" (*(uint8_t *)offsetof(CPUState, tmp0)),
- "a" (gen_func),
- "m" (*(uint8_t *)offsetof(CPUState, df)),
- "m" (*(uint8_t *)offsetof(CPUState, saved_esp))
- : "%ecx", "%edx"
- );
- }
-}
-#elif defined(__ia64)
- struct fptr {
- void *ip;
- void *gp;
- } fp;
-
- fp.ip = tc_ptr;
- fp.gp = code_gen_buffer + 2 * (1 << 20);
- (*(void (*)(void)) &fp)();
-#else
- gen_func();
-#endif
- env->current_tb = NULL;
- /* reset soft MMU for next block (it can currently
- only be set by a memory fault) */
-#if defined(TARGET_I386) && !defined(CONFIG_SOFTMMU)
- if (env->hflags & HF_SOFTMMU_MASK) {
- env->hflags &= ~HF_SOFTMMU_MASK;
- /* do not allow linking to another block */
- T0 = 0;
- }
-#endif
-#if defined(USE_KQEMU)
-#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
- if (kqemu_is_ok(env) &&
- (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
- cpu_loop_exit();
- }
-#endif
- }
- } else {
- env_to_regs();
- }
- } /* for(;;) */
-
-
-#if defined(TARGET_I386)
-#if defined(USE_CODE_COPY)
- if (env->native_fp_regs) {
- save_native_fp_state(env);
- }
-#endif
- /* restore flags in standard format */
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-#elif defined(TARGET_ARM)
- /* XXX: Save/restore host fpu exception state?. */
-#elif defined(TARGET_SPARC)
-#if defined(reg_REGWPTR)
- REGWPTR = saved_regwptr;
-#endif
-#elif defined(TARGET_PPC)
-#elif defined(TARGET_M68K)
- cpu_m68k_flush_flags(env, env->cc_op);
- env->cc_op = CC_OP_FLAGS;
- env->sr = (env->sr & 0xffe0)
- | env->cc_dest | (env->cc_x << 4);
-#elif defined(TARGET_MIPS)
-#elif defined(TARGET_SH4)
- /* XXXXX */
-#else
-#error unsupported target CPU
-#endif
-
- /* restore global registers */
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
- asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
-#endif
-#include "hostregs_helper.h"
-
- /* fail safe : never use cpu_single_env outside cpu_exec() */
- cpu_single_env = NULL;
- return ret;
-}
-
-/* must only be called from the generated code as an exception can be
- generated */
-void tb_invalidate_page_range(target_ulong start, target_ulong end)
-{
- /* XXX: cannot enable it yet because it yields to MMU exception
- where NIP != read address on PowerPC */
-#if 0
- target_ulong phys_addr;
- phys_addr = get_phys_addr_code(env, start);
- tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
-#endif
-}
-
-#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
-
-void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
-{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
- if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
- selector &= 0xffff;
- cpu_x86_load_seg_cache(env, seg_reg, selector,
- (selector << 4), 0xffff, 0);
- } else {
- load_seg(seg_reg, selector);
- }
- env = saved_env;
-}
-
-void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32)
-{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
-
- helper_fsave((target_ulong)ptr, data32);
-
- env = saved_env;
-}
-
-void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
-{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
-
- helper_frstor((target_ulong)ptr, data32);
-
- env = saved_env;
-}
-
-#endif /* TARGET_I386 */
-
-#if !defined(CONFIG_SOFTMMU)
-
-#if defined(TARGET_I386)
-
-/* 'pc' is the host PC at which the exception was raised. 'address' is
- the effective address of the memory exception. 'is_write' is 1 if a
- write caused the exception and otherwise 0'. 'old_set' is the
- signal set which should be restored */
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_x86_handle_mmu_fault(env, address, is_write,
- ((env->hflags & HF_CPL_MASK) == 3), 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
- env->eip, env->cr[2], env->error_code);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- env->hflags |= HF_SOFTMMU_MASK;
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined(TARGET_ARM)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
-}
-#elif defined(TARGET_SPARC)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
-}
-#elif defined (TARGET_PPC)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- do_raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined(TARGET_M68K)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-
-#elif defined (TARGET_MIPS)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- do_raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined (TARGET_SH4)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-#else
-#error unsupported target CPU
-#endif
-
-#if defined(__i386__)
-
-#if defined(__APPLE__)
-# include <sys/ucontext.h>
-
-# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
-# define TRAP_sig(context) ((context)->uc_mcontext->es.trapno)
-# define ERROR_sig(context) ((context)->uc_mcontext->es.err)
-#else
-# define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP])
-# define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
-# define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
-#endif
-
-#if defined(USE_CODE_COPY)
-static void cpu_send_trap(unsigned long pc, int trap,
- struct ucontext *uc)
-{
- TranslationBlock *tb;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, uc);
- }
- sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
- raise_exception_err(trap, env->error_code);
-}
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int trapno;
-
-#ifndef REG_EIP
-/* for glibc 2.1 */
-#define REG_EIP EIP
-#define REG_ERR ERR
-#define REG_TRAPNO TRAPNO
-#endif
- pc = EIP_sig(uc);
- trapno = TRAP_sig(uc);
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
- if (trapno == 0x00 || trapno == 0x05) {
- /* send division by zero or bound exception */
- cpu_send_trap(pc, trapno, uc);
- return 1;
- } else
-#endif
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- trapno == 0xe ?
- (ERROR_sig(uc) >> 1) & 1 : 0,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__x86_64__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
-
- pc = uc->uc_mcontext.gregs[REG_RIP];
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
- (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__powerpc__)
-
-/***********************************************************************
- * signal context platform-specific definitions
- * From Wine
- */
-#ifdef linux
-/* All Registers access - only for local access */
-# define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name)
-/* Gpr Registers access */
-# define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context)
-# define IAR_sig(context) REG_sig(nip, context) /* Program counter */
-# define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */
-# define CTR_sig(context) REG_sig(ctr, context) /* Count register */
-# define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */
-# define LR_sig(context) REG_sig(link, context) /* Link register */
-# define CR_sig(context) REG_sig(ccr, context) /* Condition register */
-/* Float Registers access */
-# define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
-# define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
-/* Exception Registers access */
-# define DAR_sig(context) REG_sig(dar, context)
-# define DSISR_sig(context) REG_sig(dsisr, context)
-# define TRAP_sig(context) REG_sig(trap, context)
-#endif /* linux */
-
-#ifdef __APPLE__
-# include <sys/ucontext.h>
-typedef struct ucontext SIGCONTEXT;
-/* All Registers access - only for local access */
-# define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name)
-# define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name)
-# define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name)
-# define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name)
-/* Gpr Registers access */
-# define GPR_sig(reg_num, context) REG_sig(r##reg_num, context)
-# define IAR_sig(context) REG_sig(srr0, context) /* Program counter */
-# define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */
-# define CTR_sig(context) REG_sig(ctr, context)
-# define XER_sig(context) REG_sig(xer, context) /* Link register */
-# define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */
-# define CR_sig(context) REG_sig(cr, context) /* Condition register */
-/* Float Registers access */
-# define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context)
-# define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context))
-/* Exception Registers access */
-# define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */
-# define DSISR_sig(context) EXCEPREG_sig(dsisr, context)
-# define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
-#endif /* __APPLE__ */
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = IAR_sig(uc);
- is_write = 0;
-#if 0
- /* ppc 4xx case */
- if (DSISR_sig(uc) & 0x00800000)
- is_write = 1;
-#else
- if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
- is_write = 1;
-#endif
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__alpha__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- uint32_t *pc = uc->uc_mcontext.sc_pc;
- uint32_t insn = *pc;
- int is_write = 0;
-
- /* XXX: need kernel patch to get write flag faster */
- switch (insn >> 26) {
- case 0x0d: // stw
- case 0x0e: // stb
- case 0x0f: // stq_u
- case 0x24: // stf
- case 0x25: // stg
- case 0x26: // sts
- case 0x27: // stt
- case 0x2c: // stl
- case 0x2d: // stq
- case 0x2e: // stl_c
- case 0x2f: // stq_c
- is_write = 1;
- }
-
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, &uc->uc_sigmask, puc);
-}
-#elif defined(__sparc__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- uint32_t *regs = (uint32_t *)(info + 1);
- void *sigmask = (regs + 20);
- unsigned long pc;
- int is_write;
- uint32_t insn;
-
- /* XXX: is there a standard glibc define ? */
- pc = regs[1];
- /* XXX: need kernel patch to get write flag faster */
- is_write = 0;
- insn = *(uint32_t *)pc;
- if ((insn >> 30) == 3) {
- switch((insn >> 19) & 0x3f) {
- case 0x05: // stb
- case 0x06: // sth
- case 0x04: // st
- case 0x07: // std
- case 0x24: // stf
- case 0x27: // stdf
- case 0x25: // stfsr
- is_write = 1;
- break;
- }
- }
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, sigmask, NULL);
-}
-
-#elif defined(__arm__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = uc->uc_mcontext.gregs[R15];
- /* XXX: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__mc68000)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = uc->uc_mcontext.gregs[16];
- /* XXX: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__ia64)
-
-#ifndef __ISR_VALID
- /* This ought to be in <bits/siginfo.h>... */
-# define __ISR_VALID 1
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long ip;
- int is_write = 0;
-
- ip = uc->uc_mcontext.sc_ip;
- switch (host_signum) {
- case SIGILL:
- case SIGFPE:
- case SIGSEGV:
- case SIGBUS:
- case SIGTRAP:
- if (info->si_code && (info->si_segvflags & __ISR_VALID))
- /* ISR.W (write-access) is bit 33: */
- is_write = (info->si_isr >> 33) & 1;
- break;
-
- default:
- break;
- }
- return handle_cpu_signal(ip, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__s390__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = uc->uc_mcontext.psw.addr;
- /* XXX: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#else
-
-#error host CPU specific signal handler needed
-
-#endif
-
-#endif /* !defined(CONFIG_SOFTMMU) */
diff --git a/tools/ioemu/cutils.c b/tools/ioemu/cutils.c
deleted file mode 100644
index dc51e67235..0000000000
--- a/tools/ioemu/cutils.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Simple C functions to supplement the C library
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-void pstrcpy(char *buf, size_t buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-/* strcat and truncate. */
-char *pstrcat(char *buf, size_t buf_size, const char *s)
-{
- int len;
- len = strlen(buf);
- if (len < buf_size)
- pstrcpy(buf + len, buf_size - len, s);
- return buf;
-}
-
-int strstart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (*p != *q)
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-int stristart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (toupper((uint8_t)*p) != toupper((uint8_t)*q))
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
diff --git a/tools/ioemu/d3des.c b/tools/ioemu/d3des.c
deleted file mode 100644
index eaca581653..0000000000
--- a/tools/ioemu/d3des.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * This is D3DES (V5.09) by Richard Outerbridge with the double and
- * triple-length support removed for use in VNC. Also the bytebit[] array
- * has been reversed so that the most significant bit in each byte of the
- * key is ignored, not the least significant.
- *
- * These changes are:
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* D3DES (V5.09) -
- *
- * A portable, public domain, version of the Data Encryption Standard.
- *
- * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
- * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
- * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
- * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
- * for humouring me on.
- *
- * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
- * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
- */
-
-#include "d3des.h"
-
-static void scrunch(unsigned char *, unsigned long *);
-static void unscrun(unsigned long *, unsigned char *);
-static void desfunc(unsigned long *, unsigned long *);
-static void cookey(unsigned long *);
-
-static unsigned long KnL[32] = { 0L };
-
-static unsigned short bytebit[8] = {
- 01, 02, 04, 010, 020, 040, 0100, 0200 };
-
-static unsigned long bigbyte[24] = {
- 0x800000L, 0x400000L, 0x200000L, 0x100000L,
- 0x80000L, 0x40000L, 0x20000L, 0x10000L,
- 0x8000L, 0x4000L, 0x2000L, 0x1000L,
- 0x800L, 0x400L, 0x200L, 0x100L,
- 0x80L, 0x40L, 0x20L, 0x10L,
- 0x8L, 0x4L, 0x2L, 0x1L };
-
-/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
-
-static unsigned char pc1[56] = {
- 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
- 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
- 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
- 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
-
-static unsigned char totrot[16] = {
- 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
-
-static unsigned char pc2[48] = {
- 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
- 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
- 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
- 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
-
-void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */
-unsigned char *key;
-int edf;
-{
- register int i, j, l, m, n;
- unsigned char pc1m[56], pcr[56];
- unsigned long kn[32];
-
- for ( j = 0; j < 56; j++ ) {
- l = pc1[j];
- m = l & 07;
- pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
- }
- for( i = 0; i < 16; i++ ) {
- if( edf == DE1 ) m = (15 - i) << 1;
- else m = i << 1;
- n = m + 1;
- kn[m] = kn[n] = 0L;
- for( j = 0; j < 28; j++ ) {
- l = j + totrot[i];
- if( l < 28 ) pcr[j] = pc1m[l];
- else pcr[j] = pc1m[l - 28];
- }
- for( j = 28; j < 56; j++ ) {
- l = j + totrot[i];
- if( l < 56 ) pcr[j] = pc1m[l];
- else pcr[j] = pc1m[l - 28];
- }
- for( j = 0; j < 24; j++ ) {
- if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
- if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
- }
- }
- cookey(kn);
- return;
- }
-
-static void cookey(raw1)
-register unsigned long *raw1;
-{
- register unsigned long *cook, *raw0;
- unsigned long dough[32];
- register int i;
-
- cook = dough;
- for( i = 0; i < 16; i++, raw1++ ) {
- raw0 = raw1++;
- *cook = (*raw0 & 0x00fc0000L) << 6;
- *cook |= (*raw0 & 0x00000fc0L) << 10;
- *cook |= (*raw1 & 0x00fc0000L) >> 10;
- *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
- *cook = (*raw0 & 0x0003f000L) << 12;
- *cook |= (*raw0 & 0x0000003fL) << 16;
- *cook |= (*raw1 & 0x0003f000L) >> 4;
- *cook++ |= (*raw1 & 0x0000003fL);
- }
- usekey(dough);
- return;
- }
-
-void cpkey(into)
-register unsigned long *into;
-{
- register unsigned long *from, *endp;
-
- from = KnL, endp = &KnL[32];
- while( from < endp ) *into++ = *from++;
- return;
- }
-
-void usekey(from)
-register unsigned long *from;
-{
- register unsigned long *to, *endp;
-
- to = KnL, endp = &KnL[32];
- while( to < endp ) *to++ = *from++;
- return;
- }
-
-void des(inblock, outblock)
-unsigned char *inblock, *outblock;
-{
- unsigned long work[2];
-
- scrunch(inblock, work);
- desfunc(work, KnL);
- unscrun(work, outblock);
- return;
- }
-
-static void scrunch(outof, into)
-register unsigned char *outof;
-register unsigned long *into;
-{
- *into = (*outof++ & 0xffL) << 24;
- *into |= (*outof++ & 0xffL) << 16;
- *into |= (*outof++ & 0xffL) << 8;
- *into++ |= (*outof++ & 0xffL);
- *into = (*outof++ & 0xffL) << 24;
- *into |= (*outof++ & 0xffL) << 16;
- *into |= (*outof++ & 0xffL) << 8;
- *into |= (*outof & 0xffL);
- return;
- }
-
-static void unscrun(outof, into)
-register unsigned long *outof;
-register unsigned char *into;
-{
- *into++ = (unsigned char)((*outof >> 24) & 0xffL);
- *into++ = (unsigned char)((*outof >> 16) & 0xffL);
- *into++ = (unsigned char)((*outof >> 8) & 0xffL);
- *into++ = (unsigned char)(*outof++ & 0xffL);
- *into++ = (unsigned char)((*outof >> 24) & 0xffL);
- *into++ = (unsigned char)((*outof >> 16) & 0xffL);
- *into++ = (unsigned char)((*outof >> 8) & 0xffL);
- *into = (unsigned char)(*outof & 0xffL);
- return;
- }
-
-static unsigned long SP1[64] = {
- 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
- 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
- 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
- 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
- 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
- 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
- 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
- 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
- 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
- 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
- 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
- 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
- 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
- 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
- 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
- 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
-
-static unsigned long SP2[64] = {
- 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
- 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
- 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
- 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
- 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
- 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
- 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
- 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
- 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
- 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
- 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
- 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
- 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
- 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
- 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
- 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
-
-static unsigned long SP3[64] = {
- 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
- 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
- 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
- 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
- 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
- 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
- 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
- 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
- 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
- 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
- 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
- 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
- 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
- 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
- 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
- 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
-
-static unsigned long SP4[64] = {
- 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
- 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
- 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
- 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
- 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
- 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
- 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
- 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
- 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
- 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
- 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
- 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
- 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
- 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
- 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
- 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
-
-static unsigned long SP5[64] = {
- 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
- 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
- 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
- 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
- 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
- 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
- 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
- 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
- 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
- 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
- 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
- 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
- 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
- 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
- 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
- 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
-
-static unsigned long SP6[64] = {
- 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
- 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
- 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
- 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
- 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
- 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
- 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
- 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
- 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
- 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
- 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
- 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
- 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
- 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
- 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
- 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
-
-static unsigned long SP7[64] = {
- 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
- 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
- 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
- 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
- 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
- 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
- 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
- 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
- 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
- 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
- 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
- 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
- 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
- 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
- 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
- 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
-
-static unsigned long SP8[64] = {
- 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
- 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
- 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
- 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
- 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
- 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
- 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
- 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
- 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
- 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
- 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
- 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
- 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
- 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
- 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
- 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
-
-static void desfunc(block, keys)
-register unsigned long *block, *keys;
-{
- register unsigned long fval, work, right, leftt;
- register int round;
-
- leftt = block[0];
- right = block[1];
- work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
- right ^= work;
- leftt ^= (work << 4);
- work = ((leftt >> 16) ^ right) & 0x0000ffffL;
- right ^= work;
- leftt ^= (work << 16);
- work = ((right >> 2) ^ leftt) & 0x33333333L;
- leftt ^= work;
- right ^= (work << 2);
- work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
- leftt ^= work;
- right ^= (work << 8);
- right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
- work = (leftt ^ right) & 0xaaaaaaaaL;
- leftt ^= work;
- right ^= work;
- leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
-
- for( round = 0; round < 8; round++ ) {
- work = (right << 28) | (right >> 4);
- work ^= *keys++;
- fval = SP7[ work & 0x3fL];
- fval |= SP5[(work >> 8) & 0x3fL];
- fval |= SP3[(work >> 16) & 0x3fL];
- fval |= SP1[(work >> 24) & 0x3fL];
- work = right ^ *keys++;
- fval |= SP8[ work & 0x3fL];
- fval |= SP6[(work >> 8) & 0x3fL];
- fval |= SP4[(work >> 16) & 0x3fL];
- fval |= SP2[(work >> 24) & 0x3fL];
- leftt ^= fval;
- work = (leftt << 28) | (leftt >> 4);
- work ^= *keys++;
- fval = SP7[ work & 0x3fL];
- fval |= SP5[(work >> 8) & 0x3fL];
- fval |= SP3[(work >> 16) & 0x3fL];
- fval |= SP1[(work >> 24) & 0x3fL];
- work = leftt ^ *keys++;
- fval |= SP8[ work & 0x3fL];
- fval |= SP6[(work >> 8) & 0x3fL];
- fval |= SP4[(work >> 16) & 0x3fL];
- fval |= SP2[(work >> 24) & 0x3fL];
- right ^= fval;
- }
-
- right = (right << 31) | (right >> 1);
- work = (leftt ^ right) & 0xaaaaaaaaL;
- leftt ^= work;
- right ^= work;
- leftt = (leftt << 31) | (leftt >> 1);
- work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
- right ^= work;
- leftt ^= (work << 8);
- work = ((leftt >> 2) ^ right) & 0x33333333L;
- right ^= work;
- leftt ^= (work << 2);
- work = ((right >> 16) ^ leftt) & 0x0000ffffL;
- leftt ^= work;
- right ^= (work << 16);
- work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
- leftt ^= work;
- right ^= (work << 4);
- *block++ = right;
- *block = leftt;
- return;
- }
-
-/* Validation sets:
- *
- * Single-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef
- * Plain : 0123 4567 89ab cde7
- * Cipher : c957 4425 6a5e d31d
- *
- * Double-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
- * Plain : 0123 4567 89ab cde7
- * Cipher : 7f1d 0a77 826b 8aff
- *
- * Double-length key, double-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
- * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
- * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
- *
- * Triple-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
- * Plain : 0123 4567 89ab cde7
- * Cipher : de0b 7c06 ae5e 0ed5
- *
- * Triple-length key, double-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
- * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
- * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
- *
- * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
- **********************************************************************/
diff --git a/tools/ioemu/d3des.h b/tools/ioemu/d3des.h
deleted file mode 100644
index ea3da44ce9..0000000000
--- a/tools/ioemu/d3des.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * This is D3DES (V5.09) by Richard Outerbridge with the double and
- * triple-length support removed for use in VNC.
- *
- * These changes are:
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* d3des.h -
- *
- * Headers and defines for d3des.c
- * Graven Imagery, 1992.
- *
- * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
- * (GEnie : OUTER; CIS : [71755,204])
- */
-
-#define EN0 0 /* MODE == encrypt */
-#define DE1 1 /* MODE == decrypt */
-
-extern void deskey(unsigned char *, int);
-/* hexkey[8] MODE
- * Sets the internal key register according to the hexadecimal
- * key contained in the 8 bytes of hexkey, according to the DES,
- * for encryption or decryption according to MODE.
- */
-
-extern void usekey(unsigned long *);
-/* cookedkey[32]
- * Loads the internal key register with the data in cookedkey.
- */
-
-extern void cpkey(unsigned long *);
-/* cookedkey[32]
- * Copies the contents of the internal key register into the storage
- * located at &cookedkey[0].
- */
-
-extern void des(unsigned char *, unsigned char *);
-/* from[8] to[8]
- * Encrypts/Decrypts (according to the key currently loaded in the
- * internal key register) one block of eight bytes at address 'from'
- * into the block at address 'to'. They can be the same.
- */
-
-/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
- ********************************************************************/
diff --git a/tools/ioemu/dis-asm.h b/tools/ioemu/dis-asm.h
deleted file mode 100644
index 73b4380b78..0000000000
--- a/tools/ioemu/dis-asm.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/* Interface between the opcode library and its callers.
- Written by Cygnus Support, 1993.
-
- The opcode library (libopcodes.a) provides instruction decoders for
- a large variety of instruction sets, callable with an identical
- interface, for making instruction-processing programs more independent
- of the instruction set being processed. */
-
-#ifndef DIS_ASM_H
-#define DIS_ASM_H
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#define PARAMS(x) x
-typedef void *PTR;
-typedef uint64_t bfd_vma;
-typedef int64_t bfd_signed_vma;
-typedef uint8_t bfd_byte;
-#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x)
-
-#define BFD64
-
-enum bfd_flavour {
- bfd_target_unknown_flavour,
- bfd_target_aout_flavour,
- bfd_target_coff_flavour,
- bfd_target_ecoff_flavour,
- bfd_target_elf_flavour,
- bfd_target_ieee_flavour,
- bfd_target_nlm_flavour,
- bfd_target_oasys_flavour,
- bfd_target_tekhex_flavour,
- bfd_target_srec_flavour,
- bfd_target_ihex_flavour,
- bfd_target_som_flavour,
- bfd_target_os9k_flavour,
- bfd_target_versados_flavour,
- bfd_target_msdos_flavour,
- bfd_target_evax_flavour
-};
-
-enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
-
-enum bfd_architecture
-{
- bfd_arch_unknown, /* File arch not known */
- bfd_arch_obscure, /* Arch known, not one of these */
- bfd_arch_m68k, /* Motorola 68xxx */
-#define bfd_mach_m68000 1
-#define bfd_mach_m68008 2
-#define bfd_mach_m68010 3
-#define bfd_mach_m68020 4
-#define bfd_mach_m68030 5
-#define bfd_mach_m68040 6
-#define bfd_mach_m68060 7
-#define bfd_mach_cpu32 8
-#define bfd_mach_mcf5200 9
-#define bfd_mach_mcf5206e 10
-#define bfd_mach_mcf5307 11
-#define bfd_mach_mcf5407 12
-#define bfd_mach_mcf528x 13
-#define bfd_mach_mcfv4e 14
-#define bfd_mach_mcf521x 15
-#define bfd_mach_mcf5249 16
-#define bfd_mach_mcf547x 17
-#define bfd_mach_mcf548x 18
- bfd_arch_vax, /* DEC Vax */
- bfd_arch_i960, /* Intel 960 */
- /* The order of the following is important.
- lower number indicates a machine type that
- only accepts a subset of the instructions
- available to machines with higher numbers.
- The exception is the "ca", which is
- incompatible with all other machines except
- "core". */
-
-#define bfd_mach_i960_core 1
-#define bfd_mach_i960_ka_sa 2
-#define bfd_mach_i960_kb_sb 3
-#define bfd_mach_i960_mc 4
-#define bfd_mach_i960_xa 5
-#define bfd_mach_i960_ca 6
-#define bfd_mach_i960_jx 7
-#define bfd_mach_i960_hx 8
-
- bfd_arch_a29k, /* AMD 29000 */
- bfd_arch_sparc, /* SPARC */
-#define bfd_mach_sparc 1
-/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
-#define bfd_mach_sparc_sparclet 2
-#define bfd_mach_sparc_sparclite 3
-#define bfd_mach_sparc_v8plus 4
-#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */
-#define bfd_mach_sparc_sparclite_le 6
-#define bfd_mach_sparc_v9 7
-#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */
-#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
-#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */
-/* Nonzero if MACH has the v9 instruction set. */
-#define bfd_mach_sparc_v9_p(mach) \
- ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
- && (mach) != bfd_mach_sparc_sparclite_le)
- bfd_arch_mips, /* MIPS Rxxxx */
-#define bfd_mach_mips3000 3000
-#define bfd_mach_mips3900 3900
-#define bfd_mach_mips4000 4000
-#define bfd_mach_mips4010 4010
-#define bfd_mach_mips4100 4100
-#define bfd_mach_mips4300 4300
-#define bfd_mach_mips4400 4400
-#define bfd_mach_mips4600 4600
-#define bfd_mach_mips4650 4650
-#define bfd_mach_mips5000 5000
-#define bfd_mach_mips6000 6000
-#define bfd_mach_mips8000 8000
-#define bfd_mach_mips10000 10000
-#define bfd_mach_mips16 16
- bfd_arch_i386, /* Intel 386 */
-#define bfd_mach_i386_i386 0
-#define bfd_mach_i386_i8086 1
-#define bfd_mach_i386_i386_intel_syntax 2
-#define bfd_mach_x86_64 3
-#define bfd_mach_x86_64_intel_syntax 4
- bfd_arch_we32k, /* AT&T WE32xxx */
- bfd_arch_tahoe, /* CCI/Harris Tahoe */
- bfd_arch_i860, /* Intel 860 */
- bfd_arch_romp, /* IBM ROMP PC/RT */
- bfd_arch_alliant, /* Alliant */
- bfd_arch_convex, /* Convex */
- bfd_arch_m88k, /* Motorola 88xxx */
- bfd_arch_pyramid, /* Pyramid Technology */
- bfd_arch_h8300, /* Hitachi H8/300 */
-#define bfd_mach_h8300 1
-#define bfd_mach_h8300h 2
-#define bfd_mach_h8300s 3
- bfd_arch_powerpc, /* PowerPC */
-#define bfd_mach_ppc 0
-#define bfd_mach_ppc64 1
-#define bfd_mach_ppc_403 403
-#define bfd_mach_ppc_403gc 4030
-#define bfd_mach_ppc_505 505
-#define bfd_mach_ppc_601 601
-#define bfd_mach_ppc_602 602
-#define bfd_mach_ppc_603 603
-#define bfd_mach_ppc_ec603e 6031
-#define bfd_mach_ppc_604 604
-#define bfd_mach_ppc_620 620
-#define bfd_mach_ppc_630 630
-#define bfd_mach_ppc_750 750
-#define bfd_mach_ppc_860 860
-#define bfd_mach_ppc_a35 35
-#define bfd_mach_ppc_rs64ii 642
-#define bfd_mach_ppc_rs64iii 643
-#define bfd_mach_ppc_7400 7400
- bfd_arch_rs6000, /* IBM RS/6000 */
- bfd_arch_hppa, /* HP PA RISC */
- bfd_arch_d10v, /* Mitsubishi D10V */
- bfd_arch_z8k, /* Zilog Z8000 */
-#define bfd_mach_z8001 1
-#define bfd_mach_z8002 2
- bfd_arch_h8500, /* Hitachi H8/500 */
- bfd_arch_sh, /* Hitachi SH */
-#define bfd_mach_sh 1
-#define bfd_mach_sh2 0x20
-#define bfd_mach_sh_dsp 0x2d
-#define bfd_mach_sh2a 0x2a
-#define bfd_mach_sh2a_nofpu 0x2b
-#define bfd_mach_sh2e 0x2e
-#define bfd_mach_sh3 0x30
-#define bfd_mach_sh3_nommu 0x31
-#define bfd_mach_sh3_dsp 0x3d
-#define bfd_mach_sh3e 0x3e
-#define bfd_mach_sh4 0x40
-#define bfd_mach_sh4_nofpu 0x41
-#define bfd_mach_sh4_nommu_nofpu 0x42
-#define bfd_mach_sh4a 0x4a
-#define bfd_mach_sh4a_nofpu 0x4b
-#define bfd_mach_sh4al_dsp 0x4d
-#define bfd_mach_sh5 0x50
- bfd_arch_alpha, /* Dec Alpha */
- bfd_arch_arm, /* Advanced Risc Machines ARM */
-#define bfd_mach_arm_2 1
-#define bfd_mach_arm_2a 2
-#define bfd_mach_arm_3 3
-#define bfd_mach_arm_3M 4
-#define bfd_mach_arm_4 5
-#define bfd_mach_arm_4T 6
- bfd_arch_ns32k, /* National Semiconductors ns32000 */
- bfd_arch_w65, /* WDC 65816 */
- bfd_arch_tic30, /* Texas Instruments TMS320C30 */
- bfd_arch_v850, /* NEC V850 */
-#define bfd_mach_v850 0
- bfd_arch_arc, /* Argonaut RISC Core */
-#define bfd_mach_arc_base 0
- bfd_arch_m32r, /* Mitsubishi M32R/D */
-#define bfd_mach_m32r 0 /* backwards compatibility */
- bfd_arch_mn10200, /* Matsushita MN10200 */
- bfd_arch_mn10300, /* Matsushita MN10300 */
- bfd_arch_last
- };
-
-typedef struct symbol_cache_entry
-{
- const char *name;
- union
- {
- PTR p;
- bfd_vma i;
- } udata;
-} asymbol;
-
-typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
-
-enum dis_insn_type {
- dis_noninsn, /* Not a valid instruction */
- dis_nonbranch, /* Not a branch instruction */
- dis_branch, /* Unconditional branch */
- dis_condbranch, /* Conditional branch */
- dis_jsr, /* Jump to subroutine */
- dis_condjsr, /* Conditional jump to subroutine */
- dis_dref, /* Data reference instruction */
- dis_dref2 /* Two data references in instruction */
-};
-
-/* This struct is passed into the instruction decoding routine,
- and is passed back out into each callback. The various fields are used
- for conveying information from your main routine into your callbacks,
- for passing information into the instruction decoders (such as the
- addresses of the callback functions), or for passing information
- back from the instruction decoders to their callers.
-
- It must be initialized before it is first passed; this can be done
- by hand, or using one of the initialization macros below. */
-
-typedef struct disassemble_info {
- fprintf_ftype fprintf_func;
- FILE *stream;
- PTR application_data;
-
- /* Target description. We could replace this with a pointer to the bfd,
- but that would require one. There currently isn't any such requirement
- so to avoid introducing one we record these explicitly. */
- /* The bfd_flavour. This can be bfd_target_unknown_flavour. */
- enum bfd_flavour flavour;
- /* The bfd_arch value. */
- enum bfd_architecture arch;
- /* The bfd_mach value. */
- unsigned long mach;
- /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
- enum bfd_endian endian;
-
- /* An array of pointers to symbols either at the location being disassembled
- or at the start of the function being disassembled. The array is sorted
- so that the first symbol is intended to be the one used. The others are
- present for any misc. purposes. This is not set reliably, but if it is
- not NULL, it is correct. */
- asymbol **symbols;
- /* Number of symbols in array. */
- int num_symbols;
-
- /* For use by the disassembler.
- The top 16 bits are reserved for public use (and are documented here).
- The bottom 16 bits are for the internal use of the disassembler. */
- unsigned long flags;
-#define INSN_HAS_RELOC 0x80000000
- PTR private_data;
-
- /* Function used to get bytes to disassemble. MEMADDR is the
- address of the stuff to be disassembled, MYADDR is the address to
- put the bytes in, and LENGTH is the number of bytes to read.
- INFO is a pointer to this struct.
- Returns an errno value or 0 for success. */
- int (*read_memory_func)
- PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
- struct disassemble_info *info));
-
- /* Function which should be called if we get an error that we can't
- recover from. STATUS is the errno value from read_memory_func and
- MEMADDR is the address that we were trying to read. INFO is a
- pointer to this struct. */
- void (*memory_error_func)
- PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
-
- /* Function called to print ADDR. */
- void (*print_address_func)
- PARAMS ((bfd_vma addr, struct disassemble_info *info));
-
- /* Function called to determine if there is a symbol at the given ADDR.
- If there is, the function returns 1, otherwise it returns 0.
- This is used by ports which support an overlay manager where
- the overlay number is held in the top part of an address. In
- some circumstances we want to include the overlay number in the
- address, (normally because there is a symbol associated with
- that address), but sometimes we want to mask out the overlay bits. */
- int (* symbol_at_address_func)
- PARAMS ((bfd_vma addr, struct disassemble_info * info));
-
- /* These are for buffer_read_memory. */
- bfd_byte *buffer;
- bfd_vma buffer_vma;
- int buffer_length;
-
- /* This variable may be set by the instruction decoder. It suggests
- the number of bytes objdump should display on a single line. If
- the instruction decoder sets this, it should always set it to
- the same value in order to get reasonable looking output. */
- int bytes_per_line;
-
- /* the next two variables control the way objdump displays the raw data */
- /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
- /* output will look like this:
- 00: 00000000 00000000
- with the chunks displayed according to "display_endian". */
- int bytes_per_chunk;
- enum bfd_endian display_endian;
-
- /* Results from instruction decoders. Not all decoders yet support
- this information. This info is set each time an instruction is
- decoded, and is only valid for the last such instruction.
-
- To determine whether this decoder supports this information, set
- insn_info_valid to 0, decode an instruction, then check it. */
-
- char insn_info_valid; /* Branch info has been set. */
- char branch_delay_insns; /* How many sequential insn's will run before
- a branch takes effect. (0 = normal) */
- char data_size; /* Size of data reference in insn, in bytes */
- enum dis_insn_type insn_type; /* Type of instruction */
- bfd_vma target; /* Target address of branch or dref, if known;
- zero if unknown. */
- bfd_vma target2; /* Second target address for dref2 */
-
- /* Command line options specific to the target disassembler. */
- char * disassembler_options;
-
-} disassemble_info;
-
-
-/* Standard disassemblers. Disassemble one instruction at the given
- target address. Return number of bytes processed. */
-typedef int (*disassembler_ftype)
- PARAMS((bfd_vma, disassemble_info *));
-
-extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8300s PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
-extern disassembler_ftype arc_get_disassembler PARAMS ((int, int));
-extern int print_insn_arm PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_shl PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_m32r PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_mn10200 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_mn10300 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_ppc PARAMS ((bfd_vma, disassemble_info*));
-
-#if 0
-/* Fetch the disassembler for a given BFD, if that support is available. */
-extern disassembler_ftype disassembler PARAMS ((bfd *));
-#endif
-
-
-/* This block of definitions is for particular callers who read instructions
- into a buffer before calling the instruction decoder. */
-
-/* Here is a function which callers may wish to use for read_memory_func.
- It gets bytes from a buffer. */
-extern int buffer_read_memory
- PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
-
-/* This function goes with buffer_read_memory.
- It prints a message using info->fprintf_func and info->stream. */
-extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
-
-
-/* Just print the address in hex. This is included for completeness even
- though both GDB and objdump provide their own (to print symbolic
- addresses). */
-extern void generic_print_address
- PARAMS ((bfd_vma, struct disassemble_info *));
-
-/* Always true. */
-extern int generic_symbol_at_address
- PARAMS ((bfd_vma, struct disassemble_info *));
-
-/* Macro to initialize a disassemble_info struct. This should be called
- by all applications creating such a struct. */
-#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
- (INFO).flavour = bfd_target_unknown_flavour, \
- (INFO).arch = bfd_arch_unknown, \
- (INFO).mach = 0, \
- (INFO).endian = BFD_ENDIAN_UNKNOWN, \
- INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC)
-
-/* Call this macro to initialize only the internal variables for the
- disassembler. Architecture dependent things such as byte order, or machine
- variant are not touched by this macro. This makes things much easier for
- GDB which must initialize these things seperatly. */
-
-#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
- (INFO).fprintf_func = (FPRINTF_FUNC), \
- (INFO).stream = (STREAM), \
- (INFO).symbols = NULL, \
- (INFO).num_symbols = 0, \
- (INFO).buffer = NULL, \
- (INFO).buffer_vma = 0, \
- (INFO).buffer_length = 0, \
- (INFO).read_memory_func = buffer_read_memory, \
- (INFO).memory_error_func = perror_memory, \
- (INFO).print_address_func = generic_print_address, \
- (INFO).symbol_at_address_func = generic_symbol_at_address, \
- (INFO).flags = 0, \
- (INFO).bytes_per_line = 0, \
- (INFO).bytes_per_chunk = 0, \
- (INFO).display_endian = BFD_ENDIAN_UNKNOWN, \
- (INFO).disassembler_options = NULL, \
- (INFO).insn_info_valid = 0
-
-#define _(x) x
-#define ATTRIBUTE_UNUSED __attribute__((unused))
-
-/* from libbfd */
-
-bfd_vma bfd_getl32 (const bfd_byte *addr);
-bfd_vma bfd_getb32 (const bfd_byte *addr);
-bfd_vma bfd_getl16 (const bfd_byte *addr);
-bfd_vma bfd_getb16 (const bfd_byte *addr);
-typedef enum bfd_boolean {false, true} boolean;
-typedef boolean bfd_boolean;
-
-#endif /* ! defined (DIS_ASM_H) */
diff --git a/tools/ioemu/disas.c b/tools/ioemu/disas.c
deleted file mode 100644
index 2979927984..0000000000
--- a/tools/ioemu/disas.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* General "disassemble this chunk" code. Used for debugging. */
-#include "config.h"
-#include "dis-asm.h"
-#include "elf.h"
-#include <errno.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-
-/* Filled in by elfload.c. Simplistic, but will do for now. */
-struct syminfo *syminfos = NULL;
-
-/* Get LENGTH bytes from info's buffer, at target address memaddr.
- Transfer them to myaddr. */
-int
-buffer_read_memory (memaddr, myaddr, length, info)
- bfd_vma memaddr;
- bfd_byte *myaddr;
- int length;
- struct disassemble_info *info;
-{
- if (memaddr < info->buffer_vma
- || memaddr + length > info->buffer_vma + info->buffer_length)
- /* Out of bounds. Use EIO because GDB uses it. */
- return EIO;
- memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
- return 0;
-}
-
-/* Get LENGTH bytes from info's buffer, at target address memaddr.
- Transfer them to myaddr. */
-static int
-target_read_memory (bfd_vma memaddr,
- bfd_byte *myaddr,
- int length,
- struct disassemble_info *info)
-{
- int i;
- for(i = 0; i < length; i++) {
- myaddr[i] = ldub_code(memaddr + i);
- }
- return 0;
-}
-
-/* Print an error message. We can assume that this is in response to
- an error return from buffer_read_memory. */
-void
-perror_memory (status, memaddr, info)
- int status;
- bfd_vma memaddr;
- struct disassemble_info *info;
-{
- if (status != EIO)
- /* Can't happen. */
- (*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
- else
- /* Actually, address between memaddr and memaddr + len was
- out of bounds. */
- (*info->fprintf_func) (info->stream,
- "Address 0x%" PRIx64 " is out of bounds.\n", memaddr);
-}
-
-/* This could be in a separate file, to save miniscule amounts of space
- in statically linked executables. */
-
-/* Just print the address is hex. This is included for completeness even
- though both GDB and objdump provide their own (to print symbolic
- addresses). */
-
-void
-generic_print_address (addr, info)
- bfd_vma addr;
- struct disassemble_info *info;
-{
- (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
-}
-
-/* Just return the given address. */
-
-int
-generic_symbol_at_address (addr, info)
- bfd_vma addr;
- struct disassemble_info * info;
-{
- return 1;
-}
-
-bfd_vma bfd_getl32 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0];
- v |= (unsigned long) addr[1] << 8;
- v |= (unsigned long) addr[2] << 16;
- v |= (unsigned long) addr[3] << 24;
- return (bfd_vma) v;
-}
-
-bfd_vma bfd_getb32 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0] << 24;
- v |= (unsigned long) addr[1] << 16;
- v |= (unsigned long) addr[2] << 8;
- v |= (unsigned long) addr[3];
- return (bfd_vma) v;
-}
-
-bfd_vma bfd_getl16 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0];
- v |= (unsigned long) addr[1] << 8;
- return (bfd_vma) v;
-}
-
-bfd_vma bfd_getb16 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0] << 24;
- v |= (unsigned long) addr[1] << 16;
- return (bfd_vma) v;
-}
-
-#ifdef TARGET_ARM
-static int
-print_insn_thumb1(bfd_vma pc, disassemble_info *info)
-{
- return print_insn_arm(pc | 1, info);
-}
-#endif
-
-/* Disassemble this for me please... (debugging). 'flags' has teh following
- values:
- i386 - nonzero means 16 bit code
- arm - nonzero means thumb code
- ppc - nonzero means little endian
- other targets - unused
- */
-void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
-{
- target_ulong pc;
- int count;
- struct disassemble_info disasm_info;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
-
- INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
-
- disasm_info.read_memory_func = target_read_memory;
- disasm_info.buffer_vma = code;
- disasm_info.buffer_length = size;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- disasm_info.endian = BFD_ENDIAN_BIG;
-#else
- disasm_info.endian = BFD_ENDIAN_LITTLE;
-#endif
-#if defined(TARGET_I386)
- if (flags == 2)
- disasm_info.mach = bfd_mach_x86_64;
- else if (flags == 1)
- disasm_info.mach = bfd_mach_i386_i8086;
- else
- disasm_info.mach = bfd_mach_i386_i386;
- print_insn = print_insn_i386;
-#elif defined(TARGET_ARM)
- if (flags)
- print_insn = print_insn_thumb1;
- else
- print_insn = print_insn_arm;
-#elif defined(TARGET_SPARC)
- print_insn = print_insn_sparc;
-#ifdef TARGET_SPARC64
- disasm_info.mach = bfd_mach_sparc_v9b;
-#endif
-#elif defined(TARGET_PPC)
- if (flags)
- disasm_info.endian = BFD_ENDIAN_LITTLE;
-#ifdef TARGET_PPC64
- disasm_info.mach = bfd_mach_ppc64;
-#else
- disasm_info.mach = bfd_mach_ppc;
-#endif
- print_insn = print_insn_ppc;
-#elif defined(TARGET_M68K)
- print_insn = print_insn_m68k;
-#elif defined(TARGET_MIPS)
-#ifdef TARGET_WORDS_BIGENDIAN
- print_insn = print_insn_big_mips;
-#else
- print_insn = print_insn_little_mips;
-#endif
-#elif defined(TARGET_SH4)
- disasm_info.mach = bfd_mach_sh4;
- print_insn = print_insn_sh;
-#else
- fprintf(out, "0x" TARGET_FMT_lx
- ": Asm output not supported on this arch\n", code);
- return;
-#endif
-
- for (pc = code; pc < code + size; pc += count) {
- fprintf(out, "0x" TARGET_FMT_lx ": ", pc);
- count = print_insn(pc, &disasm_info);
-#if 0
- {
- int i;
- uint8_t b;
- fprintf(out, " {");
- for(i = 0; i < count; i++) {
- target_read_memory(pc + i, &b, 1, &disasm_info);
- fprintf(out, " %02x", b);
- }
- fprintf(out, " }");
- }
-#endif
- fprintf(out, "\n");
- if (count < 0)
- break;
- }
-}
-
-/* Disassemble this for me please... (debugging). */
-void disas(FILE *out, void *code, unsigned long size)
-{
- unsigned long pc;
- int count;
- struct disassemble_info disasm_info;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
-
- INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
-
- disasm_info.buffer = code;
- disasm_info.buffer_vma = (unsigned long)code;
- disasm_info.buffer_length = size;
-
-#ifdef WORDS_BIGENDIAN
- disasm_info.endian = BFD_ENDIAN_BIG;
-#else
- disasm_info.endian = BFD_ENDIAN_LITTLE;
-#endif
-#if defined(__i386__)
- disasm_info.mach = bfd_mach_i386_i386;
- print_insn = print_insn_i386;
-#elif defined(__x86_64__)
- disasm_info.mach = bfd_mach_x86_64;
- print_insn = print_insn_i386;
-#elif defined(__powerpc__)
- print_insn = print_insn_ppc;
-#elif defined(__alpha__)
- print_insn = print_insn_alpha;
-#elif defined(__sparc__)
- print_insn = print_insn_sparc;
-#elif defined(__arm__)
- print_insn = print_insn_arm;
-#elif defined(__MIPSEB__)
- print_insn = print_insn_big_mips;
-#elif defined(__MIPSEL__)
- print_insn = print_insn_little_mips;
-#elif defined(__m68k__)
- print_insn = print_insn_m68k;
-#else
- fprintf(out, "0x%lx: Asm output not supported on this arch\n",
- (long) code);
- return;
-#endif
- for (pc = (unsigned long)code; pc < (unsigned long)code + size; pc += count) {
- fprintf(out, "0x%08lx: ", pc);
-#ifdef __arm__
- /* since data is included in the code, it is better to
- display code data too */
- fprintf(out, "%08x ", (int)bfd_getl32((const bfd_byte *)pc));
-#endif
- count = print_insn(pc, &disasm_info);
- fprintf(out, "\n");
- if (count < 0)
- break;
- }
-}
-
-/* Look up symbol for debugging purpose. Returns "" if unknown. */
-const char *lookup_symbol(target_ulong orig_addr)
-{
- unsigned int i;
- /* Hack, because we know this is x86. */
- Elf32_Sym *sym;
- struct syminfo *s;
- target_ulong addr;
-
- for (s = syminfos; s; s = s->next) {
- sym = s->disas_symtab;
- for (i = 0; i < s->disas_num_syms; i++) {
- if (sym[i].st_shndx == SHN_UNDEF
- || sym[i].st_shndx >= SHN_LORESERVE)
- continue;
-
- if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
- continue;
-
- addr = sym[i].st_value;
-#ifdef TARGET_ARM
- /* The bottom address bit marks a Thumb symbol. */
- addr &= ~(target_ulong)1;
-#endif
- if (orig_addr >= addr
- && orig_addr < addr + sym[i].st_size)
- return s->disas_strtab + sym[i].st_name;
- }
- }
- return "";
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-void term_vprintf(const char *fmt, va_list ap);
-void term_printf(const char *fmt, ...);
-
-static int monitor_disas_is_physical;
-static CPUState *monitor_disas_env;
-
-static int
-monitor_read_memory (memaddr, myaddr, length, info)
- bfd_vma memaddr;
- bfd_byte *myaddr;
- int length;
- struct disassemble_info *info;
-{
- if (monitor_disas_is_physical) {
- cpu_physical_memory_rw(memaddr, myaddr, length, 0);
- } else {
- cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0);
- }
- return 0;
-}
-
-static int monitor_fprintf(FILE *stream, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- term_vprintf(fmt, ap);
- va_end(ap);
- return 0;
-}
-
-void monitor_disas(CPUState *env,
- target_ulong pc, int nb_insn, int is_physical, int flags)
-{
- int count, i;
- struct disassemble_info disasm_info;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
-
- INIT_DISASSEMBLE_INFO(disasm_info, NULL, monitor_fprintf);
-
- monitor_disas_env = env;
- monitor_disas_is_physical = is_physical;
- disasm_info.read_memory_func = monitor_read_memory;
-
- disasm_info.buffer_vma = pc;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- disasm_info.endian = BFD_ENDIAN_BIG;
-#else
- disasm_info.endian = BFD_ENDIAN_LITTLE;
-#endif
-#if defined(TARGET_I386)
- if (flags == 2)
- disasm_info.mach = bfd_mach_x86_64;
- else if (flags == 1)
- disasm_info.mach = bfd_mach_i386_i8086;
- else
- disasm_info.mach = bfd_mach_i386_i386;
- print_insn = print_insn_i386;
-#elif defined(TARGET_ARM)
- print_insn = print_insn_arm;
-#elif defined(TARGET_SPARC)
- print_insn = print_insn_sparc;
-#elif defined(TARGET_PPC)
-#ifdef TARGET_PPC64
- disasm_info.mach = bfd_mach_ppc64;
-#else
- disasm_info.mach = bfd_mach_ppc;
-#endif
- print_insn = print_insn_ppc;
-#elif defined(TARGET_M68K)
- print_insn = print_insn_m68k;
-#elif defined(TARGET_MIPS)
-#ifdef TARGET_WORDS_BIGENDIAN
- print_insn = print_insn_big_mips;
-#else
- print_insn = print_insn_little_mips;
-#endif
-#else
- term_printf("0x" TARGET_FMT_lx
- ": Asm output not supported on this arch\n", pc);
- return;
-#endif
-
- for(i = 0; i < nb_insn; i++) {
- term_printf("0x" TARGET_FMT_lx ": ", pc);
- count = print_insn(pc, &disasm_info);
- term_printf("\n");
- if (count < 0)
- break;
- pc += count;
- }
-}
-#endif
diff --git a/tools/ioemu/disas.h b/tools/ioemu/disas.h
deleted file mode 100644
index e85b4f6b64..0000000000
--- a/tools/ioemu/disas.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _QEMU_DISAS_H
-#define _QEMU_DISAS_H
-
-#ifndef CONFIG_DM
-/* Disassemble this for me please... (debugging). */
-void disas(FILE *out, void *code, unsigned long size);
-void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
-void monitor_disas(CPUState *env,
- target_ulong pc, int nb_insn, int is_physical, int flags);
-
-/* Look up symbol for debugging purpose. Returns "" if unknown. */
-const char *lookup_symbol(target_ulong orig_addr);
-
-/* Filled in by elfload.c. Simplistic, but will do for now. */
-extern struct syminfo {
- unsigned int disas_num_syms;
- void *disas_symtab;
- const char *disas_strtab;
- struct syminfo *next;
-} *syminfos;
-#endif /* !CONFIG_DM */
-
-#endif /* _QEMU_DISAS_H */
diff --git a/tools/ioemu/dyngen-exec.h b/tools/ioemu/dyngen-exec.h
deleted file mode 100644
index 7b313d62c7..0000000000
--- a/tools/ioemu/dyngen-exec.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * dyngen defines for micro operation code
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#if !defined(__DYNGEN_EXEC_H__)
-#define __DYNGEN_EXEC_H__
-
-/* prevent Solaris from trying to typedef FILE in gcc's
- include/floatingpoint.h which will conflict with the
- definition down below */
-#ifdef __sun__
-#define _FILEDEFED
-#endif
-
-/* NOTE: standard headers should be used with special care at this
- point because host CPU registers are used as global variables. Some
- host headers do not allow that. */
-#include <stddef.h>
-
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-// Linux/Sparc64 defines uint64_t
-#if !(defined (__sparc_v9__) && defined(__linux__))
-/* XXX may be done for all 64 bits targets ? */
-#if defined (__x86_64__) || defined(__ia64)
-typedef unsigned long uint64_t;
-#else
-typedef unsigned long long uint64_t;
-#endif
-#endif
-
-/* if Solaris/__sun__, don't typedef int8_t, as it will be typedef'd
- prior to this and will cause an error in compliation, conflicting
- with /usr/include/sys/int_types.h, line 75 */
-#ifndef __sun__
-typedef signed char int8_t;
-#endif
-typedef signed short int16_t;
-typedef signed int int32_t;
-// Linux/Sparc64 defines int64_t
-#if !(defined (__sparc_v9__) && defined(__linux__))
-#if defined (__x86_64__) || defined(__ia64)
-typedef signed long int64_t;
-#else
-typedef signed long long int64_t;
-#endif
-#endif
-
-/* XXX: This may be wrong for 64-bit ILP32 hosts. */
-typedef void * host_reg_t;
-
-#define INT8_MIN (-128)
-#define INT16_MIN (-32767-1)
-#define INT32_MIN (-2147483647-1)
-#define INT64_MIN (-(int64_t)(9223372036854775807)-1)
-#define INT8_MAX (127)
-#define INT16_MAX (32767)
-#define INT32_MAX (2147483647)
-#define INT64_MAX ((int64_t)(9223372036854775807))
-#define UINT8_MAX (255)
-#define UINT16_MAX (65535)
-#define UINT32_MAX (4294967295U)
-#define UINT64_MAX ((uint64_t)(18446744073709551615))
-
-typedef struct FILE FILE;
-extern int fprintf(FILE *, const char *, ...);
-extern int printf(const char *, ...);
-#undef NULL
-#define NULL 0
-
-#ifdef __i386__
-#define AREG0 "ebp"
-#define AREG1 "ebx"
-#define AREG2 "esi"
-#define AREG3 "edi"
-#endif
-#ifdef __x86_64__
-#define AREG0 "rbp"
-#define AREG1 "rbx"
-#define AREG2 "r12"
-#define AREG3 "r13"
-//#define AREG4 "r14"
-//#define AREG5 "r15"
-#endif
-#ifdef __powerpc__
-#define AREG0 "r27"
-#define AREG1 "r24"
-#define AREG2 "r25"
-#define AREG3 "r26"
-/* XXX: suppress this hack */
-#if defined(CONFIG_USER_ONLY)
-#define AREG4 "r16"
-#define AREG5 "r17"
-#define AREG6 "r18"
-#define AREG7 "r19"
-#define AREG8 "r20"
-#define AREG9 "r21"
-#define AREG10 "r22"
-#define AREG11 "r23"
-#endif
-#define USE_INT_TO_FLOAT_HELPERS
-#define BUGGY_GCC_DIV64
-#endif
-#ifdef __arm__
-#define AREG0 "r7"
-#define AREG1 "r4"
-#define AREG2 "r5"
-#define AREG3 "r6"
-#endif
-#ifdef __mips__
-#define AREG0 "s3"
-#define AREG1 "s0"
-#define AREG2 "s1"
-#define AREG3 "s2"
-#endif
-#ifdef __sparc__
-#ifdef HOST_SOLARIS
-#define AREG0 "g2"
-#define AREG1 "g3"
-#define AREG2 "g4"
-#define AREG3 "g5"
-#define AREG4 "g6"
-#else
-#ifdef __sparc_v9__
-#define AREG0 "g1"
-#define AREG1 "g4"
-#define AREG2 "g5"
-#define AREG3 "g7"
-#else
-#define AREG0 "g6"
-#define AREG1 "g1"
-#define AREG2 "g2"
-#define AREG3 "g3"
-#define AREG4 "l0"
-#define AREG5 "l1"
-#define AREG6 "l2"
-#define AREG7 "l3"
-#define AREG8 "l4"
-#define AREG9 "l5"
-#define AREG10 "l6"
-#define AREG11 "l7"
-#endif
-#endif
-#define USE_FP_CONVERT
-#endif
-#ifdef __s390__
-#define AREG0 "r10"
-#define AREG1 "r7"
-#define AREG2 "r8"
-#define AREG3 "r9"
-#endif
-#ifdef __alpha__
-/* Note $15 is the frame pointer, so anything in op-i386.c that would
- require a frame pointer, like alloca, would probably loose. */
-#define AREG0 "$15"
-#define AREG1 "$9"
-#define AREG2 "$10"
-#define AREG3 "$11"
-#define AREG4 "$12"
-#define AREG5 "$13"
-#define AREG6 "$14"
-#endif
-#ifdef __mc68000
-#define AREG0 "%a5"
-#define AREG1 "%a4"
-#define AREG2 "%d7"
-#define AREG3 "%d6"
-#define AREG4 "%d5"
-#endif
-#ifdef __ia64__
-#define AREG0 "r7"
-#define AREG1 "r4"
-#define AREG2 "r5"
-#define AREG3 "r6"
-#endif
-
-/* force GCC to generate only one epilog at the end of the function */
-#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
-
-#ifndef OPPROTO
-#define OPPROTO
-#endif
-
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-
-#ifdef __alpha__
-/* the symbols are considered non exported so a br immediate is generated */
-#define __hidden __attribute__((visibility("hidden")))
-#else
-#define __hidden
-#endif
-
-#if defined(__alpha__)
-/* Suggested by Richard Henderson. This will result in code like
- ldah $0,__op_param1($29) !gprelhigh
- lda $0,__op_param1($0) !gprellow
- We can then conveniently change $29 to $31 and adapt the offsets to
- emit the appropriate constant. */
-extern int __op_param1 __hidden;
-extern int __op_param2 __hidden;
-extern int __op_param3 __hidden;
-#define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
-#define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
-#define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
-#else
-#if defined(__APPLE__)
-static int __op_param1, __op_param2, __op_param3;
-#else
-extern int __op_param1, __op_param2, __op_param3;
-#endif
-#define PARAM1 ((long)(&__op_param1))
-#define PARAM2 ((long)(&__op_param2))
-#define PARAM3 ((long)(&__op_param3))
-#endif /* !defined(__alpha__) */
-
-extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#if defined(_WIN32) || defined(__APPLE__)
-#define ASM_NAME(x) "_" #x
-#else
-#define ASM_NAME(x) #x
-#endif
-
-#ifdef __i386__
-#define EXIT_TB() asm volatile ("ret")
-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __x86_64__
-#define EXIT_TB() asm volatile ("ret")
-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __powerpc__
-#define EXIT_TB() asm volatile ("blr")
-#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __s390__
-#define EXIT_TB() asm volatile ("br %r14")
-#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __alpha__
-#define EXIT_TB() asm volatile ("ret")
-#endif
-#ifdef __ia64__
-#define EXIT_TB() asm volatile ("br.ret.sptk.many b0;;")
-#define GOTO_LABEL_PARAM(n) asm volatile ("br.sptk.many " \
- ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __sparc__
-#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
-#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
-#endif
-#ifdef __arm__
-#define EXIT_TB() asm volatile ("b exec_loop")
-#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#endif
-#ifdef __mc68000
-#define EXIT_TB() asm volatile ("rts")
-#endif
-
-#endif /* !defined(__DYNGEN_EXEC_H__) */
diff --git a/tools/ioemu/dyngen-op.h b/tools/ioemu/dyngen-op.h
deleted file mode 100644
index f77a4756f7..0000000000
--- a/tools/ioemu/dyngen-op.h
+++ /dev/null
@@ -1,9 +0,0 @@
-static inline int gen_new_label(void)
-{
- return nb_gen_labels++;
-}
-
-static inline void gen_set_label(int n)
-{
- gen_labels[n] = gen_opc_ptr - gen_opc_buf;
-}
diff --git a/tools/ioemu/dyngen.c b/tools/ioemu/dyngen.c
deleted file mode 100644
index bcfb86ea0d..0000000000
--- a/tools/ioemu/dyngen.c
+++ /dev/null
@@ -1,2783 +0,0 @@
-/*
- * Generic Dynamic compiler generator
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * The COFF object format support was extracted from Kazu's QEMU port
- * to Win32.
- *
- * Mach-O Support by Matt Reda and Pierre d'Herbemont
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "config-host.h"
-
-/* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross
- compilation */
-#if defined(CONFIG_WIN32)
-#define CONFIG_FORMAT_COFF
-#elif defined(CONFIG_DARWIN)
-#define CONFIG_FORMAT_MACH
-#else
-#define CONFIG_FORMAT_ELF
-#endif
-
-#ifdef CONFIG_FORMAT_ELF
-
-/* elf format definitions. We use these macros to test the CPU to
- allow cross compilation (this tool must be ran on the build
- platform) */
-#if defined(HOST_I386)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_386
-#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
-#undef ELF_USES_RELOCA
-
-#elif defined(HOST_X86_64)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_X86_64
-#define elf_check_arch(x) ((x) == EM_X86_64)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_PPC)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_PPC
-#define elf_check_arch(x) ((x) == EM_PPC)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_S390)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_S390
-#define elf_check_arch(x) ((x) == EM_S390)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_ALPHA)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_ALPHA
-#define elf_check_arch(x) ((x) == EM_ALPHA)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_IA64)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_IA_64
-#define elf_check_arch(x) ((x) == EM_IA_64)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_SPARC)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_SPARC
-#define elf_check_arch(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_SPARC64)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_SPARCV9
-#define elf_check_arch(x) ((x) == EM_SPARCV9)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_ARM)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_ARM
-#define elf_check_arch(x) ((x) == EM_ARM)
-#define ELF_USES_RELOC
-
-#elif defined(HOST_M68K)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_68K
-#define elf_check_arch(x) ((x) == EM_68K)
-#define ELF_USES_RELOCA
-
-#else
-#error unsupported CPU - please update the code
-#endif
-
-#include "elf.h"
-
-#if ELF_CLASS == ELFCLASS32
-typedef int32_t host_long;
-typedef uint32_t host_ulong;
-#define swabls(x) swab32s(x)
-#define swablss(x) swab32ss(x)
-#else
-typedef int64_t host_long;
-typedef uint64_t host_ulong;
-#define swabls(x) swab64s(x)
-#define swablss(x) swab64ss(x)
-#endif
-
-#ifdef ELF_USES_RELOCA
-#define SHT_RELOC SHT_RELA
-#else
-#define SHT_RELOC SHT_REL
-#endif
-
-#define EXE_RELOC ELF_RELOC
-#define EXE_SYM ElfW(Sym)
-
-#endif /* CONFIG_FORMAT_ELF */
-
-#ifdef CONFIG_FORMAT_COFF
-
-#include "a.out.h"
-
-typedef int32_t host_long;
-typedef uint32_t host_ulong;
-
-#define FILENAMELEN 256
-
-typedef struct coff_sym {
- struct external_syment *st_syment;
- char st_name[FILENAMELEN];
- uint32_t st_value;
- int st_size;
- uint8_t st_type;
- uint8_t st_shndx;
-} coff_Sym;
-
-typedef struct coff_rel {
- struct external_reloc *r_reloc;
- int r_offset;
- uint8_t r_type;
-} coff_Rel;
-
-#define EXE_RELOC struct coff_rel
-#define EXE_SYM struct coff_sym
-
-#endif /* CONFIG_FORMAT_COFF */
-
-#ifdef CONFIG_FORMAT_MACH
-
-#include <mach-o/loader.h>
-#include <mach-o/nlist.h>
-#include <mach-o/reloc.h>
-#include <mach-o/ppc/reloc.h>
-
-# define check_mach_header(x) (x.magic == MH_MAGIC)
-typedef int32_t host_long;
-typedef uint32_t host_ulong;
-
-struct nlist_extended
-{
- union {
- char *n_name;
- long n_strx;
- } n_un;
- unsigned char n_type;
- unsigned char n_sect;
- short st_desc;
- unsigned long st_value;
- unsigned long st_size;
-};
-
-#define EXE_RELOC struct relocation_info
-#define EXE_SYM struct nlist_extended
-
-#endif /* CONFIG_FORMAT_MACH */
-
-#include "bswap.h"
-
-enum {
- OUT_GEN_OP,
- OUT_CODE,
- OUT_INDEX_OP,
-};
-
-/* all dynamically generated functions begin with this code */
-#define OP_PREFIX "op_"
-
-int do_swap;
-
-void __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) error(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "dyngen: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- exit(1);
-}
-
-void *load_data(int fd, long offset, unsigned int size)
-{
- char *data;
-
- data = malloc(size);
- if (!data)
- return NULL;
- lseek(fd, offset, SEEK_SET);
- if (read(fd, data, size) != size) {
- free(data);
- return NULL;
- }
- return data;
-}
-
-int strstart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (*p != *q)
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-void pstrcpy(char *buf, int buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-void swab16s(uint16_t *p)
-{
- *p = bswap16(*p);
-}
-
-void swab32s(uint32_t *p)
-{
- *p = bswap32(*p);
-}
-
-void swab32ss(int32_t *p)
-{
- *p = bswap32(*p);
-}
-
-void swab64s(uint64_t *p)
-{
- *p = bswap64(*p);
-}
-
-void swab64ss(int64_t *p)
-{
- *p = bswap64(*p);
-}
-
-uint16_t get16(uint16_t *p)
-{
- uint16_t val;
- val = *p;
- if (do_swap)
- val = bswap16(val);
- return val;
-}
-
-uint32_t get32(uint32_t *p)
-{
- uint32_t val;
- val = *p;
- if (do_swap)
- val = bswap32(val);
- return val;
-}
-
-void put16(uint16_t *p, uint16_t val)
-{
- if (do_swap)
- val = bswap16(val);
- *p = val;
-}
-
-void put32(uint32_t *p, uint32_t val)
-{
- if (do_swap)
- val = bswap32(val);
- *p = val;
-}
-
-/* executable information */
-EXE_SYM *symtab;
-int nb_syms;
-int text_shndx;
-uint8_t *text;
-EXE_RELOC *relocs;
-int nb_relocs;
-
-#ifdef CONFIG_FORMAT_ELF
-
-/* ELF file info */
-struct elf_shdr *shdr;
-uint8_t **sdata;
-struct elfhdr ehdr;
-char *strtab;
-
-int elf_must_swap(struct elfhdr *h)
-{
- union {
- uint32_t i;
- uint8_t b[4];
- } swaptest;
-
- swaptest.i = 1;
- return (h->e_ident[EI_DATA] == ELFDATA2MSB) !=
- (swaptest.b[0] == 0);
-}
-
-void elf_swap_ehdr(struct elfhdr *h)
-{
- swab16s(&h->e_type); /* Object file type */
- swab16s(&h-> e_machine); /* Architecture */
- swab32s(&h-> e_version); /* Object file version */
- swabls(&h-> e_entry); /* Entry point virtual address */
- swabls(&h-> e_phoff); /* Program header table file offset */
- swabls(&h-> e_shoff); /* Section header table file offset */
- swab32s(&h-> e_flags); /* Processor-specific flags */
- swab16s(&h-> e_ehsize); /* ELF header size in bytes */
- swab16s(&h-> e_phentsize); /* Program header table entry size */
- swab16s(&h-> e_phnum); /* Program header table entry count */
- swab16s(&h-> e_shentsize); /* Section header table entry size */
- swab16s(&h-> e_shnum); /* Section header table entry count */
- swab16s(&h-> e_shstrndx); /* Section header string table index */
-}
-
-void elf_swap_shdr(struct elf_shdr *h)
-{
- swab32s(&h-> sh_name); /* Section name (string tbl index) */
- swab32s(&h-> sh_type); /* Section type */
- swabls(&h-> sh_flags); /* Section flags */
- swabls(&h-> sh_addr); /* Section virtual addr at execution */
- swabls(&h-> sh_offset); /* Section file offset */
- swabls(&h-> sh_size); /* Section size in bytes */
- swab32s(&h-> sh_link); /* Link to another section */
- swab32s(&h-> sh_info); /* Additional section information */
- swabls(&h-> sh_addralign); /* Section alignment */
- swabls(&h-> sh_entsize); /* Entry size if section holds table */
-}
-
-void elf_swap_phdr(struct elf_phdr *h)
-{
- swab32s(&h->p_type); /* Segment type */
- swabls(&h->p_offset); /* Segment file offset */
- swabls(&h->p_vaddr); /* Segment virtual address */
- swabls(&h->p_paddr); /* Segment physical address */
- swabls(&h->p_filesz); /* Segment size in file */
- swabls(&h->p_memsz); /* Segment size in memory */
- swab32s(&h->p_flags); /* Segment flags */
- swabls(&h->p_align); /* Segment alignment */
-}
-
-void elf_swap_rel(ELF_RELOC *rel)
-{
- swabls(&rel->r_offset);
- swabls(&rel->r_info);
-#ifdef ELF_USES_RELOCA
- swablss(&rel->r_addend);
-#endif
-}
-
-struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
- const char *name)
-{
- int i;
- const char *shname;
- struct elf_shdr *sec;
-
- for(i = 0; i < shnum; i++) {
- sec = &shdr[i];
- if (!sec->sh_name)
- continue;
- shname = shstr + sec->sh_name;
- if (!strcmp(shname, name))
- return sec;
- }
- return NULL;
-}
-
-int find_reloc(int sh_index)
-{
- struct elf_shdr *sec;
- int i;
-
- for(i = 0; i < ehdr.e_shnum; i++) {
- sec = &shdr[i];
- if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index)
- return i;
- }
- return 0;
-}
-
-static host_ulong get_rel_offset(EXE_RELOC *rel)
-{
- return rel->r_offset;
-}
-
-static char *get_rel_sym_name(EXE_RELOC *rel)
-{
- return strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
-}
-
-static char *get_sym_name(EXE_SYM *sym)
-{
- return strtab + sym->st_name;
-}
-
-/* load an elf object file */
-int load_object(const char *filename)
-{
- int fd;
- struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec;
- int i, j;
- ElfW(Sym) *sym;
- char *shstr;
- ELF_RELOC *rel;
-
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- error("can't open file '%s'", filename);
-
- /* Read ELF header. */
- if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
- error("unable to read file header");
-
- /* Check ELF identification. */
- if (ehdr.e_ident[EI_MAG0] != ELFMAG0
- || ehdr.e_ident[EI_MAG1] != ELFMAG1
- || ehdr.e_ident[EI_MAG2] != ELFMAG2
- || ehdr.e_ident[EI_MAG3] != ELFMAG3
- || ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
- error("bad ELF header");
- }
-
- do_swap = elf_must_swap(&ehdr);
- if (do_swap)
- elf_swap_ehdr(&ehdr);
- if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
- error("Unsupported ELF class");
- if (ehdr.e_type != ET_REL)
- error("ELF object file expected");
- if (ehdr.e_version != EV_CURRENT)
- error("Invalid ELF version");
- if (!elf_check_arch(ehdr.e_machine))
- error("Unsupported CPU (e_machine=%d)", ehdr.e_machine);
-
- /* read section headers */
- shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(struct elf_shdr));
- if (do_swap) {
- for(i = 0; i < ehdr.e_shnum; i++) {
- elf_swap_shdr(&shdr[i]);
- }
- }
-
- /* read all section data */
- sdata = malloc(sizeof(void *) * ehdr.e_shnum);
- memset(sdata, 0, sizeof(void *) * ehdr.e_shnum);
-
- for(i = 0;i < ehdr.e_shnum; i++) {
- sec = &shdr[i];
- if (sec->sh_type != SHT_NOBITS)
- sdata[i] = load_data(fd, sec->sh_offset, sec->sh_size);
- }
-
- sec = &shdr[ehdr.e_shstrndx];
- shstr = (char *)sdata[ehdr.e_shstrndx];
-
- /* swap relocations */
- for(i = 0; i < ehdr.e_shnum; i++) {
- sec = &shdr[i];
- if (sec->sh_type == SHT_RELOC) {
- nb_relocs = sec->sh_size / sec->sh_entsize;
- if (do_swap) {
- for(j = 0, rel = (ELF_RELOC *)sdata[i]; j < nb_relocs; j++, rel++)
- elf_swap_rel(rel);
- }
- }
- }
- /* text section */
-
- text_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".text");
- if (!text_sec)
- error("could not find .text section");
- text_shndx = text_sec - shdr;
- text = sdata[text_shndx];
-
- /* find text relocations, if any */
- relocs = NULL;
- nb_relocs = 0;
- i = find_reloc(text_shndx);
- if (i != 0) {
- relocs = (ELF_RELOC *)sdata[i];
- nb_relocs = shdr[i].sh_size / shdr[i].sh_entsize;
- }
-
- symtab_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".symtab");
- if (!symtab_sec)
- error("could not find .symtab section");
- strtab_sec = &shdr[symtab_sec->sh_link];
-
- symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr];
- strtab = (char *)sdata[symtab_sec->sh_link];
-
- nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym));
- if (do_swap) {
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- swab32s(&sym->st_name);
- swabls(&sym->st_value);
- swabls(&sym->st_size);
- swab16s(&sym->st_shndx);
- }
- }
- close(fd);
- return 0;
-}
-
-#endif /* CONFIG_FORMAT_ELF */
-
-#ifdef CONFIG_FORMAT_COFF
-
-/* COFF file info */
-struct external_scnhdr *shdr;
-uint8_t **sdata;
-struct external_filehdr fhdr;
-struct external_syment *coff_symtab;
-char *strtab;
-int coff_text_shndx, coff_data_shndx;
-
-int data_shndx;
-
-#define STRTAB_SIZE 4
-
-#define DIR32 0x06
-#define DISP32 0x14
-
-#define T_FUNCTION 0x20
-#define C_EXTERNAL 2
-
-void sym_ent_name(struct external_syment *ext_sym, EXE_SYM *sym)
-{
- char *q;
- int c, i, len;
-
- if (ext_sym->e.e.e_zeroes != 0) {
- q = sym->st_name;
- for(i = 0; i < 8; i++) {
- c = ext_sym->e.e_name[i];
- if (c == '\0')
- break;
- *q++ = c;
- }
- *q = '\0';
- } else {
- pstrcpy(sym->st_name, sizeof(sym->st_name), strtab + ext_sym->e.e.e_offset);
- }
-
- /* now convert the name to a C name (suppress the leading '_') */
- if (sym->st_name[0] == '_') {
- len = strlen(sym->st_name);
- memmove(sym->st_name, sym->st_name + 1, len - 1);
- sym->st_name[len - 1] = '\0';
- }
-}
-
-char *name_for_dotdata(struct coff_rel *rel)
-{
- int i;
- struct coff_sym *sym;
- uint32_t text_data;
-
- text_data = *(uint32_t *)(text + rel->r_offset);
-
- for (i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- if (sym->st_syment->e_scnum == data_shndx &&
- text_data >= sym->st_value &&
- text_data < sym->st_value + sym->st_size) {
-
- return sym->st_name;
-
- }
- }
- return NULL;
-}
-
-static char *get_sym_name(EXE_SYM *sym)
-{
- return sym->st_name;
-}
-
-static char *get_rel_sym_name(EXE_RELOC *rel)
-{
- char *name;
- name = get_sym_name(symtab + *(uint32_t *)(rel->r_reloc->r_symndx));
- if (!strcmp(name, ".data"))
- name = name_for_dotdata(rel);
- if (name[0] == '.')
- return NULL;
- return name;
-}
-
-static host_ulong get_rel_offset(EXE_RELOC *rel)
-{
- return rel->r_offset;
-}
-
-struct external_scnhdr *find_coff_section(struct external_scnhdr *shdr, int shnum, const char *name)
-{
- int i;
- const char *shname;
- struct external_scnhdr *sec;
-
- for(i = 0; i < shnum; i++) {
- sec = &shdr[i];
- if (!sec->s_name)
- continue;
- shname = sec->s_name;
- if (!strcmp(shname, name))
- return sec;
- }
- return NULL;
-}
-
-/* load a coff object file */
-int load_object(const char *filename)
-{
- int fd;
- struct external_scnhdr *sec, *text_sec, *data_sec;
- int i;
- struct external_syment *ext_sym;
- struct external_reloc *coff_relocs;
- struct external_reloc *ext_rel;
- uint32_t *n_strtab;
- EXE_SYM *sym;
- EXE_RELOC *rel;
-
- fd = open(filename, O_RDONLY
-#ifdef _WIN32
- | O_BINARY
-#endif
- );
- if (fd < 0)
- error("can't open file '%s'", filename);
-
- /* Read COFF header. */
- if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr))
- error("unable to read file header");
-
- /* Check COFF identification. */
- if (fhdr.f_magic != I386MAGIC) {
- error("bad COFF header");
- }
- do_swap = 0;
-
- /* read section headers */
- shdr = load_data(fd, sizeof(struct external_filehdr) + fhdr.f_opthdr, fhdr.f_nscns * sizeof(struct external_scnhdr));
-
- /* read all section data */
- sdata = malloc(sizeof(void *) * fhdr.f_nscns);
- memset(sdata, 0, sizeof(void *) * fhdr.f_nscns);
-
- const char *p;
- for(i = 0;i < fhdr.f_nscns; i++) {
- sec = &shdr[i];
- if (!strstart(sec->s_name, ".bss", &p))
- sdata[i] = load_data(fd, sec->s_scnptr, sec->s_size);
- }
-
-
- /* text section */
- text_sec = find_coff_section(shdr, fhdr.f_nscns, ".text");
- if (!text_sec)
- error("could not find .text section");
- coff_text_shndx = text_sec - shdr;
- text = sdata[coff_text_shndx];
-
- /* data section */
- data_sec = find_coff_section(shdr, fhdr.f_nscns, ".data");
- if (!data_sec)
- error("could not find .data section");
- coff_data_shndx = data_sec - shdr;
-
- coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ);
- for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
- for(i=0;i<8;i++)
- printf(" %02x", ((uint8_t *)ext_sym->e.e_name)[i]);
- printf("\n");
- }
-
-
- n_strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), STRTAB_SIZE);
- strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab);
-
- nb_syms = fhdr.f_nsyms;
-
- for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
- if (strstart(ext_sym->e.e_name, ".text", NULL))
- text_shndx = ext_sym->e_scnum;
- if (strstart(ext_sym->e.e_name, ".data", NULL))
- data_shndx = ext_sym->e_scnum;
- }
-
- /* set coff symbol */
- symtab = malloc(sizeof(struct coff_sym) * nb_syms);
-
- int aux_size, j;
- for (i = 0, ext_sym = coff_symtab, sym = symtab; i < nb_syms; i++, ext_sym++, sym++) {
- memset(sym, 0, sizeof(*sym));
- sym->st_syment = ext_sym;
- sym_ent_name(ext_sym, sym);
- sym->st_value = ext_sym->e_value;
-
- aux_size = *(int8_t *)ext_sym->e_numaux;
- if (ext_sym->e_scnum == text_shndx && ext_sym->e_type == T_FUNCTION) {
- for (j = aux_size + 1; j < nb_syms - i; j++) {
- if ((ext_sym + j)->e_scnum == text_shndx &&
- (ext_sym + j)->e_type == T_FUNCTION ){
- sym->st_size = (ext_sym + j)->e_value - ext_sym->e_value;
- break;
- } else if (j == nb_syms - i - 1) {
- sec = &shdr[coff_text_shndx];
- sym->st_size = sec->s_size - ext_sym->e_value;
- break;
- }
- }
- } else if (ext_sym->e_scnum == data_shndx && *(uint8_t *)ext_sym->e_sclass == C_EXTERNAL) {
- for (j = aux_size + 1; j < nb_syms - i; j++) {
- if ((ext_sym + j)->e_scnum == data_shndx) {
- sym->st_size = (ext_sym + j)->e_value - ext_sym->e_value;
- break;
- } else if (j == nb_syms - i - 1) {
- sec = &shdr[coff_data_shndx];
- sym->st_size = sec->s_size - ext_sym->e_value;
- break;
- }
- }
- } else {
- sym->st_size = 0;
- }
-
- sym->st_type = ext_sym->e_type;
- sym->st_shndx = ext_sym->e_scnum;
- }
-
-
- /* find text relocations, if any */
- sec = &shdr[coff_text_shndx];
- coff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc*RELSZ);
- nb_relocs = sec->s_nreloc;
-
- /* set coff relocation */
- relocs = malloc(sizeof(struct coff_rel) * nb_relocs);
- for (i = 0, ext_rel = coff_relocs, rel = relocs; i < nb_relocs;
- i++, ext_rel++, rel++) {
- memset(rel, 0, sizeof(*rel));
- rel->r_reloc = ext_rel;
- rel->r_offset = *(uint32_t *)ext_rel->r_vaddr;
- rel->r_type = *(uint16_t *)ext_rel->r_type;
- }
- return 0;
-}
-
-#endif /* CONFIG_FORMAT_COFF */
-
-#ifdef CONFIG_FORMAT_MACH
-
-/* File Header */
-struct mach_header mach_hdr;
-
-/* commands */
-struct segment_command *segment = 0;
-struct dysymtab_command *dysymtabcmd = 0;
-struct symtab_command *symtabcmd = 0;
-
-/* section */
-struct section *section_hdr;
-struct section *text_sec_hdr;
-uint8_t **sdata;
-
-/* relocs */
-struct relocation_info *relocs;
-
-/* symbols */
-EXE_SYM *symtab;
-struct nlist *symtab_std;
-char *strtab;
-
-/* indirect symbols */
-uint32_t *tocdylib;
-
-/* Utility functions */
-
-static inline char *find_str_by_index(int index)
-{
- return strtab+index;
-}
-
-/* Used by dyngen common code */
-static char *get_sym_name(EXE_SYM *sym)
-{
- char *name = find_str_by_index(sym->n_un.n_strx);
-
- if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */
- return "debug";
-
- if(!name)
- return name;
- if(name[0]=='_')
- return name + 1;
- else
- return name;
-}
-
-/* find a section index given its segname, sectname */
-static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,
- const char *sectname)
-{
- int i;
- struct section *sec = section_hdr;
-
- for(i = 0; i < shnum; i++, sec++) {
- if (!sec->segname || !sec->sectname)
- continue;
- if (!strcmp(sec->sectname, sectname) && !strcmp(sec->segname, segname))
- return i;
- }
- return -1;
-}
-
-/* find a section header given its segname, sectname */
-struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,
- const char *sectname)
-{
- int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);
- if(index == -1)
- return NULL;
- return section_hdr+index;
-}
-
-
-static inline void fetch_next_pair_value(struct relocation_info * rel, unsigned int *value)
-{
- struct scattered_relocation_info * scarel;
-
- if(R_SCATTERED & rel->r_address) {
- scarel = (struct scattered_relocation_info*)rel;
- if(scarel->r_type != PPC_RELOC_PAIR)
- error("fetch_next_pair_value: looking for a pair which was not found (1)");
- *value = scarel->r_value;
- } else {
- if(rel->r_type != PPC_RELOC_PAIR)
- error("fetch_next_pair_value: looking for a pair which was not found (2)");
- *value = rel->r_address;
- }
-}
-
-/* find a sym name given its value, in a section number */
-static const char * find_sym_with_value_and_sec_number( int value, int sectnum, int * offset )
-{
- int i, ret = -1;
-
- for( i = 0 ; i < nb_syms; i++ )
- {
- if( !(symtab[i].n_type & N_STAB) && (symtab[i].n_type & N_SECT) &&
- (symtab[i].n_sect == sectnum) && (symtab[i].st_value <= value) )
- {
- if( (ret<0) || (symtab[i].st_value >= symtab[ret].st_value) )
- ret = i;
- }
- }
- if( ret < 0 ) {
- *offset = 0;
- return 0;
- } else {
- *offset = value - symtab[ret].st_value;
- return get_sym_name(&symtab[ret]);
- }
-}
-
-/*
- * Find symbol name given a (virtual) address, and a section which is of type
- * S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS
- */
-static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr)
-{
- unsigned int tocindex, symindex, size;
- const char *name = 0;
-
- /* Sanity check */
- if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) )
- return (char*)0;
-
- if( sec_hdr->flags & S_SYMBOL_STUBS ){
- size = sec_hdr->reserved2;
- if(size == 0)
- error("size = 0");
-
- }
- else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||
- sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)
- size = sizeof(unsigned long);
- else
- return 0;
-
- /* Compute our index in toc */
- tocindex = (address - sec_hdr->addr)/size;
- symindex = tocdylib[sec_hdr->reserved1 + tocindex];
-
- name = get_sym_name(&symtab[symindex]);
-
- return name;
-}
-
-static const char * find_reloc_name_given_its_address(int address)
-{
- unsigned int i;
- for(i = 0; i < segment->nsects ; i++)
- {
- const char * name = find_reloc_name_in_sec_ptr(address, &section_hdr[i]);
- if((long)name != -1)
- return name;
- }
- return 0;
-}
-
-static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
-{
- char * name = 0;
- struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;
- int sectnum = rel->r_symbolnum;
- int sectoffset;
- int other_half=0;
-
- /* init the slide value */
- *sslide = 0;
-
- if(R_SCATTERED & rel->r_address)
- return (char *)find_reloc_name_given_its_address(sca_rel->r_value);
-
- if(rel->r_extern)
- {
- /* ignore debug sym */
- if ( symtab[rel->r_symbolnum].n_type & N_STAB )
- return 0;
- return get_sym_name(&symtab[rel->r_symbolnum]);
- }
-
- /* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */
- sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;
-
- if(sectnum==0xffffff)
- return 0;
-
- /* Sanity Check */
- if(sectnum > segment->nsects)
- error("sectnum > segment->nsects");
-
- switch(rel->r_type)
- {
- case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);
- break;
- case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);
- break;
- case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) + (int16_t)(other_half & 0xffff);
- break;
- case PPC_RELOC_BR24:
- sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
- if (sectoffset & 0x02000000) sectoffset |= 0xfc000000;
- break;
- default:
- error("switch(rel->type) not found");
- }
-
- if(rel->r_pcrel)
- sectoffset += rel->r_address;
-
- if (rel->r_type == PPC_RELOC_BR24)
- name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, &section_hdr[sectnum-1]);
-
- /* search it in the full symbol list, if not found */
- if(!name)
- name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);
-
- return name;
-}
-
-/* Used by dyngen common code */
-static const char * get_rel_sym_name(EXE_RELOC * rel)
-{
- int sslide;
- return get_reloc_name( rel, &sslide);
-}
-
-/* Used by dyngen common code */
-static host_ulong get_rel_offset(EXE_RELOC *rel)
-{
- struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;
- if(R_SCATTERED & rel->r_address)
- return sca_rel->r_address;
- else
- return rel->r_address;
-}
-
-/* load a mach-o object file */
-int load_object(const char *filename)
-{
- int fd;
- unsigned int offset_to_segment = 0;
- unsigned int offset_to_dysymtab = 0;
- unsigned int offset_to_symtab = 0;
- struct load_command lc;
- unsigned int i, j;
- EXE_SYM *sym;
- struct nlist *syment;
-
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- error("can't open file '%s'", filename);
-
- /* Read Mach header. */
- if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr))
- error("unable to read file header");
-
- /* Check Mach identification. */
- if (!check_mach_header(mach_hdr)) {
- error("bad Mach header");
- }
-
- if (mach_hdr.cputype != CPU_TYPE_POWERPC)
- error("Unsupported CPU");
-
- if (mach_hdr.filetype != MH_OBJECT)
- error("Unsupported Mach Object");
-
- /* read segment headers */
- for(i=0, j=sizeof(mach_hdr); i<mach_hdr.ncmds ; i++)
- {
- if(read(fd, &lc, sizeof(struct load_command)) != sizeof(struct load_command))
- error("unable to read load_command");
- if(lc.cmd == LC_SEGMENT)
- {
- offset_to_segment = j;
- lseek(fd, offset_to_segment, SEEK_SET);
- segment = malloc(sizeof(struct segment_command));
- if(read(fd, segment, sizeof(struct segment_command)) != sizeof(struct segment_command))
- error("unable to read LC_SEGMENT");
- }
- if(lc.cmd == LC_DYSYMTAB)
- {
- offset_to_dysymtab = j;
- lseek(fd, offset_to_dysymtab, SEEK_SET);
- dysymtabcmd = malloc(sizeof(struct dysymtab_command));
- if(read(fd, dysymtabcmd, sizeof(struct dysymtab_command)) != sizeof(struct dysymtab_command))
- error("unable to read LC_DYSYMTAB");
- }
- if(lc.cmd == LC_SYMTAB)
- {
- offset_to_symtab = j;
- lseek(fd, offset_to_symtab, SEEK_SET);
- symtabcmd = malloc(sizeof(struct symtab_command));
- if(read(fd, symtabcmd, sizeof(struct symtab_command)) != sizeof(struct symtab_command))
- error("unable to read LC_SYMTAB");
- }
- j+=lc.cmdsize;
-
- lseek(fd, j, SEEK_SET);
- }
-
- if(!segment)
- error("unable to find LC_SEGMENT");
-
- /* read section headers */
- section_hdr = load_data(fd, offset_to_segment + sizeof(struct segment_command), segment->nsects * sizeof(struct section));
-
- /* read all section data */
- sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
- memset(sdata, 0, sizeof(void *) * segment->nsects);
-
- /* Load the data in section data */
- for(i = 0; i < segment->nsects; i++) {
- sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
- }
-
- /* text section */
- text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
- i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
- if (i == -1 || !text_sec_hdr)
- error("could not find __TEXT,__text section");
- text = sdata[i];
-
- /* Make sure dysym was loaded */
- if(!(int)dysymtabcmd)
- error("could not find __DYSYMTAB segment");
-
- /* read the table of content of the indirect sym */
- tocdylib = load_data( fd, dysymtabcmd->indirectsymoff, dysymtabcmd->nindirectsyms * sizeof(uint32_t) );
-
- /* Make sure symtab was loaded */
- if(!(int)symtabcmd)
- error("could not find __SYMTAB segment");
- nb_syms = symtabcmd->nsyms;
-
- symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));
- strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);
-
- symtab = malloc(sizeof(EXE_SYM) * nb_syms);
-
- /* Now transform the symtab, to an extended version, with the sym size, and the C name */
- for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
- struct nlist *sym_follow, *sym_next = 0;
- unsigned int j;
- memset(sym, 0, sizeof(*sym));
-
- if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
- continue;
-
- memcpy(sym, syment, sizeof(*syment));
-
- /* Find the following symbol in order to get the current symbol size */
- for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {
- if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
- continue;
- if(!sym_next) {
- sym_next = sym_follow;
- continue;
- }
- if(!(sym_next->n_value > sym_follow->n_value))
- continue;
- sym_next = sym_follow;
- }
- if(sym_next)
- sym->st_size = sym_next->n_value - sym->st_value;
- else
- sym->st_size = text_sec_hdr->size - sym->st_value;
- }
-
- /* Find Reloc */
- relocs = load_data(fd, text_sec_hdr->reloff, text_sec_hdr->nreloc * sizeof(struct relocation_info));
- nb_relocs = text_sec_hdr->nreloc;
-
- close(fd);
- return 0;
-}
-
-#endif /* CONFIG_FORMAT_MACH */
-
-void get_reloc_expr(char *name, int name_size, const char *sym_name)
-{
- const char *p;
-
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, name_size, "param%s", p);
- } else if (strstart(sym_name, "__op_gen_label", &p)) {
- snprintf(name, name_size, "gen_labels[param%s]", p);
- } else {
-#ifdef HOST_SPARC
- if (sym_name[0] == '.')
- snprintf(name, name_size,
- "(long)(&__dot_%s)",
- sym_name + 1);
- else
-#endif
- snprintf(name, name_size, "(long)(&%s)", sym_name);
- }
-}
-
-#ifdef HOST_IA64
-
-#define PLT_ENTRY_SIZE 16 /* 1 bundle containing "brl" */
-
-struct plt_entry {
- struct plt_entry *next;
- const char *name;
- unsigned long addend;
-} *plt_list;
-
-static int
-get_plt_index (const char *name, unsigned long addend)
-{
- struct plt_entry *plt, *prev= NULL;
- int index = 0;
-
- /* see if we already have an entry for this target: */
- for (plt = plt_list; plt; ++index, prev = plt, plt = plt->next)
- if (strcmp(plt->name, name) == 0 && plt->addend == addend)
- return index;
-
- /* nope; create a new PLT entry: */
-
- plt = malloc(sizeof(*plt));
- if (!plt) {
- perror("malloc");
- exit(1);
- }
- memset(plt, 0, sizeof(*plt));
- plt->name = strdup(name);
- plt->addend = addend;
-
- /* append to plt-list: */
- if (prev)
- prev->next = plt;
- else
- plt_list = plt;
- return index;
-}
-
-#endif
-
-#ifdef HOST_ARM
-
-int arm_emit_ldr_info(const char *name, unsigned long start_offset,
- FILE *outfile, uint8_t *p_start, uint8_t *p_end,
- ELF_RELOC *relocs, int nb_relocs)
-{
- uint8_t *p;
- uint32_t insn;
- int offset, min_offset, pc_offset, data_size, spare, max_pool;
- uint8_t data_allocated[1024];
- unsigned int data_index;
- int type;
-
- memset(data_allocated, 0, sizeof(data_allocated));
-
- p = p_start;
- min_offset = p_end - p_start;
- spare = 0x7fffffff;
- while (p < p_start + min_offset) {
- insn = get32((uint32_t *)p);
- /* TODO: Armv5e ldrd. */
- /* TODO: VFP load. */
- if ((insn & 0x0d5f0000) == 0x051f0000) {
- /* ldr reg, [pc, #im] */
- offset = insn & 0xfff;
- if (!(insn & 0x00800000))
- offset = -offset;
- max_pool = 4096;
- type = 0;
- } else if ((insn & 0x0e5f0f00) == 0x0c1f0100) {
- /* FPA ldf. */
- offset = (insn & 0xff) << 2;
- if (!(insn & 0x00800000))
- offset = -offset;
- max_pool = 1024;
- type = 1;
- } else if ((insn & 0x0fff0000) == 0x028f0000) {
- /* Some gcc load a doubleword immediate with
- add regN, pc, #imm
- ldmia regN, {regN, regM}
- Hope and pray the compiler never generates somethin like
- add reg, pc, #imm1; ldr reg, [reg, #-imm2]; */
- int r;
-
- r = (insn & 0xf00) >> 7;
- offset = ((insn & 0xff) >> r) | ((insn & 0xff) << (32 - r));
- max_pool = 1024;
- type = 2;
- } else {
- max_pool = 0;
- type = -1;
- }
- if (type >= 0) {
- /* PC-relative load needs fixing up. */
- if (spare > max_pool - offset)
- spare = max_pool - offset;
- if ((offset & 3) !=0)
- error("%s:%04x: pc offset must be 32 bit aligned",
- name, start_offset + p - p_start);
- if (offset < 0)
- error("%s:%04x: Embedded literal value",
- name, start_offset + p - p_start);
- pc_offset = p - p_start + offset + 8;
- if (pc_offset <= (p - p_start) ||
- pc_offset >= (p_end - p_start))
- error("%s:%04x: pc offset must point inside the function code",
- name, start_offset + p - p_start);
- if (pc_offset < min_offset)
- min_offset = pc_offset;
- if (outfile) {
- /* The intruction position */
- fprintf(outfile, " arm_ldr_ptr->ptr = gen_code_ptr + %d;\n",
- p - p_start);
- /* The position of the constant pool data. */
- data_index = ((p_end - p_start) - pc_offset) >> 2;
- fprintf(outfile, " arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n",
- data_index);
- fprintf(outfile, " arm_ldr_ptr->type = %d;\n", type);
- fprintf(outfile, " arm_ldr_ptr++;\n");
- }
- }
- p += 4;
- }
-
- /* Copy and relocate the constant pool data. */
- data_size = (p_end - p_start) - min_offset;
- if (data_size > 0 && outfile) {
- spare += min_offset;
- fprintf(outfile, " arm_data_ptr -= %d;\n", data_size >> 2);
- fprintf(outfile, " arm_pool_ptr -= %d;\n", data_size);
- fprintf(outfile, " if (arm_pool_ptr > gen_code_ptr + %d)\n"
- " arm_pool_ptr = gen_code_ptr + %d;\n",
- spare, spare);
-
- data_index = 0;
- for (pc_offset = min_offset;
- pc_offset < p_end - p_start;
- pc_offset += 4) {
-
- ELF_RELOC *rel;
- int i, addend, type;
- const char *sym_name;
- char relname[1024];
-
- /* data value */
- addend = get32((uint32_t *)(p_start + pc_offset));
- relname[0] = '\0';
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset == (pc_offset + start_offset)) {
- sym_name = get_rel_sym_name(rel);
- /* the compiler leave some unnecessary references to the code */
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- if (type != R_ARM_ABS32)
- error("%s: unsupported data relocation", name);
- break;
- }
- }
- fprintf(outfile, " arm_data_ptr[%d] = 0x%x",
- data_index, addend);
- if (relname[0] != '\0')
- fprintf(outfile, " + %s", relname);
- fprintf(outfile, ";\n");
-
- data_index++;
- }
- }
-
- if (p == p_start)
- goto arm_ret_error;
- p -= 4;
- insn = get32((uint32_t *)p);
- /* The last instruction must be an ldm instruction. There are several
- forms generated by gcc:
- ldmib sp, {..., pc} (implies a sp adjustment of +4)
- ldmia sp, {..., pc}
- ldmea fp, {..., pc} */
- if ((insn & 0xffff8000) == 0xe99d8000) {
- if (outfile) {
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = 0xe28dd004;\n",
- p - p_start);
- }
- p += 4;
- } else if ((insn & 0xffff8000) != 0xe89d8000
- && (insn & 0xffff8000) != 0xe91b8000) {
- arm_ret_error:
- if (!outfile)
- printf("%s: invalid epilog\n", name);
- }
- return p - p_start;
-}
-#endif
-
-
-#define MAX_ARGS 3
-
-/* generate op code */
-void gen_code(const char *name, host_ulong offset, host_ulong size,
- FILE *outfile, int gen_switch)
-{
- int copy_size = 0;
- uint8_t *p_start, *p_end;
- host_ulong start_offset;
- int nb_args, i, n;
- uint8_t args_present[MAX_ARGS];
- const char *sym_name, *p;
- EXE_RELOC *rel;
-
- /* Compute exact size excluding prologue and epilogue instructions.
- * Increment start_offset to skip epilogue instructions, then compute
- * copy_size the indicate the size of the remaining instructions (in
- * bytes).
- */
- p_start = text + offset;
- p_end = p_start + size;
- start_offset = offset;
-#if defined(HOST_I386) || defined(HOST_X86_64)
-#ifdef CONFIG_FORMAT_COFF
- {
- uint8_t *p;
- p = p_end - 1;
- if (p == p_start)
- error("empty code for %s", name);
- while (*p != 0xc3) {
- p--;
- if (p <= p_start)
- error("ret or jmp expected at the end of %s", name);
- }
- copy_size = p - p_start;
- }
-#else
- {
- int len;
- len = p_end - p_start;
- if (len == 0)
- error("empty code for %s", name);
- if (p_end[-1] == 0xc3) {
- len--;
- } else {
- error("ret or jmp expected at the end of %s", name);
- }
- copy_size = len;
- }
-#endif
-#elif defined(HOST_PPC)
- {
- uint8_t *p;
- p = (void *)(p_end - 4);
- if (p == p_start)
- error("empty code for %s", name);
- if (get32((uint32_t *)p) != 0x4e800020)
- error("blr expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#elif defined(HOST_S390)
- {
- uint8_t *p;
- p = (void *)(p_end - 2);
- if (p == p_start)
- error("empty code for %s", name);
- if (get16((uint16_t *)p) != 0x07fe && get16((uint16_t *)p) != 0x07f4)
- error("br %%r14 expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#elif defined(HOST_ALPHA)
- {
- uint8_t *p;
- p = p_end - 4;
-#if 0
- /* XXX: check why it occurs */
- if (p == p_start)
- error("empty code for %s", name);
-#endif
- if (get32((uint32_t *)p) != 0x6bfa8001)
- error("ret expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#elif defined(HOST_IA64)
- {
- uint8_t *p;
- p = (void *)(p_end - 4);
- if (p == p_start)
- error("empty code for %s", name);
- /* br.ret.sptk.many b0;; */
- /* 08 00 84 00 */
- if (get32((uint32_t *)p) != 0x00840008)
- error("br.ret.sptk.many b0;; expected at the end of %s", name);
- copy_size = p_end - p_start;
- }
-#elif defined(HOST_SPARC)
- {
-#define INSN_SAVE 0x9de3a000
-#define INSN_RET 0x81c7e008
-#define INSN_RETL 0x81c3e008
-#define INSN_RESTORE 0x81e80000
-#define INSN_RETURN 0x81cfe008
-#define INSN_NOP 0x01000000
-#define INSN_ADD_SP 0x9c03a000 // add %sp, nn, %sp
-#define INSN_SUB_SP 0x9c23a000 // sub %sp, nn, %sp
-
- uint32_t start_insn, end_insn1, end_insn2;
- uint8_t *p;
- p = (void *)(p_end - 8);
- if (p <= p_start)
- error("empty code for %s", name);
- start_insn = get32((uint32_t *)(p_start + 0x0));
- end_insn1 = get32((uint32_t *)(p + 0x0));
- end_insn2 = get32((uint32_t *)(p + 0x4));
- if (((start_insn & ~0x1fff) == INSN_SAVE) ||
- (start_insn & ~0x1fff) == INSN_ADD_SP) {
- p_start += 0x4;
- start_offset += 0x4;
- if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
- /* SPARC v7: ret; restore; */ ;
- else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
- /* SPARC v9: return; nop; */ ;
- else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
- /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
- else
-
- error("ret; restore; not found at end of %s", name);
- } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
- ;
- } else {
- error("No save at the beginning of %s", name);
- }
-#if 0
- /* Skip a preceeding nop, if present. */
- if (p > p_start) {
- skip_insn = get32((uint32_t *)(p - 0x4));
- if (skip_insn == INSN_NOP)
- p -= 4;
- }
-#endif
- copy_size = p - p_start;
- }
-#elif defined(HOST_SPARC64)
- {
-#define INSN_SAVE 0x9de3a000
-#define INSN_RET 0x81c7e008
-#define INSN_RETL 0x81c3e008
-#define INSN_RESTORE 0x81e80000
-#define INSN_RETURN 0x81cfe008
-#define INSN_NOP 0x01000000
-#define INSN_ADD_SP 0x9c03a000 // add %sp, nn, %sp
-#define INSN_SUB_SP 0x9c23a000 // sub %sp, nn, %sp
-
- uint32_t start_insn, end_insn1, end_insn2, skip_insn;
- uint8_t *p;
- p = (void *)(p_end - 8);
-#if 0
- /* XXX: check why it occurs */
- if (p <= p_start)
- error("empty code for %s", name);
-#endif
- start_insn = get32((uint32_t *)(p_start + 0x0));
- end_insn1 = get32((uint32_t *)(p + 0x0));
- end_insn2 = get32((uint32_t *)(p + 0x4));
- if (((start_insn & ~0x1fff) == INSN_SAVE) ||
- (start_insn & ~0x1fff) == INSN_ADD_SP) {
- p_start += 0x4;
- start_offset += 0x4;
- if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
- /* SPARC v7: ret; restore; */ ;
- else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
- /* SPARC v9: return; nop; */ ;
- else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
- /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
- else
-
- error("ret; restore; not found at end of %s", name);
- } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
- ;
- } else {
- error("No save at the beginning of %s", name);
- }
-
- /* Skip a preceeding nop, if present. */
- if (p > p_start) {
- skip_insn = get32((uint32_t *)(p - 0x4));
- if (skip_insn == 0x01000000)
- p -= 4;
- }
-
- copy_size = p - p_start;
- }
-#elif defined(HOST_ARM)
- {
- uint32_t insn;
-
- if ((p_end - p_start) <= 16)
- error("%s: function too small", name);
- if (get32((uint32_t *)p_start) != 0xe1a0c00d ||
- (get32((uint32_t *)(p_start + 4)) & 0xffff0000) != 0xe92d0000 ||
- get32((uint32_t *)(p_start + 8)) != 0xe24cb004)
- error("%s: invalid prolog", name);
- p_start += 12;
- start_offset += 12;
- insn = get32((uint32_t *)p_start);
- if ((insn & 0xffffff00) == 0xe24dd000) {
- /* Stack adjustment. Assume op uses the frame pointer. */
- p_start -= 4;
- start_offset -= 4;
- }
- copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end,
- relocs, nb_relocs);
- }
-#elif defined(HOST_M68K)
- {
- uint8_t *p;
- p = (void *)(p_end - 2);
- if (p == p_start)
- error("empty code for %s", name);
- // remove NOP's, probably added for alignment
- while ((get16((uint16_t *)p) == 0x4e71) &&
- (p>p_start))
- p -= 2;
- if (get16((uint16_t *)p) != 0x4e75)
- error("rts expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#else
-#error unsupported CPU
-#endif
-
- /* compute the number of arguments by looking at the relocations */
- for(i = 0;i < MAX_ARGS; i++)
- args_present[i] = 0;
-
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- host_ulong offset = get_rel_offset(rel);
- if (offset >= start_offset &&
- offset < start_offset + (p_end - p_start)) {
- sym_name = get_rel_sym_name(rel);
- if(!sym_name)
- continue;
- if (strstart(sym_name, "__op_param", &p) ||
- strstart(sym_name, "__op_gen_label", &p)) {
- n = strtoul(p, NULL, 10);
- if (n > MAX_ARGS)
- error("too many arguments in %s", name);
- args_present[n - 1] = 1;
- }
- }
- }
-
- nb_args = 0;
- while (nb_args < MAX_ARGS && args_present[nb_args])
- nb_args++;
- for(i = nb_args; i < MAX_ARGS; i++) {
- if (args_present[i])
- error("inconsistent argument numbering in %s", name);
- }
-
- if (gen_switch == 2) {
- fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, copy_size);
- } else if (gen_switch == 1) {
-
- /* output C code */
- fprintf(outfile, "case INDEX_%s: {\n", name);
- if (nb_args > 0) {
- fprintf(outfile, " long ");
- for(i = 0; i < nb_args; i++) {
- if (i != 0)
- fprintf(outfile, ", ");
- fprintf(outfile, "param%d", i + 1);
- }
- fprintf(outfile, ";\n");
- }
-#if defined(HOST_IA64)
- fprintf(outfile, " extern char %s;\n", name);
-#else
- fprintf(outfile, " extern void %s();\n", name);
-#endif
-
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- host_ulong offset = get_rel_offset(rel);
- if (offset >= start_offset &&
- offset < start_offset + (p_end - p_start)) {
- sym_name = get_rel_sym_name(rel);
- if(!sym_name)
- continue;
- if (*sym_name &&
- !strstart(sym_name, "__op_param", NULL) &&
- !strstart(sym_name, "__op_jmp", NULL) &&
- !strstart(sym_name, "__op_gen_label", NULL)) {
-#if defined(HOST_SPARC)
- if (sym_name[0] == '.') {
- fprintf(outfile,
- "extern char __dot_%s __asm__(\"%s\");\n",
- sym_name+1, sym_name);
- continue;
- }
-#endif
-#if defined(__APPLE__)
-/* set __attribute((unused)) on darwin because we wan't to avoid warning when we don't use the symbol */
- fprintf(outfile, "extern char %s __attribute__((unused));\n", sym_name);
-#elif defined(HOST_IA64)
- if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
- /*
- * PCREL21 br.call targets generally
- * are out of range and need to go
- * through an "import stub".
- */
- fprintf(outfile, " extern char %s;\n",
- sym_name);
-#else
- fprintf(outfile, "extern char %s;\n", sym_name);
-#endif
- }
- }
- }
-
- fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n",
- name, (int)(start_offset - offset), copy_size);
-
- /* emit code offset information */
- {
- EXE_SYM *sym;
- const char *sym_name, *p;
- unsigned long val;
- int n;
-
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- sym_name = get_sym_name(sym);
- if (strstart(sym_name, "__op_label", &p)) {
- uint8_t *ptr;
- unsigned long offset;
-
- /* test if the variable refers to a label inside
- the code we are generating */
-#ifdef CONFIG_FORMAT_COFF
- if (sym->st_shndx == text_shndx) {
- ptr = sdata[coff_text_shndx];
- } else if (sym->st_shndx == data_shndx) {
- ptr = sdata[coff_data_shndx];
- } else {
- ptr = NULL;
- }
-#elif defined(CONFIG_FORMAT_MACH)
- if(!sym->n_sect)
- continue;
- ptr = sdata[sym->n_sect-1];
-#else
- ptr = sdata[sym->st_shndx];
-#endif
- if (!ptr)
- error("__op_labelN in invalid section");
- offset = sym->st_value;
-#ifdef CONFIG_FORMAT_MACH
- offset -= section_hdr[sym->n_sect-1].addr;
-#endif
- val = *(unsigned long *)(ptr + offset);
-#ifdef ELF_USES_RELOCA
- {
- int reloc_shndx, nb_relocs1, j;
-
- /* try to find a matching relocation */
- reloc_shndx = find_reloc(sym->st_shndx);
- if (reloc_shndx) {
- nb_relocs1 = shdr[reloc_shndx].sh_size /
- shdr[reloc_shndx].sh_entsize;
- rel = (ELF_RELOC *)sdata[reloc_shndx];
- for(j = 0; j < nb_relocs1; j++) {
- if (rel->r_offset == offset) {
- val = rel->r_addend;
- break;
- }
- rel++;
- }
- }
- }
-#endif
- if (val >= start_offset && val <= start_offset + copy_size) {
- n = strtol(p, NULL, 10);
- fprintf(outfile, " label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));
- }
- }
- }
- }
-
- /* load parameres in variables */
- for(i = 0; i < nb_args; i++) {
- fprintf(outfile, " param%d = *opparam_ptr++;\n", i + 1);
- }
-
- /* patch relocations */
-#if defined(HOST_I386)
- {
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = get_rel_sym_name(rel);
- if (!sym_name)
- continue;
- reloc_offset = rel->r_offset - start_offset;
- if (strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- /* __op_jmp relocations are done at
- runtime to do translated block
- chaining: the offset of the instruction
- needs to be stored */
- fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
- n, reloc_offset);
- continue;
- }
-
- get_reloc_expr(name, sizeof(name), sym_name);
- addend = get32((uint32_t *)(text + rel->r_offset));
-#ifdef CONFIG_FORMAT_ELF
- type = ELF32_R_TYPE(rel->r_info);
- switch(type) {
- case R_386_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_386_PC32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
- reloc_offset, name, reloc_offset, addend);
- break;
- default:
- error("unsupported i386 relocation (%d)", type);
- }
-#elif defined(CONFIG_FORMAT_COFF)
- {
- char *temp_name;
- int j;
- EXE_SYM *sym;
- temp_name = get_sym_name(symtab + *(uint32_t *)(rel->r_reloc->r_symndx));
- if (!strcmp(temp_name, ".data")) {
- for (j = 0, sym = symtab; j < nb_syms; j++, sym++) {
- if (strstart(sym->st_name, sym_name, NULL)) {
- addend -= sym->st_value;
- }
- }
- }
- }
- type = rel->r_type;
- switch(type) {
- case DIR32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case DISP32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
- reloc_offset, name, reloc_offset, addend);
- break;
- default:
- error("unsupported i386 relocation (%d)", type);
- }
-#else
-#error unsupport object format
-#endif
- }
- }
- }
-#elif defined(HOST_X86_64)
- {
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_X86_64_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_X86_64_32S:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_X86_64_PC32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
- reloc_offset, name, reloc_offset, addend);
- break;
- default:
- error("unsupported X86_64 relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_PPC)
- {
-#ifdef CONFIG_FORMAT_ELF
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- reloc_offset = rel->r_offset - start_offset;
- if (strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- /* __op_jmp relocations are done at
- runtime to do translated block
- chaining: the offset of the instruction
- needs to be stored */
- fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
- n, reloc_offset);
- continue;
- }
-
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- switch(type) {
- case R_PPC_ADDR32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_PPC_ADDR16_LO:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
- reloc_offset, name, addend);
- break;
- case R_PPC_ADDR16_HI:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
- reloc_offset, name, addend);
- break;
- case R_PPC_ADDR16_HA:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
- reloc_offset, name, addend);
- break;
- case R_PPC_REL24:
- /* warning: must be at 32 MB distancy */
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
- reloc_offset, reloc_offset, name, reloc_offset, addend);
- break;
- default:
- error("unsupported powerpc relocation (%d)", type);
- }
- }
- }
-#elif defined(CONFIG_FORMAT_MACH)
- struct scattered_relocation_info *scarel;
- struct relocation_info * rel;
- char final_sym_name[256];
- const char *sym_name;
- const char *p;
- int slide, sslide;
- int i;
-
- for(i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
- unsigned int offset, length, value = 0;
- unsigned int type, pcrel, isym = 0;
- unsigned int usesym = 0;
-
- if(R_SCATTERED & rel->r_address) {
- scarel = (struct scattered_relocation_info*)rel;
- offset = (unsigned int)scarel->r_address;
- length = scarel->r_length;
- pcrel = scarel->r_pcrel;
- type = scarel->r_type;
- value = scarel->r_value;
- } else {
- value = isym = rel->r_symbolnum;
- usesym = (rel->r_extern);
- offset = rel->r_address;
- length = rel->r_length;
- pcrel = rel->r_pcrel;
- type = rel->r_type;
- }
-
- slide = offset - start_offset;
-
- if (!(offset >= start_offset && offset < start_offset + size))
- continue; /* not in our range */
-
- sym_name = get_reloc_name(rel, &sslide);
-
- if(usesym && symtab[isym].n_type & N_STAB)
- continue; /* don't handle STAB (debug sym) */
-
- if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
- n, slide);
- continue; /* Nothing more to do */
- }
-
- if(!sym_name)
- {
- fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
- name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
- continue; /* dunno how to handle without final_sym_name */
- }
-
- get_reloc_expr(final_sym_name, sizeof(final_sym_name),
- sym_name);
- switch(type) {
- case PPC_RELOC_BR24:
- if (!strstart(sym_name,"__op_gen_label",&p)) {
- fprintf(outfile, "{\n");
- fprintf(outfile, " uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
- slide, slide, name, sslide );
- fprintf(outfile, "}\n");
- } else {
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | (((long)%s - (long)gen_code_ptr - %d) & 0x03fffffc);\n",
- slide, slide, final_sym_name, slide);
- }
- break;
- case PPC_RELOC_HI16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n",
- slide, final_sym_name, sslide);
- break;
- case PPC_RELOC_LO16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d);\n",
- slide, final_sym_name, sslide);
- break;
- case PPC_RELOC_HA16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d + 0x8000) >> 16;\n",
- slide, final_sym_name, sslide);
- break;
- default:
- error("unsupported powerpc relocation (%d)", type);
- }
- }
-#else
-#error unsupport object format
-#endif
- }
-#elif defined(HOST_S390)
- {
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_390_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_390_16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_390_8:
- fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- default:
- error("unsupported s390 relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_ALPHA)
- {
- for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
- int type;
- long reloc_offset;
-
- type = ELF64_R_TYPE(rel->r_info);
- sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
- reloc_offset = rel->r_offset - start_offset;
- switch (type) {
- case R_ALPHA_GPDISP:
- /* The gp is just 32 bit, and never changes, so it's easiest to emit it
- as an immediate instead of constructing it from the pv or ra. */
- fprintf(outfile, " immediate_ldah(gen_code_ptr + %ld, gp);\n",
- reloc_offset);
- fprintf(outfile, " immediate_lda(gen_code_ptr + %ld, gp);\n",
- reloc_offset + (int)rel->r_addend);
- break;
- case R_ALPHA_LITUSE:
- /* jsr to literal hint. Could be used to optimize to bsr. Ignore for
- now, since some called functions (libc) need pv to be set up. */
- break;
- case R_ALPHA_HINT:
- /* Branch target prediction hint. Ignore for now. Should be already
- correct for in-function jumps. */
- break;
- case R_ALPHA_LITERAL:
- /* Load a literal from the GOT relative to the gp. Since there's only a
- single gp, nothing is to be done. */
- break;
- case R_ALPHA_GPRELHIGH:
- /* Handle fake relocations against __op_param symbol. Need to emit the
- high part of the immediate value instead. Other symbols need no
- special treatment. */
- if (strstart(sym_name, "__op_param", &p))
- fprintf(outfile, " immediate_ldah(gen_code_ptr + %ld, param%s);\n",
- reloc_offset, p);
- break;
- case R_ALPHA_GPRELLOW:
- if (strstart(sym_name, "__op_param", &p))
- fprintf(outfile, " immediate_lda(gen_code_ptr + %ld, param%s);\n",
- reloc_offset, p);
- break;
- case R_ALPHA_BRSGP:
- /* PC-relative jump. Tweak offset to skip the two instructions that try to
- set up the gp from the pv. */
- fprintf(outfile, " fix_bsr(gen_code_ptr + %ld, (uint8_t *) &%s - (gen_code_ptr + %ld + 4) + 8);\n",
- reloc_offset, sym_name, reloc_offset);
- break;
- default:
- error("unsupported Alpha relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_IA64)
- {
- unsigned long sym_idx;
- long code_offset;
- char name[256];
- int type;
- long addend;
-
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- sym_idx = ELF64_R_SYM(rel->r_info);
- if (rel->r_offset < start_offset
- || rel->r_offset >= start_offset + copy_size)
- continue;
- sym_name = (strtab + symtab[sym_idx].st_name);
- code_offset = rel->r_offset - start_offset;
- if (strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- /* __op_jmp relocations are done at
- runtime to do translated block
- chaining: the offset of the instruction
- needs to be stored */
- fprintf(outfile, " jmp_offsets[%d] ="
- "%ld + (gen_code_ptr - gen_code_buf);\n",
- n, code_offset);
- continue;
- }
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF64_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- switch(type) {
- case R_IA64_IMM64:
- fprintf(outfile,
- " ia64_imm64(gen_code_ptr + %ld, "
- "%s + %ld);\n",
- code_offset, name, addend);
- break;
- case R_IA64_LTOFF22X:
- case R_IA64_LTOFF22:
- fprintf(outfile, " IA64_LTOFF(gen_code_ptr + %ld,"
- " %s + %ld, %d);\n",
- code_offset, name, addend,
- (type == R_IA64_LTOFF22X));
- break;
- case R_IA64_LDXMOV:
- fprintf(outfile,
- " ia64_ldxmov(gen_code_ptr + %ld,"
- " %s + %ld);\n", code_offset, name, addend);
- break;
-
- case R_IA64_PCREL21B:
- if (strstart(sym_name, "__op_gen_label", NULL)) {
- fprintf(outfile,
- " ia64_imm21b(gen_code_ptr + %ld,"
- " (long) (%s + %ld -\n\t\t"
- "((long) gen_code_ptr + %ld)) >> 4);\n",
- code_offset, name, addend,
- code_offset & ~0xfUL);
- } else {
- fprintf(outfile,
- " IA64_PLT(gen_code_ptr + %ld, "
- "%d);\t/* %s + %ld */\n",
- code_offset,
- get_plt_index(sym_name, addend),
- sym_name, addend);
- }
- break;
- default:
- error("unsupported ia64 relocation (0x%x)",
- type);
- }
- }
- fprintf(outfile, " ia64_nop_b(gen_code_ptr + %d);\n",
- copy_size - 16 + 2);
- }
-#elif defined(HOST_SPARC)
- {
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_SPARC_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_SPARC_HI22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | (((%s + %d) >> 10) & 0x3fffff);\n",
- reloc_offset, reloc_offset, name, addend);
- break;
- case R_SPARC_LO10:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3ff) "
- " | ((%s + %d) & 0x3ff);\n",
- reloc_offset, reloc_offset, name, addend);
- break;
- case R_SPARC_WDISP30:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffffff);\n",
- reloc_offset, reloc_offset, name, addend,
- reloc_offset);
- break;
- case R_SPARC_WDISP22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffff);\n",
- rel->r_offset - start_offset,
- rel->r_offset - start_offset,
- name, addend,
- rel->r_offset - start_offset);
- break;
- default:
- error("unsupported sparc relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_SPARC64)
- {
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_SPARC_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_SPARC_HI22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | (((%s + %d) >> 10) & 0x3fffff);\n",
- reloc_offset, reloc_offset, name, addend);
- break;
- case R_SPARC_LO10:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3ff) "
- " | ((%s + %d) & 0x3ff);\n",
- reloc_offset, reloc_offset, name, addend);
- break;
- case R_SPARC_OLO10:
- addend += ELF64_R_TYPE_DATA (rel->r_info);
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3ff) "
- " | ((%s + %d) & 0x3ff);\n",
- reloc_offset, reloc_offset, name, addend);
- break;
- case R_SPARC_WDISP30:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffffff);\n",
- reloc_offset, reloc_offset, name, addend,
- reloc_offset);
- break;
- case R_SPARC_WDISP22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffff);\n",
- reloc_offset, reloc_offset, name, addend,
- reloc_offset);
- break;
- default:
- error("unsupported sparc64 relocation (%d) for symbol %s", type, name);
- }
- }
- }
- }
-#elif defined(HOST_ARM)
- {
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- uint32_t insn;
-
- insn = get32((uint32_t *)(p_start + 4));
- /* If prologue ends in sub sp, sp, #const then assume
- op has a stack frame and needs the frame pointer. */
- if ((insn & 0xffffff00) == 0xe24dd000) {
- int i;
- uint32_t opcode;
- opcode = 0xe28db000; /* add fp, sp, #0. */
-#if 0
-/* ??? Need to undo the extra stack adjustment at the end of the op.
- For now just leave the stack misaligned and hope it doesn't break anything
- too important. */
- if ((insn & 4) != 0) {
- /* Preserve doubleword stack alignment. */
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + 4)= 0x%x;\n",
- insn + 4);
- opcode -= 4;
- }
-#endif
- insn = get32((uint32_t *)(p_start - 4));
- /* Calculate the size of the saved registers,
- excluding pc. */
- for (i = 0; i < 15; i++) {
- if (insn & (1 << i))
- opcode += 4;
- }
- fprintf(outfile,
- " *(uint32_t *)gen_code_ptr = 0x%x;\n", opcode);
- }
- arm_emit_ldr_info(name, start_offset, outfile, p_start, p_end,
- relocs, nb_relocs);
-
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- /* the compiler leave some unnecessary references to the code */
- if (sym_name[0] == '\0')
- continue;
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = get32((uint32_t *)(text + rel->r_offset));
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_ARM_ABS32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, name, addend);
- break;
- case R_ARM_PC24:
- case R_ARM_JUMP24:
- case R_ARM_CALL:
- fprintf(outfile, " arm_reloc_pc24((uint32_t *)(gen_code_ptr + %d), 0x%x, %s);\n",
- reloc_offset, addend, name);
- break;
- default:
- error("unsupported arm relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_M68K)
- {
- char name[256];
- int type;
- int addend;
- int reloc_offset;
- Elf32_Sym *sym;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym = &(symtab[ELFW(R_SYM)(rel->r_info)]);
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- get_reloc_expr(name, sizeof(name), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_68K_32:
- fprintf(outfile, " /* R_68K_32 RELOC, offset %x */\n", rel->r_offset) ;
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",
- reloc_offset, name, addend );
- break;
- case R_68K_PC32:
- fprintf(outfile, " /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",
- reloc_offset, name, reloc_offset, /*sym->st_value+*/ addend);
- break;
- default:
- error("unsupported m68k relocation (%d)", type);
- }
- }
- }
- }
-#else
-#error unsupported CPU
-#endif
- fprintf(outfile, " gen_code_ptr += %d;\n", copy_size);
- fprintf(outfile, "}\n");
- fprintf(outfile, "break;\n\n");
- } else {
- fprintf(outfile, "static inline void gen_%s(", name);
- if (nb_args == 0) {
- fprintf(outfile, "void");
- } else {
- for(i = 0; i < nb_args; i++) {
- if (i != 0)
- fprintf(outfile, ", ");
- fprintf(outfile, "long param%d", i + 1);
- }
- }
- fprintf(outfile, ")\n");
- fprintf(outfile, "{\n");
- for(i = 0; i < nb_args; i++) {
- fprintf(outfile, " *gen_opparam_ptr++ = param%d;\n", i + 1);
- }
- fprintf(outfile, " *gen_opc_ptr++ = INDEX_%s;\n", name);
- fprintf(outfile, "}\n\n");
- }
-}
-
-int gen_file(FILE *outfile, int out_type)
-{
- int i;
- EXE_SYM *sym;
-
- if (out_type == OUT_INDEX_OP) {
- fprintf(outfile, "DEF(end, 0, 0)\n");
- fprintf(outfile, "DEF(nop, 0, 0)\n");
- fprintf(outfile, "DEF(nop1, 1, 0)\n");
- fprintf(outfile, "DEF(nop2, 2, 0)\n");
- fprintf(outfile, "DEF(nop3, 3, 0)\n");
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = get_sym_name(sym);
- if (strstart(name, OP_PREFIX, NULL)) {
- gen_code(name, sym->st_value, sym->st_size, outfile, 2);
- }
- }
- } else if (out_type == OUT_GEN_OP) {
- /* generate gen_xxx functions */
- fprintf(outfile, "#include \"dyngen-op.h\"\n");
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = get_sym_name(sym);
- if (strstart(name, OP_PREFIX, NULL)) {
-#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
- if (sym->st_shndx != text_shndx)
- error("invalid section for opcode (0x%x)", sym->st_shndx);
-#endif
- gen_code(name, sym->st_value, sym->st_size, outfile, 0);
- }
- }
-
- } else {
- /* generate big code generation switch */
-
-#ifdef HOST_ARM
- /* We need to know the size of all the ops so we can figure out when
- to emit constant pools. This must be consistent with opc.h. */
-fprintf(outfile,
-"static const uint32_t arm_opc_size[] = {\n"
-" 0,\n" /* end */
-" 0,\n" /* nop */
-" 0,\n" /* nop1 */
-" 0,\n" /* nop2 */
-" 0,\n"); /* nop3 */
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = get_sym_name(sym);
- if (strstart(name, OP_PREFIX, NULL)) {
- fprintf(outfile, " %d,\n", sym->st_size);
- }
- }
-fprintf(outfile,
-"};\n");
-#endif
-
-fprintf(outfile,
-"int dyngen_code(uint8_t *gen_code_buf,\n"
-" uint16_t *label_offsets, uint16_t *jmp_offsets,\n"
-" const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels)\n"
-"{\n"
-" uint8_t *gen_code_ptr;\n"
-" const uint16_t *opc_ptr;\n"
-" const uint32_t *opparam_ptr;\n");
-
-#ifdef HOST_ARM
-/* Arm is tricky because it uses constant pools for loading immediate values.
- We assume (and require) each function is code followed by a constant pool.
- All the ops are small so this should be ok. For each op we figure
- out how much "spare" range we have in the load instructions. This allows
- us to insert subsequent ops in between the op and the constant pool,
- eliminating the neeed to jump around the pool.
-
- We currently generate:
-
- [ For this example we assume merging would move op1_pool out of range.
- In practice we should be able to combine many ops before the offset
- limits are reached. ]
- op1_code;
- op2_code;
- goto op3;
- op2_pool;
- op1_pool;
-op3:
- op3_code;
- ret;
- op3_pool;
-
- Ideally we'd put op1_pool before op2_pool, but that requires two passes.
- */
-fprintf(outfile,
-" uint8_t *last_gen_code_ptr = gen_code_buf;\n"
-" LDREntry *arm_ldr_ptr = arm_ldr_table;\n"
-" uint32_t *arm_data_ptr = arm_data_table + ARM_LDR_TABLE_SIZE;\n"
-/* Initialise the parmissible pool offset to an arbitary large value. */
-" uint8_t *arm_pool_ptr = gen_code_buf + 0x1000000;\n");
-#endif
-#ifdef HOST_IA64
- {
- long addend, not_first = 0;
- unsigned long sym_idx;
- int index, max_index;
- const char *sym_name;
- EXE_RELOC *rel;
-
- max_index = -1;
- for (i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- sym_idx = ELF64_R_SYM(rel->r_info);
- sym_name = (strtab + symtab[sym_idx].st_name);
- if (strstart(sym_name, "__op_gen_label", NULL))
- continue;
- if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
- continue;
-
- addend = rel->r_addend;
- index = get_plt_index(sym_name, addend);
- if (index <= max_index)
- continue;
- max_index = index;
- fprintf(outfile, " extern void %s(void);\n", sym_name);
- }
-
- fprintf(outfile,
- " struct ia64_fixup *plt_fixes = NULL, "
- "*ltoff_fixes = NULL;\n"
- " static long plt_target[] = {\n\t");
-
- max_index = -1;
- for (i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- sym_idx = ELF64_R_SYM(rel->r_info);
- sym_name = (strtab + symtab[sym_idx].st_name);
- if (strstart(sym_name, "__op_gen_label", NULL))
- continue;
- if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
- continue;
-
- addend = rel->r_addend;
- index = get_plt_index(sym_name, addend);
- if (index <= max_index)
- continue;
- max_index = index;
-
- if (not_first)
- fprintf(outfile, ",\n\t");
- not_first = 1;
- if (addend)
- fprintf(outfile, "(long) &%s + %ld", sym_name, addend);
- else
- fprintf(outfile, "(long) &%s", sym_name);
- }
- fprintf(outfile, "\n };\n"
- " unsigned int plt_offset[%u] = { 0 };\n", max_index + 1);
- }
-#endif
-
-fprintf(outfile,
-"\n"
-" gen_code_ptr = gen_code_buf;\n"
-" opc_ptr = opc_buf;\n"
-" opparam_ptr = opparam_buf;\n");
-
- /* Generate prologue, if needed. */
-
-fprintf(outfile,
-" for(;;) {\n");
-
-#ifdef HOST_ARM
-/* Generate constant pool if needed */
-fprintf(outfile,
-" if (gen_code_ptr + arm_opc_size[*opc_ptr] >= arm_pool_ptr) {\n"
-" gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, "
-"arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 1);\n"
-" last_gen_code_ptr = gen_code_ptr;\n"
-" arm_ldr_ptr = arm_ldr_table;\n"
-" arm_data_ptr = arm_data_table + ARM_LDR_TABLE_SIZE;\n"
-" arm_pool_ptr = gen_code_ptr + 0x1000000;\n"
-" }\n");
-#endif
-
-fprintf(outfile,
-" switch(*opc_ptr++) {\n");
-
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = get_sym_name(sym);
- if (strstart(name, OP_PREFIX, NULL)) {
-#if 0
- printf("%4d: %s pos=0x%08x len=%d\n",
- i, name, sym->st_value, sym->st_size);
-#endif
-#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
- if (sym->st_shndx != text_shndx)
- error("invalid section for opcode (0x%x)", sym->st_shndx);
-#endif
- gen_code(name, sym->st_value, sym->st_size, outfile, 1);
- }
- }
-
-fprintf(outfile,
-" case INDEX_op_nop:\n"
-" break;\n"
-" case INDEX_op_nop1:\n"
-" opparam_ptr++;\n"
-" break;\n"
-" case INDEX_op_nop2:\n"
-" opparam_ptr += 2;\n"
-" break;\n"
-" case INDEX_op_nop3:\n"
-" opparam_ptr += 3;\n"
-" break;\n"
-" default:\n"
-" goto the_end;\n"
-" }\n");
-
-
-fprintf(outfile,
-" }\n"
-" the_end:\n"
-);
-#ifdef HOST_IA64
- fprintf(outfile,
- " {\n"
- " extern char code_gen_buffer[];\n"
- " ia64_apply_fixes(&gen_code_ptr, ltoff_fixes, "
- "(uint64_t) code_gen_buffer + 2*(1<<20), plt_fixes,\n\t\t\t"
- "sizeof(plt_target)/sizeof(plt_target[0]),\n\t\t\t"
- "plt_target, plt_offset);\n }\n");
-#endif
-
-/* generate some code patching */
-#ifdef HOST_ARM
-fprintf(outfile,
-"if (arm_data_ptr != arm_data_table + ARM_LDR_TABLE_SIZE)\n"
-" gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, "
-"arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 0);\n");
-#endif
- /* flush instruction cache */
- fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n");
-
- fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");
- fprintf(outfile, "}\n\n");
-
- }
-
- return 0;
-}
-
-void usage(void)
-{
- printf("dyngen (c) 2003 Fabrice Bellard\n"
- "usage: dyngen [-o outfile] [-c] objfile\n"
- "Generate a dynamic code generator from an object file\n"
- "-c output enum of operations\n"
- "-g output gen_op_xx() functions\n"
- );
- exit(1);
-}
-
-int main(int argc, char **argv)
-{
- int c, out_type;
- const char *filename, *outfilename;
- FILE *outfile;
-
- outfilename = "out.c";
- out_type = OUT_CODE;
- for(;;) {
- c = getopt(argc, argv, "ho:cg");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- usage();
- break;
- case 'o':
- outfilename = optarg;
- break;
- case 'c':
- out_type = OUT_INDEX_OP;
- break;
- case 'g':
- out_type = OUT_GEN_OP;
- break;
- }
- }
- if (optind >= argc)
- usage();
- filename = argv[optind];
- outfile = fopen(outfilename, "w");
- if (!outfile)
- error("could not open '%s'", outfilename);
-
- load_object(filename);
- gen_file(outfile, out_type);
- fclose(outfile);
- return 0;
-}
diff --git a/tools/ioemu/dyngen.h b/tools/ioemu/dyngen.h
deleted file mode 100644
index 2a87c448fd..0000000000
--- a/tools/ioemu/dyngen.h
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * dyngen helpers
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-int __op_param1, __op_param2, __op_param3;
-#if defined(__sparc__) || defined(__arm__)
- void __op_gen_label1(){}
- void __op_gen_label2(){}
- void __op_gen_label3(){}
-#else
- int __op_gen_label1, __op_gen_label2, __op_gen_label3;
-#endif
-int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#ifdef __i386__
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
-#endif
-
-#ifdef __x86_64__
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
-#endif
-
-#ifdef __s390__
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
-#endif
-
-#ifdef __ia64__
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- while (start < stop) {
- asm volatile ("fc %0" :: "r"(start));
- start += 32;
- }
- asm volatile (";;sync.i;;srlz.i;;");
-}
-#endif
-
-#ifdef __powerpc__
-
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static void inline flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- start &= ~(MIN_CACHE_LINE_SIZE - 1);
- stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
-#endif
-
-#ifdef __alpha__
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- asm ("imb");
-}
-#endif
-
-#ifdef __sparc__
-
-static void inline flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- p = start & ~(8UL - 1UL);
- stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
-
- for (; p < stop; p += 8)
- __asm__ __volatile__("flush\t%0" : : "r" (p));
-}
-
-#endif
-
-#ifdef __arm__
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- register unsigned long _beg __asm ("a1") = start;
- register unsigned long _end __asm ("a2") = stop;
- register unsigned long _flg __asm ("a3") = 0;
- __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
-}
-#endif
-
-#ifdef __mc68000
-#include <asm/cachectl.h>
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- cacheflush(start,FLUSH_SCOPE_LINE,FLUSH_CACHE_BOTH,stop-start+16);
-}
-#endif
-
-#ifdef __alpha__
-
-register int gp asm("$29");
-
-static inline void immediate_ldah(void *p, int val) {
- uint32_t *dest = p;
- long high = ((val >> 16) + ((val >> 15) & 1)) & 0xffff;
-
- *dest &= ~0xffff;
- *dest |= high;
- *dest |= 31 << 16;
-}
-static inline void immediate_lda(void *dest, int val) {
- *(uint16_t *) dest = val;
-}
-void fix_bsr(void *p, int offset) {
- uint32_t *dest = p;
- *dest &= ~((1 << 21) - 1);
- *dest |= (offset >> 2) & ((1 << 21) - 1);
-}
-
-#endif /* __alpha__ */
-
-#ifdef __arm__
-
-#define ARM_LDR_TABLE_SIZE 1024
-
-typedef struct LDREntry {
- uint8_t *ptr;
- uint32_t *data_ptr;
- unsigned type:2;
-} LDREntry;
-
-static LDREntry arm_ldr_table[1024];
-static uint32_t arm_data_table[ARM_LDR_TABLE_SIZE];
-
-extern char exec_loop;
-
-static inline void arm_reloc_pc24(uint32_t *ptr, uint32_t insn, int val)
-{
- *ptr = (insn & ~0xffffff) | ((insn + ((val - (int)ptr) >> 2)) & 0xffffff);
-}
-
-static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr,
- LDREntry *ldr_start, LDREntry *ldr_end,
- uint32_t *data_start, uint32_t *data_end,
- int gen_jmp)
-{
- LDREntry *le;
- uint32_t *ptr;
- int offset, data_size, target;
- uint8_t *data_ptr;
- uint32_t insn;
- uint32_t mask;
-
- data_size = (data_end - data_start) << 2;
-
- if (gen_jmp) {
- /* generate branch to skip the data */
- if (data_size == 0)
- return gen_code_ptr;
- target = (long)gen_code_ptr + data_size + 4;
- arm_reloc_pc24((uint32_t *)gen_code_ptr, 0xeafffffe, target);
- gen_code_ptr += 4;
- }
-
- /* copy the data */
- data_ptr = gen_code_ptr;
- memcpy(gen_code_ptr, data_start, data_size);
- gen_code_ptr += data_size;
-
- /* patch the ldr to point to the data */
- for(le = ldr_start; le < ldr_end; le++) {
- ptr = (uint32_t *)le->ptr;
- offset = ((unsigned long)(le->data_ptr) - (unsigned long)data_start) +
- (unsigned long)data_ptr -
- (unsigned long)ptr - 8;
- if (offset < 0) {
- fprintf(stderr, "Negative constant pool offset\n");
- abort();
- }
- switch (le->type) {
- case 0: /* ldr */
- mask = ~0x00800fff;
- if (offset >= 4096) {
- fprintf(stderr, "Bad ldr offset\n");
- abort();
- }
- break;
- case 1: /* ldc */
- mask = ~0x008000ff;
- if (offset >= 1024 ) {
- fprintf(stderr, "Bad ldc offset\n");
- abort();
- }
- break;
- case 2: /* add */
- mask = ~0xfff;
- if (offset >= 1024 ) {
- fprintf(stderr, "Bad add offset\n");
- abort();
- }
- break;
- default:
- fprintf(stderr, "Bad pc relative fixup\n");
- abort();
- }
- insn = *ptr & mask;
- switch (le->type) {
- case 0: /* ldr */
- insn |= offset | 0x00800000;
- break;
- case 1: /* ldc */
- insn |= (offset >> 2) | 0x00800000;
- break;
- case 2: /* add */
- insn |= (offset >> 2) | 0xf00;
- break;
- }
- *ptr = insn;
- }
- return gen_code_ptr;
-}
-
-#endif /* __arm__ */
-
-#ifdef __ia64
-
-
-/* Patch instruction with "val" where "mask" has 1 bits. */
-static inline void ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val)
-{
- uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) (insn_addr & -16);
-# define insn_mask ((1UL << 41) - 1)
- unsigned long shift;
-
- b0 = b[0]; b1 = b[1];
- shift = 5 + 41 * (insn_addr % 16); /* 5 template, 3 x 41-bit insns */
- if (shift >= 64) {
- m1 = mask << (shift - 64);
- v1 = val << (shift - 64);
- } else {
- m0 = mask << shift; m1 = mask >> (64 - shift);
- v0 = val << shift; v1 = val >> (64 - shift);
- b[0] = (b0 & ~m0) | (v0 & m0);
- }
- b[1] = (b1 & ~m1) | (v1 & m1);
-}
-
-static inline void ia64_patch_imm60 (uint64_t insn_addr, uint64_t val)
-{
- ia64_patch(insn_addr,
- 0x011ffffe000UL,
- ( ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
- | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
- ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18);
-}
-
-static inline void ia64_imm64 (void *insn, uint64_t val)
-{
- /* Ignore the slot number of the relocation; GCC and Intel
- toolchains differed for some time on whether IMM64 relocs are
- against slot 1 (Intel) or slot 2 (GCC). */
- uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
- ia64_patch(insn_addr + 2,
- 0x01fffefe000UL,
- ( ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
- | ((val & 0x0000000000200000UL) << 0) /* bit 21 -> 21 */
- | ((val & 0x00000000001f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x000000000000ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x000000000000007fUL) << 13) /* bit 0 -> 13 */)
- );
- ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
-}
-
-static inline void ia64_imm60b (void *insn, uint64_t val)
-{
- /* Ignore the slot number of the relocation; GCC and Intel
- toolchains differed for some time on whether IMM64 relocs are
- against slot 1 (Intel) or slot 2 (GCC). */
- uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
- if (val + ((uint64_t) 1 << 59) >= (1UL << 60))
- fprintf(stderr, "%s: value %ld out of IMM60 range\n",
- __FUNCTION__, (int64_t) val);
- ia64_patch_imm60(insn_addr + 2, val);
-}
-
-static inline void ia64_imm22 (void *insn, uint64_t val)
-{
- if (val + (1 << 21) >= (1 << 22))
- fprintf(stderr, "%s: value %li out of IMM22 range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x01fffcfe000UL,
- ( ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
- | ((val & 0x1f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x00ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x00007fUL) << 13) /* bit 0 -> 13 */));
-}
-
-/* Like ia64_imm22(), but also clear bits 20-21. For addl, this has
- the effect of turning "addl rX=imm22,rY" into "addl
- rX=imm22,r0". */
-static inline void ia64_imm22_r0 (void *insn, uint64_t val)
-{
- if (val + (1 << 21) >= (1 << 22))
- fprintf(stderr, "%s: value %li out of IMM22 range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x01fffcfe000UL | (0x3UL << 20),
- ( ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
- | ((val & 0x1f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x00ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x00007fUL) << 13) /* bit 0 -> 13 */));
-}
-
-static inline void ia64_imm21b (void *insn, uint64_t val)
-{
- if (val + (1 << 20) >= (1 << 21))
- fprintf(stderr, "%s: value %li out of IMM21b range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x11ffffe000UL,
- ( ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
- | ((val & 0x0fffffUL) << 13) /* bit 0 -> 13 */));
-}
-
-static inline void ia64_nop_b (void *insn)
-{
- ia64_patch((uint64_t) insn, (1UL << 41) - 1, 2UL << 37);
-}
-
-static inline void ia64_ldxmov(void *insn, uint64_t val)
-{
- if (val + (1 << 21) < (1 << 22))
- ia64_patch((uint64_t) insn, 0x1fff80fe000UL, 8UL << 37);
-}
-
-static inline int ia64_patch_ltoff(void *insn, uint64_t val,
- int relaxable)
-{
- if (relaxable && (val + (1 << 21) < (1 << 22))) {
- ia64_imm22_r0(insn, val);
- return 0;
- }
- return 1;
-}
-
-struct ia64_fixup {
- struct ia64_fixup *next;
- void *addr; /* address that needs to be patched */
- long value;
-};
-
-#define IA64_PLT(insn, plt_index) \
-do { \
- struct ia64_fixup *fixup = alloca(sizeof(*fixup)); \
- fixup->next = plt_fixes; \
- plt_fixes = fixup; \
- fixup->addr = (insn); \
- fixup->value = (plt_index); \
- plt_offset[(plt_index)] = 1; \
-} while (0)
-
-#define IA64_LTOFF(insn, val, relaxable) \
-do { \
- if (ia64_patch_ltoff(insn, val, relaxable)) { \
- struct ia64_fixup *fixup = alloca(sizeof(*fixup)); \
- fixup->next = ltoff_fixes; \
- ltoff_fixes = fixup; \
- fixup->addr = (insn); \
- fixup->value = (val); \
- } \
-} while (0)
-
-static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
- struct ia64_fixup *ltoff_fixes,
- uint64_t gp,
- struct ia64_fixup *plt_fixes,
- int num_plts,
- unsigned long *plt_target,
- unsigned int *plt_offset)
-{
- static const uint8_t plt_bundle[] = {
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; movl r1=GP */
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60,
-
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; brl IP */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
- };
- uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start, *vp;
- struct ia64_fixup *fixup;
- unsigned int offset = 0;
- struct fdesc {
- long ip;
- long gp;
- } *fdesc;
- int i;
-
- if (plt_fixes) {
- plt_start = gen_code_ptr;
-
- for (i = 0; i < num_plts; ++i) {
- if (plt_offset[i]) {
- plt_offset[i] = offset;
- offset += sizeof(plt_bundle);
-
- fdesc = (struct fdesc *) plt_target[i];
- memcpy(gen_code_ptr, plt_bundle, sizeof(plt_bundle));
- ia64_imm64 (gen_code_ptr + 0x02, fdesc->gp);
- ia64_imm60b(gen_code_ptr + 0x12,
- (fdesc->ip - (long) (gen_code_ptr + 0x10)) >> 4);
- gen_code_ptr += sizeof(plt_bundle);
- }
- }
-
- for (fixup = plt_fixes; fixup; fixup = fixup->next)
- ia64_imm21b(fixup->addr,
- ((long) plt_start + plt_offset[fixup->value]
- - ((long) fixup->addr & ~0xf)) >> 4);
- }
-
- got_start = gen_code_ptr;
-
- /* First, create the GOT: */
- for (fixup = ltoff_fixes; fixup; fixup = fixup->next) {
- /* first check if we already have this value in the GOT: */
- for (vp = got_start; vp < gen_code_ptr; ++vp)
- if (*(uint64_t *) vp == fixup->value)
- break;
- if (vp == gen_code_ptr) {
- /* Nope, we need to put the value in the GOT: */
- *(uint64_t *) vp = fixup->value;
- gen_code_ptr += 8;
- }
- ia64_imm22(fixup->addr, (long) vp - gp);
- }
- /* Keep code ptr aligned. */
- if ((long) gen_code_ptr & 15)
- gen_code_ptr += 8;
- *gen_code_pp = gen_code_ptr;
-}
-
-#endif
diff --git a/tools/ioemu/elf.h b/tools/ioemu/elf.h
deleted file mode 100644
index 1825d50e82..0000000000
--- a/tools/ioemu/elf.h
+++ /dev/null
@@ -1,1164 +0,0 @@
-#ifndef _QEMU_ELF_H
-#define _QEMU_ELF_H
-
-#include <inttypes.h>
-
-/* 32-bit ELF base types. */
-typedef uint32_t Elf32_Addr;
-typedef uint16_t Elf32_Half;
-typedef uint32_t Elf32_Off;
-typedef int32_t Elf32_Sword;
-typedef uint32_t Elf32_Word;
-
-/* 64-bit ELF base types. */
-typedef uint64_t Elf64_Addr;
-typedef uint16_t Elf64_Half;
-typedef int16_t Elf64_SHalf;
-typedef uint64_t Elf64_Off;
-typedef int32_t Elf64_Sword;
-typedef uint32_t Elf64_Word;
-typedef uint64_t Elf64_Xword;
-typedef int64_t Elf64_Sxword;
-
-/* These constants are for the segment types stored in the image headers */
-#define PT_NULL 0
-#define PT_LOAD 1
-#define PT_DYNAMIC 2
-#define PT_INTERP 3
-#define PT_NOTE 4
-#define PT_SHLIB 5
-#define PT_PHDR 6
-#define PT_LOPROC 0x70000000
-#define PT_HIPROC 0x7fffffff
-#define PT_MIPS_REGINFO 0x70000000
-#define PT_MIPS_OPTIONS 0x70000001
-
-/* Flags in the e_flags field of the header */
-/* MIPS architecture level. */
-#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
-#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
-#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
-#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
-#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
-#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
-#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
-
-/* The ABI of a file. */
-#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
-#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */
-
-#define EF_MIPS_NOREORDER 0x00000001
-#define EF_MIPS_PIC 0x00000002
-#define EF_MIPS_CPIC 0x00000004
-#define EF_MIPS_ABI2 0x00000020
-#define EF_MIPS_OPTIONS_FIRST 0x00000080
-#define EF_MIPS_32BITMODE 0x00000100
-#define EF_MIPS_ABI 0x0000f000
-#define EF_MIPS_ARCH 0xf0000000
-
-/* These constants define the different elf file types */
-#define ET_NONE 0
-#define ET_REL 1
-#define ET_EXEC 2
-#define ET_DYN 3
-#define ET_CORE 4
-#define ET_LOPROC 0xff00
-#define ET_HIPROC 0xffff
-
-/* These constants define the various ELF target machines */
-#define EM_NONE 0
-#define EM_M32 1
-#define EM_SPARC 2
-#define EM_386 3
-#define EM_68K 4
-#define EM_88K 5
-#define EM_486 6 /* Perhaps disused */
-#define EM_860 7
-
-#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
-
-#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
-
-#define EM_PARISC 15 /* HPPA */
-
-#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
-
-#define EM_PPC 20 /* PowerPC */
-#define EM_PPC64 21 /* PowerPC64 */
-
-#define EM_ARM 40 /* ARM */
-
-#define EM_SH 42 /* SuperH */
-
-#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-
-#define EM_IA_64 50 /* HP/Intel IA-64 */
-
-#define EM_X86_64 62 /* AMD x86-64 */
-
-#define EM_S390 22 /* IBM S/390 */
-
-#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
-
-#define EM_V850 87 /* NEC v850 */
-
-#define EM_H8_300H 47 /* Hitachi H8/300H */
-#define EM_H8S 48 /* Hitachi H8S */
-
-/*
- * This is an interim value that we will use until the committee comes
- * up with a final number.
- */
-#define EM_ALPHA 0x9026
-
-/* Bogus old v850 magic number, used by old tools. */
-#define EM_CYGNUS_V850 0x9080
-
-/*
- * This is the old interim value for S/390 architecture
- */
-#define EM_S390_OLD 0xA390
-
-/* This is the info that is needed to parse the dynamic section of the file */
-#define DT_NULL 0
-#define DT_NEEDED 1
-#define DT_PLTRELSZ 2
-#define DT_PLTGOT 3
-#define DT_HASH 4
-#define DT_STRTAB 5
-#define DT_SYMTAB 6
-#define DT_RELA 7
-#define DT_RELASZ 8
-#define DT_RELAENT 9
-#define DT_STRSZ 10
-#define DT_SYMENT 11
-#define DT_INIT 12
-#define DT_FINI 13
-#define DT_SONAME 14
-#define DT_RPATH 15
-#define DT_SYMBOLIC 16
-#define DT_REL 17
-#define DT_RELSZ 18
-#define DT_RELENT 19
-#define DT_PLTREL 20
-#define DT_DEBUG 21
-#define DT_TEXTREL 22
-#define DT_JMPREL 23
-#define DT_LOPROC 0x70000000
-#define DT_HIPROC 0x7fffffff
-#define DT_MIPS_RLD_VERSION 0x70000001
-#define DT_MIPS_TIME_STAMP 0x70000002
-#define DT_MIPS_ICHECKSUM 0x70000003
-#define DT_MIPS_IVERSION 0x70000004
-#define DT_MIPS_FLAGS 0x70000005
- #define RHF_NONE 0
- #define RHF_HARDWAY 1
- #define RHF_NOTPOT 2
-#define DT_MIPS_BASE_ADDRESS 0x70000006
-#define DT_MIPS_CONFLICT 0x70000008
-#define DT_MIPS_LIBLIST 0x70000009
-#define DT_MIPS_LOCAL_GOTNO 0x7000000a
-#define DT_MIPS_CONFLICTNO 0x7000000b
-#define DT_MIPS_LIBLISTNO 0x70000010
-#define DT_MIPS_SYMTABNO 0x70000011
-#define DT_MIPS_UNREFEXTNO 0x70000012
-#define DT_MIPS_GOTSYM 0x70000013
-#define DT_MIPS_HIPAGENO 0x70000014
-#define DT_MIPS_RLD_MAP 0x70000016
-
-/* This info is needed when parsing the symbol table */
-#define STB_LOCAL 0
-#define STB_GLOBAL 1
-#define STB_WEAK 2
-
-#define STT_NOTYPE 0
-#define STT_OBJECT 1
-#define STT_FUNC 2
-#define STT_SECTION 3
-#define STT_FILE 4
-
-#define ELF_ST_BIND(x) ((x) >> 4)
-#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
-#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
-#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
-#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
-#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
-
-/* Symbolic values for the entries in the auxiliary table
- put on the initial stack */
-#define AT_NULL 0 /* end of vector */
-#define AT_IGNORE 1 /* entry should be ignored */
-#define AT_EXECFD 2 /* file descriptor of program */
-#define AT_PHDR 3 /* program headers for program */
-#define AT_PHENT 4 /* size of program header entry */
-#define AT_PHNUM 5 /* number of program headers */
-#define AT_PAGESZ 6 /* system page size */
-#define AT_BASE 7 /* base address of interpreter */
-#define AT_FLAGS 8 /* flags */
-#define AT_ENTRY 9 /* entry point of program */
-#define AT_NOTELF 10 /* program is not ELF */
-#define AT_UID 11 /* real uid */
-#define AT_EUID 12 /* effective uid */
-#define AT_GID 13 /* real gid */
-#define AT_EGID 14 /* effective gid */
-#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
-#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
-#define AT_CLKTCK 17 /* frequency at which times() increments */
-
-typedef struct dynamic{
- Elf32_Sword d_tag;
- union{
- Elf32_Sword d_val;
- Elf32_Addr d_ptr;
- } d_un;
-} Elf32_Dyn;
-
-typedef struct {
- Elf64_Sxword d_tag; /* entry tag value */
- union {
- Elf64_Xword d_val;
- Elf64_Addr d_ptr;
- } d_un;
-} Elf64_Dyn;
-
-/* The following are used with relocations */
-#define ELF32_R_SYM(x) ((x) >> 8)
-#define ELF32_R_TYPE(x) ((x) & 0xff)
-
-#define ELF64_R_SYM(i) ((i) >> 32)
-#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
-#define ELF64_R_TYPE_DATA(i) (((ELF64_R_TYPE(i) >> 8) ^ 0x00800000) - 0x00800000)
-
-#define R_386_NONE 0
-#define R_386_32 1
-#define R_386_PC32 2
-#define R_386_GOT32 3
-#define R_386_PLT32 4
-#define R_386_COPY 5
-#define R_386_GLOB_DAT 6
-#define R_386_JMP_SLOT 7
-#define R_386_RELATIVE 8
-#define R_386_GOTOFF 9
-#define R_386_GOTPC 10
-#define R_386_NUM 11
-
-#define R_MIPS_NONE 0
-#define R_MIPS_16 1
-#define R_MIPS_32 2
-#define R_MIPS_REL32 3
-#define R_MIPS_26 4
-#define R_MIPS_HI16 5
-#define R_MIPS_LO16 6
-#define R_MIPS_GPREL16 7
-#define R_MIPS_LITERAL 8
-#define R_MIPS_GOT16 9
-#define R_MIPS_PC16 10
-#define R_MIPS_CALL16 11
-#define R_MIPS_GPREL32 12
-/* The remaining relocs are defined on Irix, although they are not
- in the MIPS ELF ABI. */
-#define R_MIPS_UNUSED1 13
-#define R_MIPS_UNUSED2 14
-#define R_MIPS_UNUSED3 15
-#define R_MIPS_SHIFT5 16
-#define R_MIPS_SHIFT6 17
-#define R_MIPS_64 18
-#define R_MIPS_GOT_DISP 19
-#define R_MIPS_GOT_PAGE 20
-#define R_MIPS_GOT_OFST 21
-/*
- * The following two relocation types are specified in the MIPS ABI
- * conformance guide version 1.2 but not yet in the psABI.
- */
-#define R_MIPS_GOTHI16 22
-#define R_MIPS_GOTLO16 23
-#define R_MIPS_SUB 24
-#define R_MIPS_INSERT_A 25
-#define R_MIPS_INSERT_B 26
-#define R_MIPS_DELETE 27
-#define R_MIPS_HIGHER 28
-#define R_MIPS_HIGHEST 29
-/*
- * The following two relocation types are specified in the MIPS ABI
- * conformance guide version 1.2 but not yet in the psABI.
- */
-#define R_MIPS_CALLHI16 30
-#define R_MIPS_CALLLO16 31
-/*
- * This range is reserved for vendor specific relocations.
- */
-#define R_MIPS_LOVENDOR 100
-#define R_MIPS_HIVENDOR 127
-
-
-/*
- * Sparc ELF relocation types
- */
-#define R_SPARC_NONE 0
-#define R_SPARC_8 1
-#define R_SPARC_16 2
-#define R_SPARC_32 3
-#define R_SPARC_DISP8 4
-#define R_SPARC_DISP16 5
-#define R_SPARC_DISP32 6
-#define R_SPARC_WDISP30 7
-#define R_SPARC_WDISP22 8
-#define R_SPARC_HI22 9
-#define R_SPARC_22 10
-#define R_SPARC_13 11
-#define R_SPARC_LO10 12
-#define R_SPARC_GOT10 13
-#define R_SPARC_GOT13 14
-#define R_SPARC_GOT22 15
-#define R_SPARC_PC10 16
-#define R_SPARC_PC22 17
-#define R_SPARC_WPLT30 18
-#define R_SPARC_COPY 19
-#define R_SPARC_GLOB_DAT 20
-#define R_SPARC_JMP_SLOT 21
-#define R_SPARC_RELATIVE 22
-#define R_SPARC_UA32 23
-#define R_SPARC_PLT32 24
-#define R_SPARC_HIPLT22 25
-#define R_SPARC_LOPLT10 26
-#define R_SPARC_PCPLT32 27
-#define R_SPARC_PCPLT22 28
-#define R_SPARC_PCPLT10 29
-#define R_SPARC_10 30
-#define R_SPARC_11 31
-#define R_SPARC_64 32
-#define R_SPARC_OLO10 33
-#define R_SPARC_WDISP16 40
-#define R_SPARC_WDISP19 41
-#define R_SPARC_7 43
-#define R_SPARC_5 44
-#define R_SPARC_6 45
-
-/* Bits present in AT_HWCAP, primarily for Sparc32. */
-
-#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
-#define HWCAP_SPARC_STBAR 2
-#define HWCAP_SPARC_SWAP 4
-#define HWCAP_SPARC_MULDIV 8
-#define HWCAP_SPARC_V9 16
-#define HWCAP_SPARC_ULTRA3 32
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE 0
-#define R_68K_32 1
-#define R_68K_16 2
-#define R_68K_8 3
-#define R_68K_PC32 4
-#define R_68K_PC16 5
-#define R_68K_PC8 6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8 9
-#define R_68K_GOT32O 10
-#define R_68K_GOT16O 11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8 15
-#define R_68K_PLT32O 16
-#define R_68K_PLT16O 17
-#define R_68K_PLT8O 18
-#define R_68K_COPY 19
-#define R_68K_GLOB_DAT 20
-#define R_68K_JMP_SLOT 21
-#define R_68K_RELATIVE 22
-
-/*
- * Alpha ELF relocation types
- */
-#define R_ALPHA_NONE 0 /* No reloc */
-#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
-#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
-#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
-#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
-#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
-#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
-#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
-#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
-#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
-#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
-#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
-#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
-#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
-#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
-#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
-#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
-#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
-#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
-#define R_ALPHA_BRSGP 28
-#define R_ALPHA_TLSGD 29
-#define R_ALPHA_TLS_LDM 30
-#define R_ALPHA_DTPMOD64 31
-#define R_ALPHA_GOTDTPREL 32
-#define R_ALPHA_DTPREL64 33
-#define R_ALPHA_DTPRELHI 34
-#define R_ALPHA_DTPRELLO 35
-#define R_ALPHA_DTPREL16 36
-#define R_ALPHA_GOTTPREL 37
-#define R_ALPHA_TPREL64 38
-#define R_ALPHA_TPRELHI 39
-#define R_ALPHA_TPRELLO 40
-#define R_ALPHA_TPREL16 41
-
-#define SHF_ALPHA_GPREL 0x10000000
-
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE 0
-#define R_PPC_ADDR32 1 /* 32bit absolute address */
-#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-#define R_PPC_ADDR16 3 /* 16bit absolute address */
-#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN 8
-#define R_PPC_ADDR14_BRNTAKEN 9
-#define R_PPC_REL24 10 /* PC relative 26 bit */
-#define R_PPC_REL14 11 /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN 12
-#define R_PPC_REL14_BRNTAKEN 13
-#define R_PPC_GOT16 14
-#define R_PPC_GOT16_LO 15
-#define R_PPC_GOT16_HI 16
-#define R_PPC_GOT16_HA 17
-#define R_PPC_PLTREL24 18
-#define R_PPC_COPY 19
-#define R_PPC_GLOB_DAT 20
-#define R_PPC_JMP_SLOT 21
-#define R_PPC_RELATIVE 22
-#define R_PPC_LOCAL24PC 23
-#define R_PPC_UADDR32 24
-#define R_PPC_UADDR16 25
-#define R_PPC_REL32 26
-#define R_PPC_PLT32 27
-#define R_PPC_PLTREL32 28
-#define R_PPC_PLT16_LO 29
-#define R_PPC_PLT16_HI 30
-#define R_PPC_PLT16_HA 31
-#define R_PPC_SDAREL16 32
-#define R_PPC_SECTOFF 33
-#define R_PPC_SECTOFF_LO 34
-#define R_PPC_SECTOFF_HI 35
-#define R_PPC_SECTOFF_HA 36
-/* Keep this the last entry. */
-#define R_PPC_NUM 37
-
-/* ARM specific declarations */
-
-/* Processor specific flags for the ELF header e_flags field. */
-#define EF_ARM_RELEXEC 0x01
-#define EF_ARM_HASENTRY 0x02
-#define EF_ARM_INTERWORK 0x04
-#define EF_ARM_APCS_26 0x08
-#define EF_ARM_APCS_FLOAT 0x10
-#define EF_ARM_PIC 0x20
-#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */
-#define EF_NEW_ABI 0x80
-#define EF_OLD_ABI 0x100
-
-/* Additional symbol types for Thumb */
-#define STT_ARM_TFUNC 0xd
-
-/* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
-#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
- in the input to a link step */
-
-/* ARM-specific program header flags */
-#define PF_ARM_SB 0x10000000 /* Segment contains the location
- addressed by the static base */
-
-/* ARM relocs. */
-#define R_ARM_NONE 0 /* No reloc */
-#define R_ARM_PC24 1 /* PC relative 26 bit branch */
-#define R_ARM_ABS32 2 /* Direct 32 bit */
-#define R_ARM_REL32 3 /* PC relative 32 bit */
-#define R_ARM_PC13 4
-#define R_ARM_ABS16 5 /* Direct 16 bit */
-#define R_ARM_ABS12 6 /* Direct 12 bit */
-#define R_ARM_THM_ABS5 7
-#define R_ARM_ABS8 8 /* Direct 8 bit */
-#define R_ARM_SBREL32 9
-#define R_ARM_THM_PC22 10
-#define R_ARM_THM_PC8 11
-#define R_ARM_AMP_VCALL9 12
-#define R_ARM_SWI24 13
-#define R_ARM_THM_SWI8 14
-#define R_ARM_XPC25 15
-#define R_ARM_THM_XPC22 16
-#define R_ARM_COPY 20 /* Copy symbol at runtime */
-#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
-#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
-#define R_ARM_RELATIVE 23 /* Adjust by program base */
-#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
-#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
-#define R_ARM_GOT32 26 /* 32 bit GOT entry */
-#define R_ARM_PLT32 27 /* 32 bit PLT address */
-#define R_ARM_CALL 28
-#define R_ARM_JUMP24 29
-#define R_ARM_GNU_VTENTRY 100
-#define R_ARM_GNU_VTINHERIT 101
-#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
-#define R_ARM_THM_PC9 103 /* thumb conditional branch */
-#define R_ARM_RXPC25 249
-#define R_ARM_RSBREL32 250
-#define R_ARM_THM_RPC22 251
-#define R_ARM_RREL32 252
-#define R_ARM_RABS22 253
-#define R_ARM_RPC24 254
-#define R_ARM_RBASE 255
-/* Keep this the last entry. */
-#define R_ARM_NUM 256
-
-/* s390 relocations defined by the ABIs */
-#define R_390_NONE 0 /* No reloc. */
-#define R_390_8 1 /* Direct 8 bit. */
-#define R_390_12 2 /* Direct 12 bit. */
-#define R_390_16 3 /* Direct 16 bit. */
-#define R_390_32 4 /* Direct 32 bit. */
-#define R_390_PC32 5 /* PC relative 32 bit. */
-#define R_390_GOT12 6 /* 12 bit GOT offset. */
-#define R_390_GOT32 7 /* 32 bit GOT offset. */
-#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
-#define R_390_COPY 9 /* Copy symbol at runtime. */
-#define R_390_GLOB_DAT 10 /* Create GOT entry. */
-#define R_390_JMP_SLOT 11 /* Create PLT entry. */
-#define R_390_RELATIVE 12 /* Adjust by program base. */
-#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
-#define R_390_GOTPC 14 /* 32 bit PC rel. offset to GOT. */
-#define R_390_GOT16 15 /* 16 bit GOT offset. */
-#define R_390_PC16 16 /* PC relative 16 bit. */
-#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
-#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
-#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
-#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
-#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
-#define R_390_64 22 /* Direct 64 bit. */
-#define R_390_PC64 23 /* PC relative 64 bit. */
-#define R_390_GOT64 24 /* 64 bit GOT offset. */
-#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
-#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
-#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
-#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
-#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
-#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
-#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
-#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
-#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
-#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
-#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
-#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
-#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
-#define R_390_TLS_GDCALL 38 /* Tag for function call in general
- dynamic TLS code. */
-#define R_390_TLS_LDCALL 39 /* Tag for function call in local
- dynamic TLS code. */
-#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
- thread local data. */
-#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
- thread local data. */
-#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
- thread local data in LD code. */
-#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
- thread local data in LD code. */
-#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
- static TLS block. */
-#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
- static TLS block. */
-#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
- block. */
-#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
- block. */
-#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
-#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
-#define R_390_TLS_TPOFF 56 /* Negate offset in static TLS
- block. */
-/* Keep this the last entry. */
-#define R_390_NUM 57
-
-/* x86-64 relocation types */
-#define R_X86_64_NONE 0 /* No reloc */
-#define R_X86_64_64 1 /* Direct 64 bit */
-#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
-#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
-#define R_X86_64_PLT32 4 /* 32 bit PLT address */
-#define R_X86_64_COPY 5 /* Copy symbol at runtime */
-#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
-#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
-#define R_X86_64_RELATIVE 8 /* Adjust by program base */
-#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative
- offset to GOT */
-#define R_X86_64_32 10 /* Direct 32 bit zero extended */
-#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
-#define R_X86_64_16 12 /* Direct 16 bit zero extended */
-#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
-#define R_X86_64_8 14 /* Direct 8 bit sign extended */
-#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
-
-#define R_X86_64_NUM 16
-
-/* Legal values for e_flags field of Elf64_Ehdr. */
-
-#define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */
-
-/* HPPA specific definitions. */
-
-/* Legal values for e_flags field of Elf32_Ehdr. */
-
-#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
-#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
-#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
-#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
-#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
- prediction. */
-#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
-#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
-
-/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
-
-#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
-#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
-#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
-
-/* Additional section indeces. */
-
-#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
- symbols in ANSI C. */
-#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
-
-/* Legal values for sh_type field of Elf32_Shdr. */
-
-#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
-#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
-#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
-
-/* Legal values for sh_flags field of Elf32_Shdr. */
-
-#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
-#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
-#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-
-#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
-
-#define STT_HP_OPAQUE (STT_LOOS + 0x1)
-#define STT_HP_STUB (STT_LOOS + 0x2)
-
-/* HPPA relocs. */
-
-#define R_PARISC_NONE 0 /* No reloc. */
-#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
-#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
-#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
-#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
-#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
-#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
-#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
-#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
-#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
-#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
-#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
-#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
-#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
-#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
-#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
-#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
-#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
-#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
-#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
-#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
-#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
-#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
-#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
-#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
-#define R_PARISC_FPTR64 64 /* 64 bits function address. */
-#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
-#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
-#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
-#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
-#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
-#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
-#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
-#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
-#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
-#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
-#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
-#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
-#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
-#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
-#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
-#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
-#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
-#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
-#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
-#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
-#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
-#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
-#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
-#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
-#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
-#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
-#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
-#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
-#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
-#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
-#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
-#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LORESERVE 128
-#define R_PARISC_COPY 128 /* Copy relocation. */
-#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
-#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
-#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
-#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
-#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
-#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
-#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
-#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
-#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
-#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
-#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_HIRESERVE 255
-
-/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
-
-#define PT_HP_TLS (PT_LOOS + 0x0)
-#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
-#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
-#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
-#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
-#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
-#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
-#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
-#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
-#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
-#define PT_HP_PARALLEL (PT_LOOS + 0x10)
-#define PT_HP_FASTBIND (PT_LOOS + 0x11)
-#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
-#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
-#define PT_HP_STACK (PT_LOOS + 0x14)
-
-#define PT_PARISC_ARCHEXT 0x70000000
-#define PT_PARISC_UNWIND 0x70000001
-
-/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
-
-#define PF_PARISC_SBP 0x08000000
-
-#define PF_HP_PAGE_SIZE 0x00100000
-#define PF_HP_FAR_SHARED 0x00200000
-#define PF_HP_NEAR_SHARED 0x00400000
-#define PF_HP_CODE 0x01000000
-#define PF_HP_MODIFY 0x02000000
-#define PF_HP_LAZYSWAP 0x04000000
-#define PF_HP_SBP 0x08000000
-
-/* IA-64 specific declarations. */
-
-/* Processor specific flags for the Ehdr e_flags field. */
-#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
-#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
-#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
-
-/* Processor specific values for the Phdr p_type field. */
-#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
-#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
-
-/* Processor specific flags for the Phdr p_flags field. */
-#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
-
-/* Processor specific values for the Shdr sh_type field. */
-#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
-#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
-
-/* Processor specific flags for the Shdr sh_flags field. */
-#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
-#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
-
-/* Processor specific values for the Dyn d_tag field. */
-#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
-#define DT_IA_64_NUM 1
-
-/* IA-64 relocations. */
-#define R_IA64_NONE 0x00 /* none */
-#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
-#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
-#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
-#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
-#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
-#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
-#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
-#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
-#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
-#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */
-#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */
-#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
-#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
-#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
-#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
-#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
-#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
-#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
-#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
-#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
-#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
-#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */
-#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
-#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
-#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
-#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
-#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
-#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
-#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
-#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
-#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */
-#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */
-#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */
-#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */
-#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
-#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
-#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
-#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
-#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
-#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
-#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
-#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
-#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
-#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
-#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
-#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
-#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
-#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
-#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
-#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
-#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */
-#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */
-#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */
-#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
-#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
-#define R_IA64_COPY 0x84 /* copy relocation */
-#define R_IA64_SUB 0x85 /* Addend and symbol difference */
-#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
-#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
-#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */
-#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */
-#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */
-#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */
-#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */
-#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */
-#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */
-#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */
-#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */
-#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */
-#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */
-#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */
-#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */
-#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
-
-typedef struct elf32_rel {
- Elf32_Addr r_offset;
- Elf32_Word r_info;
-} Elf32_Rel;
-
-typedef struct elf64_rel {
- Elf64_Addr r_offset; /* Location at which to apply the action */
- Elf64_Xword r_info; /* index and type of relocation */
-} Elf64_Rel;
-
-typedef struct elf32_rela{
- Elf32_Addr r_offset;
- Elf32_Word r_info;
- Elf32_Sword r_addend;
-} Elf32_Rela;
-
-typedef struct elf64_rela {
- Elf64_Addr r_offset; /* Location at which to apply the action */
- Elf64_Xword r_info; /* index and type of relocation */
- Elf64_Sxword r_addend; /* Constant addend used to compute value */
-} Elf64_Rela;
-
-typedef struct elf32_sym{
- Elf32_Word st_name;
- Elf32_Addr st_value;
- Elf32_Word st_size;
- unsigned char st_info;
- unsigned char st_other;
- Elf32_Half st_shndx;
-} Elf32_Sym;
-
-typedef struct elf64_sym {
- Elf64_Word st_name; /* Symbol name, index in string tbl */
- unsigned char st_info; /* Type and binding attributes */
- unsigned char st_other; /* No defined meaning, 0 */
- Elf64_Half st_shndx; /* Associated section index */
- Elf64_Addr st_value; /* Value of the symbol */
- Elf64_Xword st_size; /* Associated symbol size */
-} Elf64_Sym;
-
-
-#define EI_NIDENT 16
-
-typedef struct elf32_hdr{
- unsigned char e_ident[EI_NIDENT];
- Elf32_Half e_type;
- Elf32_Half e_machine;
- Elf32_Word e_version;
- Elf32_Addr e_entry; /* Entry point */
- Elf32_Off e_phoff;
- Elf32_Off e_shoff;
- Elf32_Word e_flags;
- Elf32_Half e_ehsize;
- Elf32_Half e_phentsize;
- Elf32_Half e_phnum;
- Elf32_Half e_shentsize;
- Elf32_Half e_shnum;
- Elf32_Half e_shstrndx;
-} Elf32_Ehdr;
-
-typedef struct elf64_hdr {
- unsigned char e_ident[16]; /* ELF "magic number" */
- Elf64_Half e_type;
- Elf64_Half e_machine;
- Elf64_Word e_version;
- Elf64_Addr e_entry; /* Entry point virtual address */
- Elf64_Off e_phoff; /* Program header table file offset */
- Elf64_Off e_shoff; /* Section header table file offset */
- Elf64_Word e_flags;
- Elf64_Half e_ehsize;
- Elf64_Half e_phentsize;
- Elf64_Half e_phnum;
- Elf64_Half e_shentsize;
- Elf64_Half e_shnum;
- Elf64_Half e_shstrndx;
-} Elf64_Ehdr;
-
-/* These constants define the permissions on sections in the program
- header, p_flags. */
-#define PF_R 0x4
-#define PF_W 0x2
-#define PF_X 0x1
-
-typedef struct elf32_phdr{
- Elf32_Word p_type;
- Elf32_Off p_offset;
- Elf32_Addr p_vaddr;
- Elf32_Addr p_paddr;
- Elf32_Word p_filesz;
- Elf32_Word p_memsz;
- Elf32_Word p_flags;
- Elf32_Word p_align;
-} Elf32_Phdr;
-
-typedef struct elf64_phdr {
- Elf64_Word p_type;
- Elf64_Word p_flags;
- Elf64_Off p_offset; /* Segment file offset */
- Elf64_Addr p_vaddr; /* Segment virtual address */
- Elf64_Addr p_paddr; /* Segment physical address */
- Elf64_Xword p_filesz; /* Segment size in file */
- Elf64_Xword p_memsz; /* Segment size in memory */
- Elf64_Xword p_align; /* Segment alignment, file & memory */
-} Elf64_Phdr;
-
-/* sh_type */
-#define SHT_NULL 0
-#define SHT_PROGBITS 1
-#define SHT_SYMTAB 2
-#define SHT_STRTAB 3
-#define SHT_RELA 4
-#define SHT_HASH 5
-#define SHT_DYNAMIC 6
-#define SHT_NOTE 7
-#define SHT_NOBITS 8
-#define SHT_REL 9
-#define SHT_SHLIB 10
-#define SHT_DYNSYM 11
-#define SHT_NUM 12
-#define SHT_LOPROC 0x70000000
-#define SHT_HIPROC 0x7fffffff
-#define SHT_LOUSER 0x80000000
-#define SHT_HIUSER 0xffffffff
-#define SHT_MIPS_LIST 0x70000000
-#define SHT_MIPS_CONFLICT 0x70000002
-#define SHT_MIPS_GPTAB 0x70000003
-#define SHT_MIPS_UCODE 0x70000004
-
-/* sh_flags */
-#define SHF_WRITE 0x1
-#define SHF_ALLOC 0x2
-#define SHF_EXECINSTR 0x4
-#define SHF_MASKPROC 0xf0000000
-#define SHF_MIPS_GPREL 0x10000000
-
-/* special section indexes */
-#define SHN_UNDEF 0
-#define SHN_LORESERVE 0xff00
-#define SHN_LOPROC 0xff00
-#define SHN_HIPROC 0xff1f
-#define SHN_ABS 0xfff1
-#define SHN_COMMON 0xfff2
-#define SHN_HIRESERVE 0xffff
-#define SHN_MIPS_ACCOMON 0xff00
-
-typedef struct elf32_shdr {
- Elf32_Word sh_name;
- Elf32_Word sh_type;
- Elf32_Word sh_flags;
- Elf32_Addr sh_addr;
- Elf32_Off sh_offset;
- Elf32_Word sh_size;
- Elf32_Word sh_link;
- Elf32_Word sh_info;
- Elf32_Word sh_addralign;
- Elf32_Word sh_entsize;
-} Elf32_Shdr;
-
-typedef struct elf64_shdr {
- Elf64_Word sh_name; /* Section name, index in string tbl */
- Elf64_Word sh_type; /* Type of section */
- Elf64_Xword sh_flags; /* Miscellaneous section attributes */
- Elf64_Addr sh_addr; /* Section virtual addr at execution */
- Elf64_Off sh_offset; /* Section file offset */
- Elf64_Xword sh_size; /* Size of section in bytes */
- Elf64_Word sh_link; /* Index of another section */
- Elf64_Word sh_info; /* Additional section information */
- Elf64_Xword sh_addralign; /* Section alignment */
- Elf64_Xword sh_entsize; /* Entry size if section holds table */
-} Elf64_Shdr;
-
-#define EI_MAG0 0 /* e_ident[] indexes */
-#define EI_MAG1 1
-#define EI_MAG2 2
-#define EI_MAG3 3
-#define EI_CLASS 4
-#define EI_DATA 5
-#define EI_VERSION 6
-#define EI_PAD 7
-
-#define ELFMAG0 0x7f /* EI_MAG */
-#define ELFMAG1 'E'
-#define ELFMAG2 'L'
-#define ELFMAG3 'F'
-#define ELFMAG "\177ELF"
-#define SELFMAG 4
-
-#define ELFCLASSNONE 0 /* EI_CLASS */
-#define ELFCLASS32 1
-#define ELFCLASS64 2
-#define ELFCLASSNUM 3
-
-#define ELFDATANONE 0 /* e_ident[EI_DATA] */
-#define ELFDATA2LSB 1
-#define ELFDATA2MSB 2
-
-#define EV_NONE 0 /* e_version, EI_VERSION */
-#define EV_CURRENT 1
-#define EV_NUM 2
-
-/* Notes used in ET_CORE */
-#define NT_PRSTATUS 1
-#define NT_PRFPREG 2
-#define NT_PRPSINFO 3
-#define NT_TASKSTRUCT 4
-#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
-
-
-/* Note header in a PT_NOTE section */
-typedef struct elf32_note {
- Elf32_Word n_namesz; /* Name size */
- Elf32_Word n_descsz; /* Content size */
- Elf32_Word n_type; /* Content type */
-} Elf32_Nhdr;
-
-/* Note header in a PT_NOTE section */
-typedef struct elf64_note {
- Elf64_Word n_namesz; /* Name size */
- Elf64_Word n_descsz; /* Content size */
- Elf64_Word n_type; /* Content type */
-} Elf64_Nhdr;
-
-#if ELF_CLASS == ELFCLASS32
-
-#define elfhdr elf32_hdr
-#define elf_phdr elf32_phdr
-#define elf_note elf32_note
-#define elf_shdr elf32_shdr
-#define elf_sym elf32_sym
-
-#ifdef ELF_USES_RELOCA
-# define ELF_RELOC Elf32_Rela
-#else
-# define ELF_RELOC Elf32_Rel
-#endif
-
-#else
-
-#define elfhdr elf64_hdr
-#define elf_phdr elf64_phdr
-#define elf_note elf64_note
-#define elf_shdr elf64_shdr
-#define elf_sym elf64_sym
-
-#ifdef ELF_USES_RELOCA
-# define ELF_RELOC Elf64_Rela
-#else
-# define ELF_RELOC Elf64_Rel
-#endif
-
-#endif /* ELF_CLASS */
-
-#ifndef ElfW
-# if ELF_CLASS == ELFCLASS32
-# define ElfW(x) Elf32_ ## x
-# define ELFW(x) ELF32_ ## x
-# else
-# define ElfW(x) Elf64_ ## x
-# define ELFW(x) ELF64_ ## x
-# endif
-#endif
-
-
-#endif /* _QEMU_ELF_H */
diff --git a/tools/ioemu/elf_ops.h b/tools/ioemu/elf_ops.h
deleted file mode 100644
index abcce093ef..0000000000
--- a/tools/ioemu/elf_ops.h
+++ /dev/null
@@ -1,207 +0,0 @@
-static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
-{
- bswap16s(&ehdr->e_type); /* Object file type */
- bswap16s(&ehdr->e_machine); /* Architecture */
- bswap32s(&ehdr->e_version); /* Object file version */
- bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
- bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
- bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
- bswap32s(&ehdr->e_flags); /* Processor-specific flags */
- bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
- bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
- bswap16s(&ehdr->e_phnum); /* Program header table entry count */
- bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
- bswap16s(&ehdr->e_shnum); /* Section header table entry count */
- bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
-}
-
-static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
-{
- bswap32s(&phdr->p_type); /* Segment type */
- bswapSZs(&phdr->p_offset); /* Segment file offset */
- bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
- bswapSZs(&phdr->p_paddr); /* Segment physical address */
- bswapSZs(&phdr->p_filesz); /* Segment size in file */
- bswapSZs(&phdr->p_memsz); /* Segment size in memory */
- bswap32s(&phdr->p_flags); /* Segment flags */
- bswapSZs(&phdr->p_align); /* Segment alignment */
-}
-
-static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
-{
- bswap32s(&shdr->sh_name);
- bswap32s(&shdr->sh_type);
- bswapSZs(&shdr->sh_flags);
- bswapSZs(&shdr->sh_addr);
- bswapSZs(&shdr->sh_offset);
- bswapSZs(&shdr->sh_size);
- bswap32s(&shdr->sh_link);
- bswap32s(&shdr->sh_info);
- bswapSZs(&shdr->sh_addralign);
- bswapSZs(&shdr->sh_entsize);
-}
-
-static void glue(bswap_sym, SZ)(struct elf_sym *sym)
-{
- bswap32s(&sym->st_name);
- bswapSZs(&sym->st_value);
- bswapSZs(&sym->st_size);
- bswap16s(&sym->st_shndx);
-}
-
-static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,
- int n, int type)
-{
- int i;
- for(i=0;i<n;i++) {
- if (shdr_table[i].sh_type == type)
- return shdr_table + i;
- }
- return NULL;
-}
-
-static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
-{
- struct elf_shdr *symtab, *strtab, *shdr_table = NULL;
- struct elf_sym *syms = NULL;
-#if (SZ == 64)
- struct elf32_sym *syms32 = NULL;
-#endif
- struct syminfo *s;
- int nsyms, i;
- char *str = NULL;
-
- shdr_table = load_at(fd, ehdr->e_shoff,
- sizeof(struct elf_shdr) * ehdr->e_shnum);
- if (!shdr_table)
- return -1;
-
- if (must_swab) {
- for (i = 0; i < ehdr->e_shnum; i++) {
- glue(bswap_shdr, SZ)(shdr_table + i);
- }
- }
-
- symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB);
- if (!symtab)
- goto fail;
- syms = load_at(fd, symtab->sh_offset, symtab->sh_size);
- if (!syms)
- goto fail;
-
- nsyms = symtab->sh_size / sizeof(struct elf_sym);
-#if (SZ == 64)
- syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym));
-#endif
- for (i = 0; i < nsyms; i++) {
- if (must_swab)
- glue(bswap_sym, SZ)(&syms[i]);
-#if (SZ == 64)
- syms32[i].st_name = syms[i].st_name;
- syms32[i].st_info = syms[i].st_info;
- syms32[i].st_other = syms[i].st_other;
- syms32[i].st_shndx = syms[i].st_shndx;
- syms32[i].st_value = syms[i].st_value & 0xffffffff;
- syms32[i].st_size = syms[i].st_size & 0xffffffff;
-#endif
- }
- /* String table */
- if (symtab->sh_link >= ehdr->e_shnum)
- goto fail;
- strtab = &shdr_table[symtab->sh_link];
-
- str = load_at(fd, strtab->sh_offset, strtab->sh_size);
- if (!str)
- goto fail;
-
- /* Commit */
- s = qemu_mallocz(sizeof(*s));
-#if (SZ == 64)
- s->disas_symtab = syms32;
- qemu_free(syms);
-#else
- s->disas_symtab = syms;
-#endif
- s->disas_num_syms = nsyms;
- s->disas_strtab = str;
- s->next = syminfos;
- syminfos = s;
- qemu_free(shdr_table);
- return 0;
- fail:
-#if (SZ == 64)
- qemu_free(syms32);
-#endif
- qemu_free(syms);
- qemu_free(str);
- qemu_free(shdr_table);
- return -1;
-}
-
-int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
- int must_swab, uint64_t *pentry)
-{
- struct elfhdr ehdr;
- struct elf_phdr *phdr = NULL, *ph;
- int size, i, total_size;
- elf_word mem_size, addr;
- uint8_t *data = NULL;
-
- if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
- goto fail;
- if (must_swab) {
- glue(bswap_ehdr, SZ)(&ehdr);
- }
-
- if (ELF_MACHINE != ehdr.e_machine)
- goto fail;
-
- if (pentry)
- *pentry = (uint64_t)ehdr.e_entry;
-
- glue(load_symbols, SZ)(&ehdr, fd, must_swab);
-
- size = ehdr.e_phnum * sizeof(phdr[0]);
- lseek(fd, ehdr.e_phoff, SEEK_SET);
- phdr = qemu_mallocz(size);
- if (!phdr)
- goto fail;
- if (read(fd, phdr, size) != size)
- goto fail;
- if (must_swab) {
- for(i = 0; i < ehdr.e_phnum; i++) {
- ph = &phdr[i];
- glue(bswap_phdr, SZ)(ph);
- }
- }
-
- total_size = 0;
- for(i = 0; i < ehdr.e_phnum; i++) {
- ph = &phdr[i];
- if (ph->p_type == PT_LOAD) {
- mem_size = ph->p_memsz;
- /* XXX: avoid allocating */
- data = qemu_mallocz(mem_size);
- if (ph->p_filesz > 0) {
- if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
- goto fail;
- if (read(fd, data, ph->p_filesz) != ph->p_filesz)
- goto fail;
- }
- addr = ph->p_vaddr + virt_to_phys_addend;
-
- cpu_physical_memory_write_rom(addr, data, mem_size);
-
- total_size += mem_size;
-
- qemu_free(data);
- data = NULL;
- }
- }
- qemu_free(phdr);
- return total_size;
- fail:
- qemu_free(data);
- qemu_free(phdr);
- return -1;
-}
diff --git a/tools/ioemu/exec-all.h b/tools/ioemu/exec-all.h
deleted file mode 100644
index 28c120d4ca..0000000000
--- a/tools/ioemu/exec-all.h
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * internal execution defines for qemu
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* allow to see translation results - the slowdown should be negligible, so we leave it */
-#define DEBUG_DISAS
-
-#ifndef glue
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-#endif
-
-#if __GNUC__ < 3
-#define __builtin_expect(x, n) (x)
-#endif
-
-#ifdef __i386__
-#define REGPARM(n) __attribute((regparm(n)))
-#else
-#define REGPARM(n)
-#endif
-
-/* is_jmp field values */
-#define DISAS_NEXT 0 /* next instruction can be analyzed */
-#define DISAS_JUMP 1 /* only pc was modified dynamically */
-#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
-
-struct TranslationBlock;
-
-/* XXX: make safe guess about sizes */
-#define MAX_OP_PER_INSTR 32
-#define OPC_BUF_SIZE 512
-#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
-
-#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3)
-
-extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
-extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
-extern long gen_labels[OPC_BUF_SIZE];
-extern int nb_gen_labels;
-extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
-extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
-extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
-extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-extern target_ulong gen_opc_jump_pc[2];
-extern uint32_t gen_opc_hflags[OPC_BUF_SIZE];
-
-typedef void (GenOpFunc)(void);
-typedef void (GenOpFunc1)(long);
-typedef void (GenOpFunc2)(long, long);
-typedef void (GenOpFunc3)(long, long, long);
-
-#if defined(TARGET_I386)
-
-void optimize_flags_init(void);
-
-#endif
-
-extern FILE *logfile;
-extern int loglevel;
-
-int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
-int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
-void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
-int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
- int max_code_size, int *gen_code_size_ptr);
-int cpu_restore_state(struct TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc);
-int cpu_gen_code_copy(CPUState *env, struct TranslationBlock *tb,
- int max_code_size, int *gen_code_size_ptr);
-int cpu_restore_state_copy(struct TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc);
-void cpu_resume_from_signal(CPUState *env1, void *puc);
-void cpu_exec_init(CPUState *env);
-int page_unprotect(target_ulong address, unsigned long pc, void *puc);
-void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
- int is_cpu_write_access);
-void tb_invalidate_page_range(target_ulong start, target_ulong end);
-void tlb_flush_page(CPUState *env, target_ulong addr);
-void tlb_flush(CPUState *env, int flush_global);
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int is_user, int is_softmmu);
-static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int is_user, int is_softmmu)
-{
- if (prot & PAGE_READ)
- prot |= PAGE_EXEC;
- return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
-}
-
-#define CODE_GEN_MAX_SIZE 65536
-#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
-
-#define CODE_GEN_PHYS_HASH_BITS 15
-#define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS)
-
-/* maximum total translate dcode allocated */
-
-/* NOTE: the translated code area cannot be too big because on some
- archs the range of "fast" function calls is limited. Here is a
- summary of the ranges:
-
- i386 : signed 32 bits
- arm : signed 26 bits
- ppc : signed 24 bits
- sparc : signed 32 bits
- alpha : signed 23 bits
-*/
-
-#if defined(__alpha__)
-#define CODE_GEN_BUFFER_SIZE (2 * 1024 * 1024)
-#elif defined(__ia64)
-#define CODE_GEN_BUFFER_SIZE (4 * 1024 * 1024) /* range of addl */
-#elif defined(__powerpc__)
-#define CODE_GEN_BUFFER_SIZE (6 * 1024 * 1024)
-#else
-#define CODE_GEN_BUFFER_SIZE (16 * 1024 * 1024)
-#endif
-
-//#define CODE_GEN_BUFFER_SIZE (128 * 1024)
-
-/* estimated block size for TB allocation */
-/* XXX: use a per code average code fragment size and modulate it
- according to the host CPU */
-#if defined(CONFIG_SOFTMMU)
-#define CODE_GEN_AVG_BLOCK_SIZE 128
-#else
-#define CODE_GEN_AVG_BLOCK_SIZE 64
-#endif
-
-#define CODE_GEN_MAX_BLOCKS (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)
-
-#if defined(__powerpc__)
-#define USE_DIRECT_JUMP
-#endif
-#if defined(__i386__) && !defined(_WIN32)
-#define USE_DIRECT_JUMP
-#endif
-
-typedef struct TranslationBlock {
- target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */
- target_ulong cs_base; /* CS base for this block */
- unsigned int flags; /* flags defining in which context the code was generated */
- uint16_t size; /* size of target code for this block (1 <=
- size <= TARGET_PAGE_SIZE) */
- uint16_t cflags; /* compile flags */
-#define CF_CODE_COPY 0x0001 /* block was generated in code copy mode */
-#define CF_TB_FP_USED 0x0002 /* fp ops are used in the TB */
-#define CF_FP_USED 0x0004 /* fp ops are used in the TB or in a chained TB */
-#define CF_SINGLE_INSN 0x0008 /* compile only a single instruction */
-
- uint8_t *tc_ptr; /* pointer to the translated code */
- /* next matching tb for physical address. */
- struct TranslationBlock *phys_hash_next;
- /* first and second physical page containing code. The lower bit
- of the pointer tells the index in page_next[] */
- struct TranslationBlock *page_next[2];
- target_ulong page_addr[2];
-
- /* the following data are used to directly call another TB from
- the code of this one. */
- uint16_t tb_next_offset[2]; /* offset of original jump target */
-#ifdef USE_DIRECT_JUMP
- uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
-#else
- uint32_t tb_next[2]; /* address of jump generated code */
-#endif
- /* list of TBs jumping to this one. This is a circular list using
- the two least significant bits of the pointers to tell what is
- the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
- jmp_first */
- struct TranslationBlock *jmp_next[2];
- struct TranslationBlock *jmp_first;
-} TranslationBlock;
-
-static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
-{
- target_ulong tmp;
- tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
- return (tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK;
-}
-
-static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
-{
- target_ulong tmp;
- tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
- return (((tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK) |
- (tmp & TB_JMP_ADDR_MASK));
-}
-
-static inline unsigned int tb_phys_hash_func(unsigned long pc)
-{
- return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
-}
-
-TranslationBlock *tb_alloc(target_ulong pc);
-void tb_flush(CPUState *env);
-void tb_link_phys(TranslationBlock *tb,
- target_ulong phys_pc, target_ulong phys_page2);
-
-extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-
-extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
-extern uint8_t *code_gen_ptr;
-
-#if defined(USE_DIRECT_JUMP)
-
-#if defined(__powerpc__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
-{
- uint32_t val, *ptr;
-
- /* patch the branch destination */
- ptr = (uint32_t *)jmp_addr;
- val = *ptr;
- val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc);
- *ptr = val;
- /* flush icache */
- asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("icbi 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
-#elif defined(__i386__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
-{
- /* patch the branch destination */
- *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
- /* no need to flush icache explicitely */
-}
-#endif
-
-static inline void tb_set_jmp_target(TranslationBlock *tb,
- int n, unsigned long addr)
-{
- unsigned long offset;
-
- offset = tb->tb_jmp_offset[n];
- tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
- offset = tb->tb_jmp_offset[n + 2];
- if (offset != 0xffff)
- tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
-}
-
-#else
-
-/* set the jump target */
-static inline void tb_set_jmp_target(TranslationBlock *tb,
- int n, unsigned long addr)
-{
- tb->tb_next[n] = addr;
-}
-
-#endif
-
-static inline void tb_add_jump(TranslationBlock *tb, int n,
- TranslationBlock *tb_next)
-{
- /* NOTE: this test is only needed for thread safety */
- if (!tb->jmp_next[n]) {
- /* patch the native jump address */
- tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
-
- /* add in TB jmp circular list */
- tb->jmp_next[n] = tb_next->jmp_first;
- tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
- }
-}
-
-TranslationBlock *tb_find_pc(unsigned long pc_ptr);
-
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-#if defined(_WIN32)
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".section .text\n"
-#elif defined(__APPLE__)
-#define ASM_DATA_SECTION ".data\n"
-#define ASM_PREVIOUS_SECTION ".text\n"
-#else
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".previous\n"
-#endif
-
-#define ASM_OP_LABEL_NAME(n, opname) \
- ASM_NAME(__op_label) #n "." ASM_NAME(opname)
-
-#if defined(__powerpc__)
-
-/* we patch the jump instruction directly */
-#define GOTO_TB(opname, tbparam, n)\
-do {\
- asm volatile (ASM_DATA_SECTION\
- ASM_OP_LABEL_NAME(n, opname) ":\n"\
- ".long 1f\n"\
- ASM_PREVIOUS_SECTION \
- "b " ASM_NAME(__op_jmp) #n "\n"\
- "1:\n");\
-} while (0)
-
-#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
-
-/* we patch the jump instruction directly */
-#define GOTO_TB(opname, tbparam, n)\
-do {\
- asm volatile (".section .data\n"\
- ASM_OP_LABEL_NAME(n, opname) ":\n"\
- ".long 1f\n"\
- ASM_PREVIOUS_SECTION \
- "jmp " ASM_NAME(__op_jmp) #n "\n"\
- "1:\n");\
-} while (0)
-
-#else
-
-/* jump to next block operations (more portable code, does not need
- cache flushing, but slower because of indirect jump) */
-#define GOTO_TB(opname, tbparam, n)\
-do {\
- static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
- static void __attribute__((unused)) *__op_label ## n \
- __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
- goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
-label ## n: ;\
-dummy_label ## n: ;\
-} while (0)
-
-#endif
-
-extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-
-#ifdef __powerpc__
-static inline int testandset (int *p)
-{
- int ret;
- __asm__ __volatile__ (
- "0: lwarx %0,0,%1\n"
- " xor. %0,%3,%0\n"
- " bne 1f\n"
- " stwcx. %2,0,%1\n"
- " bne- 0b\n"
- "1: "
- : "=&r" (ret)
- : "r" (p), "r" (1), "r" (0)
- : "cr0", "memory");
- return ret;
-}
-#endif
-
-#ifdef __i386__
-static inline int testandset (int *p)
-{
- long int readval = 0;
-
- __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
- : "+m" (*p), "+a" (readval)
- : "r" (1)
- : "cc");
- return readval;
-}
-#endif
-
-#ifdef __x86_64__
-static inline int testandset (int *p)
-{
- long int readval = 0;
-
- __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
- : "+m" (*p), "+a" (readval)
- : "r" (1)
- : "cc");
- return readval;
-}
-#endif
-
-#ifdef __s390__
-static inline int testandset (int *p)
-{
- int ret;
-
- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
- " jl 0b"
- : "=&d" (ret)
- : "r" (1), "a" (p), "0" (*p)
- : "cc", "memory" );
- return ret;
-}
-#endif
-
-#ifdef __alpha__
-static inline int testandset (int *p)
-{
- int ret;
- unsigned long one;
-
- __asm__ __volatile__ ("0: mov 1,%2\n"
- " ldl_l %0,%1\n"
- " stl_c %2,%1\n"
- " beq %2,1f\n"
- ".subsection 2\n"
- "1: br 0b\n"
- ".previous"
- : "=r" (ret), "=m" (*p), "=r" (one)
- : "m" (*p));
- return ret;
-}
-#endif
-
-#ifdef __sparc__
-static inline int testandset (int *p)
-{
- int ret;
-
- __asm__ __volatile__("ldstub [%1], %0"
- : "=r" (ret)
- : "r" (p)
- : "memory");
-
- return (ret ? 1 : 0);
-}
-#endif
-
-#ifdef __arm__
-static inline int testandset (int *spinlock)
-{
- register unsigned int ret;
- __asm__ __volatile__("swp %0, %1, [%2]"
- : "=r"(ret)
- : "0"(1), "r"(spinlock));
-
- return ret;
-}
-#endif
-
-#ifdef __mc68000
-static inline int testandset (int *p)
-{
- char ret;
- __asm__ __volatile__("tas %1; sne %0"
- : "=r" (ret)
- : "m" (p)
- : "cc","memory");
- return ret;
-}
-#endif
-
-#ifdef __ia64
-#include <ia64intrin.h>
-
-static inline int testandset (int *p)
-{
- return __sync_lock_test_and_set (p, 1);
-}
-#endif
-
-#ifdef CONFIG_STUBDOM
-#include <spinlock.h>
-#else
-typedef int spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED 0
-
-#if defined(CONFIG_USER_ONLY)
-static inline void spin_lock(spinlock_t *lock)
-{
- while (testandset(lock));
-}
-
-static inline void spin_unlock(spinlock_t *lock)
-{
- *lock = 0;
-}
-
-static inline int spin_trylock(spinlock_t *lock)
-{
- return !testandset(lock);
-}
-#else
-static inline void spin_lock(spinlock_t *lock)
-{
-}
-
-static inline void spin_unlock(spinlock_t *lock)
-{
-}
-
-static inline int spin_trylock(spinlock_t *lock)
-{
- return 1;
-}
-#endif
-#endif
-
-extern spinlock_t tb_lock;
-
-extern int tb_invalidated_flag;
-
-#if !defined(CONFIG_USER_ONLY) && !defined(CONFIG_DM)
-
-void tlb_fill(target_ulong addr, int is_write, int is_user,
- void *retaddr);
-
-#define ACCESS_TYPE 3
-#define MEMSUFFIX _code
-#define env cpu_single_env
-
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-#undef env
-
-#endif
-
-#if defined(CONFIG_USER_ONLY) || defined(CONFIG_DM)
-static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-#else
-/* NOTE: this function can trigger an exception */
-/* NOTE2: the returned address is not exactly the physical address: it
- is the offset relative to phys_ram_base */
-static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
-{
- int is_user, index, pd;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-#if defined(TARGET_I386)
- is_user = ((env->hflags & HF_CPL_MASK) == 3);
-#elif defined (TARGET_PPC)
- is_user = msr_pr;
-#elif defined (TARGET_MIPS)
- is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
-#elif defined (TARGET_SPARC)
- is_user = (env->psrs == 0);
-#elif defined (TARGET_ARM)
- is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
-#elif defined (TARGET_SH4)
- is_user = ((env->sr & SR_MD) == 0);
-#else
-#error unimplemented CPU
-#endif
- if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
- (addr & TARGET_PAGE_MASK), 0)) {
- ldub_code(addr);
- }
- pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
- if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
- cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr);
- }
- return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
-}
-#endif
-
-
-#ifdef USE_KQEMU
-#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
-
-int kqemu_init(CPUState *env);
-int kqemu_cpu_exec(CPUState *env);
-void kqemu_flush_page(CPUState *env, target_ulong addr);
-void kqemu_flush(CPUState *env, int global);
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
-void kqemu_cpu_interrupt(CPUState *env);
-void kqemu_record_dump(void);
-
-static inline int kqemu_is_ok(CPUState *env)
-{
- return(env->kqemu_enabled &&
- (env->cr[0] & CR0_PE_MASK) &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
- (env->eflags & IF_MASK) &&
- !(env->eflags & VM_MASK) &&
- (env->kqemu_enabled == 2 ||
- ((env->hflags & HF_CPL_MASK) == 3 &&
- (env->eflags & IOPL_MASK) != IOPL_MASK)));
-}
-
-#endif
diff --git a/tools/ioemu/exec.c b/tools/ioemu/exec.c
deleted file mode 100644
index ae2d825da3..0000000000
--- a/tools/ioemu/exec.c
+++ /dev/null
@@ -1,2411 +0,0 @@
-/*
- * virtual page mapping and translated block handling
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <sys/types.h>
-#include <sys/mman.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#if defined(CONFIG_USER_ONLY)
-#include <qemu.h>
-#endif
-
-//#define DEBUG_TB_INVALIDATE
-//#define DEBUG_FLUSH
-//#define DEBUG_TLB
-//#define DEBUG_UNASSIGNED
-
-/* make various TB consistency checks */
-//#define DEBUG_TB_CHECK
-//#define DEBUG_TLB_CHECK
-
-#if !defined(CONFIG_USER_ONLY)
-/* TB consistency checks only implemented for usermode emulation. */
-#undef DEBUG_TB_CHECK
-#endif
-
-/* threshold to flush the translated code buffer */
-#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
-
-#define SMC_BITMAP_USE_THRESHOLD 10
-
-#define MMAP_AREA_START 0x00000000
-#define MMAP_AREA_END 0xa8000000
-
-#if defined(TARGET_SPARC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 41
-#elif defined(TARGET_PPC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#else
-/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#endif
-
-TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
-TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-int nb_tbs;
-/* any access to the tbs or the page table must use this lock */
-spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
-
-uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32)));
-uint8_t *code_gen_ptr;
-
-int phys_ram_size;
-int phys_ram_fd;
-uint8_t *phys_ram_base;
-uint8_t *phys_ram_dirty;
-
-CPUState *first_cpu;
-/* current CPU in the current thread. It is only valid inside
- cpu_exec() */
-CPUState *cpu_single_env;
-
-typedef struct PageDesc {
- /* list of TBs intersecting this ram page */
- TranslationBlock *first_tb;
- /* in order to optimize self modifying code, we count the number
- of lookups we do to a given page to use a bitmap */
- unsigned int code_write_count;
- uint8_t *code_bitmap;
-#if defined(CONFIG_USER_ONLY)
- unsigned long flags;
-#endif
-} PageDesc;
-
-typedef struct PhysPageDesc {
- /* offset in host memory of the page + io_index in the low 12 bits */
- uint32_t phys_offset;
-} PhysPageDesc;
-
-#define L2_BITS 10
-#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
-
-#define L1_SIZE (1 << L1_BITS)
-#define L2_SIZE (1 << L2_BITS)
-
-static void io_mem_init(void);
-
-unsigned long qemu_real_host_page_size;
-unsigned long qemu_host_page_bits;
-unsigned long qemu_host_page_size;
-unsigned long qemu_host_page_mask;
-
-/* XXX: for system emulation, it could just be an array */
-static PageDesc *l1_map[L1_SIZE];
-PhysPageDesc **l1_phys_map;
-
-/* io memory support */
-CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb;
-
-/* log support */
-char *logfilename = "/tmp/qemu.log";
-FILE *logfile;
-int loglevel;
-
-/* statistics */
-static int tlb_flush_count;
-static int tb_flush_count;
-static int tb_phys_invalidate_count;
-
-static void page_init(void)
-{
- /* NOTE: we can always suppose that qemu_host_page_size >=
- TARGET_PAGE_SIZE */
-#ifdef _WIN32
- {
- SYSTEM_INFO system_info;
- DWORD old_protect;
-
- GetSystemInfo(&system_info);
- qemu_real_host_page_size = system_info.dwPageSize;
-
- VirtualProtect(code_gen_buffer, sizeof(code_gen_buffer),
- PAGE_EXECUTE_READWRITE, &old_protect);
- }
-#else
- qemu_real_host_page_size = getpagesize();
- {
- unsigned long start, end;
-
- start = (unsigned long)code_gen_buffer;
- start &= ~(qemu_real_host_page_size - 1);
-
- end = (unsigned long)code_gen_buffer + sizeof(code_gen_buffer);
- end += qemu_real_host_page_size - 1;
- end &= ~(qemu_real_host_page_size - 1);
-
- mprotect((void *)start, end - start,
- PROT_READ | PROT_WRITE | PROT_EXEC);
- }
-#endif
-
- if (qemu_host_page_size == 0)
- qemu_host_page_size = qemu_real_host_page_size;
- if (qemu_host_page_size < TARGET_PAGE_SIZE)
- qemu_host_page_size = TARGET_PAGE_SIZE;
- qemu_host_page_bits = 0;
- while ((1 << qemu_host_page_bits) < qemu_host_page_size)
- qemu_host_page_bits++;
- qemu_host_page_mask = ~(qemu_host_page_size - 1);
- l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
- memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
-}
-
-static inline PageDesc *page_find_alloc(unsigned int index)
-{
- PageDesc **lp, *p;
-
- lp = &l1_map[index >> L2_BITS];
- p = *lp;
- if (!p) {
- /* allocate if not found */
- p = qemu_malloc(sizeof(PageDesc) * L2_SIZE);
- memset(p, 0, sizeof(PageDesc) * L2_SIZE);
- *lp = p;
- }
- return p + (index & (L2_SIZE - 1));
-}
-
-static inline PageDesc *page_find(unsigned int index)
-{
- PageDesc *p;
-
- p = l1_map[index >> L2_BITS];
- if (!p)
- return 0;
- return p + (index & (L2_SIZE - 1));
-}
-
-static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
-{
- void **lp, **p;
- PhysPageDesc *pd;
-
- p = (void **)l1_phys_map;
-#if TARGET_PHYS_ADDR_SPACE_BITS > 32
-
-#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
-#error unsupported TARGET_PHYS_ADDR_SPACE_BITS
-#endif
- lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
- p = *lp;
- if (!p) {
- /* allocate if not found */
- if (!alloc)
- return NULL;
- p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
- memset(p, 0, sizeof(void *) * L1_SIZE);
- *lp = p;
- }
-#endif
- lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
- pd = *lp;
- if (!pd) {
- int i;
- /* allocate if not found */
- if (!alloc)
- return NULL;
- pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
- *lp = pd;
- for (i = 0; i < L2_SIZE; i++)
- pd[i].phys_offset = IO_MEM_UNASSIGNED;
- }
- return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
-}
-
-static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
-{
- return phys_page_find_alloc(index, 0);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void tlb_protect_code(ram_addr_t ram_addr);
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
- target_ulong vaddr);
-#endif
-
-void cpu_exec_init(CPUState *env)
-{
- CPUState **penv;
- int cpu_index;
-
- if (!code_gen_ptr) {
- code_gen_ptr = code_gen_buffer;
- page_init();
- io_mem_init();
- }
- env->next_cpu = NULL;
- penv = &first_cpu;
- cpu_index = 0;
- while (*penv != NULL) {
- penv = (CPUState **)&(*penv)->next_cpu;
- cpu_index++;
- }
- env->cpu_index = cpu_index;
- *penv = env;
-}
-
-static inline void invalidate_page_bitmap(PageDesc *p)
-{
- if (p->code_bitmap) {
- qemu_free(p->code_bitmap);
- p->code_bitmap = NULL;
- }
- p->code_write_count = 0;
-}
-
-/* set to NULL all the 'first_tb' fields in all PageDescs */
-static void page_flush_tb(void)
-{
- int i, j;
- PageDesc *p;
-
- for(i = 0; i < L1_SIZE; i++) {
- p = l1_map[i];
- if (p) {
- for(j = 0; j < L2_SIZE; j++) {
- p->first_tb = NULL;
- invalidate_page_bitmap(p);
- p++;
- }
- }
- }
-}
-
-/* flush all the translation blocks */
-/* XXX: tb_flush is currently not thread safe */
-void tb_flush(CPUState *env1)
-{
- CPUState *env;
-#if defined(DEBUG_FLUSH)
- printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
- code_gen_ptr - code_gen_buffer,
- nb_tbs,
- nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
-#endif
- nb_tbs = 0;
-
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
- }
-
- memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
- page_flush_tb();
-
- code_gen_ptr = code_gen_buffer;
- /* XXX: flush processor icache at this point if cache flush is
- expensive */
- tb_flush_count++;
-}
-
-#ifdef DEBUG_TB_CHECK
-
-static void tb_invalidate_check(unsigned long address)
-{
- TranslationBlock *tb;
- int i;
- address &= TARGET_PAGE_MASK;
- for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
- for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
- if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
- address >= tb->pc + tb->size)) {
- printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
- address, (long)tb->pc, tb->size);
- }
- }
- }
-}
-
-/* verify that all the pages have correct rights for code */
-static void tb_page_check(void)
-{
- TranslationBlock *tb;
- int i, flags1, flags2;
-
- for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
- for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
- flags1 = page_get_flags(tb->pc);
- flags2 = page_get_flags(tb->pc + tb->size - 1);
- if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
- printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
- (long)tb->pc, tb->size, flags1, flags2);
- }
- }
- }
-}
-
-void tb_jmp_check(TranslationBlock *tb)
-{
- TranslationBlock *tb1;
- unsigned int n1;
-
- /* suppress any remaining jumps to this TB */
- tb1 = tb->jmp_first;
- for(;;) {
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == 2)
- break;
- tb1 = tb1->jmp_next[n1];
- }
- /* check end of list */
- if (tb1 != tb) {
- printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
- }
-}
-
-#endif
-
-/* invalidate one TB */
-static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
- int next_offset)
-{
- TranslationBlock *tb1;
- for(;;) {
- tb1 = *ptb;
- if (tb1 == tb) {
- *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);
- break;
- }
- ptb = (TranslationBlock **)((char *)tb1 + next_offset);
- }
-}
-
-static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
-{
- TranslationBlock *tb1;
- unsigned int n1;
-
- for(;;) {
- tb1 = *ptb;
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (tb1 == tb) {
- *ptb = tb1->page_next[n1];
- break;
- }
- ptb = &tb1->page_next[n1];
- }
-}
-
-static inline void tb_jmp_remove(TranslationBlock *tb, int n)
-{
- TranslationBlock *tb1, **ptb;
- unsigned int n1;
-
- ptb = &tb->jmp_next[n];
- tb1 = *ptb;
- if (tb1) {
- /* find tb(n) in circular list */
- for(;;) {
- tb1 = *ptb;
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == n && tb1 == tb)
- break;
- if (n1 == 2) {
- ptb = &tb1->jmp_first;
- } else {
- ptb = &tb1->jmp_next[n1];
- }
- }
- /* now we can suppress tb(n) from the list */
- *ptb = tb->jmp_next[n];
-
- tb->jmp_next[n] = NULL;
- }
-}
-
-/* reset the jump entry 'n' of a TB so that it is not chained to
- another TB */
-static inline void tb_reset_jump(TranslationBlock *tb, int n)
-{
- tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
-}
-
-static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
-{
- CPUState *env;
- PageDesc *p;
- unsigned int h, n1;
- target_ulong phys_pc;
- TranslationBlock *tb1, *tb2;
-
- /* remove the TB from the hash list */
- phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
- h = tb_phys_hash_func(phys_pc);
- tb_remove(&tb_phys_hash[h], tb,
- offsetof(TranslationBlock, phys_hash_next));
-
- /* remove the TB from the page list */
- if (tb->page_addr[0] != page_addr) {
- p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
- tb_page_remove(&p->first_tb, tb);
- invalidate_page_bitmap(p);
- }
- if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
- p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
- tb_page_remove(&p->first_tb, tb);
- invalidate_page_bitmap(p);
- }
-
- tb_invalidated_flag = 1;
-
- /* remove the TB from the hash list */
- h = tb_jmp_cache_hash_func(tb->pc);
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- if (env->tb_jmp_cache[h] == tb)
- env->tb_jmp_cache[h] = NULL;
- }
-
- /* suppress this TB from the two jump lists */
- tb_jmp_remove(tb, 0);
- tb_jmp_remove(tb, 1);
-
- /* suppress any remaining jumps to this TB */
- tb1 = tb->jmp_first;
- for(;;) {
- n1 = (long)tb1 & 3;
- if (n1 == 2)
- break;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- tb2 = tb1->jmp_next[n1];
- tb_reset_jump(tb1, n1);
- tb1->jmp_next[n1] = NULL;
- tb1 = tb2;
- }
- tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
-
- tb_phys_invalidate_count++;
-}
-
-static inline void set_bits(uint8_t *tab, int start, int len)
-{
- int end, mask, end1;
-
- end = start + len;
- tab += start >> 3;
- mask = 0xff << (start & 7);
- if ((start & ~7) == (end & ~7)) {
- if (start < end) {
- mask &= ~(0xff << (end & 7));
- *tab |= mask;
- }
- } else {
- *tab++ |= mask;
- start = (start + 8) & ~7;
- end1 = end & ~7;
- while (start < end1) {
- *tab++ = 0xff;
- start += 8;
- }
- if (start < end) {
- mask = ~(0xff << (end & 7));
- *tab |= mask;
- }
- }
-}
-
-static void build_page_bitmap(PageDesc *p)
-{
- int n, tb_start, tb_end;
- TranslationBlock *tb;
-
- p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);
- if (!p->code_bitmap)
- return;
- memset(p->code_bitmap, 0, TARGET_PAGE_SIZE / 8);
-
- tb = p->first_tb;
- while (tb != NULL) {
- n = (long)tb & 3;
- tb = (TranslationBlock *)((long)tb & ~3);
- /* NOTE: this is subtle as a TB may span two physical pages */
- if (n == 0) {
- /* NOTE: tb_end may be after the end of the page, but
- it is not a problem */
- tb_start = tb->pc & ~TARGET_PAGE_MASK;
- tb_end = tb_start + tb->size;
- if (tb_end > TARGET_PAGE_SIZE)
- tb_end = TARGET_PAGE_SIZE;
- } else {
- tb_start = 0;
- tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
- }
- set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
- tb = tb->page_next[n];
- }
-}
-
-#ifdef TARGET_HAS_PRECISE_SMC
-
-static void tb_gen_code(CPUState *env,
- target_ulong pc, target_ulong cs_base, int flags,
- int cflags)
-{
- TranslationBlock *tb;
- uint8_t *tc_ptr;
- target_ulong phys_pc, phys_page2, virt_page2;
- int code_gen_size;
-
- phys_pc = get_phys_addr_code(env, pc);
- tb = tb_alloc(pc);
- if (!tb) {
- /* flush must be done */
- tb_flush(env);
- /* cannot fail at this point */
- tb = tb_alloc(pc);
- }
- tc_ptr = code_gen_ptr;
- tb->tc_ptr = tc_ptr;
- tb->cs_base = cs_base;
- tb->flags = flags;
- tb->cflags = cflags;
- cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
- code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-
- /* check next page if needed */
- virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
- phys_page2 = -1;
- if ((pc & TARGET_PAGE_MASK) != virt_page2) {
- phys_page2 = get_phys_addr_code(env, virt_page2);
- }
- tb_link_phys(tb, phys_pc, phys_page2);
-}
-#endif
-
-/* invalidate all TBs which intersect with the target physical page
- starting in range [start;end[. NOTE: start and end must refer to
- the same physical page. 'is_cpu_write_access' should be true if called
- from a real cpu write access: the virtual CPU will exit the current
- TB if code is modified inside this TB. */
-void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
- int is_cpu_write_access)
-{
- int n, current_tb_modified, current_tb_not_found, current_flags;
- CPUState *env = cpu_single_env;
- PageDesc *p;
- TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
- target_ulong tb_start, tb_end;
- target_ulong current_pc, current_cs_base;
-
- p = page_find(start >> TARGET_PAGE_BITS);
- if (!p)
- return;
- if (!p->code_bitmap &&
- ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&
- is_cpu_write_access) {
- /* build code bitmap */
- build_page_bitmap(p);
- }
-
- /* we remove all the TBs in the range [start, end[ */
- /* XXX: see if in some cases it could be faster to invalidate all the code */
- current_tb_not_found = is_cpu_write_access;
- current_tb_modified = 0;
- current_tb = NULL; /* avoid warning */
- current_pc = 0; /* avoid warning */
- current_cs_base = 0; /* avoid warning */
- current_flags = 0; /* avoid warning */
- tb = p->first_tb;
- while (tb != NULL) {
- n = (long)tb & 3;
- tb = (TranslationBlock *)((long)tb & ~3);
- tb_next = tb->page_next[n];
- /* NOTE: this is subtle as a TB may span two physical pages */
- if (n == 0) {
- /* NOTE: tb_end may be after the end of the page, but
- it is not a problem */
- tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
- tb_end = tb_start + tb->size;
- } else {
- tb_start = tb->page_addr[1];
- tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
- }
- if (!(tb_end <= start || tb_start >= end)) {
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb_not_found) {
- current_tb_not_found = 0;
- current_tb = NULL;
- if (env->mem_write_pc) {
- /* now we have a real cpu fault */
- current_tb = tb_find_pc(env->mem_write_pc);
- }
- }
- if (current_tb == tb &&
- !(current_tb->cflags & CF_SINGLE_INSN)) {
- /* If we are modifying the current TB, we must stop
- its execution. We could be more precise by checking
- that the modification is after the current PC, but it
- would require a specialized function to partially
- restore the CPU state */
-
- current_tb_modified = 1;
- cpu_restore_state(current_tb, env,
- env->mem_write_pc, NULL);
-#if defined(TARGET_I386)
- current_flags = env->hflags;
- current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- current_cs_base = (target_ulong)env->segs[R_CS].base;
- current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
- }
-#endif /* TARGET_HAS_PRECISE_SMC */
- /* we need to do that to handle the case where a signal
- occurs while doing tb_phys_invalidate() */
- saved_tb = NULL;
- if (env) {
- saved_tb = env->current_tb;
- env->current_tb = NULL;
- }
- tb_phys_invalidate(tb, -1);
- if (env) {
- env->current_tb = saved_tb;
- if (env->interrupt_request && env->current_tb)
- cpu_interrupt(env, env->interrupt_request);
- }
- }
- tb = tb_next;
- }
-#if !defined(CONFIG_USER_ONLY)
- /* if no code remaining, no need to continue to use slow writes */
- if (!p->first_tb) {
- invalidate_page_bitmap(p);
- if (is_cpu_write_access) {
- tlb_unprotect_code_phys(env, start, env->mem_write_vaddr);
- }
- }
-#endif
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb_modified) {
- /* we generate a block containing just the instruction
- modifying the memory. It will ensure that it cannot modify
- itself */
- env->current_tb = NULL;
- tb_gen_code(env, current_pc, current_cs_base, current_flags,
- CF_SINGLE_INSN);
- cpu_resume_from_signal(env, NULL);
- }
-#endif
-}
-
-/* len must be <= 8 and start must be a multiple of len */
-static inline void tb_invalidate_phys_page_fast(target_ulong start, int len)
-{
- PageDesc *p;
- int offset, b;
-#if 0
- if (1) {
- if (loglevel) {
- fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
- cpu_single_env->mem_write_vaddr, len,
- cpu_single_env->eip,
- cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
- }
- }
-#endif
- p = page_find(start >> TARGET_PAGE_BITS);
- if (!p)
- return;
- if (p->code_bitmap) {
- offset = start & ~TARGET_PAGE_MASK;
- b = p->code_bitmap[offset >> 3] >> (offset & 7);
- if (b & ((1 << len) - 1))
- goto do_invalidate;
- } else {
- do_invalidate:
- tb_invalidate_phys_page_range(start, start + len, 1);
- }
-}
-
-#if !defined(CONFIG_SOFTMMU)
-static void tb_invalidate_phys_page(target_ulong addr,
- unsigned long pc, void *puc)
-{
- int n, current_flags, current_tb_modified;
- target_ulong current_pc, current_cs_base;
- PageDesc *p;
- TranslationBlock *tb, *current_tb;
-#ifdef TARGET_HAS_PRECISE_SMC
- CPUState *env = cpu_single_env;
-#endif
-
- addr &= TARGET_PAGE_MASK;
- p = page_find(addr >> TARGET_PAGE_BITS);
- if (!p)
- return;
- tb = p->first_tb;
- current_tb_modified = 0;
- current_tb = NULL;
- current_pc = 0; /* avoid warning */
- current_cs_base = 0; /* avoid warning */
- current_flags = 0; /* avoid warning */
-#ifdef TARGET_HAS_PRECISE_SMC
- if (tb && pc != 0) {
- current_tb = tb_find_pc(pc);
- }
-#endif
- while (tb != NULL) {
- n = (long)tb & 3;
- tb = (TranslationBlock *)((long)tb & ~3);
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb == tb &&
- !(current_tb->cflags & CF_SINGLE_INSN)) {
- /* If we are modifying the current TB, we must stop
- its execution. We could be more precise by checking
- that the modification is after the current PC, but it
- would require a specialized function to partially
- restore the CPU state */
-
- current_tb_modified = 1;
- cpu_restore_state(current_tb, env, pc, puc);
-#if defined(TARGET_I386)
- current_flags = env->hflags;
- current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- current_cs_base = (target_ulong)env->segs[R_CS].base;
- current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
- }
-#endif /* TARGET_HAS_PRECISE_SMC */
- tb_phys_invalidate(tb, addr);
- tb = tb->page_next[n];
- }
- p->first_tb = NULL;
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb_modified) {
- /* we generate a block containing just the instruction
- modifying the memory. It will ensure that it cannot modify
- itself */
- env->current_tb = NULL;
- tb_gen_code(env, current_pc, current_cs_base, current_flags,
- CF_SINGLE_INSN);
- cpu_resume_from_signal(env, puc);
- }
-#endif
-}
-#endif
-
-/* add the tb in the target page and protect it if necessary */
-static inline void tb_alloc_page(TranslationBlock *tb,
- unsigned int n, target_ulong page_addr)
-{
- PageDesc *p;
- TranslationBlock *last_first_tb;
-
- tb->page_addr[n] = page_addr;
- p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);
- tb->page_next[n] = p->first_tb;
- last_first_tb = p->first_tb;
- p->first_tb = (TranslationBlock *)((long)tb | n);
- invalidate_page_bitmap(p);
-
-#if defined(TARGET_HAS_SMC) || 1
-
-#if defined(CONFIG_USER_ONLY)
- if (p->flags & PAGE_WRITE) {
- target_ulong addr;
- PageDesc *p2;
- int prot;
-
- /* force the host page as non writable (writes will have a
- page fault + mprotect overhead) */
- page_addr &= qemu_host_page_mask;
- prot = 0;
- for(addr = page_addr; addr < page_addr + qemu_host_page_size;
- addr += TARGET_PAGE_SIZE) {
-
- p2 = page_find (addr >> TARGET_PAGE_BITS);
- if (!p2)
- continue;
- prot |= p2->flags;
- p2->flags &= ~PAGE_WRITE;
- page_get_flags(addr);
- }
- mprotect(g2h(page_addr), qemu_host_page_size,
- (prot & PAGE_BITS) & ~PAGE_WRITE);
-#ifdef DEBUG_TB_INVALIDATE
- printf("protecting code page: 0x%08lx\n",
- page_addr);
-#endif
- }
-#else
- /* if some code is already present, then the pages are already
- protected. So we handle the case where only the first TB is
- allocated in a physical page */
- if (!last_first_tb) {
- tlb_protect_code(page_addr);
- }
-#endif
-
-#endif /* TARGET_HAS_SMC */
-}
-
-/* Allocate a new translation block. Flush the translation buffer if
- too many translation blocks or too much generated code. */
-TranslationBlock *tb_alloc(target_ulong pc)
-{
- TranslationBlock *tb;
-
- if (nb_tbs >= CODE_GEN_MAX_BLOCKS ||
- (code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)
- return NULL;
- tb = &tbs[nb_tbs++];
- tb->pc = pc;
- tb->cflags = 0;
- return tb;
-}
-
-/* add a new TB and link it to the physical page tables. phys_page2 is
- (-1) to indicate that only one page contains the TB. */
-void tb_link_phys(TranslationBlock *tb,
- target_ulong phys_pc, target_ulong phys_page2)
-{
- unsigned int h;
- TranslationBlock **ptb;
-
- /* add in the physical hash table */
- h = tb_phys_hash_func(phys_pc);
- ptb = &tb_phys_hash[h];
- tb->phys_hash_next = *ptb;
- *ptb = tb;
-
- /* add in the page list */
- tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
- if (phys_page2 != -1)
- tb_alloc_page(tb, 1, phys_page2);
- else
- tb->page_addr[1] = -1;
-
- tb->jmp_first = (TranslationBlock *)((long)tb | 2);
- tb->jmp_next[0] = NULL;
- tb->jmp_next[1] = NULL;
-#ifdef USE_CODE_COPY
- tb->cflags &= ~CF_FP_USED;
- if (tb->cflags & CF_TB_FP_USED)
- tb->cflags |= CF_FP_USED;
-#endif
-
- /* init original jump addresses */
- if (tb->tb_next_offset[0] != 0xffff)
- tb_reset_jump(tb, 0);
- if (tb->tb_next_offset[1] != 0xffff)
- tb_reset_jump(tb, 1);
-
-#ifdef DEBUG_TB_CHECK
- tb_page_check();
-#endif
-}
-
-/* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
- tb[1].tc_ptr. Return NULL if not found */
-TranslationBlock *tb_find_pc(unsigned long tc_ptr)
-{
- int m_min, m_max, m;
- unsigned long v;
- TranslationBlock *tb;
-
- if (nb_tbs <= 0)
- return NULL;
- if (tc_ptr < (unsigned long)code_gen_buffer ||
- tc_ptr >= (unsigned long)code_gen_ptr)
- return NULL;
- /* binary search (cf Knuth) */
- m_min = 0;
- m_max = nb_tbs - 1;
- while (m_min <= m_max) {
- m = (m_min + m_max) >> 1;
- tb = &tbs[m];
- v = (unsigned long)tb->tc_ptr;
- if (v == tc_ptr)
- return tb;
- else if (tc_ptr < v) {
- m_max = m - 1;
- } else {
- m_min = m + 1;
- }
- }
- return &tbs[m_max];
-}
-
-static void tb_reset_jump_recursive(TranslationBlock *tb);
-
-static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
-{
- TranslationBlock *tb1, *tb_next, **ptb;
- unsigned int n1;
-
- tb1 = tb->jmp_next[n];
- if (tb1 != NULL) {
- /* find head of list */
- for(;;) {
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == 2)
- break;
- tb1 = tb1->jmp_next[n1];
- }
- /* we are now sure now that tb jumps to tb1 */
- tb_next = tb1;
-
- /* remove tb from the jmp_first list */
- ptb = &tb_next->jmp_first;
- for(;;) {
- tb1 = *ptb;
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == n && tb1 == tb)
- break;
- ptb = &tb1->jmp_next[n1];
- }
- *ptb = tb->jmp_next[n];
- tb->jmp_next[n] = NULL;
-
- /* suppress the jump to next tb in generated code */
- tb_reset_jump(tb, n);
-
- /* suppress jumps in the tb on which we could have jumped */
- tb_reset_jump_recursive(tb_next);
- }
-}
-
-static void tb_reset_jump_recursive(TranslationBlock *tb)
-{
- tb_reset_jump_recursive2(tb, 0);
- tb_reset_jump_recursive2(tb, 1);
-}
-
-#if defined(TARGET_HAS_ICE)
-static void breakpoint_invalidate(CPUState *env, target_ulong pc)
-{
- target_ulong addr, pd;
- ram_addr_t ram_addr;
- PhysPageDesc *p;
-
- addr = cpu_get_phys_page_debug(env, pc);
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
- ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);
- tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
-}
-#endif
-
-/* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
- breakpoint is reached */
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
-{
-#if defined(TARGET_HAS_ICE)
- int i;
-
- for(i = 0; i < env->nb_breakpoints; i++) {
- if (env->breakpoints[i] == pc)
- return 0;
- }
-
- if (env->nb_breakpoints >= MAX_BREAKPOINTS)
- return -1;
- env->breakpoints[env->nb_breakpoints++] = pc;
-
- breakpoint_invalidate(env, pc);
- return 0;
-#else
- return -1;
-#endif
-}
-
-/* remove a breakpoint */
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
-{
-#if defined(TARGET_HAS_ICE)
- int i;
- for(i = 0; i < env->nb_breakpoints; i++) {
- if (env->breakpoints[i] == pc)
- goto found;
- }
- return -1;
- found:
- env->nb_breakpoints--;
- if (i < env->nb_breakpoints)
- env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
-
- breakpoint_invalidate(env, pc);
- return 0;
-#else
- return -1;
-#endif
-}
-
-/* enable or disable single step mode. EXCP_DEBUG is returned by the
- CPU loop after each instruction */
-void cpu_single_step(CPUState *env, int enabled)
-{
-#if defined(TARGET_HAS_ICE)
- if (env->singlestep_enabled != enabled) {
- env->singlestep_enabled = enabled;
- /* must flush all the translated code to avoid inconsistancies */
- /* XXX: only flush what is necessary */
- tb_flush(env);
- }
-#endif
-}
-
-/* enable or disable low levels log */
-void cpu_set_log(int log_flags)
-{
- loglevel = log_flags;
- if (loglevel && !logfile) {
- logfile = fopen(logfilename, "w");
- if (!logfile) {
- perror(logfilename);
- _exit(1);
- }
-#if !defined(CONFIG_SOFTMMU)
- /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
- {
- static uint8_t logfile_buf[4096];
- setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
- }
-#else
- setvbuf(logfile, NULL, _IOLBF, 0);
-#endif
- }
-}
-
-void cpu_set_log_filename(const char *filename)
-{
- logfilename = strdup(filename);
-}
-
-/* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
-{
- TranslationBlock *tb;
- static int interrupt_lock;
-
- env->interrupt_request |= mask;
- /* if the cpu is currently executing code, we must unlink it and
- all the potentially executing TB */
- tb = env->current_tb;
- if (tb && !testandset(&interrupt_lock)) {
- env->current_tb = NULL;
- tb_reset_jump_recursive(tb);
- interrupt_lock = 0;
- }
-}
-
-void cpu_reset_interrupt(CPUState *env, int mask)
-{
- env->interrupt_request &= ~mask;
-}
-
-CPULogItem cpu_log_items[] = {
- { CPU_LOG_TB_OUT_ASM, "out_asm",
- "show generated host assembly code for each compiled TB" },
- { CPU_LOG_TB_IN_ASM, "in_asm",
- "show target assembly code for each compiled TB" },
- { CPU_LOG_TB_OP, "op",
- "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
-#ifdef TARGET_I386
- { CPU_LOG_TB_OP_OPT, "op_opt",
- "show micro ops after optimization for each compiled TB" },
-#endif
- { CPU_LOG_INT, "int",
- "show interrupts/exceptions in short format" },
- { CPU_LOG_EXEC, "exec",
- "show trace before each executed TB (lots of logs)" },
- { CPU_LOG_TB_CPU, "cpu",
- "show CPU state before bloc translation" },
-#ifdef TARGET_I386
- { CPU_LOG_PCALL, "pcall",
- "show protected mode far calls/returns/exceptions" },
-#endif
-#ifdef DEBUG_IOPORT
- { CPU_LOG_IOPORT, "ioport",
- "show all i/o ports accesses" },
-#endif
- { 0, NULL, NULL },
-};
-
-static int cmp1(const char *s1, int n, const char *s2)
-{
- if (strlen(s2) != n)
- return 0;
- return memcmp(s1, s2, n) == 0;
-}
-
-/* takes a comma separated list of log masks. Return 0 if error. */
-int cpu_str_to_log_mask(const char *str)
-{
- CPULogItem *item;
- int mask;
- const char *p, *p1;
-
- p = str;
- mask = 0;
- for(;;) {
- p1 = strchr(p, ',');
- if (!p1)
- p1 = p + strlen(p);
- if(cmp1(p,p1-p,"all")) {
- for(item = cpu_log_items; item->mask != 0; item++) {
- mask |= item->mask;
- }
- } else {
- for(item = cpu_log_items; item->mask != 0; item++) {
- if (cmp1(p, p1 - p, item->name))
- goto found;
- }
- return 0;
- }
- found:
- mask |= item->mask;
- if (*p1 != ',')
- break;
- p = p1 + 1;
- }
- return mask;
-}
-
-void cpu_abort(CPUState *env, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "qemu: fatal: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
-#ifdef TARGET_I386
- cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
-#else
- cpu_dump_state(env, stderr, fprintf, 0);
-#endif
- va_end(ap);
- abort();
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-/* NOTE: if flush_global is true, also flush global entries (not
- implemented yet) */
-void tlb_flush(CPUState *env, int flush_global)
-{
- int i;
-
-#if defined(DEBUG_TLB)
- printf("tlb_flush:\n");
-#endif
- /* must reset current TB so that interrupts cannot modify the
- links while we are modifying them */
- env->current_tb = NULL;
-
- for(i = 0; i < CPU_TLB_SIZE; i++) {
- env->tlb_table[0][i].addr_read = -1;
- env->tlb_table[0][i].addr_write = -1;
- env->tlb_table[0][i].addr_code = -1;
- env->tlb_table[1][i].addr_read = -1;
- env->tlb_table[1][i].addr_write = -1;
- env->tlb_table[1][i].addr_code = -1;
- }
-
- memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
-
-#if !defined(CONFIG_SOFTMMU)
- munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
-#endif
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_flush(env, flush_global);
- }
-#endif
- tlb_flush_count++;
-}
-
-static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
-{
- if (addr == (tlb_entry->addr_read &
- (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
- addr == (tlb_entry->addr_write &
- (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
- addr == (tlb_entry->addr_code &
- (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- tlb_entry->addr_read = -1;
- tlb_entry->addr_write = -1;
- tlb_entry->addr_code = -1;
- }
-}
-
-void tlb_flush_page(CPUState *env, target_ulong addr)
-{
- int i;
- TranslationBlock *tb;
-
-#if defined(DEBUG_TLB)
- printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
-#endif
- /* must reset current TB so that interrupts cannot modify the
- links while we are modifying them */
- env->current_tb = NULL;
-
- addr &= TARGET_PAGE_MASK;
- i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- tlb_flush_entry(&env->tlb_table[0][i], addr);
- tlb_flush_entry(&env->tlb_table[1][i], addr);
-
- /* Discard jump cache entries for any tb which might potentially
- overlap the flushed page. */
- i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
- memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
-
- i = tb_jmp_cache_hash_page(addr);
- memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
-
-#if !defined(CONFIG_SOFTMMU)
- if (addr < MMAP_AREA_END)
- munmap((void *)addr, TARGET_PAGE_SIZE);
-#endif
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_flush_page(env, addr);
- }
-#endif
-}
-
-/* update the TLBs so that writes to code in the virtual page 'addr'
- can be detected */
-static void tlb_protect_code(ram_addr_t ram_addr)
-{
- cpu_physical_memory_reset_dirty(ram_addr,
- ram_addr + TARGET_PAGE_SIZE,
- CODE_DIRTY_FLAG);
-}
-
-/* update the TLB so that writes in physical page 'phys_addr' are no longer
- tested for self modifying code */
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
- target_ulong vaddr)
-{
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
-}
-
-static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
- unsigned long start, unsigned long length)
-{
- unsigned long addr;
- if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
- addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
- if ((addr - start) < length) {
- tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
- }
- }
-}
-
-void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
- int dirty_flags)
-{
- CPUState *env;
- unsigned long length, start1;
- int i, mask, len;
- uint8_t *p;
-
- start &= TARGET_PAGE_MASK;
- end = TARGET_PAGE_ALIGN(end);
-
- length = end - start;
- if (length == 0)
- return;
- len = length >> TARGET_PAGE_BITS;
-#ifdef USE_KQEMU
- /* XXX: should not depend on cpu context */
- env = first_cpu;
- if (env->kqemu_enabled) {
- ram_addr_t addr;
- addr = start;
- for(i = 0; i < len; i++) {
- kqemu_set_notdirty(env, addr);
- addr += TARGET_PAGE_SIZE;
- }
- }
-#endif
- mask = ~dirty_flags;
- p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
- for(i = 0; i < len; i++)
- p[i] &= mask;
-
- /* we modify the TLB cache so that the dirty bit will be set again
- when accessing the range */
- start1 = start + (unsigned long)phys_ram_base;
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
- }
-
-#if !defined(CONFIG_SOFTMMU)
- /* XXX: this is expensive */
- {
- VirtPageDesc *p;
- int j;
- target_ulong addr;
-
- for(i = 0; i < L1_SIZE; i++) {
- p = l1_virt_map[i];
- if (p) {
- addr = i << (TARGET_PAGE_BITS + L2_BITS);
- for(j = 0; j < L2_SIZE; j++) {
- if (p->valid_tag == virt_valid_tag &&
- p->phys_addr >= start && p->phys_addr < end &&
- (p->prot & PROT_WRITE)) {
- if (addr < MMAP_AREA_END) {
- mprotect((void *)addr, TARGET_PAGE_SIZE,
- p->prot & ~PROT_WRITE);
- }
- }
- addr += TARGET_PAGE_SIZE;
- p++;
- }
- }
- }
- }
-#endif
-}
-
-static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
-{
- ram_addr_t ram_addr;
-
- if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
- ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
- tlb_entry->addend - (unsigned long)phys_ram_base;
- if (!cpu_physical_memory_is_dirty(ram_addr)) {
- tlb_entry->addr_write |= IO_MEM_NOTDIRTY;
- }
- }
-}
-
-/* update the TLB according to the current state of the dirty bits */
-void cpu_tlb_update_dirty(CPUState *env)
-{
- int i;
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[0][i]);
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[1][i]);
-}
-
-static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
- unsigned long start)
-{
- unsigned long addr;
- if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
- addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
- if (addr == start) {
- tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_RAM;
- }
- }
-}
-
-/* update the TLB corresponding to virtual page vaddr and phys addr
- addr so that it is no longer dirty */
-static inline void tlb_set_dirty(CPUState *env,
- unsigned long addr, target_ulong vaddr)
-{
- int i;
-
- addr &= TARGET_PAGE_MASK;
- i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- tlb_set_dirty1(&env->tlb_table[0][i], addr);
- tlb_set_dirty1(&env->tlb_table[1][i], addr);
-}
-
-/* add a new TLB entry. At most one entry for a given virtual address
- is permitted. Return 0 if OK or 2 if the page could not be mapped
- (can only happen in non SOFTMMU mode for I/O pages or pages
- conflicting with the host address space). */
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int is_user, int is_softmmu)
-{
- PhysPageDesc *p;
- unsigned long pd;
- unsigned int index;
- target_ulong address;
- target_phys_addr_t addend;
- int ret;
- CPUTLBEntry *te;
-
- p = phys_page_find(paddr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-#if defined(DEBUG_TLB)
- printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
- vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
-#endif
-
- ret = 0;
-#if !defined(CONFIG_SOFTMMU)
- if (is_softmmu)
-#endif
- {
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
- /* IO memory case */
- address = vaddr | pd;
- addend = paddr;
- } else {
- /* standard memory */
- address = vaddr;
- addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
- }
-
- index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- addend -= vaddr;
- te = &env->tlb_table[is_user][index];
- te->addend = addend;
- if (prot & PAGE_READ) {
- te->addr_read = address;
- } else {
- te->addr_read = -1;
- }
- if (prot & PAGE_EXEC) {
- te->addr_code = address;
- } else {
- te->addr_code = -1;
- }
- if (prot & PAGE_WRITE) {
- if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
- (pd & IO_MEM_ROMD)) {
- /* write access calls the I/O callback */
- te->addr_write = vaddr |
- (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
- } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
- !cpu_physical_memory_is_dirty(pd)) {
- te->addr_write = vaddr | IO_MEM_NOTDIRTY;
- } else {
- te->addr_write = address;
- }
- } else {
- te->addr_write = -1;
- }
- }
-#if !defined(CONFIG_SOFTMMU)
- else {
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
- /* IO access: no mapping is done as it will be handled by the
- soft MMU */
- if (!(env->hflags & HF_SOFTMMU_MASK))
- ret = 2;
- } else {
- void *map_addr;
-
- if (vaddr >= MMAP_AREA_END) {
- ret = 2;
- } else {
- if (prot & PROT_WRITE) {
- if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
-#if defined(TARGET_HAS_SMC) || 1
- first_tb ||
-#endif
- ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
- !cpu_physical_memory_is_dirty(pd))) {
- /* ROM: we do as if code was inside */
- /* if code is present, we only map as read only and save the
- original mapping */
- VirtPageDesc *vp;
-
- vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1);
- vp->phys_addr = pd;
- vp->prot = prot;
- vp->valid_tag = virt_valid_tag;
- prot &= ~PAGE_WRITE;
- }
- }
- map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot,
- MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK));
- if (map_addr == MAP_FAILED) {
- cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
- paddr, vaddr);
- }
- }
- }
- }
-#endif
- return ret;
-}
-
-/* called from signal handler: invalidate the code and unprotect the
- page. Return TRUE if the fault was succesfully handled. */
-int page_unprotect(target_ulong addr, unsigned long pc, void *puc)
-{
-#if !defined(CONFIG_SOFTMMU)
- VirtPageDesc *vp;
-
-#if defined(DEBUG_TLB)
- printf("page_unprotect: addr=0x%08x\n", addr);
-#endif
- addr &= TARGET_PAGE_MASK;
-
- /* if it is not mapped, no need to worry here */
- if (addr >= MMAP_AREA_END)
- return 0;
- vp = virt_page_find(addr >> TARGET_PAGE_BITS);
- if (!vp)
- return 0;
- /* NOTE: in this case, validate_tag is _not_ tested as it
- validates only the code TLB */
- if (vp->valid_tag != virt_valid_tag)
- return 0;
- if (!(vp->prot & PAGE_WRITE))
- return 0;
-#if defined(DEBUG_TLB)
- printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n",
- addr, vp->phys_addr, vp->prot);
-#endif
- if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0)
- cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
- (unsigned long)addr, vp->prot);
- /* set the dirty bit */
- phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff;
- /* flush the code inside */
- tb_invalidate_phys_page(vp->phys_addr, pc, puc);
- return 1;
-#else
- return 0;
-#endif
-}
-
-#else
-
-void tlb_flush(CPUState *env, int flush_global)
-{
-}
-
-void tlb_flush_page(CPUState *env, target_ulong addr)
-{
-}
-
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int is_user, int is_softmmu)
-{
- return 0;
-}
-
-/* dump memory mappings */
-void page_dump(FILE *f)
-{
- unsigned long start, end;
- int i, j, prot, prot1;
- PageDesc *p;
-
- fprintf(f, "%-8s %-8s %-8s %s\n",
- "start", "end", "size", "prot");
- start = -1;
- end = -1;
- prot = 0;
- for(i = 0; i <= L1_SIZE; i++) {
- if (i < L1_SIZE)
- p = l1_map[i];
- else
- p = NULL;
- for(j = 0;j < L2_SIZE; j++) {
- if (!p)
- prot1 = 0;
- else
- prot1 = p[j].flags;
- if (prot1 != prot) {
- end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
- if (start != -1) {
- fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
- start, end, end - start,
- prot & PAGE_READ ? 'r' : '-',
- prot & PAGE_WRITE ? 'w' : '-',
- prot & PAGE_EXEC ? 'x' : '-');
- }
- if (prot1 != 0)
- start = end;
- else
- start = -1;
- prot = prot1;
- }
- if (!p)
- break;
- }
- }
-}
-
-int page_get_flags(target_ulong address)
-{
- PageDesc *p;
-
- p = page_find(address >> TARGET_PAGE_BITS);
- if (!p)
- return 0;
- return p->flags;
-}
-
-/* modify the flags of a page and invalidate the code if
- necessary. The flag PAGE_WRITE_ORG is positionned automatically
- depending on PAGE_WRITE */
-void page_set_flags(target_ulong start, target_ulong end, int flags)
-{
- PageDesc *p;
- target_ulong addr;
-
- start = start & TARGET_PAGE_MASK;
- end = TARGET_PAGE_ALIGN(end);
- if (flags & PAGE_WRITE)
- flags |= PAGE_WRITE_ORG;
- spin_lock(&tb_lock);
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
- p = page_find_alloc(addr >> TARGET_PAGE_BITS);
- /* if the write protection is set, then we invalidate the code
- inside */
- if (!(p->flags & PAGE_WRITE) &&
- (flags & PAGE_WRITE) &&
- p->first_tb) {
- tb_invalidate_phys_page(addr, 0, NULL);
- }
- p->flags = flags;
- }
- spin_unlock(&tb_lock);
-}
-
-/* called from signal handler: invalidate the code and unprotect the
- page. Return TRUE if the fault was succesfully handled. */
-int page_unprotect(target_ulong address, unsigned long pc, void *puc)
-{
- unsigned int page_index, prot, pindex;
- PageDesc *p, *p1;
- target_ulong host_start, host_end, addr;
-
- host_start = address & qemu_host_page_mask;
- page_index = host_start >> TARGET_PAGE_BITS;
- p1 = page_find(page_index);
- if (!p1)
- return 0;
- host_end = host_start + qemu_host_page_size;
- p = p1;
- prot = 0;
- for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
- prot |= p->flags;
- p++;
- }
- /* if the page was really writable, then we change its
- protection back to writable */
- if (prot & PAGE_WRITE_ORG) {
- pindex = (address - host_start) >> TARGET_PAGE_BITS;
- if (!(p1[pindex].flags & PAGE_WRITE)) {
- mprotect((void *)g2h(host_start), qemu_host_page_size,
- (prot & PAGE_BITS) | PAGE_WRITE);
- p1[pindex].flags |= PAGE_WRITE;
- /* and since the content will be modified, we must invalidate
- the corresponding translated code. */
- tb_invalidate_phys_page(address, pc, puc);
-#ifdef DEBUG_TB_CHECK
- tb_invalidate_check(address);
-#endif
- return 1;
- }
- }
- return 0;
-}
-
-/* call this function when system calls directly modify a memory area */
-/* ??? This should be redundant now we have lock_user. */
-void page_unprotect_range(target_ulong data, target_ulong data_size)
-{
- target_ulong start, end, addr;
-
- start = data;
- end = start + data_size;
- start &= TARGET_PAGE_MASK;
- end = TARGET_PAGE_ALIGN(end);
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
- page_unprotect(addr, 0, NULL);
- }
-}
-
-static inline void tlb_set_dirty(CPUState *env,
- unsigned long addr, target_ulong vaddr)
-{
-}
-#endif /* defined(CONFIG_USER_ONLY) */
-
-/* register physical memory. 'size' must be a multiple of the target
- page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
- io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- unsigned long size,
- unsigned long phys_offset)
-{
- target_phys_addr_t addr, end_addr;
- PhysPageDesc *p;
- CPUState *env;
-
- size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
- end_addr = start_addr + size;
- for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
- p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
- p->phys_offset = phys_offset;
- if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
- (phys_offset & IO_MEM_ROMD))
- phys_offset += TARGET_PAGE_SIZE;
- }
-
- /* since each CPU stores ram addresses in its TLB cache, we must
- reset the modified entries */
- /* XXX: slow ! */
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- tlb_flush(env, 1);
- }
-}
-
-/* XXX: temporary until new memory mapping API */
-uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr)
-{
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p)
- return IO_MEM_UNASSIGNED;
- return p->phys_offset;
-}
-
-static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
-{
-#ifdef DEBUG_UNASSIGNED
- printf("Unassigned mem read 0x%08x\n", (int)addr);
-#endif
- return 0;
-}
-
-static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef DEBUG_UNASSIGNED
- printf("Unassigned mem write 0x%08x = 0x%x\n", (int)addr, val);
-#endif
-}
-
-static CPUReadMemoryFunc *unassigned_mem_read[3] = {
- unassigned_mem_readb,
- unassigned_mem_readb,
- unassigned_mem_readb,
-};
-
-static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
- unassigned_mem_writeb,
- unassigned_mem_writeb,
- unassigned_mem_writeb,
-};
-
-static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- unsigned long ram_addr;
- int dirty_flags;
- ram_addr = addr - (unsigned long)phys_ram_base;
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
- if (!(dirty_flags & CODE_DIRTY_FLAG)) {
-#if !defined(CONFIG_USER_ONLY)
- tb_invalidate_phys_page_fast(ram_addr, 1);
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
-#endif
- }
- stb_p((uint8_t *)(long)addr, val);
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
- dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
- /* we remove the notdirty callback only if the code has been
- flushed */
- if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
-}
-
-static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- unsigned long ram_addr;
- int dirty_flags;
- ram_addr = addr - (unsigned long)phys_ram_base;
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
- if (!(dirty_flags & CODE_DIRTY_FLAG)) {
-#if !defined(CONFIG_USER_ONLY)
- tb_invalidate_phys_page_fast(ram_addr, 2);
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
-#endif
- }
- stw_p((uint8_t *)(long)addr, val);
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
- dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
- /* we remove the notdirty callback only if the code has been
- flushed */
- if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
-}
-
-static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- unsigned long ram_addr;
- int dirty_flags;
- ram_addr = addr - (unsigned long)phys_ram_base;
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
- if (!(dirty_flags & CODE_DIRTY_FLAG)) {
-#if !defined(CONFIG_USER_ONLY)
- tb_invalidate_phys_page_fast(ram_addr, 4);
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
-#endif
- }
- stl_p((uint8_t *)(long)addr, val);
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
- dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
- /* we remove the notdirty callback only if the code has been
- flushed */
- if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
-}
-
-static CPUReadMemoryFunc *error_mem_read[3] = {
- NULL, /* never used */
- NULL, /* never used */
- NULL, /* never used */
-};
-
-static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
- notdirty_mem_writeb,
- notdirty_mem_writew,
- notdirty_mem_writel,
-};
-
-static void io_mem_init(void)
-{
- cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
- cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
- cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
- io_mem_nb = 5;
-
- /* alloc dirty bits array */
- phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
- memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
-}
-
-/* mem_read and mem_write are arrays of functions containing the
- function to access byte (index 0), word (index 1) and dword (index
- 2). All functions must be supplied. If io_index is non zero, the
- corresponding io zone is modified. If it is zero, a new io zone is
- allocated. The return value can be used with
- cpu_register_physical_memory(). (-1) is returned if error. */
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque)
-{
- int i;
-
- if (io_index <= 0) {
- if (io_mem_nb >= IO_MEM_NB_ENTRIES)
- return -1;
- io_index = io_mem_nb++;
- } else {
- if (io_index >= IO_MEM_NB_ENTRIES)
- return -1;
- }
-
- for(i = 0;i < 3; i++) {
- io_mem_read[io_index][i] = mem_read[i];
- io_mem_write[io_index][i] = mem_write[i];
- }
- io_mem_opaque[io_index] = opaque;
- return io_index << IO_MEM_SHIFT;
-}
-
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
-{
- return io_mem_write[io_index >> IO_MEM_SHIFT];
-}
-
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
-{
- return io_mem_read[io_index >> IO_MEM_SHIFT];
-}
-
-/* physical memory access (slow version, mainly for debug) */
-#if defined(CONFIG_USER_ONLY)
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-{
- int l, flags;
- target_ulong page;
- void * p;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- flags = page_get_flags(page);
- if (!(flags & PAGE_VALID))
- return;
- if (is_write) {
- if (!(flags & PAGE_WRITE))
- return;
- p = lock_user(addr, len, 0);
- memcpy(p, buf, len);
- unlock_user(p, addr, len);
- } else {
- if (!(flags & PAGE_READ))
- return;
- p = lock_user(addr, len, 1);
- memcpy(buf, p, len);
- unlock_user(p, addr, 0);
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-
-#else
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-{
- int l, io_index;
- uint8_t *ptr;
- uint32_t val;
- target_phys_addr_t page;
- unsigned long pd;
- PhysPageDesc *p;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- p = phys_page_find(page >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if (is_write) {
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- /* XXX: could force cpu_single_env to NULL to avoid
- potential bugs */
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit write access */
- val = ldl_p(buf);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit write access */
- val = lduw_p(buf);
- io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
- l = 2;
- } else {
- /* 8 bit write access */
- val = ldub_p(buf);
- io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
- l = 1;
- }
- } else {
- unsigned long addr1;
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* RAM case */
- ptr = phys_ram_base + addr1;
- memcpy(ptr, buf, l);
- if (!cpu_physical_memory_is_dirty(addr1)) {
- /* invalidate code */
- tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
- /* set dirty bit */
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
- (0xff & ~CODE_DIRTY_FLAG);
- }
- }
- } else {
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* I/O case */
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit read access */
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- stl_p(buf, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit read access */
- val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
- stw_p(buf, val);
- l = 2;
- } else {
- /* 8 bit read access */
- val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
- stb_p(buf, val);
- l = 1;
- }
- } else {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- memcpy(buf, ptr, l);
- }
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-
-/* used for ROM loading : can write in RAM and ROM */
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
- const uint8_t *buf, int len)
-{
- int l;
- uint8_t *ptr;
- target_phys_addr_t page;
- unsigned long pd;
- PhysPageDesc *p;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- p = phys_page_find(page >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
- (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* do nothing */
- } else {
- unsigned long addr1;
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* ROM/RAM case */
- ptr = phys_ram_base + addr1;
- memcpy(ptr, buf, l);
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-
-
-/* warning: addr must be aligned */
-uint32_t ldl_phys(target_phys_addr_t addr)
-{
- int io_index;
- uint8_t *ptr;
- uint32_t val;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* I/O case */
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- } else {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- val = ldl_p(ptr);
- }
- return val;
-}
-
-/* warning: addr must be aligned */
-uint64_t ldq_phys(target_phys_addr_t addr)
-{
- int io_index;
- uint8_t *ptr;
- uint64_t val;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* I/O case */
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
- val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
-#else
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
-#endif
- } else {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- val = ldq_p(ptr);
- }
- return val;
-}
-
-/* XXX: optimize */
-uint32_t ldub_phys(target_phys_addr_t addr)
-{
- uint8_t val;
- cpu_physical_memory_read(addr, &val, 1);
- return val;
-}
-
-/* XXX: optimize */
-uint32_t lduw_phys(target_phys_addr_t addr)
-{
- uint16_t val;
- cpu_physical_memory_read(addr, (uint8_t *)&val, 2);
- return tswap16(val);
-}
-
-/* warning: addr must be aligned. The ram page is not masked as dirty
- and the code inside is not invalidated. It is useful if the dirty
- bits are used to track modified PTEs */
-void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
-{
- int io_index;
- uint8_t *ptr;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- } else {
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- stl_p(ptr, val);
- }
-}
-
-/* warning: addr must be aligned */
-void stl_phys(target_phys_addr_t addr, uint32_t val)
-{
- int io_index;
- uint8_t *ptr;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- } else {
- unsigned long addr1;
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* RAM case */
- ptr = phys_ram_base + addr1;
- stl_p(ptr, val);
- if (!cpu_physical_memory_is_dirty(addr1)) {
- /* invalidate code */
- tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
- /* set dirty bit */
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
- (0xff & ~CODE_DIRTY_FLAG);
- }
- }
-}
-
-/* XXX: optimize */
-void stb_phys(target_phys_addr_t addr, uint32_t val)
-{
- uint8_t v = val;
- cpu_physical_memory_write(addr, &v, 1);
-}
-
-/* XXX: optimize */
-void stw_phys(target_phys_addr_t addr, uint32_t val)
-{
- uint16_t v = tswap16(val);
- cpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
-}
-
-/* XXX: optimize */
-void stq_phys(target_phys_addr_t addr, uint64_t val)
-{
- val = tswap64(val);
- cpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
-}
-
-#endif
-
-/* virtual memory access for debug */
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write)
-{
- int l;
- target_ulong page, phys_addr;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- phys_addr = cpu_get_phys_page_debug(env, page);
- /* if no physical page mapped, return an error */
- if (phys_addr == -1)
- return -1;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
- buf, l, is_write);
- len -= l;
- buf += l;
- addr += l;
- }
- return 0;
-}
-
-void dump_exec_info(FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
- int i, target_code_size, max_target_code_size;
- int direct_jmp_count, direct_jmp2_count, cross_page;
- TranslationBlock *tb;
-
- target_code_size = 0;
- max_target_code_size = 0;
- cross_page = 0;
- direct_jmp_count = 0;
- direct_jmp2_count = 0;
- for(i = 0; i < nb_tbs; i++) {
- tb = &tbs[i];
- target_code_size += tb->size;
- if (tb->size > max_target_code_size)
- max_target_code_size = tb->size;
- if (tb->page_addr[1] != -1)
- cross_page++;
- if (tb->tb_next_offset[0] != 0xffff) {
- direct_jmp_count++;
- if (tb->tb_next_offset[1] != 0xffff) {
- direct_jmp2_count++;
- }
- }
- }
- /* XXX: avoid using doubles ? */
- cpu_fprintf(f, "TB count %d\n", nb_tbs);
- cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
- nb_tbs ? target_code_size / nb_tbs : 0,
- max_target_code_size);
- cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n",
- nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
- target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
- cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
- cross_page,
- nb_tbs ? (cross_page * 100) / nb_tbs : 0);
- cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n",
- direct_jmp_count,
- nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
- direct_jmp2_count,
- nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
- cpu_fprintf(f, "TB flush count %d\n", tb_flush_count);
- cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);
- cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-#define MMUSUFFIX _cmmu
-#define GETPC() NULL
-#define env cpu_single_env
-#define SOFTMMU_CODE_ACCESS
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
-#undef env
-
-#endif
diff --git a/tools/ioemu/fpu/.CVS/Entries b/tools/ioemu/fpu/.CVS/Entries
deleted file mode 100644
index cd33c001d2..0000000000
--- a/tools/ioemu/fpu/.CVS/Entries
+++ /dev/null
@@ -1,7 +0,0 @@
-/softfloat-macros.h/1.1/Wed Oct 18 10:11:20 2006//Trelease_0_9_0
-/softfloat-native.c/1.6/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/softfloat-native.h/1.8/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/softfloat-specialize.h/1.2/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/softfloat.c/1.4/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/softfloat.h/1.5/Thu May 3 17:18:00 2007//Trelease_0_9_0
-D
diff --git a/tools/ioemu/fpu/.CVS/Repository b/tools/ioemu/fpu/.CVS/Repository
deleted file mode 100644
index 6aaee19f2c..0000000000
--- a/tools/ioemu/fpu/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu/fpu
diff --git a/tools/ioemu/fpu/.CVS/Root b/tools/ioemu/fpu/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/fpu/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/fpu/.CVS/Tag b/tools/ioemu/fpu/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/fpu/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/fpu/softfloat-macros.h b/tools/ioemu/fpu/softfloat-macros.h
deleted file mode 100644
index 2c8f18b1ce..0000000000
--- a/tools/ioemu/fpu/softfloat-macros.h
+++ /dev/null
@@ -1,720 +0,0 @@
-
-/*============================================================================
-
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 32, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-| The result is stored in the location pointed to by `zPtr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
-{
- bits32 z;
-
- if ( count == 0 ) {
- z = a;
- }
- else if ( count < 32 ) {
- z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
- }
- else {
- z = ( a != 0 );
- }
- *zPtr = z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 64, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-| The result is stored in the location pointed to by `zPtr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
-{
- bits64 z;
-
- if ( count == 0 ) {
- z = a;
- }
- else if ( count < 64 ) {
- z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
- }
- else {
- z = ( a != 0 );
- }
- *zPtr = z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
-| _plus_ the number of bits given in `count'. The shifted result is at most
-| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
-| bits shifted off form a second 64-bit result as follows: The _last_ bit
-| shifted off is the most-significant bit of the extra result, and the other
-| 63 bits of the extra result are all zero if and only if _all_but_the_last_
-| bits shifted off were all zero. This extra result is stored in the location
-| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0' and `a1' are considered to form
-| a fixed-point value with binary point between `a0' and `a1'. This fixed-
-| point value is shifted right by the number of bits given in `count', and
-| the integer part of the result is returned at the location pointed to by
-| `z0Ptr'. The fractional part of the result may be slightly corrupted as
-| described above, and is returned at the location pointed to by `z1Ptr'.)
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift64ExtraRightJamming(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z0, z1;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z1 = a1;
- z0 = a0;
- }
- else if ( count < 64 ) {
- z1 = ( a0<<negCount ) | ( a1 != 0 );
- z0 = a0>>count;
- }
- else {
- if ( count == 64 ) {
- z1 = a0 | ( a1 != 0 );
- }
- else {
- z1 = ( ( a0 | a1 ) != 0 );
- }
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. Any bits shifted off are lost. The value
-| of `count' can be arbitrarily large; in particular, if `count' is greater
-| than 128, the result will be 0. The result is broken into two 64-bit pieces
-| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift128Right(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z0, z1;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z1 = a1;
- z0 = a0;
- }
- else if ( count < 64 ) {
- z1 = ( a0<<negCount ) | ( a1>>count );
- z0 = a0>>count;
- }
- else {
- z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. If any nonzero bits are shifted off, they
-| are ``jammed'' into the least significant bit of the result by setting the
-| least significant bit to 1. The value of `count' can be arbitrarily large;
-| in particular, if `count' is greater than 128, the result will be either
-| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
-| nonzero. The result is broken into two 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift128RightJamming(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z0, z1;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z1 = a1;
- z0 = a0;
- }
- else if ( count < 64 ) {
- z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
- z0 = a0>>count;
- }
- else {
- if ( count == 64 ) {
- z1 = a0 | ( a1 != 0 );
- }
- else if ( count < 128 ) {
- z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
- }
- else {
- z1 = ( ( a0 | a1 ) != 0 );
- }
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
-| by 64 _plus_ the number of bits given in `count'. The shifted result is
-| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
-| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
-| off form a third 64-bit result as follows: The _last_ bit shifted off is
-| the most-significant bit of the extra result, and the other 63 bits of the
-| extra result are all zero if and only if _all_but_the_last_ bits shifted off
-| were all zero. This extra result is stored in the location pointed to by
-| `z2Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0', `a1', and `a2' are considered
-| to form a fixed-point value with binary point between `a1' and `a2'. This
-| fixed-point value is shifted right by the number of bits given in `count',
-| and the integer part of the result is returned at the locations pointed to
-| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
-| corrupted as described above, and is returned at the location pointed to by
-| `z2Ptr'.)
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift128ExtraRightJamming(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- int16 count,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z2 = a2;
- z1 = a1;
- z0 = a0;
- }
- else {
- if ( count < 64 ) {
- z2 = a1<<negCount;
- z1 = ( a0<<negCount ) | ( a1>>count );
- z0 = a0>>count;
- }
- else {
- if ( count == 64 ) {
- z2 = a1;
- z1 = a0;
- }
- else {
- a2 |= a1;
- if ( count < 128 ) {
- z2 = a0<<negCount;
- z1 = a0>>( count & 63 );
- }
- else {
- z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
- z1 = 0;
- }
- }
- z0 = 0;
- }
- z2 |= ( a2 != 0 );
- }
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
-| number of bits given in `count'. Any bits shifted off are lost. The value
-| of `count' must be less than 64. The result is broken into two 64-bit
-| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shortShift128Left(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
-
- *z1Ptr = a1<<count;
- *z0Ptr =
- ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
-| by the number of bits given in `count'. Any bits shifted off are lost.
-| The value of `count' must be less than 64. The result is broken into three
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
-| `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shortShift192Left(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- int16 count,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 negCount;
-
- z2 = a2<<count;
- z1 = a1<<count;
- z0 = a0<<count;
- if ( 0 < count ) {
- negCount = ( ( - count ) & 63 );
- z1 |= a2>>negCount;
- z0 |= a1>>negCount;
- }
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
-| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
-| any carry out is lost. The result is broken into two 64-bit pieces which
-| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- add128(
- bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z1;
-
- z1 = a1 + b1;
- *z1Ptr = z1;
- *z0Ptr = a0 + b0 + ( z1 < a1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
-| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
-| modulo 2^192, so any carry out is lost. The result is broken into three
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
-| `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- add192(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- bits64 b0,
- bits64 b1,
- bits64 b2,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 carry0, carry1;
-
- z2 = a2 + b2;
- carry1 = ( z2 < a2 );
- z1 = a1 + b1;
- carry0 = ( z1 < a1 );
- z0 = a0 + b0;
- z1 += carry1;
- z0 += ( z1 < carry1 );
- z0 += carry0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
-| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
-| 2^128, so any borrow out (carry out) is lost. The result is broken into two
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
-| `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- sub128(
- bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
-{
-
- *z1Ptr = a1 - b1;
- *z0Ptr = a0 - b0 - ( a1 < b1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
-| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
-| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
-| result is broken into three 64-bit pieces which are stored at the locations
-| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- sub192(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- bits64 b0,
- bits64 b1,
- bits64 b2,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 borrow0, borrow1;
-
- z2 = a2 - b2;
- borrow1 = ( a2 < b2 );
- z1 = a1 - b1;
- borrow0 = ( a1 < b1 );
- z0 = a0 - b0;
- z0 -= ( z1 < borrow1 );
- z1 -= borrow1;
- z0 -= borrow0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
-| into two 64-bit pieces which are stored at the locations pointed to by
-| `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits32 aHigh, aLow, bHigh, bLow;
- bits64 z0, zMiddleA, zMiddleB, z1;
-
- aLow = a;
- aHigh = a>>32;
- bLow = b;
- bHigh = b>>32;
- z1 = ( (bits64) aLow ) * bLow;
- zMiddleA = ( (bits64) aLow ) * bHigh;
- zMiddleB = ( (bits64) aHigh ) * bLow;
- z0 = ( (bits64) aHigh ) * bHigh;
- zMiddleA += zMiddleB;
- z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
- zMiddleA <<= 32;
- z1 += zMiddleA;
- z0 += ( z1 < zMiddleA );
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
-| `b' to obtain a 192-bit product. The product is broken into three 64-bit
-| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
-| `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- mul128By64To192(
- bits64 a0,
- bits64 a1,
- bits64 b,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2, more1;
-
- mul64To128( a1, b, &z1, &z2 );
- mul64To128( a0, b, &z0, &more1 );
- add128( z0, more1, 0, z1, &z0, &z1 );
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
-| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
-| product. The product is broken into four 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- mul128To256(
- bits64 a0,
- bits64 a1,
- bits64 b0,
- bits64 b1,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr,
- bits64 *z3Ptr
- )
-{
- bits64 z0, z1, z2, z3;
- bits64 more1, more2;
-
- mul64To128( a1, b1, &z2, &z3 );
- mul64To128( a1, b0, &z1, &more2 );
- add128( z1, more2, 0, z2, &z1, &z2 );
- mul64To128( a0, b0, &z0, &more1 );
- add128( z0, more1, 0, z1, &z0, &z1 );
- mul64To128( a0, b1, &more1, &more2 );
- add128( more1, more2, 0, z2, &more1, &z2 );
- add128( z0, z1, 0, more1, &z0, &z1 );
- *z3Ptr = z3;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the 64-bit integer quotient obtained by dividing
-| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
-| divisor `b' must be at least 2^63. If q is the exact quotient truncated
-| toward zero, the approximation returned lies between q and q + 2 inclusive.
-| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
-| unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
-{
- bits64 b0, b1;
- bits64 rem0, rem1, term0, term1;
- bits64 z;
-
- if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
- b0 = b>>32;
- z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
- mul64To128( b, z, &term0, &term1 );
- sub128( a0, a1, term0, term1, &rem0, &rem1 );
- while ( ( (sbits64) rem0 ) < 0 ) {
- z -= LIT64( 0x100000000 );
- b1 = b<<32;
- add128( rem0, rem1, b0, b1, &rem0, &rem1 );
- }
- rem0 = ( rem0<<32 ) | ( rem1>>32 );
- z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the square root of the 32-bit significand given
-| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
-| `aExp' (the least significant bit) is 1, the integer returned approximates
-| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
-| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
-| case, the approximation returned lies strictly within +/-2 of the exact
-| value.
-*----------------------------------------------------------------------------*/
-
-static bits32 estimateSqrt32( int16 aExp, bits32 a )
-{
- static const bits16 sqrtOddAdjustments[] = {
- 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
- 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
- };
- static const bits16 sqrtEvenAdjustments[] = {
- 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
- 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
- };
- int8 index;
- bits32 z;
-
- index = ( a>>27 ) & 15;
- if ( aExp & 1 ) {
- z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
- z = ( ( a / z )<<14 ) + ( z<<15 );
- a >>= 1;
- }
- else {
- z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
- z = a / z + z;
- z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
- if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
- }
- return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 32 is returned.
-*----------------------------------------------------------------------------*/
-
-static int8 countLeadingZeros32( bits32 a )
-{
- static const int8 countLeadingZerosHigh[] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- int8 shiftCount;
-
- shiftCount = 0;
- if ( a < 0x10000 ) {
- shiftCount += 16;
- a <<= 16;
- }
- if ( a < 0x1000000 ) {
- shiftCount += 8;
- a <<= 8;
- }
- shiftCount += countLeadingZerosHigh[ a>>24 ];
- return shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 64 is returned.
-*----------------------------------------------------------------------------*/
-
-static int8 countLeadingZeros64( bits64 a )
-{
- int8 shiftCount;
-
- shiftCount = 0;
- if ( a < ( (bits64) 1 )<<32 ) {
- shiftCount += 32;
- }
- else {
- a >>= 32;
- }
- shiftCount += countLeadingZeros32( a );
- return shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
-| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 == b0 ) && ( a1 == b1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
-| returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
-| not equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 != b0 ) || ( a1 != b1 );
-
-}
-
diff --git a/tools/ioemu/fpu/softfloat-native.c b/tools/ioemu/fpu/softfloat-native.c
deleted file mode 100644
index f20d5c45f6..0000000000
--- a/tools/ioemu/fpu/softfloat-native.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/* Native implementation of soft float functions. Only a single status
- context is supported */
-#include "softfloat.h"
-#include <math.h>
-
-void set_float_rounding_mode(int val STATUS_PARAM)
-{
- STATUS(float_rounding_mode) = val;
-#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
- fpsetround(val);
-#elif defined(__arm__)
- /* nothing to do */
-#else
- fesetround(val);
-#endif
-}
-
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM)
-{
- STATUS(floatx80_rounding_precision) = val;
-}
-#endif
-
-#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
-#define lrint(d) ((int32_t)rint(d))
-#define llrint(d) ((int64_t)rint(d))
-#define lrintf(f) ((int32_t)rint(f))
-#define llrintf(f) ((int64_t)rint(f))
-#define sqrtf(f) ((float)sqrt(f))
-#define remainderf(fa, fb) ((float)remainder(fa, fb))
-#define rintf(f) ((float)rint(f))
-#endif
-
-#if defined(__powerpc__)
-
-/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
-double qemu_rint(double x)
-{
- double y = 4503599627370496.0;
- if (fabs(x) >= y)
- return x;
- if (x < 0)
- y = -y;
- y = (x + y) - y;
- if (y == 0.0)
- y = copysign(y, x);
- return y;
-}
-
-#define rint qemu_rint
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32(int v STATUS_PARAM)
-{
- return (float32)v;
-}
-
-float64 int32_to_float64(int v STATUS_PARAM)
-{
- return (float64)v;
-}
-
-#ifdef FLOATX80
-floatx80 int32_to_floatx80(int v STATUS_PARAM)
-{
- return (floatx80)v;
-}
-#endif
-float32 int64_to_float32( int64_t v STATUS_PARAM)
-{
- return (float32)v;
-}
-float64 int64_to_float64( int64_t v STATUS_PARAM)
-{
- return (float64)v;
-}
-#ifdef FLOATX80
-floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
-{
- return (floatx80)v;
-}
-#endif
-
-/* XXX: this code implements the x86 behaviour, not the IEEE one. */
-#if HOST_LONG_BITS == 32
-static inline int long_to_int32(long a)
-{
- return a;
-}
-#else
-static inline int long_to_int32(long a)
-{
- if (a != (int32_t)a)
- a = 0x80000000;
- return a;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float32_to_int32( float32 a STATUS_PARAM)
-{
- return long_to_int32(lrintf(a));
-}
-int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
-{
- return (int)a;
-}
-int64_t float32_to_int64( float32 a STATUS_PARAM)
-{
- return llrintf(a);
-}
-
-int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
-{
- return (int64_t)a;
-}
-
-float64 float32_to_float64( float32 a STATUS_PARAM)
-{
- return a;
-}
-#ifdef FLOATX80
-floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
-{
- return a;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 a STATUS_PARAM)
-{
- return rintf(a);
-}
-
-float32 float32_rem( float32 a, float32 b STATUS_PARAM)
-{
- return remainderf(a, b);
-}
-
-float32 float32_sqrt( float32 a STATUS_PARAM)
-{
- return sqrtf(a);
-}
-int float32_compare( float32 a, float32 b STATUS_PARAM )
-{
- if (a < b) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (a > b) {
- return 1;
- } else {
- return 2;
- }
-}
-int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
-{
- if (isless(a, b)) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (isgreater(a, b)) {
- return 1;
- } else {
- return 2;
- }
-}
-int float32_is_signaling_nan( float32 a1)
-{
- float32u u;
- uint32_t a;
- u.f = a1;
- a = u.i;
- return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float64_to_int32( float64 a STATUS_PARAM)
-{
- return long_to_int32(lrint(a));
-}
-int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
-{
- return (int)a;
-}
-int64_t float64_to_int64( float64 a STATUS_PARAM)
-{
- return llrint(a);
-}
-int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
-{
- return (int64_t)a;
-}
-float32 float64_to_float32( float64 a STATUS_PARAM)
-{
- return a;
-}
-#ifdef FLOATX80
-floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
-{
- return a;
-}
-#endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 a STATUS_PARAM)
-{
- return a;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_trunc_to_int( float64 a STATUS_PARAM )
-{
- return trunc(a);
-}
-
-float64 float64_round_to_int( float64 a STATUS_PARAM )
-{
-#if defined(__arm__)
- switch(STATUS(float_rounding_mode)) {
- default:
- case float_round_nearest_even:
- asm("rndd %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_down:
- asm("rnddm %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_up:
- asm("rnddp %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_to_zero:
- asm("rnddz %0, %1" : "=f" (a) : "f"(a));
- break;
- }
-#else
- return rint(a);
-#endif
-}
-
-float64 float64_rem( float64 a, float64 b STATUS_PARAM)
-{
- return remainder(a, b);
-}
-
-float64 float64_sqrt( float64 a STATUS_PARAM)
-{
- return sqrt(a);
-}
-int float64_compare( float64 a, float64 b STATUS_PARAM )
-{
- if (a < b) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (a > b) {
- return 1;
- } else {
- return 2;
- }
-}
-int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
-{
- if (isless(a, b)) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (isgreater(a, b)) {
- return 1;
- } else {
- return 2;
- }
-}
-int float64_is_signaling_nan( float64 a1)
-{
- float64u u;
- uint64_t a;
- u.f = a1;
- a = u.i;
- return
- ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
- && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-
-}
-
-int float64_is_nan( float64 a1 )
-{
- float64u u;
- uint64_t a;
- u.f = a1;
- a = u.i;
-
- return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 a STATUS_PARAM)
-{
- return long_to_int32(lrintl(a));
-}
-int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
-{
- return (int)a;
-}
-int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
-{
- return llrintl(a);
-}
-int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
-{
- return (int64_t)a;
-}
-float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
-{
- return a;
-}
-float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
-{
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
-{
- return rintl(a);
-}
-floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return remainderl(a, b);
-}
-floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
-{
- return sqrtl(a);
-}
-int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
-{
- if (a < b) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (a > b) {
- return 1;
- } else {
- return 2;
- }
-}
-int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
-{
- if (isless(a, b)) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (isgreater(a, b)) {
- return 1;
- } else {
- return 2;
- }
-}
-int floatx80_is_signaling_nan( floatx80 a1)
-{
- floatx80u u;
- u.f = a1;
- return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
-}
-
-#endif
diff --git a/tools/ioemu/fpu/softfloat-native.h b/tools/ioemu/fpu/softfloat-native.h
deleted file mode 100644
index 8c27708771..0000000000
--- a/tools/ioemu/fpu/softfloat-native.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/* Native implementation of soft float functions */
-#include <math.h>
-
-#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
-#include <ieeefp.h>
-#define fabsf(f) ((float)fabs(f))
-#else
-#include <fenv.h>
-#endif
-
-/*
- * Define some C99-7.12.3 classification macros and
- * some C99-.12.4 for Solaris systems OS less than 10,
- * or Solaris 10 systems running GCC 3.x or less.
- * Solaris 10 with GCC4 does not need these macros as they
- * are defined in <iso/math_c99.h> with a compiler directive
- */
-#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ( ( HOST_SOLARIS >= 10 ) && ( __GNUC__ <= 4) ))
-/*
- * C99 7.12.3 classification macros
- * and
- * C99 7.12.14 comparison macros
- *
- * ... do not work on Solaris 10 using GNU CC 3.4.x.
- * Try to workaround the missing / broken C99 math macros.
- */
-
-#define isnormal(x) (fpclass(x) >= FP_NZERO)
-#define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y)))
-#define isgreaterequal(x, y) ((!unordered(x, y)) && ((x) >= (y)))
-#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
-#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
-#define isunordered(x,y) unordered(x, y)
-#endif
-
-typedef float float32;
-typedef double float64;
-#ifdef FLOATX80
-typedef long double floatx80;
-#endif
-
-typedef union {
- float32 f;
- uint32_t i;
-} float32u;
-typedef union {
- float64 f;
- uint64_t i;
-} float64u;
-#ifdef FLOATX80
-typedef union {
- floatx80 f;
- struct {
- uint64_t low;
- uint16_t high;
- } i;
-} floatx80u;
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
-enum {
- float_round_nearest_even = FP_RN,
- float_round_down = FP_RM,
- float_round_up = FP_RP,
- float_round_to_zero = FP_RZ
-};
-#elif defined(__arm__)
-enum {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-#else
-enum {
- float_round_nearest_even = FE_TONEAREST,
- float_round_down = FE_DOWNWARD,
- float_round_up = FE_UPWARD,
- float_round_to_zero = FE_TOWARDZERO
-};
-#endif
-
-typedef struct float_status {
- signed char float_rounding_mode;
-#ifdef FLOATX80
- signed char floatx80_rounding_precision;
-#endif
-} float_status;
-
-void set_float_rounding_mode(int val STATUS_PARAM);
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32( int STATUS_PARAM);
-float64 int32_to_float64( int STATUS_PARAM);
-#ifdef FLOATX80
-floatx80 int32_to_floatx80( int STATUS_PARAM);
-#endif
-#ifdef FLOAT128
-float128 int32_to_float128( int STATUS_PARAM);
-#endif
-float32 int64_to_float32( int64_t STATUS_PARAM);
-float64 int64_to_float64( int64_t STATUS_PARAM);
-#ifdef FLOATX80
-floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
-#endif
-#ifdef FLOAT128
-float128 int64_to_float128( int64_t STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float32_to_int32( float32 STATUS_PARAM);
-int float32_to_int32_round_to_zero( float32 STATUS_PARAM);
-int64_t float32_to_int64( float32 STATUS_PARAM);
-int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM);
-float64 float32_to_float64( float32 STATUS_PARAM);
-#ifdef FLOATX80
-floatx80 float32_to_floatx80( float32 STATUS_PARAM);
-#endif
-#ifdef FLOAT128
-float128 float32_to_float128( float32 STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 STATUS_PARAM);
-INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
-{
- return a + b;
-}
-INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
-{
- return a - b;
-}
-INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
-{
- return a * b;
-}
-INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
-{
- return a / b;
-}
-float32 float32_rem( float32, float32 STATUS_PARAM);
-float32 float32_sqrt( float32 STATUS_PARAM);
-INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
-{
- return a == b;
-}
-INLINE int float32_le( float32 a, float32 b STATUS_PARAM)
-{
- return a <= b;
-}
-INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
-{
- return a < b;
-}
-INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
-{
- return a <= b && a >= b;
-}
-INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM)
-{
- return islessequal(a, b);
-}
-INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
-{
- return isless(a, b);
-}
-INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
-{
- return isunordered(a, b);
-
-}
-int float32_compare( float32, float32 STATUS_PARAM );
-int float32_compare_quiet( float32, float32 STATUS_PARAM );
-int float32_is_signaling_nan( float32 );
-
-INLINE float32 float32_abs(float32 a)
-{
- return fabsf(a);
-}
-
-INLINE float32 float32_chs(float32 a)
-{
- return -a;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float64_to_int32( float64 STATUS_PARAM );
-int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
-int64_t float64_to_int64( float64 STATUS_PARAM );
-int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
-float32 float64_to_float32( float64 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float64_to_floatx80( float64 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int( float64 STATUS_PARAM );
-float64 float64_trunc_to_int( float64 STATUS_PARAM );
-INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
-{
- return a + b;
-}
-INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
-{
- return a - b;
-}
-INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
-{
- return a * b;
-}
-INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
-{
- return a / b;
-}
-float64 float64_rem( float64, float64 STATUS_PARAM );
-float64 float64_sqrt( float64 STATUS_PARAM );
-INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
-{
- return a == b;
-}
-INLINE int float64_le( float64 a, float64 b STATUS_PARAM)
-{
- return a <= b;
-}
-INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
-{
- return a < b;
-}
-INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
-{
- return a <= b && a >= b;
-}
-INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM)
-{
- return islessequal(a, b);
-}
-INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
-{
- return isless(a, b);
-
-}
-INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
-{
- return isunordered(a, b);
-
-}
-int float64_compare( float64, float64 STATUS_PARAM );
-int float64_compare_quiet( float64, float64 STATUS_PARAM );
-int float64_is_signaling_nan( float64 );
-int float64_is_nan( float64 );
-
-INLINE float64 float64_abs(float64 a)
-{
- return fabs(a);
-}
-
-INLINE float64 float64_chs(float64 a)
-{
- return -a;
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 STATUS_PARAM );
-int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
-int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
-int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
-float32 floatx80_to_float32( floatx80 STATUS_PARAM );
-float64 floatx80_to_float64( floatx80 STATUS_PARAM );
-#ifdef FLOAT128
-float128 floatx80_to_float128( floatx80 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
-INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a + b;
-}
-INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a - b;
-}
-INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a * b;
-}
-INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a / b;
-}
-floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a == b;
-}
-INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a <= b;
-}
-INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a < b;
-}
-INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a <= b && a >= b;
-}
-INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return islessequal(a, b);
-}
-INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return isless(a, b);
-
-}
-INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return isunordered(a, b);
-
-}
-int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
-int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_is_signaling_nan( floatx80 );
-
-INLINE floatx80 floatx80_abs(floatx80 a)
-{
- return fabsl(a);
-}
-
-INLINE floatx80 floatx80_chs(floatx80 a)
-{
- return -a;
-}
-#endif
diff --git a/tools/ioemu/fpu/softfloat-specialize.h b/tools/ioemu/fpu/softfloat-specialize.h
deleted file mode 100644
index f9b6f0cbc6..0000000000
--- a/tools/ioemu/fpu/softfloat-specialize.h
+++ /dev/null
@@ -1,464 +0,0 @@
-
-/*============================================================================
-
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-/*----------------------------------------------------------------------------
-| Underflow tininess-detection mode, statically initialized to default value.
-| (The declaration in `softfloat.h' must match the `int8' type here.)
-*----------------------------------------------------------------------------*/
-int8 float_detect_tininess = float_tininess_after_rounding;
-
-/*----------------------------------------------------------------------------
-| Raises the exceptions specified by `flags'. Floating-point traps can be
-| defined here if desired. It is currently not possible for such a trap
-| to substitute a result value. If traps are not implemented, this routine
-| should be simply `float_exception_flags |= flags;'.
-*----------------------------------------------------------------------------*/
-
-void float_raise( int8 flags STATUS_PARAM )
-{
-
- STATUS(float_exception_flags) |= flags;
-
-}
-
-/*----------------------------------------------------------------------------
-| Internal canonical NaN format.
-*----------------------------------------------------------------------------*/
-typedef struct {
- flag sign;
- bits64 high, low;
-} commonNaNT;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-#define float32_default_nan 0xFFC00000
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float32_is_nan( float32 a )
-{
-
- return ( 0xFF000000 < (bits32) ( a<<1 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float32_is_signaling_nan( float32 a )
-{
-
- return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
-{
- commonNaNT z;
-
- if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
- z.sign = a>>31;
- z.low = 0;
- z.high = ( (bits64) a )<<41;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the single-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static float32 commonNaNToFloat32( commonNaNT a )
-{
-
- return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes two single-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = float32_is_nan( a );
- aIsSignalingNaN = float32_is_signaling_nan( a );
- bIsNaN = float32_is_nan( b );
- bIsSignalingNaN = float32_is_signaling_nan( b );
- a |= 0x00400000;
- b |= 0x00400000;
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
- returnLargerSignificand:
- if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
- if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
- return ( a < b ) ? a : b;
- }
- else {
- return b;
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-#define float64_default_nan LIT64( 0xFFF8000000000000 )
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float64_is_nan( float64 a )
-{
-
- return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float64_is_signaling_nan( float64 a )
-{
-
- return
- ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
- && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
-{
- commonNaNT z;
-
- if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = a>>63;
- z.low = 0;
- z.high = a<<12;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the double-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static float64 commonNaNToFloat64( commonNaNT a )
-{
-
- return
- ( ( (bits64) a.sign )<<63 )
- | LIT64( 0x7FF8000000000000 )
- | ( a.high>>12 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes two double-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = float64_is_nan( a );
- aIsSignalingNaN = float64_is_signaling_nan( a );
- bIsNaN = float64_is_nan( b );
- bIsSignalingNaN = float64_is_signaling_nan( b );
- a |= LIT64( 0x0008000000000000 );
- b |= LIT64( 0x0008000000000000 );
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
- returnLargerSignificand:
- if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
- if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
- return ( a < b ) ? a : b;
- }
- else {
- return b;
- }
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN. The
-| `high' and `low' values hold the most- and least-significant bits,
-| respectively.
-*----------------------------------------------------------------------------*/
-#define floatx80_default_nan_high 0xFFFF
-#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int floatx80_is_nan( floatx80 a )
-{
-
- return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int floatx80_is_signaling_nan( floatx80 a )
-{
- bits64 aLow;
-
- aLow = a.low & ~ LIT64( 0x4000000000000000 );
- return
- ( ( a.high & 0x7FFF ) == 0x7FFF )
- && (bits64) ( aLow<<1 )
- && ( a.low == aLow );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
-| invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
-{
- commonNaNT z;
-
- if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = a.high>>15;
- z.low = 0;
- z.high = a.low<<1;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the extended
-| double-precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static floatx80 commonNaNToFloatx80( commonNaNT a )
-{
- floatx80 z;
-
- z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
- z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes two extended double-precision floating-point values `a' and `b', one
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = floatx80_is_nan( a );
- aIsSignalingNaN = floatx80_is_signaling_nan( a );
- bIsNaN = floatx80_is_nan( b );
- bIsSignalingNaN = floatx80_is_signaling_nan( b );
- a.low |= LIT64( 0xC000000000000000 );
- b.low |= LIT64( 0xC000000000000000 );
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
- returnLargerSignificand:
- if ( a.low < b.low ) return b;
- if ( b.low < a.low ) return a;
- return ( a.high < b.high ) ? a : b;
- }
- else {
- return b;
- }
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN. The `high' and
-| `low' values hold the most- and least-significant bits, respectively.
-*----------------------------------------------------------------------------*/
-#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
-#define float128_default_nan_low LIT64( 0x0000000000000000 )
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float128_is_nan( float128 a )
-{
-
- return
- ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
- && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float128_is_signaling_nan( float128 a )
-{
-
- return
- ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
- && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
-{
- commonNaNT z;
-
- if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = a.high>>63;
- shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the quadruple-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static float128 commonNaNToFloat128( commonNaNT a )
-{
- float128 z;
-
- shift128Right( a.high, a.low, 16, &z.high, &z.low );
- z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes two quadruple-precision floating-point values `a' and `b', one of
-| which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = float128_is_nan( a );
- aIsSignalingNaN = float128_is_signaling_nan( a );
- bIsNaN = float128_is_nan( b );
- bIsSignalingNaN = float128_is_signaling_nan( b );
- a.high |= LIT64( 0x0000800000000000 );
- b.high |= LIT64( 0x0000800000000000 );
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
- returnLargerSignificand:
- if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
- if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
- return ( a.high < b.high ) ? a : b;
- }
- else {
- return b;
- }
-
-}
-
-#endif
-
diff --git a/tools/ioemu/fpu/softfloat.c b/tools/ioemu/fpu/softfloat.c
deleted file mode 100644
index 5dbfa81e43..0000000000
--- a/tools/ioemu/fpu/softfloat.c
+++ /dev/null
@@ -1,5331 +0,0 @@
-
-/*============================================================================
-
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-#include "softfloat.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target if
-| desired.)
-*----------------------------------------------------------------------------*/
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-void set_float_rounding_mode(int val STATUS_PARAM)
-{
- STATUS(float_rounding_mode) = val;
-}
-
-void set_float_exception_flags(int val STATUS_PARAM)
-{
- STATUS(float_exception_flags) = val;
-}
-
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM)
-{
- STATUS(floatx80_rounding_precision) = val;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
-| and 7, and returns the properly rounded 32-bit integer corresponding to the
-| input. If `zSign' is 1, the input is negated before being converted to an
-| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
-| is simply rounded to an integer, with the inexact exception raised if the
-| input cannot be represented exactly as an integer. However, if the fixed-
-| point input is too large, the invalid exception is raised and the largest
-| positive or negative integer is returned.
-*----------------------------------------------------------------------------*/
-
-static int32 roundAndPackInt32( flag zSign, bits64 absZ STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven;
- int8 roundIncrement, roundBits;
- int32 z;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- roundIncrement = 0x40;
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = 0x7F;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = absZ & 0x7F;
- absZ = ( absZ + roundIncrement )>>7;
- absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
- z = absZ;
- if ( zSign ) z = - z;
- if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit integer corresponding to the input.
-| If `zSign' is 1, the input is negated before being converted to an integer.
-| Ordinarily, the fixed-point input is simply rounded to an integer, with
-| the inexact exception raised if the input cannot be represented exactly as
-| an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the largest positive or negative integer is
-| returned.
-*----------------------------------------------------------------------------*/
-
-static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven, increment;
- int64 z;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- increment = ( (sbits64) absZ1 < 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- increment = 0;
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && absZ1;
- }
- else {
- increment = ( roundingMode == float_round_up ) && absZ1;
- }
- }
- }
- if ( increment ) {
- ++absZ0;
- if ( absZ0 == 0 ) goto overflow;
- absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven );
- }
- z = absZ0;
- if ( zSign ) z = - z;
- if ( z && ( ( z < 0 ) ^ zSign ) ) {
- overflow:
- float_raise( float_flag_invalid STATUS_VAR);
- return
- zSign ? (sbits64) LIT64( 0x8000000000000000 )
- : LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- if ( absZ1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits32 extractFloat32Frac( float32 a )
-{
-
- return a & 0x007FFFFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int16 extractFloat32Exp( float32 a )
-{
-
- return ( a>>23 ) & 0xFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloat32Sign( float32 a )
-{
-
- return a>>31;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal single-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros32( aSig ) - 8;
- *zSigPtr = aSig<<shiftCount;
- *zExpPtr = 1 - shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
-{
-
- return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the single-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal single-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 30
-| and 29, which is 7 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven;
- int8 roundIncrement, roundBits;
- flag isTiny;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- roundIncrement = 0x40;
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = 0x7F;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = zSig & 0x7F;
- if ( 0xFD <= (bits16) zExp ) {
- if ( ( 0xFD < zExp )
- || ( ( zExp == 0xFD )
- && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
- ) {
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
- }
- if ( zExp < 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < -1 )
- || ( zSig + roundIncrement < 0x80000000 );
- shift32RightJamming( zSig, - zExp, &zSig );
- zExp = 0;
- roundBits = zSig & 0x7F;
- if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
- }
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig = ( zSig + roundIncrement )>>7;
- zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
- if ( zSig == 0 ) zExp = 0;
- return packFloat32( zSign, zExp, zSig );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
-| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-static float32
- normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM)
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros32( zSig ) - 1;
- return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloat64Frac( float64 a )
-{
-
- return a & LIT64( 0x000FFFFFFFFFFFFF );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int16 extractFloat64Exp( float64 a )
-{
-
- return ( a>>52 ) & 0x7FF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloat64Sign( float64 a )
-{
-
- return a>>63;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal double-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros64( aSig ) - 11;
- *zSigPtr = aSig<<shiftCount;
- *zExpPtr = 1 - shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| double-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
-{
-
- return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the double-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded
-| to a subnormal number, and the underflow and inexact exceptions are raised
-| if the abstract input cannot be represented exactly as a subnormal double-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 62
-| and 61, which is 10 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven;
- int16 roundIncrement, roundBits;
- flag isTiny;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- roundIncrement = 0x200;
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = 0x3FF;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = zSig & 0x3FF;
- if ( 0x7FD <= (bits16) zExp ) {
- if ( ( 0x7FD < zExp )
- || ( ( zExp == 0x7FD )
- && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
- ) {
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
- }
- if ( zExp < 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < -1 )
- || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
- shift64RightJamming( zSig, - zExp, &zSig );
- zExp = 0;
- roundBits = zSig & 0x3FF;
- if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
- }
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig = ( zSig + roundIncrement )>>10;
- zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
- if ( zSig == 0 ) zExp = 0;
- return packFloat64( zSign, zExp, zSig );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
-| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-static float64
- normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM)
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros64( zSig ) - 1;
- return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloatx80Frac( floatx80 a )
-{
-
- return a.low;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int32 extractFloatx80Exp( floatx80 a )
-{
-
- return a.high & 0x7FFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the extended double-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloatx80Sign( floatx80 a )
-{
-
- return a.high>>15;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal extended double-precision floating-point value
-| represented by the denormalized significand `aSig'. The normalized exponent
-| and significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros64( aSig );
- *zSigPtr = aSig<<shiftCount;
- *zExpPtr = 1 - shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
-| extended double-precision floating-point value, returning the result.
-*----------------------------------------------------------------------------*/
-
-INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
-{
- floatx80 z;
-
- z.low = zSig;
- z.high = ( ( (bits16) zSign )<<15 ) + zExp;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| rounded and packed into the extended double-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal extended
-| double-precision floating-point number.
-| If `roundingPrecision' is 32 or 64, the result is rounded to the same
-| number of bits as single or double precision, respectively. Otherwise, the
-| result is rounded to the full precision of the extended double-precision
-| format.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. The
-| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80
- roundAndPackFloatx80(
- int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
- STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven, increment, isTiny;
- int64 roundIncrement, roundMask, roundBits;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- if ( roundingPrecision == 80 ) goto precision80;
- if ( roundingPrecision == 64 ) {
- roundIncrement = LIT64( 0x0000000000000400 );
- roundMask = LIT64( 0x00000000000007FF );
- }
- else if ( roundingPrecision == 32 ) {
- roundIncrement = LIT64( 0x0000008000000000 );
- roundMask = LIT64( 0x000000FFFFFFFFFF );
- }
- else {
- goto precision80;
- }
- zSig0 |= ( zSig1 != 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = roundMask;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = zSig0 & roundMask;
- if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
- if ( ( 0x7FFE < zExp )
- || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
- ) {
- goto overflow;
- }
- if ( zExp <= 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < 0 )
- || ( zSig0 <= zSig0 + roundIncrement );
- shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
- zExp = 0;
- roundBits = zSig0 & roundMask;
- if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig0 += roundIncrement;
- if ( (sbits64) zSig0 < 0 ) zExp = 1;
- roundIncrement = roundMask + 1;
- if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
- roundMask |= roundIncrement;
- }
- zSig0 &= ~ roundMask;
- return packFloatx80( zSign, zExp, zSig0 );
- }
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig0 += roundIncrement;
- if ( zSig0 < roundIncrement ) {
- ++zExp;
- zSig0 = LIT64( 0x8000000000000000 );
- }
- roundIncrement = roundMask + 1;
- if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
- roundMask |= roundIncrement;
- }
- zSig0 &= ~ roundMask;
- if ( zSig0 == 0 ) zExp = 0;
- return packFloatx80( zSign, zExp, zSig0 );
- precision80:
- increment = ( (sbits64) zSig1 < 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- increment = 0;
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig1;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig1;
- }
- }
- }
- if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
- if ( ( 0x7FFE < zExp )
- || ( ( zExp == 0x7FFE )
- && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
- && increment
- )
- ) {
- roundMask = 0;
- overflow:
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- if ( ( roundingMode == float_round_to_zero )
- || ( zSign && ( roundingMode == float_round_up ) )
- || ( ! zSign && ( roundingMode == float_round_down ) )
- ) {
- return packFloatx80( zSign, 0x7FFE, ~ roundMask );
- }
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( zExp <= 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < 0 )
- || ! increment
- || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
- shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
- zExp = 0;
- if ( isTiny && zSig1 ) float_raise( float_flag_underflow STATUS_VAR);
- if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- if ( roundNearestEven ) {
- increment = ( (sbits64) zSig1 < 0 );
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig1;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig1;
- }
- }
- if ( increment ) {
- ++zSig0;
- zSig0 &=
- ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
- if ( (sbits64) zSig0 < 0 ) zExp = 1;
- }
- return packFloatx80( zSign, zExp, zSig0 );
- }
- }
- if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- if ( increment ) {
- ++zSig0;
- if ( zSig0 == 0 ) {
- ++zExp;
- zSig0 = LIT64( 0x8000000000000000 );
- }
- else {
- zSig0 &= ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
- }
- }
- else {
- if ( zSig0 == 0 ) zExp = 0;
- }
- return packFloatx80( zSign, zExp, zSig0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent
-| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. This routine is just like
-| `roundAndPackFloatx80' except that the input significand does not have to be
-| normalized.
-*----------------------------------------------------------------------------*/
-
-static floatx80
- normalizeRoundAndPackFloatx80(
- int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
- STATUS_PARAM)
-{
- int8 shiftCount;
-
- if ( zSig0 == 0 ) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- shiftCount = countLeadingZeros64( zSig0 );
- shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
- zExp -= shiftCount;
- return
- roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 STATUS_VAR);
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the least-significant 64 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloat128Frac1( float128 a )
-{
-
- return a.low;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the most-significant 48 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloat128Frac0( float128 a )
-{
-
- return a.high & LIT64( 0x0000FFFFFFFFFFFF );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the quadruple-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int32 extractFloat128Exp( float128 a )
-{
-
- return ( a.high>>48 ) & 0x7FFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the quadruple-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloat128Sign( float128 a )
-{
-
- return a.high>>63;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal quadruple-precision floating-point value
-| represented by the denormalized significand formed by the concatenation of
-| `aSig0' and `aSig1'. The normalized exponent is stored at the location
-| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
-| significand are stored at the location pointed to by `zSig0Ptr', and the
-| least significant 64 bits of the normalized significand are stored at the
-| location pointed to by `zSig1Ptr'.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloat128Subnormal(
- bits64 aSig0,
- bits64 aSig1,
- int32 *zExpPtr,
- bits64 *zSig0Ptr,
- bits64 *zSig1Ptr
- )
-{
- int8 shiftCount;
-
- if ( aSig0 == 0 ) {
- shiftCount = countLeadingZeros64( aSig1 ) - 15;
- if ( shiftCount < 0 ) {
- *zSig0Ptr = aSig1>>( - shiftCount );
- *zSig1Ptr = aSig1<<( shiftCount & 63 );
- }
- else {
- *zSig0Ptr = aSig1<<shiftCount;
- *zSig1Ptr = 0;
- }
- *zExpPtr = - shiftCount - 63;
- }
- else {
- shiftCount = countLeadingZeros64( aSig0 ) - 15;
- shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
- *zExpPtr = 1 - shiftCount;
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', the exponent `zExp', and the significand formed
-| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
-| floating-point value, returning the result. After being shifted into the
-| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
-| added together to form the most significant 32 bits of the result. This
-| means that any integer portion of `zSig0' will be added into the exponent.
-| Since a properly normalized significand will have an integer portion equal
-| to 1, the `zExp' input should be 1 less than the desired result exponent
-| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-INLINE float128
- packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
-{
- float128 z;
-
- z.low = zSig1;
- z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0', `zSig1',
-| and `zSig2', and returns the proper quadruple-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| simply rounded and packed into the quadruple-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal quadruple-
-| precision floating-point number.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. In the
-| usual case that the input significand is normalized, `zExp' must be 1 less
-| than the ``true'' floating-point exponent. The handling of underflow and
-| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128
- roundAndPackFloat128(
- flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven, increment, isTiny;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- increment = ( (sbits64) zSig2 < 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- increment = 0;
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig2;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig2;
- }
- }
- }
- if ( 0x7FFD <= (bits32) zExp ) {
- if ( ( 0x7FFD < zExp )
- || ( ( zExp == 0x7FFD )
- && eq128(
- LIT64( 0x0001FFFFFFFFFFFF ),
- LIT64( 0xFFFFFFFFFFFFFFFF ),
- zSig0,
- zSig1
- )
- && increment
- )
- ) {
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- if ( ( roundingMode == float_round_to_zero )
- || ( zSign && ( roundingMode == float_round_up ) )
- || ( ! zSign && ( roundingMode == float_round_down ) )
- ) {
- return
- packFloat128(
- zSign,
- 0x7FFE,
- LIT64( 0x0000FFFFFFFFFFFF ),
- LIT64( 0xFFFFFFFFFFFFFFFF )
- );
- }
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( zExp < 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < -1 )
- || ! increment
- || lt128(
- zSig0,
- zSig1,
- LIT64( 0x0001FFFFFFFFFFFF ),
- LIT64( 0xFFFFFFFFFFFFFFFF )
- );
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
- zExp = 0;
- if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR);
- if ( roundNearestEven ) {
- increment = ( (sbits64) zSig2 < 0 );
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig2;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig2;
- }
- }
- }
- }
- if ( zSig2 ) STATUS(float_exception_flags) |= float_flag_inexact;
- if ( increment ) {
- add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
- zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
- }
- else {
- if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
- }
- return packFloat128( zSign, zExp, zSig0, zSig1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand formed by the concatenation of `zSig0' and `zSig1', and
-| returns the proper quadruple-precision floating-point value corresponding
-| to the abstract input. This routine is just like `roundAndPackFloat128'
-| except that the input significand has fewer bits and does not have to be
-| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
-| point exponent.
-*----------------------------------------------------------------------------*/
-
-static float128
- normalizeRoundAndPackFloat128(
- flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 STATUS_PARAM)
-{
- int8 shiftCount;
- bits64 zSig2;
-
- if ( zSig0 == 0 ) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- shiftCount = countLeadingZeros64( zSig0 ) - 15;
- if ( 0 <= shiftCount ) {
- zSig2 = 0;
- shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
- }
- else {
- shift128ExtraRightJamming(
- zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
- }
- zExp -= shiftCount;
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR);
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the single-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 int32_to_float32( int32 a STATUS_PARAM )
-{
- flag zSign;
-
- if ( a == 0 ) return 0;
- if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
- zSign = ( a < 0 );
- return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 int32_to_float64( int32 a STATUS_PARAM )
-{
- flag zSign;
- uint32 absA;
- int8 shiftCount;
- bits64 zSig;
-
- if ( a == 0 ) return 0;
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros32( absA ) + 21;
- zSig = absA;
- return packFloat64( zSign, 0x432 - shiftCount, zSig<<shiftCount );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 int32_to_floatx80( int32 a STATUS_PARAM )
-{
- flag zSign;
- uint32 absA;
- int8 shiftCount;
- bits64 zSig;
-
- if ( a == 0 ) return packFloatx80( 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros32( absA ) + 32;
- zSig = absA;
- return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a' to
-| the quadruple-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 int32_to_float128( int32 a STATUS_PARAM )
-{
- flag zSign;
- uint32 absA;
- int8 shiftCount;
- bits64 zSig0;
-
- if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros32( absA ) + 17;
- zSig0 = absA;
- return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a'
-| to the single-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 int64_to_float32( int64 a STATUS_PARAM )
-{
- flag zSign;
- uint64 absA;
- int8 shiftCount;
-
- if ( a == 0 ) return 0;
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros64( absA ) - 40;
- if ( 0 <= shiftCount ) {
- return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
- }
- else {
- shiftCount += 7;
- if ( shiftCount < 0 ) {
- shift64RightJamming( absA, - shiftCount, &absA );
- }
- else {
- absA <<= shiftCount;
- }
- return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a'
-| to the double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 int64_to_float64( int64 a STATUS_PARAM )
-{
- flag zSign;
-
- if ( a == 0 ) return 0;
- if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) {
- return packFloat64( 1, 0x43E, 0 );
- }
- zSign = ( a < 0 );
- return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a'
-| to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 int64_to_floatx80( int64 a STATUS_PARAM )
-{
- flag zSign;
- uint64 absA;
- int8 shiftCount;
-
- if ( a == 0 ) return packFloatx80( 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros64( absA );
- return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a' to
-| the quadruple-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 int64_to_float128( int64 a STATUS_PARAM )
-{
- flag zSign;
- uint64 absA;
- int8 shiftCount;
- int32 zExp;
- bits64 zSig0, zSig1;
-
- if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros64( absA ) + 49;
- zExp = 0x406E - shiftCount;
- if ( 64 <= shiftCount ) {
- zSig1 = 0;
- zSig0 = absA;
- shiftCount -= 64;
- }
- else {
- zSig1 = absA;
- zSig0 = 0;
- }
- shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
- return packFloat128( zSign, zExp, zSig0, zSig1 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 float32_to_int32( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- bits64 aSig64;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
- if ( aExp ) aSig |= 0x00800000;
- shiftCount = 0xAF - aExp;
- aSig64 = aSig;
- aSig64 <<= 32;
- if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 );
- return roundAndPackInt32( aSign, aSig64 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- int32 z;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- shiftCount = aExp - 0x9E;
- if ( 0 <= shiftCount ) {
- if ( a != 0xCF000000 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
- }
- return (sbits32) 0x80000000;
- }
- else if ( aExp <= 0x7E ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig = ( aSig | 0x00800000 )<<8;
- z = aSig>>( - shiftCount );
- if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 float32_to_int64( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- bits64 aSig64, aSigExtra;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- shiftCount = 0xBE - aExp;
- if ( shiftCount < 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- if ( aExp ) aSig |= 0x00800000;
- aSig64 = aSig;
- aSig64 <<= 40;
- shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra );
- return roundAndPackInt64( aSign, aSig64, aSigExtra STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero. If
-| `a' is a NaN, the largest positive integer is returned. Otherwise, if the
-| conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- bits64 aSig64;
- int64 z;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- shiftCount = aExp - 0xBE;
- if ( 0 <= shiftCount ) {
- if ( a != 0xDF000000 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- else if ( aExp <= 0x7E ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig64 = aSig | 0x00800000;
- aSig64 <<= 40;
- z = aSig64>>( - shiftCount );
- if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the double-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float32_to_float64( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits32 aSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ));
- return packFloat64( aSign, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- --aExp;
- }
- return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float32_to_floatx80( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits32 aSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) );
- return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- aSig |= 0x00800000;
- return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the double-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float32_to_float128( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits32 aSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) );
- return packFloat128( aSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- --aExp;
- }
- return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the single-precision floating-point value `a' to an integer, and
-| returns the result as a single-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_round_to_int( float32 a STATUS_PARAM)
-{
- flag aSign;
- int16 aExp;
- bits32 lastBitMask, roundBitsMask;
- int8 roundingMode;
- float32 z;
-
- aExp = extractFloat32Exp( a );
- if ( 0x96 <= aExp ) {
- if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
- return propagateFloat32NaN( a, a STATUS_VAR );
- }
- return a;
- }
- if ( aExp <= 0x7E ) {
- if ( (bits32) ( a<<1 ) == 0 ) return a;
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloat32Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
- return packFloat32( aSign, 0x7F, 0 );
- }
- break;
- case float_round_down:
- return aSign ? 0xBF800000 : 0;
- case float_round_up:
- return aSign ? 0x80000000 : 0x3F800000;
- }
- return packFloat32( aSign, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x96 - aExp;
- roundBitsMask = lastBitMask - 1;
- z = a;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z += lastBitMask>>1;
- if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
- z += roundBitsMask;
- }
- }
- z &= ~ roundBitsMask;
- if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the single-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
-{
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 6;
- bSig <<= 6;
- if ( 0 < expDiff ) {
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= 0x20000000;
- }
- shift32RightJamming( bSig, expDiff, &bSig );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= 0x20000000;
- }
- shift32RightJamming( aSig, - expDiff, &aSig );
- zExp = bExp;
- }
- else {
- if ( aExp == 0xFF ) {
- if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
- zSig = 0x40000000 + aSig + bSig;
- zExp = aExp;
- goto roundAndPack;
- }
- aSig |= 0x20000000;
- zSig = ( aSig + bSig )<<1;
- --zExp;
- if ( (sbits32) zSig < 0 ) {
- zSig = aSig + bSig;
- ++zExp;
- }
- roundAndPack:
- return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the single-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
-{
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 7;
- bSig <<= 7;
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0xFF ) {
- if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- if ( bSig < aSig ) goto aBigger;
- if ( aSig < bSig ) goto bBigger;
- return packFloat32( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
- bExpBigger:
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return packFloat32( zSign ^ 1, 0xFF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= 0x40000000;
- }
- shift32RightJamming( aSig, - expDiff, &aSig );
- bSig |= 0x40000000;
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= 0x40000000;
- }
- shift32RightJamming( bSig, expDiff, &bSig );
- aSig |= 0x40000000;
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the single-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_add( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign == bSign ) {
- return addFloat32Sigs( a, b, aSign STATUS_VAR);
- }
- else {
- return subFloat32Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sub( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign == bSign ) {
- return subFloat32Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloat32Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_mul( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig;
- bits64 zSig64;
- bits32 zSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0xFF ) {
- if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
- return propagateFloat32NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
- normalizeFloat32Subnormal( bSig, &bExp, &bSig );
- }
- zExp = aExp + bExp - 0x7F;
- aSig = ( aSig | 0x00800000 )<<7;
- bSig = ( bSig | 0x00800000 )<<8;
- shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
- zSig = zSig64;
- if ( 0 <= (sbits32) ( zSig<<1 ) ) {
- zSig <<= 1;
- --zExp;
- }
- return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the single-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_div( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig, zSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return packFloat32( zSign, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloat32( zSign, 0xFF, 0 );
- }
- normalizeFloat32Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- zExp = aExp - bExp + 0x7D;
- aSig = ( aSig | 0x00800000 )<<7;
- bSig = ( bSig | 0x00800000 )<<8;
- if ( bSig <= ( aSig + aSig ) ) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = ( ( (bits64) aSig )<<32 ) / bSig;
- if ( ( zSig & 0x3F ) == 0 ) {
- zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 );
- }
- return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the single-precision floating-point value `a'
-| with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_rem( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, expDiff;
- bits32 aSig, bSig;
- bits32 q;
- bits64 aSig64, bSig64, q64;
- bits32 alternateASig;
- sbits32 sigMean;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
- if ( aExp == 0xFF ) {
- if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
- return propagateFloat32NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- normalizeFloat32Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return a;
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- expDiff = aExp - bExp;
- aSig |= 0x00800000;
- bSig |= 0x00800000;
- if ( expDiff < 32 ) {
- aSig <<= 8;
- bSig <<= 8;
- if ( expDiff < 0 ) {
- if ( expDiff < -1 ) return a;
- aSig >>= 1;
- }
- q = ( bSig <= aSig );
- if ( q ) aSig -= bSig;
- if ( 0 < expDiff ) {
- q = ( ( (bits64) aSig )<<32 ) / bSig;
- q >>= 32 - expDiff;
- bSig >>= 2;
- aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
- }
- else {
- aSig >>= 2;
- bSig >>= 2;
- }
- }
- else {
- if ( bSig <= aSig ) aSig -= bSig;
- aSig64 = ( (bits64) aSig )<<40;
- bSig64 = ( (bits64) bSig )<<40;
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q64 = estimateDiv128To64( aSig64, 0, bSig64 );
- q64 = ( 2 < q64 ) ? q64 - 2 : 0;
- aSig64 = - ( ( bSig * q64 )<<38 );
- expDiff -= 62;
- }
- expDiff += 64;
- q64 = estimateDiv128To64( aSig64, 0, bSig64 );
- q64 = ( 2 < q64 ) ? q64 - 2 : 0;
- q = q64>>( 64 - expDiff );
- bSig <<= 6;
- aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
- }
- do {
- alternateASig = aSig;
- ++q;
- aSig -= bSig;
- } while ( 0 <= (sbits32) aSig );
- sigMean = aSig + alternateASig;
- if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
- aSig = alternateASig;
- }
- zSign = ( (sbits32) aSig < 0 );
- if ( zSign ) aSig = - aSig;
- return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the single-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sqrt( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, zExp;
- bits32 aSig, zSig;
- bits64 rem, term;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, 0 STATUS_VAR );
- if ( ! aSign ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( aSign ) {
- if ( ( aExp | aSig ) == 0 ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return 0;
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
- aSig = ( aSig | 0x00800000 )<<8;
- zSig = estimateSqrt32( aExp, aSig ) + 2;
- if ( ( zSig & 0x7F ) <= 5 ) {
- if ( zSig < 2 ) {
- zSig = 0x7FFFFFFF;
- goto roundAndPack;
- }
- aSig >>= aExp & 1;
- term = ( (bits64) zSig ) * zSig;
- rem = ( ( (bits64) aSig )<<32 ) - term;
- while ( (sbits64) rem < 0 ) {
- --zSig;
- rem += ( ( (bits64) zSig )<<1 ) | 1;
- }
- zSig |= ( rem != 0 );
- }
- shift32RightJamming( zSig, 1, &zSig );
- roundAndPack:
- return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_eq( float32 a, float32 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_le( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
- return ( a == b ) || ( aSign ^ ( a < b ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_lt( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
- return ( a != b ) && ( aSign ^ ( a < b ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
-| cause an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_le_quiet( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
- return ( a == b ) || ( aSign ^ ( a < b ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
-| exception. Otherwise, the comparison is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
- return ( a != b ) && ( aSign ^ ( a < b ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 float64_to_int32( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
- if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
- shiftCount = 0x42C - aExp;
- if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
- return roundAndPackInt32( aSign, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig, savedASig;
- int32 z;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( 0x41E < aExp ) {
- if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
- goto invalid;
- }
- else if ( aExp < 0x3FF ) {
- if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig |= LIT64( 0x0010000000000000 );
- shiftCount = 0x433 - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = aSig;
- if ( aSign ) z = - z;
- if ( ( z < 0 ) ^ aSign ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( ( aSig<<shiftCount ) != savedASig ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 float64_to_int64( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig, aSigExtra;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
- shiftCount = 0x433 - aExp;
- if ( shiftCount <= 0 ) {
- if ( 0x43E < aExp ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FF )
- && ( aSig != LIT64( 0x0010000000000000 ) ) )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- aSigExtra = 0;
- aSig <<= - shiftCount;
- }
- else {
- shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
- }
- return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig;
- int64 z;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
- shiftCount = aExp - 0x433;
- if ( 0 <= shiftCount ) {
- if ( 0x43E <= aExp ) {
- if ( a != LIT64( 0xC3E0000000000000 ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FF )
- && ( aSig != LIT64( 0x0010000000000000 ) ) )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- z = aSig<<shiftCount;
- }
- else {
- if ( aExp < 0x3FE ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- z = aSig>>( - shiftCount );
- if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the single-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float64_to_float32( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig;
- bits32 zSig;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) );
- return packFloat32( aSign, 0xFF, 0 );
- }
- shift64RightJamming( aSig, 22, &aSig );
- zSig = aSig;
- if ( aExp || zSig ) {
- zSig |= 0x40000000;
- aExp -= 0x381;
- }
- return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) );
- return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- return
- packFloatx80(
- aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the quadruple-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float64_to_float128( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig, zSig0, zSig1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) );
- return packFloat128( aSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- --aExp;
- }
- shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
- return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the double-precision floating-point value `a' to an integer, and
-| returns the result as a double-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_round_to_int( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 lastBitMask, roundBitsMask;
- int8 roundingMode;
- float64 z;
-
- aExp = extractFloat64Exp( a );
- if ( 0x433 <= aExp ) {
- if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
- return propagateFloat64NaN( a, a STATUS_VAR );
- }
- return a;
- }
- if ( aExp < 0x3FF ) {
- if ( (bits64) ( a<<1 ) == 0 ) return a;
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloat64Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
- return packFloat64( aSign, 0x3FF, 0 );
- }
- break;
- case float_round_down:
- return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
- case float_round_up:
- return
- aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
- }
- return packFloat64( aSign, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x433 - aExp;
- roundBitsMask = lastBitMask - 1;
- z = a;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z += lastBitMask>>1;
- if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
- z += roundBitsMask;
- }
- }
- z &= ~ roundBitsMask;
- if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-float64 float64_trunc_to_int( float64 a STATUS_PARAM)
-{
- int oldmode;
- float64 res;
- oldmode = STATUS(float_rounding_mode);
- STATUS(float_rounding_mode) = float_round_to_zero;
- res = float64_round_to_int(a STATUS_VAR);
- STATUS(float_rounding_mode) = oldmode;
- return res;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the double-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
-{
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 9;
- bSig <<= 9;
- if ( 0 < expDiff ) {
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= LIT64( 0x2000000000000000 );
- }
- shift64RightJamming( bSig, expDiff, &bSig );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= LIT64( 0x2000000000000000 );
- }
- shift64RightJamming( aSig, - expDiff, &aSig );
- zExp = bExp;
- }
- else {
- if ( aExp == 0x7FF ) {
- if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
- zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
- zExp = aExp;
- goto roundAndPack;
- }
- aSig |= LIT64( 0x2000000000000000 );
- zSig = ( aSig + bSig )<<1;
- --zExp;
- if ( (sbits64) zSig < 0 ) {
- zSig = aSig + bSig;
- ++zExp;
- }
- roundAndPack:
- return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
-{
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 10;
- bSig <<= 10;
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0x7FF ) {
- if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- if ( bSig < aSig ) goto aBigger;
- if ( aSig < bSig ) goto bBigger;
- return packFloat64( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
- bExpBigger:
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return packFloat64( zSign ^ 1, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= LIT64( 0x4000000000000000 );
- }
- shift64RightJamming( aSig, - expDiff, &aSig );
- bSig |= LIT64( 0x4000000000000000 );
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= LIT64( 0x4000000000000000 );
- }
- shift64RightJamming( bSig, expDiff, &bSig );
- aSig |= LIT64( 0x4000000000000000 );
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the double-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_add( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign == bSign ) {
- return addFloat64Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return subFloat64Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sub( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign == bSign ) {
- return subFloat64Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloat64Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_mul( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FF ) {
- if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
- return propagateFloat64NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
- normalizeFloat64Subnormal( bSig, &bExp, &bSig );
- }
- zExp = aExp + bExp - 0x3FF;
- aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
- bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
- mul64To128( aSig, bSig, &zSig0, &zSig1 );
- zSig0 |= ( zSig1 != 0 );
- if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
- zSig0 <<= 1;
- --zExp;
- }
- return roundAndPackFloat64( zSign, zExp, zSig0 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the double-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_div( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig;
- bits64 rem0, rem1;
- bits64 term0, term1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return packFloat64( zSign, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloat64( zSign, 0x7FF, 0 );
- }
- normalizeFloat64Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- zExp = aExp - bExp + 0x3FD;
- aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
- bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
- if ( bSig <= ( aSig + aSig ) ) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = estimateDiv128To64( aSig, 0, bSig );
- if ( ( zSig & 0x1FF ) <= 2 ) {
- mul64To128( bSig, zSig, &term0, &term1 );
- sub128( aSig, 0, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig;
- add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
- }
- zSig |= ( rem1 != 0 );
- }
- return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the double-precision floating-point value `a'
-| with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_rem( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, expDiff;
- bits64 aSig, bSig;
- bits64 q, alternateASig;
- sbits64 sigMean;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
- if ( aExp == 0x7FF ) {
- if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
- return propagateFloat64NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- normalizeFloat64Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return a;
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- expDiff = aExp - bExp;
- aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
- bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
- if ( expDiff < 0 ) {
- if ( expDiff < -1 ) return a;
- aSig >>= 1;
- }
- q = ( bSig <= aSig );
- if ( q ) aSig -= bSig;
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig, 0, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- aSig = - ( ( bSig>>2 ) * q );
- expDiff -= 62;
- }
- expDiff += 64;
- if ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig, 0, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- q >>= 64 - expDiff;
- bSig >>= 2;
- aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
- }
- else {
- aSig >>= 2;
- bSig >>= 2;
- }
- do {
- alternateASig = aSig;
- ++q;
- aSig -= bSig;
- } while ( 0 <= (sbits64) aSig );
- sigMean = aSig + alternateASig;
- if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
- aSig = alternateASig;
- }
- zSign = ( (sbits64) aSig < 0 );
- if ( zSign ) aSig = - aSig;
- return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the double-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sqrt( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, zExp;
- bits64 aSig, zSig, doubleZSig;
- bits64 rem0, rem1, term0, term1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
- if ( ! aSign ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( aSign ) {
- if ( ( aExp | aSig ) == 0 ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return 0;
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
- aSig |= LIT64( 0x0010000000000000 );
- zSig = estimateSqrt32( aExp, aSig>>21 );
- aSig <<= 9 - ( aExp & 1 );
- zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
- if ( ( zSig & 0x1FF ) <= 5 ) {
- doubleZSig = zSig<<1;
- mul64To128( zSig, zSig, &term0, &term1 );
- sub128( aSig, 0, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig;
- doubleZSig -= 2;
- add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
- }
- zSig |= ( ( rem0 | rem1 ) != 0 );
- }
- return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_eq( float64 a, float64 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise. The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_le( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
- return ( a == b ) || ( aSign ^ ( a < b ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_lt( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
- return ( a != b ) && ( aSign ^ ( a < b ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise. The invalid exception is raised
-| if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
-| cause an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_le_quiet( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
- return ( a == b ) || ( aSign ^ ( a < b ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
-| exception. Otherwise, the comparison is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
- return ( a != b ) && ( aSign ^ ( a < b ) );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 32-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic---which means in particular that the conversion
-| is rounded according to the current rounding mode. If `a' is a NaN, the
-| largest positive integer is returned. Otherwise, if the conversion
-| overflows, the largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
- shiftCount = 0x4037 - aExp;
- if ( shiftCount <= 0 ) shiftCount = 1;
- shift64RightJamming( aSig, shiftCount, &aSig );
- return roundAndPackInt32( aSign, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 32-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic, except that the conversion is always rounded
-| toward zero. If `a' is a NaN, the largest positive integer is returned.
-| Otherwise, if the conversion overflows, the largest integer with the same
-| sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig, savedASig;
- int32 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( 0x401E < aExp ) {
- if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
- goto invalid;
- }
- else if ( aExp < 0x3FFF ) {
- if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- shiftCount = 0x403E - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = aSig;
- if ( aSign ) z = - z;
- if ( ( z < 0 ) ^ aSign ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( ( aSig<<shiftCount ) != savedASig ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 64-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic---which means in particular that the conversion
-| is rounded according to the current rounding mode. If `a' is a NaN,
-| the largest positive integer is returned. Otherwise, if the conversion
-| overflows, the largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig, aSigExtra;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- shiftCount = 0x403E - aExp;
- if ( shiftCount <= 0 ) {
- if ( shiftCount ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FFF )
- && ( aSig != LIT64( 0x8000000000000000 ) ) )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- aSigExtra = 0;
- }
- else {
- shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
- }
- return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 64-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic, except that the conversion is always rounded
-| toward zero. If `a' is a NaN, the largest positive integer is returned.
-| Otherwise, if the conversion overflows, the largest integer with the same
-| sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig;
- int64 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- shiftCount = aExp - 0x403E;
- if ( 0 <= shiftCount ) {
- aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
- if ( ( a.high != 0xC03E ) || aSig ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- else if ( aExp < 0x3FFF ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- z = aSig>>( - shiftCount );
- if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the single-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) {
- return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat32( aSign, 0xFF, 0 );
- }
- shift64RightJamming( aSig, 33, &aSig );
- if ( aExp || aSig ) aExp -= 0x3F81;
- return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig, zSig;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) {
- return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat64( aSign, 0x7FF, 0 );
- }
- shift64RightJamming( aSig, 1, &zSig );
- if ( aExp || aSig ) aExp -= 0x3C01;
- return roundAndPackFloat64( aSign, aExp, zSig STATUS_VAR );
-
-}
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the quadruple-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig, zSig0, zSig1;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
- return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) );
- }
- shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
- return packFloat128( aSign, aExp, zSig0, zSig1 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the extended double-precision floating-point value `a' to an integer,
-| and returns the result as an extended quadruple-precision floating-point
-| value. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 lastBitMask, roundBitsMask;
- int8 roundingMode;
- floatx80 z;
-
- aExp = extractFloatx80Exp( a );
- if ( 0x403E <= aExp ) {
- if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
- return propagateFloatx80NaN( a, a STATUS_VAR );
- }
- return a;
- }
- if ( aExp < 0x3FFF ) {
- if ( ( aExp == 0 )
- && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
- return a;
- }
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloatx80Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
- ) {
- return
- packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
- }
- break;
- case float_round_down:
- return
- aSign ?
- packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
- : packFloatx80( 0, 0, 0 );
- case float_round_up:
- return
- aSign ? packFloatx80( 1, 0, 0 )
- : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
- }
- return packFloatx80( aSign, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x403E - aExp;
- roundBitsMask = lastBitMask - 1;
- z = a;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z.low += lastBitMask>>1;
- if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
- z.low += roundBitsMask;
- }
- }
- z.low &= ~ roundBitsMask;
- if ( z.low == 0 ) {
- ++z.high;
- z.low = LIT64( 0x8000000000000000 );
- }
- if ( z.low != a.low ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the extended double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is
-| negated before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM)
-{
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- int32 expDiff;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- expDiff = aExp - bExp;
- if ( 0 < expDiff ) {
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) --expDiff;
- shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) ++expDiff;
- shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
- zExp = bExp;
- }
- else {
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- return a;
- }
- zSig1 = 0;
- zSig0 = aSig + bSig;
- if ( aExp == 0 ) {
- normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
- goto roundAndPack;
- }
- zExp = aExp;
- goto shiftRight1;
- }
- zSig0 = aSig + bSig;
- if ( (sbits64) zSig0 < 0 ) goto roundAndPack;
- shiftRight1:
- shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
- zSig0 |= LIT64( 0x8000000000000000 );
- ++zExp;
- roundAndPack:
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the extended
-| double-precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM )
-{
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- int32 expDiff;
- floatx80 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- expDiff = aExp - bExp;
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- zSig1 = 0;
- if ( bSig < aSig ) goto aBigger;
- if ( aSig < bSig ) goto bBigger;
- return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
- bExpBigger:
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) ++expDiff;
- shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
- bBigger:
- sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) --expDiff;
- shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
- aBigger:
- sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
- zExp = aExp;
- normalizeRoundAndPack:
- return
- normalizeRoundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the extended double-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign == bSign ) {
- return addFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return subFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign == bSign ) {
- return subFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- floatx80 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 )
- || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig ) == 0 ) goto invalid;
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
- normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
- normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
- }
- zExp = aExp + bExp - 0x3FFE;
- mul64To128( aSig, bSig, &zSig0, &zSig1 );
- if ( 0 < (sbits64) zSig0 ) {
- shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
- --zExp;
- }
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the extended double-precision floating-point
-| value `a' by the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- bits64 rem0, rem1, rem2, term0, term1, term2;
- floatx80 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- goto invalid;
- }
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return packFloatx80( zSign, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- if ( ( aExp | aSig ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
- normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
- }
- zExp = aExp - bExp + 0x3FFE;
- rem1 = 0;
- if ( bSig <= aSig ) {
- shift128Right( aSig, 0, 1, &aSig, &rem1 );
- ++zExp;
- }
- zSig0 = estimateDiv128To64( aSig, rem1, bSig );
- mul64To128( bSig, zSig0, &term0, &term1 );
- sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
- }
- zSig1 = estimateDiv128To64( rem1, 0, bSig );
- if ( (bits64) ( zSig1<<1 ) <= 8 ) {
- mul64To128( bSig, zSig1, &term1, &term2 );
- sub128( rem1, 0, term1, term2, &rem1, &rem2 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
- }
- zSig1 |= ( ( rem1 | rem2 ) != 0 );
- }
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the extended double-precision floating-point value
-| `a' with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, expDiff;
- bits64 aSig0, aSig1, bSig;
- bits64 q, term0, term1, alternateASig0, alternateASig1;
- floatx80 z;
-
- aSig0 = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig0<<1 )
- || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- goto invalid;
- }
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
- normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
- }
- bSig |= LIT64( 0x8000000000000000 );
- zSign = aSign;
- expDiff = aExp - bExp;
- aSig1 = 0;
- if ( expDiff < 0 ) {
- if ( expDiff < -1 ) return a;
- shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
- expDiff = 0;
- }
- q = ( bSig <= aSig0 );
- if ( q ) aSig0 -= bSig;
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- mul64To128( bSig, q, &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
- shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
- expDiff -= 62;
- }
- expDiff += 64;
- if ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- q >>= 64 - expDiff;
- mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
- shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
- while ( le128( term0, term1, aSig0, aSig1 ) ) {
- ++q;
- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
- }
- }
- else {
- term1 = 0;
- term0 = bSig;
- }
- sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
- if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
- || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
- && ( q & 1 ) )
- ) {
- aSig0 = alternateASig0;
- aSig1 = alternateASig1;
- zSign = ! zSign;
- }
- return
- normalizeRoundAndPackFloatx80(
- 80, zSign, bExp + expDiff, aSig0, aSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the extended double-precision floating-point
-| value `a'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, zExp;
- bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0;
- bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
- floatx80 z;
-
- aSig0 = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
- if ( ! aSign ) return a;
- goto invalid;
- }
- if ( aSign ) {
- if ( ( aExp | aSig0 ) == 0 ) return a;
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
- normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
- }
- zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
- zSig0 = estimateSqrt32( aExp, aSig0>>32 );
- shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
- zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
- doubleZSig0 = zSig0<<1;
- mul64To128( zSig0, zSig0, &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- doubleZSig0 -= 2;
- add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
- }
- zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
- if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
- if ( zSig1 == 0 ) zSig1 = 1;
- mul64To128( doubleZSig0, zSig1, &term1, &term2 );
- sub128( rem1, 0, term1, term2, &rem1, &rem2 );
- mul64To128( zSig1, zSig1, &term2, &term3 );
- sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- shortShift128Left( 0, zSig1, 1, &term2, &term3 );
- term3 |= 1;
- term2 |= doubleZSig0;
- add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
- }
- zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
- }
- shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
- zSig0 |= doubleZSig0;
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), 0, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| equal to the corresponding value `b', and 0 otherwise. The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- if ( floatx80_is_signaling_nan( a )
- || floatx80_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| less than or equal to the corresponding value `b', and 0 otherwise. The
-| comparison is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| less than the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is equal
-| to the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is less
-| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs
-| do not cause an exception. Otherwise, the comparison is performed according
-| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- if ( floatx80_is_signaling_nan( a )
- || floatx80_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is less
-| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause
-| an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- if ( floatx80_is_signaling_nan( a )
- || floatx80_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 32-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 float128_to_int32( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
- if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
- aSig0 |= ( aSig1 != 0 );
- shiftCount = 0x4028 - aExp;
- if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
- return roundAndPackInt32( aSign, aSig0 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 32-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero. If
-| `a' is a NaN, the largest positive integer is returned. Otherwise, if the
-| conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1, savedASig;
- int32 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- aSig0 |= ( aSig1 != 0 );
- if ( 0x401E < aExp ) {
- if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
- goto invalid;
- }
- else if ( aExp < 0x3FFF ) {
- if ( aExp || aSig0 ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig0 |= LIT64( 0x0001000000000000 );
- shiftCount = 0x402F - aExp;
- savedASig = aSig0;
- aSig0 >>= shiftCount;
- z = aSig0;
- if ( aSign ) z = - z;
- if ( ( z < 0 ) ^ aSign ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( ( aSig0<<shiftCount ) != savedASig ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 64-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 float128_to_int64( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
- shiftCount = 0x402F - aExp;
- if ( shiftCount <= 0 ) {
- if ( 0x403E < aExp ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FFF )
- && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
- )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
- }
- else {
- shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
- }
- return roundAndPackInt64( aSign, aSig0, aSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 64-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1;
- int64 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
- shiftCount = aExp - 0x402F;
- if ( 0 < shiftCount ) {
- if ( 0x403E <= aExp ) {
- aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
- if ( ( a.high == LIT64( 0xC03E000000000000 ) )
- && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
- if ( aSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- }
- else {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
- if ( (bits64) ( aSig1<<shiftCount ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- }
- else {
- if ( aExp < 0x3FFF ) {
- if ( aExp | aSig0 | aSig1 ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return 0;
- }
- z = aSig0>>( - shiftCount );
- if ( aSig1
- || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the single-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float128_to_float32( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig0, aSig1;
- bits32 zSig;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) {
- return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat32( aSign, 0xFF, 0 );
- }
- aSig0 |= ( aSig1 != 0 );
- shift64RightJamming( aSig0, 18, &aSig0 );
- zSig = aSig0;
- if ( aExp || zSig ) {
- zSig |= 0x40000000;
- aExp -= 0x3F81;
- }
- return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float128_to_float64( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) {
- return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat64( aSign, 0x7FF, 0 );
- }
- shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
- aSig0 |= ( aSig1 != 0 );
- if ( aExp || aSig0 ) {
- aSig0 |= LIT64( 0x4000000000000000 );
- aExp -= 0x3C01;
- }
- return roundAndPackFloat64( aSign, aExp, aSig0 STATUS_VAR );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the extended double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) {
- return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- else {
- aSig0 |= LIT64( 0x0001000000000000 );
- }
- shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
- return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 STATUS_VAR );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the quadruple-precision floating-point value `a' to an integer, and
-| returns the result as a quadruple-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_round_to_int( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 lastBitMask, roundBitsMask;
- int8 roundingMode;
- float128 z;
-
- aExp = extractFloat128Exp( a );
- if ( 0x402F <= aExp ) {
- if ( 0x406F <= aExp ) {
- if ( ( aExp == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
- ) {
- return propagateFloat128NaN( a, a STATUS_VAR );
- }
- return a;
- }
- lastBitMask = 1;
- lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
- roundBitsMask = lastBitMask - 1;
- z = a;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- if ( lastBitMask ) {
- add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
- if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
- }
- else {
- if ( (sbits64) z.low < 0 ) {
- ++z.high;
- if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1;
- }
- }
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat128Sign( z )
- ^ ( roundingMode == float_round_up ) ) {
- add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
- }
- }
- z.low &= ~ roundBitsMask;
- }
- else {
- if ( aExp < 0x3FFF ) {
- if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloat128Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x3FFE )
- && ( extractFloat128Frac0( a )
- | extractFloat128Frac1( a ) )
- ) {
- return packFloat128( aSign, 0x3FFF, 0, 0 );
- }
- break;
- case float_round_down:
- return
- aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
- : packFloat128( 0, 0, 0, 0 );
- case float_round_up:
- return
- aSign ? packFloat128( 1, 0, 0, 0 )
- : packFloat128( 0, 0x3FFF, 0, 0 );
- }
- return packFloat128( aSign, 0, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x402F - aExp;
- roundBitsMask = lastBitMask - 1;
- z.low = 0;
- z.high = a.high;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z.high += lastBitMask>>1;
- if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
- z.high &= ~ lastBitMask;
- }
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat128Sign( z )
- ^ ( roundingMode == float_round_up ) ) {
- z.high |= ( a.low != 0 );
- z.high += roundBitsMask;
- }
- }
- z.high &= ~ roundBitsMask;
- }
- if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the quadruple-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
-{
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- int32 expDiff;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- expDiff = aExp - bExp;
- if ( 0 < expDiff ) {
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig0 |= LIT64( 0x0001000000000000 );
- }
- shift128ExtraRightJamming(
- bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig0 |= LIT64( 0x0001000000000000 );
- }
- shift128ExtraRightJamming(
- aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
- zExp = bExp;
- }
- else {
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- return a;
- }
- add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
- if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
- zSig2 = 0;
- zSig0 |= LIT64( 0x0002000000000000 );
- zExp = aExp;
- goto shiftRight1;
- }
- aSig0 |= LIT64( 0x0001000000000000 );
- add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
- --zExp;
- if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
- ++zExp;
- shiftRight1:
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
- roundAndPack:
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the quadruple-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
-{
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
- int32 expDiff;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- expDiff = aExp - bExp;
- shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
- shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- if ( bSig0 < aSig0 ) goto aBigger;
- if ( aSig0 < bSig0 ) goto bBigger;
- if ( bSig1 < aSig1 ) goto aBigger;
- if ( aSig1 < bSig1 ) goto bBigger;
- return packFloat128( STATUS(float_rounding_mode) == float_round_down, 0, 0, 0 );
- bExpBigger:
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig0 |= LIT64( 0x4000000000000000 );
- }
- shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
- bSig0 |= LIT64( 0x4000000000000000 );
- bBigger:
- sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig0 |= LIT64( 0x4000000000000000 );
- }
- shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
- aSig0 |= LIT64( 0x4000000000000000 );
- aBigger:
- sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the quadruple-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_add( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign == bSign ) {
- return addFloat128Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return subFloat128Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_sub( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign == bSign ) {
- return subFloat128Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloat128Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_mul( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( ( aSig0 | aSig1 )
- || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- if ( bExp == 0 ) {
- if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
- normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
- }
- zExp = aExp + bExp - 0x4000;
- aSig0 |= LIT64( 0x0001000000000000 );
- shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
- mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
- add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
- zSig2 |= ( zSig3 != 0 );
- if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
- ++zExp;
- }
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the quadruple-precision floating-point value
-| `a' by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_div( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- goto invalid;
- }
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return packFloat128( zSign, 0, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( ( bSig0 | bSig1 ) == 0 ) {
- if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- zExp = aExp - bExp + 0x3FFD;
- shortShift128Left(
- aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
- shortShift128Left(
- bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
- if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
- shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
- ++zExp;
- }
- zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
- mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
- sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
- }
- zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
- if ( ( zSig1 & 0x3FFF ) <= 4 ) {
- mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
- sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
- }
- zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
- }
- shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the quadruple-precision floating-point value `a'
-| with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_rem( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, expDiff;
- bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
- bits64 allZero, alternateASig0, alternateASig1, sigMean1;
- sbits64 sigMean0;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
- if ( aExp == 0x7FFF ) {
- if ( ( aSig0 | aSig1 )
- || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- goto invalid;
- }
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( ( bSig0 | bSig1 ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return a;
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- expDiff = aExp - bExp;
- if ( expDiff < -1 ) return a;
- shortShift128Left(
- aSig0 | LIT64( 0x0001000000000000 ),
- aSig1,
- 15 - ( expDiff < 0 ),
- &aSig0,
- &aSig1
- );
- shortShift128Left(
- bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
- q = le128( bSig0, bSig1, aSig0, aSig1 );
- if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig0 );
- q = ( 4 < q ) ? q - 4 : 0;
- mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
- shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
- shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
- sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
- expDiff -= 61;
- }
- if ( -64 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig0 );
- q = ( 4 < q ) ? q - 4 : 0;
- q >>= - expDiff;
- shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
- expDiff += 52;
- if ( expDiff < 0 ) {
- shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
- }
- else {
- shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
- }
- mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
- sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
- }
- else {
- shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
- shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
- }
- do {
- alternateASig0 = aSig0;
- alternateASig1 = aSig1;
- ++q;
- sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
- } while ( 0 <= (sbits64) aSig0 );
- add128(
- aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
- if ( ( sigMean0 < 0 )
- || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
- aSig0 = alternateASig0;
- aSig1 = alternateASig1;
- }
- zSign = ( (sbits64) aSig0 < 0 );
- if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
- return
- normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the quadruple-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_sqrt( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, zExp;
- bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
- bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
- if ( ! aSign ) return a;
- goto invalid;
- }
- if ( aSign ) {
- if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
- aSig0 |= LIT64( 0x0001000000000000 );
- zSig0 = estimateSqrt32( aExp, aSig0>>17 );
- shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
- zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
- doubleZSig0 = zSig0<<1;
- mul64To128( zSig0, zSig0, &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- doubleZSig0 -= 2;
- add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
- }
- zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
- if ( ( zSig1 & 0x1FFF ) <= 5 ) {
- if ( zSig1 == 0 ) zSig1 = 1;
- mul64To128( doubleZSig0, zSig1, &term1, &term2 );
- sub128( rem1, 0, term1, term2, &rem1, &rem2 );
- mul64To128( zSig1, zSig1, &term2, &term3 );
- sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- shortShift128Left( 0, zSig1, 1, &term2, &term3 );
- term3 |= 1;
- term2 |= doubleZSig0;
- add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
- }
- zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
- }
- shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
- return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_eq( float128 a, float128 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- if ( float128_is_signaling_nan( a )
- || float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_le( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_lt( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
-| cause an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- if ( float128_is_signaling_nan( a )
- || float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
-| exception. Otherwise, the comparison is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- if ( float128_is_signaling_nan( a )
- || float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-#endif
-
-/* misc functions */
-float32 uint32_to_float32( unsigned int a STATUS_PARAM )
-{
- return int64_to_float32(a STATUS_VAR);
-}
-
-float64 uint32_to_float64( unsigned int a STATUS_PARAM )
-{
- return int64_to_float64(a STATUS_VAR);
-}
-
-unsigned int float32_to_uint32( float32 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float32_to_int64(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float32_to_int64_round_to_zero(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-unsigned int float64_to_uint32( float64 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float64_to_int64(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float64_to_int64_round_to_zero(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-#define COMPARE(s, nan_exp) \
-INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \
- int is_quiet STATUS_PARAM ) \
-{ \
- flag aSign, bSign; \
- \
- if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \
- extractFloat ## s ## Frac( a ) ) || \
- ( ( extractFloat ## s ## Exp( b ) == nan_exp ) && \
- extractFloat ## s ## Frac( b ) )) { \
- if (!is_quiet || \
- float ## s ## _is_signaling_nan( a ) || \
- float ## s ## _is_signaling_nan( b ) ) { \
- float_raise( float_flag_invalid STATUS_VAR); \
- } \
- return float_relation_unordered; \
- } \
- aSign = extractFloat ## s ## Sign( a ); \
- bSign = extractFloat ## s ## Sign( b ); \
- if ( aSign != bSign ) { \
- if ( (bits ## s) ( ( a | b )<<1 ) == 0 ) { \
- /* zero case */ \
- return float_relation_equal; \
- } else { \
- return 1 - (2 * aSign); \
- } \
- } else { \
- if (a == b) { \
- return float_relation_equal; \
- } else { \
- return 1 - 2 * (aSign ^ ( a < b )); \
- } \
- } \
-} \
- \
-int float ## s ## _compare( float ## s a, float ## s b STATUS_PARAM ) \
-{ \
- return float ## s ## _compare_internal(a, b, 0 STATUS_VAR); \
-} \
- \
-int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \
-{ \
- return float ## s ## _compare_internal(a, b, 1 STATUS_VAR); \
-}
-
-COMPARE(32, 0xff)
-COMPARE(64, 0x7ff)
diff --git a/tools/ioemu/fpu/softfloat.h b/tools/ioemu/fpu/softfloat.h
deleted file mode 100644
index a326af8322..0000000000
--- a/tools/ioemu/fpu/softfloat.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*============================================================================
-
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-#ifndef SOFTFLOAT_H
-#define SOFTFLOAT_H
-
-#include <inttypes.h>
-#include "config.h"
-
-/*----------------------------------------------------------------------------
-| Each of the following `typedef's defines the most convenient type that holds
-| integers of at least as many bits as specified. For example, `uint8' should
-| be the most convenient type that can hold unsigned integers of as many as
-| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most
-| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
-| to the same as `int'.
-*----------------------------------------------------------------------------*/
-typedef uint8_t flag;
-typedef uint8_t uint8;
-typedef int8_t int8;
-typedef int uint16;
-typedef int int16;
-typedef unsigned int uint32;
-typedef signed int int32;
-typedef uint64_t uint64;
-typedef int64_t int64;
-
-/*----------------------------------------------------------------------------
-| Each of the following `typedef's defines a type that holds integers
-| of _exactly_ the number of bits specified. For instance, for most
-| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
-| `unsigned short int' and `signed short int' (or `short int'), respectively.
-*----------------------------------------------------------------------------*/
-typedef uint8_t bits8;
-typedef int8_t sbits8;
-typedef uint16_t bits16;
-typedef int16_t sbits16;
-typedef uint32_t bits32;
-typedef int32_t sbits32;
-typedef uint64_t bits64;
-typedef int64_t sbits64;
-
-#define LIT64( a ) a##LL
-#define INLINE static inline
-
-/*----------------------------------------------------------------------------
-| The macro `FLOATX80' must be defined to enable the extended double-precision
-| floating-point format `floatx80'. If this macro is not defined, the
-| `floatx80' type will not be defined, and none of the functions that either
-| input or output the `floatx80' type will be defined. The same applies to
-| the `FLOAT128' macro and the quadruple-precision format `float128'.
-*----------------------------------------------------------------------------*/
-#ifdef CONFIG_SOFTFLOAT
-/* bit exact soft float support */
-#define FLOATX80
-#define FLOAT128
-#else
-/* native float support */
-#if (defined(__i386__) || defined(__x86_64__)) && !defined(_BSD)
-#define FLOATX80
-#endif
-#endif /* !CONFIG_SOFTFLOAT */
-
-#define STATUS_PARAM , float_status *status
-#define STATUS(field) status->field
-#define STATUS_VAR , status
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point ordering relations
-*----------------------------------------------------------------------------*/
-enum {
- float_relation_less = -1,
- float_relation_equal = 0,
- float_relation_greater = 1,
- float_relation_unordered = 2
-};
-
-#ifdef CONFIG_SOFTFLOAT
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-typedef uint32_t float32;
-typedef uint64_t float64;
-#ifdef FLOATX80
-typedef struct {
- uint64_t low;
- uint16_t high;
-} floatx80;
-#endif
-#ifdef FLOAT128
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- uint64_t high, low;
-#else
- uint64_t low, high;
-#endif
-} float128;
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point underflow tininess-detection mode.
-*----------------------------------------------------------------------------*/
-enum {
- float_tininess_after_rounding = 0,
- float_tininess_before_rounding = 1
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-enum {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-enum {
- float_flag_invalid = 1,
- float_flag_divbyzero = 4,
- float_flag_overflow = 8,
- float_flag_underflow = 16,
- float_flag_inexact = 32
-};
-
-typedef struct float_status {
- signed char float_detect_tininess;
- signed char float_rounding_mode;
- signed char float_exception_flags;
-#ifdef FLOATX80
- signed char floatx80_rounding_precision;
-#endif
-} float_status;
-
-void set_float_rounding_mode(int val STATUS_PARAM);
-void set_float_exception_flags(int val STATUS_PARAM);
-INLINE int get_float_exception_flags(float_status *status)
-{
- return STATUS(float_exception_flags);
-}
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Routine to raise any or all of the software IEC/IEEE floating-point
-| exception flags.
-*----------------------------------------------------------------------------*/
-void float_raise( int8 flags STATUS_PARAM);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32( int STATUS_PARAM );
-float64 int32_to_float64( int STATUS_PARAM );
-float32 uint32_to_float32( unsigned int STATUS_PARAM );
-float64 uint32_to_float64( unsigned int STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 int32_to_floatx80( int STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 int32_to_float128( int STATUS_PARAM );
-#endif
-float32 int64_to_float32( int64_t STATUS_PARAM );
-float64 int64_to_float64( int64_t STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 int64_to_floatx80( int64_t STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 int64_to_float128( int64_t STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float32_to_int32( float32 STATUS_PARAM );
-int float32_to_int32_round_to_zero( float32 STATUS_PARAM );
-unsigned int float32_to_uint32( float32 STATUS_PARAM );
-unsigned int float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
-int64_t float32_to_int64( float32 STATUS_PARAM );
-int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM );
-float64 float32_to_float64( float32 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float32_to_floatx80( float32 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 float32_to_float128( float32 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 STATUS_PARAM );
-float32 float32_add( float32, float32 STATUS_PARAM );
-float32 float32_sub( float32, float32 STATUS_PARAM );
-float32 float32_mul( float32, float32 STATUS_PARAM );
-float32 float32_div( float32, float32 STATUS_PARAM );
-float32 float32_rem( float32, float32 STATUS_PARAM );
-float32 float32_sqrt( float32 STATUS_PARAM );
-int float32_eq( float32, float32 STATUS_PARAM );
-int float32_le( float32, float32 STATUS_PARAM );
-int float32_lt( float32, float32 STATUS_PARAM );
-int float32_eq_signaling( float32, float32 STATUS_PARAM );
-int float32_le_quiet( float32, float32 STATUS_PARAM );
-int float32_lt_quiet( float32, float32 STATUS_PARAM );
-int float32_compare( float32, float32 STATUS_PARAM );
-int float32_compare_quiet( float32, float32 STATUS_PARAM );
-int float32_is_signaling_nan( float32 );
-int float64_is_nan( float64 a );
-
-INLINE float32 float32_abs(float32 a)
-{
- return a & 0x7fffffff;
-}
-
-INLINE float32 float32_chs(float32 a)
-{
- return a ^ 0x80000000;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float64_to_int32( float64 STATUS_PARAM );
-int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
-unsigned int float64_to_uint32( float64 STATUS_PARAM );
-unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
-int64_t float64_to_int64( float64 STATUS_PARAM );
-int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
-float32 float64_to_float32( float64 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float64_to_floatx80( float64 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int( float64 STATUS_PARAM );
-float64 float64_trunc_to_int( float64 STATUS_PARAM );
-float64 float64_add( float64, float64 STATUS_PARAM );
-float64 float64_sub( float64, float64 STATUS_PARAM );
-float64 float64_mul( float64, float64 STATUS_PARAM );
-float64 float64_div( float64, float64 STATUS_PARAM );
-float64 float64_rem( float64, float64 STATUS_PARAM );
-float64 float64_sqrt( float64 STATUS_PARAM );
-int float64_eq( float64, float64 STATUS_PARAM );
-int float64_le( float64, float64 STATUS_PARAM );
-int float64_lt( float64, float64 STATUS_PARAM );
-int float64_eq_signaling( float64, float64 STATUS_PARAM );
-int float64_le_quiet( float64, float64 STATUS_PARAM );
-int float64_lt_quiet( float64, float64 STATUS_PARAM );
-int float64_compare( float64, float64 STATUS_PARAM );
-int float64_compare_quiet( float64, float64 STATUS_PARAM );
-int float64_is_signaling_nan( float64 );
-
-INLINE float64 float64_abs(float64 a)
-{
- return a & 0x7fffffffffffffffLL;
-}
-
-INLINE float64 float64_chs(float64 a)
-{
- return a ^ 0x8000000000000000LL;
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 STATUS_PARAM );
-int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
-int64_t floatx80_to_int64( floatx80 STATUS_PARAM );
-int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
-float32 floatx80_to_float32( floatx80 STATUS_PARAM );
-float64 floatx80_to_float64( floatx80 STATUS_PARAM );
-#ifdef FLOAT128
-float128 floatx80_to_float128( floatx80 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
-floatx80 floatx80_add( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sub( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
-int floatx80_le( floatx80, floatx80 STATUS_PARAM );
-int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
-int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
-int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_is_signaling_nan( floatx80 );
-
-INLINE floatx80 floatx80_abs(floatx80 a)
-{
- a.high &= 0x7fff;
- return a;
-}
-
-INLINE floatx80 floatx80_chs(floatx80 a)
-{
- a.high ^= 0x8000;
- return a;
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float128_to_int32( float128 STATUS_PARAM );
-int float128_to_int32_round_to_zero( float128 STATUS_PARAM );
-int64_t float128_to_int64( float128 STATUS_PARAM );
-int64_t float128_to_int64_round_to_zero( float128 STATUS_PARAM );
-float32 float128_to_float32( float128 STATUS_PARAM );
-float64 float128_to_float64( float128 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float128_to_floatx80( float128 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision operations.
-*----------------------------------------------------------------------------*/
-float128 float128_round_to_int( float128 STATUS_PARAM );
-float128 float128_add( float128, float128 STATUS_PARAM );
-float128 float128_sub( float128, float128 STATUS_PARAM );
-float128 float128_mul( float128, float128 STATUS_PARAM );
-float128 float128_div( float128, float128 STATUS_PARAM );
-float128 float128_rem( float128, float128 STATUS_PARAM );
-float128 float128_sqrt( float128 STATUS_PARAM );
-int float128_eq( float128, float128 STATUS_PARAM );
-int float128_le( float128, float128 STATUS_PARAM );
-int float128_lt( float128, float128 STATUS_PARAM );
-int float128_eq_signaling( float128, float128 STATUS_PARAM );
-int float128_le_quiet( float128, float128 STATUS_PARAM );
-int float128_lt_quiet( float128, float128 STATUS_PARAM );
-int float128_is_signaling_nan( float128 );
-
-INLINE float128 float128_abs(float128 a)
-{
- a.high &= 0x7fffffffffffffffLL;
- return a;
-}
-
-INLINE float128 float128_chs(float128 a)
-{
- a.high ^= 0x8000000000000000LL;
- return a;
-}
-
-#endif
-
-#else /* CONFIG_SOFTFLOAT */
-
-#include "softfloat-native.h"
-
-#endif /* !CONFIG_SOFTFLOAT */
-
-#endif /* !SOFTFLOAT_H */
diff --git a/tools/ioemu/gdbstub.c b/tools/ioemu/gdbstub.c
deleted file mode 100644
index aeddc34745..0000000000
--- a/tools/ioemu/gdbstub.c
+++ /dev/null
@@ -1,1251 +0,0 @@
-/*
- * gdb server stub
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef CONFIG_USER_ONLY
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "qemu.h"
-#else
-#include "vl.h"
-#endif
-
-#include "qemu_socket.h"
-#ifdef _WIN32
-/* XXX: these constants may be independent of the host ones even for Unix */
-#ifndef SIGTRAP
-#define SIGTRAP 5
-#endif
-#ifndef SIGINT
-#define SIGINT 2
-#endif
-#else
-#include <signal.h>
-#endif
-
-//#define DEBUG_GDB
-
-enum RSState {
- RS_IDLE,
- RS_GETLINE,
- RS_CHKSUM1,
- RS_CHKSUM2,
- RS_SYSCALL,
-};
-typedef struct GDBState {
- CPUState *env; /* current CPU */
- enum RSState state; /* parsing state */
- char line_buf[4096];
- int line_buf_index;
- int line_csum;
- char last_packet[4100];
- int last_packet_len;
-#ifdef CONFIG_USER_ONLY
- int fd;
- int running_state;
-#else
- CharDriverState *chr;
-#endif
-} GDBState;
-
-#ifdef CONFIG_USER_ONLY
-/* XXX: This is not thread safe. Do we care? */
-static int gdbserver_fd = -1;
-
-/* XXX: remove this hack. */
-static GDBState gdbserver_state;
-
-static int get_char(GDBState *s)
-{
- uint8_t ch;
- int ret;
-
- for(;;) {
- ret = recv(s->fd, &ch, 1, 0);
- if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN)
- return -1;
- } else if (ret == 0) {
- return -1;
- } else {
- break;
- }
- }
- return ch;
-}
-#endif
-
-/* GDB stub state for use by semihosting syscalls. */
-static GDBState *gdb_syscall_state;
-static gdb_syscall_complete_cb gdb_current_syscall_cb;
-
-enum {
- GDB_SYS_UNKNOWN,
- GDB_SYS_ENABLED,
- GDB_SYS_DISABLED,
-} gdb_syscall_mode;
-
-/* If gdb is connected when the first semihosting syscall occurs then use
- remote gdb syscalls. Otherwise use native file IO. */
-int use_gdb_syscalls(void)
-{
- if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
- gdb_syscall_mode = (gdb_syscall_state ? GDB_SYS_ENABLED
- : GDB_SYS_DISABLED);
- }
- return gdb_syscall_mode == GDB_SYS_ENABLED;
-}
-
-static void put_buffer(GDBState *s, const uint8_t *buf, int len)
-{
-#ifdef CONFIG_USER_ONLY
- int ret;
-
- while (len > 0) {
- ret = send(s->fd, buf, len, 0);
- if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN)
- return;
- } else {
- buf += ret;
- len -= ret;
- }
- }
-#else
- qemu_chr_write(s->chr, buf, len);
-#endif
-}
-
-static inline int fromhex(int v)
-{
- if (v >= '0' && v <= '9')
- return v - '0';
- else if (v >= 'A' && v <= 'F')
- return v - 'A' + 10;
- else if (v >= 'a' && v <= 'f')
- return v - 'a' + 10;
- else
- return 0;
-}
-
-static inline int tohex(int v)
-{
- if (v < 10)
- return v + '0';
- else
- return v - 10 + 'a';
-}
-
-static void memtohex(char *buf, const uint8_t *mem, int len)
-{
- int i, c;
- char *q;
- q = buf;
- for(i = 0; i < len; i++) {
- c = mem[i];
- *q++ = tohex(c >> 4);
- *q++ = tohex(c & 0xf);
- }
- *q = '\0';
-}
-
-static void hextomem(uint8_t *mem, const char *buf, int len)
-{
- int i;
-
- for(i = 0; i < len; i++) {
- mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
- buf += 2;
- }
-}
-
-/* return -1 if error, 0 if OK */
-static int put_packet(GDBState *s, char *buf)
-{
- int len, csum, i;
- char *p;
-
-#ifdef DEBUG_GDB
- printf("reply='%s'\n", buf);
-#endif
-
- for(;;) {
- p = s->last_packet;
- *(p++) = '$';
- len = strlen(buf);
- memcpy(p, buf, len);
- p += len;
- csum = 0;
- for(i = 0; i < len; i++) {
- csum += buf[i];
- }
- *(p++) = '#';
- *(p++) = tohex((csum >> 4) & 0xf);
- *(p++) = tohex((csum) & 0xf);
-
- s->last_packet_len = p - s->last_packet;
- put_buffer(s, s->last_packet, s->last_packet_len);
-
-#ifdef CONFIG_USER_ONLY
- i = get_char(s);
- if (i < 0)
- return -1;
- if (i == '+')
- break;
-#else
- break;
-#endif
- }
- return 0;
-}
-
-#if defined(TARGET_I386)
-
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- uint32_t *registers = (uint32_t *)mem_buf;
- int i, fpus;
-
- for(i = 0; i < 8; i++) {
- registers[i] = env->regs[i];
- }
- registers[8] = env->eip;
- registers[9] = env->eflags;
- registers[10] = env->segs[R_CS].selector;
- registers[11] = env->segs[R_SS].selector;
- registers[12] = env->segs[R_DS].selector;
- registers[13] = env->segs[R_ES].selector;
- registers[14] = env->segs[R_FS].selector;
- registers[15] = env->segs[R_GS].selector;
- /* XXX: convert floats */
- for(i = 0; i < 8; i++) {
- memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
- }
- registers[36] = env->fpuc;
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- registers[37] = fpus;
- registers[38] = 0; /* XXX: convert tags */
- registers[39] = 0; /* fiseg */
- registers[40] = 0; /* fioff */
- registers[41] = 0; /* foseg */
- registers[42] = 0; /* fooff */
- registers[43] = 0; /* fop */
-
- for(i = 0; i < 16; i++)
- tswapls(&registers[i]);
- for(i = 36; i < 44; i++)
- tswapls(&registers[i]);
- return 44 * 4;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- uint32_t *registers = (uint32_t *)mem_buf;
- int i;
-
- for(i = 0; i < 8; i++) {
- env->regs[i] = tswapl(registers[i]);
- }
- env->eip = tswapl(registers[8]);
- env->eflags = tswapl(registers[9]);
-#if defined(CONFIG_USER_ONLY)
-#define LOAD_SEG(index, sreg)\
- if (tswapl(registers[index]) != env->segs[sreg].selector)\
- cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
- LOAD_SEG(10, R_CS);
- LOAD_SEG(11, R_SS);
- LOAD_SEG(12, R_DS);
- LOAD_SEG(13, R_ES);
- LOAD_SEG(14, R_FS);
- LOAD_SEG(15, R_GS);
-#endif
-}
-
-#elif defined (TARGET_PPC)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- uint32_t *registers = (uint32_t *)mem_buf, tmp;
- int i;
-
- /* fill in gprs */
- for(i = 0; i < 32; i++) {
- registers[i] = tswapl(env->gpr[i]);
- }
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
- registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
- }
- /* nip, msr, ccr, lnk, ctr, xer, mq */
- registers[96] = tswapl(env->nip);
- registers[97] = tswapl(do_load_msr(env));
- tmp = 0;
- for (i = 0; i < 8; i++)
- tmp |= env->crf[i] << (32 - ((i + 1) * 4));
- registers[98] = tswapl(tmp);
- registers[99] = tswapl(env->lr);
- registers[100] = tswapl(env->ctr);
- registers[101] = tswapl(do_load_xer(env));
- registers[102] = 0;
-
- return 103 * 4;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- uint32_t *registers = (uint32_t *)mem_buf;
- int i;
-
- /* fill in gprs */
- for (i = 0; i < 32; i++) {
- env->gpr[i] = tswapl(registers[i]);
- }
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
- *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
- }
- /* nip, msr, ccr, lnk, ctr, xer, mq */
- env->nip = tswapl(registers[96]);
- do_store_msr(env, tswapl(registers[97]));
- registers[98] = tswapl(registers[98]);
- for (i = 0; i < 8; i++)
- env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
- env->lr = tswapl(registers[99]);
- env->ctr = tswapl(registers[100]);
- do_store_xer(env, tswapl(registers[101]));
-}
-#elif defined (TARGET_SPARC)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- target_ulong *registers = (target_ulong *)mem_buf;
- int i;
-
- /* fill in g0..g7 */
- for(i = 0; i < 8; i++) {
- registers[i] = tswapl(env->gregs[i]);
- }
- /* fill in register window */
- for(i = 0; i < 24; i++) {
- registers[i + 8] = tswapl(env->regwptr[i]);
- }
-#ifndef TARGET_SPARC64
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
- }
- /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
- registers[64] = tswapl(env->y);
- {
- target_ulong tmp;
-
- tmp = GET_PSR(env);
- registers[65] = tswapl(tmp);
- }
- registers[66] = tswapl(env->wim);
- registers[67] = tswapl(env->tbr);
- registers[68] = tswapl(env->pc);
- registers[69] = tswapl(env->npc);
- registers[70] = tswapl(env->fsr);
- registers[71] = 0; /* csr */
- registers[72] = 0;
- return 73 * sizeof(target_ulong);
-#else
- /* fill in fprs */
- for (i = 0; i < 64; i += 2) {
- uint64_t tmp;
-
- tmp = (uint64_t)tswap32(*((uint32_t *)&env->fpr[i])) << 32;
- tmp |= tswap32(*((uint32_t *)&env->fpr[i + 1]));
- registers[i/2 + 32] = tmp;
- }
- registers[64] = tswapl(env->pc);
- registers[65] = tswapl(env->npc);
- registers[66] = tswapl(env->tstate[env->tl]);
- registers[67] = tswapl(env->fsr);
- registers[68] = tswapl(env->fprs);
- registers[69] = tswapl(env->y);
- return 70 * sizeof(target_ulong);
-#endif
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- target_ulong *registers = (target_ulong *)mem_buf;
- int i;
-
- /* fill in g0..g7 */
- for(i = 0; i < 7; i++) {
- env->gregs[i] = tswapl(registers[i]);
- }
- /* fill in register window */
- for(i = 0; i < 24; i++) {
- env->regwptr[i] = tswapl(registers[i + 8]);
- }
-#ifndef TARGET_SPARC64
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
- }
- /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
- env->y = tswapl(registers[64]);
- PUT_PSR(env, tswapl(registers[65]));
- env->wim = tswapl(registers[66]);
- env->tbr = tswapl(registers[67]);
- env->pc = tswapl(registers[68]);
- env->npc = tswapl(registers[69]);
- env->fsr = tswapl(registers[70]);
-#else
- for (i = 0; i < 64; i += 2) {
- *((uint32_t *)&env->fpr[i]) = tswap32(registers[i/2 + 32] >> 32);
- *((uint32_t *)&env->fpr[i + 1]) = tswap32(registers[i/2 + 32] & 0xffffffff);
- }
- env->pc = tswapl(registers[64]);
- env->npc = tswapl(registers[65]);
- env->tstate[env->tl] = tswapl(registers[66]);
- env->fsr = tswapl(registers[67]);
- env->fprs = tswapl(registers[68]);
- env->y = tswapl(registers[69]);
-#endif
-}
-#elif defined (TARGET_ARM)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- /* 16 core integer registers (4 bytes each). */
- for (i = 0; i < 16; i++)
- {
- *(uint32_t *)ptr = tswapl(env->regs[i]);
- ptr += 4;
- }
- /* 8 FPA registers (12 bytes each), FPS (4 bytes).
- Not yet implemented. */
- memset (ptr, 0, 8 * 12 + 4);
- ptr += 8 * 12 + 4;
- /* CPSR (4 bytes). */
- *(uint32_t *)ptr = tswapl (cpsr_read(env));
- ptr += 4;
-
- return ptr - mem_buf;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- /* Core integer registers. */
- for (i = 0; i < 16; i++)
- {
- env->regs[i] = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
- /* Ignore FPA regs and scr. */
- ptr += 8 * 12 + 4;
- cpsr_write (env, tswapl(*(uint32_t *)ptr), 0xffffffff);
-}
-#elif defined (TARGET_M68K)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- int i;
- uint8_t *ptr;
- CPU_DoubleU u;
-
- ptr = mem_buf;
- /* D0-D7 */
- for (i = 0; i < 8; i++) {
- *(uint32_t *)ptr = tswapl(env->dregs[i]);
- ptr += 4;
- }
- /* A0-A7 */
- for (i = 0; i < 8; i++) {
- *(uint32_t *)ptr = tswapl(env->aregs[i]);
- ptr += 4;
- }
- *(uint32_t *)ptr = tswapl(env->sr);
- ptr += 4;
- *(uint32_t *)ptr = tswapl(env->pc);
- ptr += 4;
- /* F0-F7. The 68881/68040 have 12-bit extended precision registers.
- ColdFire has 8-bit double precision registers. */
- for (i = 0; i < 8; i++) {
- u.d = env->fregs[i];
- *(uint32_t *)ptr = tswap32(u.l.upper);
- *(uint32_t *)ptr = tswap32(u.l.lower);
- }
- /* FP control regs (not implemented). */
- memset (ptr, 0, 3 * 4);
- ptr += 3 * 4;
-
- return ptr - mem_buf;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- int i;
- uint8_t *ptr;
- CPU_DoubleU u;
-
- ptr = mem_buf;
- /* D0-D7 */
- for (i = 0; i < 8; i++) {
- env->dregs[i] = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
- /* A0-A7 */
- for (i = 0; i < 8; i++) {
- env->aregs[i] = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
- env->sr = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- env->pc = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- /* F0-F7. The 68881/68040 have 12-bit extended precision registers.
- ColdFire has 8-bit double precision registers. */
- for (i = 0; i < 8; i++) {
- u.l.upper = tswap32(*(uint32_t *)ptr);
- u.l.lower = tswap32(*(uint32_t *)ptr);
- env->fregs[i] = u.d;
- }
- /* FP control regs (not implemented). */
- ptr += 3 * 4;
-}
-#elif defined (TARGET_MIPS)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- for (i = 0; i < 32; i++)
- {
- *(uint32_t *)ptr = tswapl(env->gpr[i]);
- ptr += 4;
- }
-
- *(uint32_t *)ptr = tswapl(env->CP0_Status);
- ptr += 4;
-
- *(uint32_t *)ptr = tswapl(env->LO);
- ptr += 4;
-
- *(uint32_t *)ptr = tswapl(env->HI);
- ptr += 4;
-
- *(uint32_t *)ptr = tswapl(env->CP0_BadVAddr);
- ptr += 4;
-
- *(uint32_t *)ptr = tswapl(env->CP0_Cause);
- ptr += 4;
-
- *(uint32_t *)ptr = tswapl(env->PC);
- ptr += 4;
-
-#ifdef MIPS_USES_FPU
- for (i = 0; i < 32; i++)
- {
- *(uint32_t *)ptr = tswapl(FPR_W (env, i));
- ptr += 4;
- }
-
- *(uint32_t *)ptr = tswapl(env->fcr31);
- ptr += 4;
-
- *(uint32_t *)ptr = tswapl(env->fcr0);
- ptr += 4;
-#endif
-
- /* 32 FP registers, fsr, fir, fp. Not yet implemented. */
- /* what's 'fp' mean here? */
-
- return ptr - mem_buf;
-}
-
-/* convert MIPS rounding mode in FCR31 to IEEE library */
-static unsigned int ieee_rm[] =
- {
- float_round_nearest_even,
- float_round_to_zero,
- float_round_up,
- float_round_down
- };
-#define RESTORE_ROUNDING_MODE \
- set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- for (i = 0; i < 32; i++)
- {
- env->gpr[i] = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
-
- env->CP0_Status = tswapl(*(uint32_t *)ptr);
- ptr += 4;
-
- env->LO = tswapl(*(uint32_t *)ptr);
- ptr += 4;
-
- env->HI = tswapl(*(uint32_t *)ptr);
- ptr += 4;
-
- env->CP0_BadVAddr = tswapl(*(uint32_t *)ptr);
- ptr += 4;
-
- env->CP0_Cause = tswapl(*(uint32_t *)ptr);
- ptr += 4;
-
- env->PC = tswapl(*(uint32_t *)ptr);
- ptr += 4;
-
-#ifdef MIPS_USES_FPU
- for (i = 0; i < 32; i++)
- {
- FPR_W (env, i) = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
-
- env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF;
- ptr += 4;
-
- env->fcr0 = tswapl(*(uint32_t *)ptr);
- ptr += 4;
-
- /* set rounding mode */
- RESTORE_ROUNDING_MODE;
-
-#ifndef CONFIG_SOFTFLOAT
- /* no floating point exception for native float */
- SET_FP_ENABLE(env->fcr31, 0);
-#endif
-#endif
-}
-#elif defined (TARGET_SH4)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- uint32_t *ptr = (uint32_t *)mem_buf;
- int i;
-
-#define SAVE(x) *ptr++=tswapl(x)
- if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
- for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
- } else {
- for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
- }
- for (i = 8; i < 16; i++) SAVE(env->gregs[i]);
- SAVE (env->pc);
- SAVE (env->pr);
- SAVE (env->gbr);
- SAVE (env->vbr);
- SAVE (env->mach);
- SAVE (env->macl);
- SAVE (env->sr);
- SAVE (0); /* TICKS */
- SAVE (0); /* STALLS */
- SAVE (0); /* CYCLES */
- SAVE (0); /* INSTS */
- SAVE (0); /* PLR */
-
- return ((uint8_t *)ptr - mem_buf);
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- uint32_t *ptr = (uint32_t *)mem_buf;
- int i;
-
-#define LOAD(x) (x)=*ptr++;
- if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
- for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
- } else {
- for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
- }
- for (i = 8; i < 16; i++) LOAD(env->gregs[i]);
- LOAD (env->pc);
- LOAD (env->pr);
- LOAD (env->gbr);
- LOAD (env->vbr);
- LOAD (env->mach);
- LOAD (env->macl);
- LOAD (env->sr);
-}
-#else
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- return 0;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
-}
-
-#endif
-
-static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
-{
- const char *p;
- int ch, reg_size, type;
- char buf[4096];
- uint8_t mem_buf[2000];
- uint32_t *registers;
- target_ulong addr, len;
-
-#ifdef DEBUG_GDB
- printf("command='%s'\n", line_buf);
-#endif
- p = line_buf;
- ch = *p++;
- switch(ch) {
- case '?':
- /* TODO: Make this return the correct value for user-mode. */
- snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
- put_packet(s, buf);
- break;
- case 'c':
- if (*p != '\0') {
- addr = strtoull(p, (char **)&p, 16);
-#if defined(TARGET_I386)
- env->eip = addr;
-#elif defined (TARGET_PPC)
- env->nip = addr;
-#elif defined (TARGET_SPARC)
- env->pc = addr;
- env->npc = addr + 4;
-#elif defined (TARGET_ARM)
- env->regs[15] = addr;
-#elif defined (TARGET_SH4)
- env->pc = addr;
-#endif
- }
-#ifdef CONFIG_USER_ONLY
- s->running_state = 1;
-#else
- vm_start();
-#endif
- return RS_IDLE;
- case 's':
- if (*p != '\0') {
- addr = strtoul(p, (char **)&p, 16);
-#if defined(TARGET_I386)
- env->eip = addr;
-#elif defined (TARGET_PPC)
- env->nip = addr;
-#elif defined (TARGET_SPARC)
- env->pc = addr;
- env->npc = addr + 4;
-#elif defined (TARGET_ARM)
- env->regs[15] = addr;
-#elif defined (TARGET_SH4)
- env->pc = addr;
-#endif
- }
- cpu_single_step(env, 1);
-#ifdef CONFIG_USER_ONLY
- s->running_state = 1;
-#else
- vm_start();
-#endif
- return RS_IDLE;
- case 'F':
- {
- target_ulong ret;
- target_ulong err;
-
- ret = strtoull(p, (char **)&p, 16);
- if (*p == ',') {
- p++;
- err = strtoull(p, (char **)&p, 16);
- } else {
- err = 0;
- }
- if (*p == ',')
- p++;
- type = *p;
- if (gdb_current_syscall_cb)
- gdb_current_syscall_cb(s->env, ret, err);
- if (type == 'C') {
- put_packet(s, "T02");
- } else {
-#ifdef CONFIG_USER_ONLY
- s->running_state = 1;
-#else
- vm_start();
-#endif
- }
- }
- break;
- case 'g':
- reg_size = cpu_gdb_read_registers(env, mem_buf);
- memtohex(buf, mem_buf, reg_size);
- put_packet(s, buf);
- break;
- case 'G':
- registers = (void *)mem_buf;
- len = strlen(p) / 2;
- hextomem((uint8_t *)registers, p, len);
- cpu_gdb_write_registers(env, mem_buf, len);
- put_packet(s, "OK");
- break;
- case 'm':
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, NULL, 16);
- if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {
- put_packet (s, "E14");
- } else {
- memtohex(buf, mem_buf, len);
- put_packet(s, buf);
- }
- break;
- case 'M':
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, (char **)&p, 16);
- if (*p == ':')
- p++;
- hextomem(mem_buf, p, len);
- if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
- put_packet(s, "E14");
- else
- put_packet(s, "OK");
- break;
- case 'Z':
- type = strtoul(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, (char **)&p, 16);
- if (type == 0 || type == 1) {
- if (cpu_breakpoint_insert(env, addr) < 0)
- goto breakpoint_error;
- put_packet(s, "OK");
- } else {
- breakpoint_error:
- put_packet(s, "E22");
- }
- break;
- case 'z':
- type = strtoul(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, (char **)&p, 16);
- if (type == 0 || type == 1) {
- cpu_breakpoint_remove(env, addr);
- put_packet(s, "OK");
- } else {
- goto breakpoint_error;
- }
- break;
-#ifdef CONFIG_LINUX_USER
- case 'q':
- if (strncmp(p, "Offsets", 7) == 0) {
- TaskState *ts = env->opaque;
-
- sprintf(buf, "Text=%x;Data=%x;Bss=%x", ts->info->code_offset,
- ts->info->data_offset, ts->info->data_offset);
- put_packet(s, buf);
- break;
- }
- /* Fall through. */
-#endif
- default:
- // unknown_command:
- /* put empty packet */
- buf[0] = '\0';
- put_packet(s, buf);
- break;
- }
- return RS_IDLE;
-}
-
-extern void tb_flush(CPUState *env);
-
-#ifndef CONFIG_USER_ONLY
-static void gdb_vm_stopped(void *opaque, int reason)
-{
- GDBState *s = opaque;
- char buf[256];
- int ret;
-
- if (s->state == RS_SYSCALL)
- return;
-
- /* disable single step if it was enable */
- cpu_single_step(s->env, 0);
-
- if (reason == EXCP_DEBUG) {
- tb_flush(s->env);
- ret = SIGTRAP;
- } else if (reason == EXCP_INTERRUPT) {
- ret = SIGINT;
- } else {
- ret = 0;
- }
- snprintf(buf, sizeof(buf), "S%02x", ret);
- put_packet(s, buf);
-}
-#endif
-
-/* Send a gdb syscall request.
- This accepts limited printf-style format specifiers, specifically:
- %x - target_ulong argument printed in hex.
- %s - string pointer (target_ulong) and length (int) pair. */
-void gdb_do_syscall(gdb_syscall_complete_cb cb, char *fmt, ...)
-{
- va_list va;
- char buf[256];
- char *p;
- target_ulong addr;
- GDBState *s;
-
- s = gdb_syscall_state;
- if (!s)
- return;
- gdb_current_syscall_cb = cb;
- s->state = RS_SYSCALL;
-#ifndef CONFIG_USER_ONLY
- vm_stop(EXCP_DEBUG);
-#endif
- s->state = RS_IDLE;
- va_start(va, fmt);
- p = buf;
- *(p++) = 'F';
- while (*fmt) {
- if (*fmt == '%') {
- fmt++;
- switch (*fmt++) {
- case 'x':
- addr = va_arg(va, target_ulong);
- p += sprintf(p, TARGET_FMT_lx, addr);
- break;
- case 's':
- addr = va_arg(va, target_ulong);
- p += sprintf(p, TARGET_FMT_lx "/%x", addr, va_arg(va, int));
- break;
- default:
- fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n",
- fmt - 1);
- break;
- }
- } else {
- *(p++) = *(fmt++);
- }
- }
- va_end(va);
- put_packet(s, buf);
-#ifdef CONFIG_USER_ONLY
- gdb_handlesig(s->env, 0);
-#else
- cpu_interrupt(s->env, CPU_INTERRUPT_EXIT);
-#endif
-}
-
-static void gdb_read_byte(GDBState *s, int ch)
-{
- CPUState *env = s->env;
- int i, csum;
- char reply[1];
-
-#ifndef CONFIG_USER_ONLY
- if (s->last_packet_len) {
- /* Waiting for a response to the last packet. If we see the start
- of a new command then abandon the previous response. */
- if (ch == '-') {
-#ifdef DEBUG_GDB
- printf("Got NACK, retransmitting\n");
-#endif
- put_buffer(s, s->last_packet, s->last_packet_len);
- }
-#ifdef DEBUG_GDB
- else if (ch == '+')
- printf("Got ACK\n");
- else
- printf("Got '%c' when expecting ACK/NACK\n", ch);
-#endif
- if (ch == '+' || ch == '$')
- s->last_packet_len = 0;
- if (ch != '$')
- return;
- }
- if (vm_running) {
- /* when the CPU is running, we cannot do anything except stop
- it when receiving a char */
- vm_stop(EXCP_INTERRUPT);
- } else
-#endif
- {
- switch(s->state) {
- case RS_IDLE:
- if (ch == '$') {
- s->line_buf_index = 0;
- s->state = RS_GETLINE;
- }
- break;
- case RS_GETLINE:
- if (ch == '#') {
- s->state = RS_CHKSUM1;
- } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
- s->state = RS_IDLE;
- } else {
- s->line_buf[s->line_buf_index++] = ch;
- }
- break;
- case RS_CHKSUM1:
- s->line_buf[s->line_buf_index] = '\0';
- s->line_csum = fromhex(ch) << 4;
- s->state = RS_CHKSUM2;
- break;
- case RS_CHKSUM2:
- s->line_csum |= fromhex(ch);
- csum = 0;
- for(i = 0; i < s->line_buf_index; i++) {
- csum += s->line_buf[i];
- }
- if (s->line_csum != (csum & 0xff)) {
- reply[0] = '-';
- put_buffer(s, reply, 1);
- s->state = RS_IDLE;
- } else {
- reply[0] = '+';
- put_buffer(s, reply, 1);
- s->state = gdb_handle_packet(s, env, s->line_buf);
- }
- break;
- default:
- abort();
- }
- }
-}
-
-#ifdef CONFIG_USER_ONLY
-int
-gdb_handlesig (CPUState *env, int sig)
-{
- GDBState *s;
- char buf[256];
- int n;
-
- if (gdbserver_fd < 0)
- return sig;
-
- s = &gdbserver_state;
-
- /* disable single step if it was enabled */
- cpu_single_step(env, 0);
- tb_flush(env);
-
- if (sig != 0)
- {
- snprintf(buf, sizeof(buf), "S%02x", sig);
- put_packet(s, buf);
- }
-
- sig = 0;
- s->state = RS_IDLE;
- s->running_state = 0;
- while (s->running_state == 0) {
- n = read (s->fd, buf, 256);
- if (n > 0)
- {
- int i;
-
- for (i = 0; i < n; i++)
- gdb_read_byte (s, buf[i]);
- }
- else if (n == 0 || errno != EAGAIN)
- {
- /* XXX: Connection closed. Should probably wait for annother
- connection before continuing. */
- return sig;
- }
- }
- return sig;
-}
-
-/* Tell the remote gdb that the process has exited. */
-void gdb_exit(CPUState *env, int code)
-{
- GDBState *s;
- char buf[4];
-
- if (gdbserver_fd < 0)
- return;
-
- s = &gdbserver_state;
-
- snprintf(buf, sizeof(buf), "W%02x", code);
- put_packet(s, buf);
-}
-
-
-static void gdb_accept(void *opaque)
-{
- GDBState *s;
- struct sockaddr_in sockaddr;
- socklen_t len;
- int val, fd;
-
- for(;;) {
- len = sizeof(sockaddr);
- fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
- if (fd < 0 && errno != EINTR) {
- perror("accept");
- return;
- } else if (fd >= 0) {
- break;
- }
- }
-
- /* set short latency */
- val = 1;
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
-
- s = &gdbserver_state;
- memset (s, 0, sizeof (GDBState));
- s->env = first_cpu; /* XXX: allow to change CPU */
- s->fd = fd;
-
- gdb_syscall_state = s;
-
- fcntl(fd, F_SETFL, O_NONBLOCK);
-}
-
-static int gdbserver_open(int port)
-{
- struct sockaddr_in sockaddr;
- int fd, val, ret;
-
- fd = socket(PF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- perror("socket");
- return -1;
- }
-
- /* allow fast reuse */
- val = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(port);
- sockaddr.sin_addr.s_addr = 0;
- ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
- if (ret < 0) {
- perror("bind");
- return -1;
- }
- ret = listen(fd, 0);
- if (ret < 0) {
- perror("listen");
- return -1;
- }
- return fd;
-}
-
-int gdbserver_start(int port)
-{
- gdbserver_fd = gdbserver_open(port);
- if (gdbserver_fd < 0)
- return -1;
- /* accept connections */
- gdb_accept (NULL);
- return 0;
-}
-#else
-static int gdb_chr_can_recieve(void *opaque)
-{
- return 1;
-}
-
-static void gdb_chr_recieve(void *opaque, const uint8_t *buf, int size)
-{
- GDBState *s = opaque;
- int i;
-
- for (i = 0; i < size; i++) {
- gdb_read_byte(s, buf[i]);
- }
-}
-
-static void gdb_chr_event(void *opaque, int event)
-{
- switch (event) {
- case CHR_EVENT_RESET:
- vm_stop(EXCP_INTERRUPT);
- gdb_syscall_state = opaque;
- break;
- default:
- break;
- }
-}
-
-int gdbserver_start(CharDriverState *chr)
-{
- GDBState *s;
-
- if (!chr)
- return -1;
-
- s = qemu_mallocz(sizeof(GDBState));
- if (!s) {
- return -1;
- }
- s->env = first_cpu; /* XXX: allow to change CPU */
- s->chr = chr;
- qemu_chr_add_handlers(chr, gdb_chr_can_recieve, gdb_chr_recieve,
- gdb_chr_event, s);
- qemu_add_vm_stop_handler(gdb_vm_stopped, s);
- return 0;
-}
-
-int gdbserver_start_port(int port)
-{
- CharDriverState *chr;
- char gdbstub_port_name[128];
-
- snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
- "tcp::%d,nowait,nodelay,server", port);
- chr = qemu_chr_open(gdbstub_port_name);
- if (!chr)
- return -EIO;
- return gdbserver_start(chr);
-}
-
-#endif
diff --git a/tools/ioemu/gdbstub.h b/tools/ioemu/gdbstub.h
deleted file mode 100644
index 41ffc6d089..0000000000
--- a/tools/ioemu/gdbstub.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef GDBSTUB_H
-#define GDBSTUB_H
-
-#define DEFAULT_GDBSTUB_PORT 1234
-
-typedef void (*gdb_syscall_complete_cb)(CPUState *env,
- target_ulong ret, target_ulong err);
-
-void gdb_do_syscall(gdb_syscall_complete_cb cb, char *fmt, ...);
-int use_gdb_syscalls(void);
-#ifdef CONFIG_USER_ONLY
-int gdb_handlesig (CPUState *, int);
-void gdb_exit(CPUState *, int);
-int gdbserver_start(int);
-#else
-int gdbserver_start(CharDriverState *chr);
-int gdbserver_start_port(int port);
-#endif
-
-#endif
diff --git a/tools/ioemu/hostregs_helper.h b/tools/ioemu/hostregs_helper.h
deleted file mode 100644
index 4fdf8ad964..0000000000
--- a/tools/ioemu/hostregs_helper.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Save/restore host registrs.
- *
- * Copyright (c) 2007 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* The GCC global register vairable extension is used to reserve some
- host registers for use by dyngen. However only the core parts of the
- translation engine are compiled with these settings. We must manually
- save/restore these registers when called from regular code.
- It is not sufficient to save/restore T0 et. al. as these may be declared
- with a datatype smaller than the actual register. */
-
-#if defined(DECLARE_HOST_REGS)
-
-#define DO_REG(REG) \
- register host_reg_t reg_AREG##REG asm(AREG##REG); \
- volatile host_reg_t saved_AREG##REG;
-
-#elif defined(SAVE_HOST_REGS)
-
-#define DO_REG(REG) \
- __asm__ __volatile__ ("" : "=r" (reg_AREG##REG)); \
- saved_AREG##REG = reg_AREG##REG;
-
-#else
-
-#define DO_REG(REG) \
- reg_AREG##REG = saved_AREG##REG; \
- __asm__ __volatile__ ("" : : "r" (reg_AREG##REG));
-
-#endif
-
-#ifdef AREG0
-DO_REG(0)
-#endif
-
-#ifdef AREG1
-DO_REG(1)
-#endif
-
-#ifdef AREG2
-DO_REG(2)
-#endif
-
-#ifdef AREG3
-DO_REG(3)
-#endif
-
-#ifdef AREG4
-DO_REG(4)
-#endif
-
-#ifdef AREG5
-DO_REG(5)
-#endif
-
-#ifdef AREG6
-DO_REG(6)
-#endif
-
-#ifdef AREG7
-DO_REG(7)
-#endif
-
-#ifdef AREG8
-DO_REG(8)
-#endif
-
-#ifdef AREG9
-DO_REG(9)
-#endif
-
-#ifdef AREG10
-DO_REG(10)
-#endif
-
-#ifdef AREG11
-DO_REG(11)
-#endif
-
-#undef SAVE_HOST_REGS
-#undef DECLARE_HOST_REGS
-#undef DO_REG
diff --git a/tools/ioemu/hw/.CVS/Entries b/tools/ioemu/hw/.CVS/Entries
deleted file mode 100644
index b74f8ad9b2..0000000000
--- a/tools/ioemu/hw/.CVS/Entries
+++ /dev/null
@@ -1,98 +0,0 @@
-/acpi.c/1.8/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/adb.c/1.7/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/adlib.c/1.6/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/apb_pci.c/1.4/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/apic.c/1.12/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/arm_boot.c/1.3/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/arm_gic.c/1.3/Tue Jan 2 19:33:15 2007//Trelease_0_9_0
-/arm_pic.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/arm_pic.h/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/arm_sysctl.c/1.1/Sat Sep 23 17:40:58 2006//Trelease_0_9_0
-/arm_timer.c/1.2/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/cdrom.c/1.1/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/cirrus_vga.c/1.23/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/cirrus_vga_rop.h/1.1/Thu May 3 17:17:34 2007//Trelease_0_9_0
-/cirrus_vga_rop2.h/1.7/Thu May 3 17:17:34 2007//Trelease_0_9_0
-/cs4231.c/1.1/Sun Sep 10 19:25:12 2006//Trelease_0_9_0
-/cuda.c/1.11/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/dma.c/1.14/Thu May 3 17:17:33 2007//Trelease_0_9_0
-/es1370.c/1.6/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/esp.c/1.18/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/fdc.c/1.21/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/fmopl.c/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/fmopl.h/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/grackle_pci.c/1.3/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/gt64xxx.c/1.4/Wed Jan 31 12:02:12 2007//Trelease_0_9_0
-/heathrow_pic.c/1.2/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/i8254.c/1.8/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/i8259.c/1.20/Thu May 3 17:18:00 2007//Trelease_0_9_0
-/ide.c/1.53/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/integratorcp.c/1.11/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/iommu.c/1.8/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/isa_mmio.c/1.1/Mon Sep 18 01:15:29 2006//Trelease_0_9_0
-/lsi53c895a.c/1.3/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/m48t59.c/1.8/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/m48t59.h/1.5/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/mc146818rtc.c/1.7/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/mips_int.c/1.1/Wed Jan 24 01:47:51 2007//Trelease_0_9_0
-/mips_malta.c/1.7/Wed Jan 31 11:48:27 2007//Trelease_0_9_0
-/mips_r4k.c/1.33/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/mips_timer.c/1.2/Wed Jan 24 01:47:51 2007//Trelease_0_9_0
-/ne2000.c/1.23/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/openpic.c/1.9/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/parallel.c/1.4/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/pc.c/1.69/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pci.c/1.34/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pci_host.h/1.1/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/pckbd.c/1.15/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/pcnet.c/1.8/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pcspk.c/1.2/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/pflash_cfi02.c/1.3/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/piix_pci.c/1.9/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pl011.c/1.2/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pl050.c/1.2/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/pl080.c/1.2/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pl110.c/1.7/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pl110_template.h/1.3/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/pl190.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/ppc.c/1.10/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/ppc_chrp.c/1.26/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/ppc_prep.c/1.29/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/prep_pci.c/1.3/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/ps2.c/1.5/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/realview.c/1.3/Tue Jan 16 18:54:31 2007//Trelease_0_9_0
-/rtl8139.c/1.6/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/sb16.c/1.22/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/scsi-disk.c/1.13/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/serial.c/1.14/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/sh7750.c/1.3/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/sh7750_regnames.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/sh7750_regnames.h/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/sh7750_regs.h/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/shix.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/slavio_intctl.c/1.7/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/slavio_misc.c/1.4/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/slavio_serial.c/1.11/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/slavio_timer.c/1.4/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/smbus.h/1.1/Fri Feb 2 03:13:18 2007//Trelease_0_9_0
-/smbus_eeprom.c/1.1/Fri Feb 2 03:13:18 2007//Trelease_0_9_0
-/smc91c111.c/1.5/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/sparc32_dma.c/1.2/Sun Sep 3 19:48:17 2006//Trelease_0_9_0
-/sun4m.c/1.24/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/sun4u.c/1.12/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/tc58128.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/tcx.c/1.10/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/unin_pci.c/1.4/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/usb-hid.c/1.7/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/usb-hub.c/1.9/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/usb-msd.c/1.7/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/usb-ohci.c/1.4/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/usb-uhci.c/1.13/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/usb.c/1.9/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/usb.h/1.10/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/versatile_pci.c/1.4/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/versatilepb.c/1.8/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/vga.c/1.48/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/vga_int.h/1.10/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/vga_template.h/1.13/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-D
diff --git a/tools/ioemu/hw/.CVS/Repository b/tools/ioemu/hw/.CVS/Repository
deleted file mode 100644
index e65456b391..0000000000
--- a/tools/ioemu/hw/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu/hw
diff --git a/tools/ioemu/hw/.CVS/Root b/tools/ioemu/hw/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/hw/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/hw/.CVS/Tag b/tools/ioemu/hw/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/hw/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/hw/acpi.c b/tools/ioemu/hw/acpi.c
deleted file mode 100644
index 78c4feabbf..0000000000
--- a/tools/ioemu/hw/acpi.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * ACPI implementation
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "vl.h"
-
-//#define DEBUG
-
-/* i82731AB (PIIX4) compatible power management function */
-#define PM_FREQ 3579545
-
-#define ACPI_DBG_IO_ADDR 0xb044
-#define SMB_IO_BASE 0xb100
-
-typedef struct PIIX4PMState {
- PCIDevice dev;
- uint16_t pmsts;
- uint16_t pmen;
- uint16_t pmcntrl;
- uint8_t apmc;
- uint8_t apms;
- QEMUTimer *tmr_timer;
- int64_t tmr_overflow_time;
- SMBusDevice *smb_dev[128];
- uint8_t smb_stat;
- uint8_t smb_ctl;
- uint8_t smb_cmd;
- uint8_t smb_addr;
- uint8_t smb_data0;
- uint8_t smb_data1;
- uint8_t smb_data[32];
- uint8_t smb_index;
-} PIIX4PMState;
-
-#define RTC_EN (1 << 10)
-#define PWRBTN_EN (1 << 8)
-#define GBL_EN (1 << 5)
-#define TMROF_EN (1 << 0)
-
-#define SCI_EN (1 << 0)
-
-#define SUS_EN (1 << 13)
-
-#define SMBHSTSTS 0x00
-#define SMBHSTCNT 0x02
-#define SMBHSTCMD 0x03
-#define SMBHSTADD 0x04
-#define SMBHSTDAT0 0x05
-#define SMBHSTDAT1 0x06
-#define SMBBLKDAT 0x07
-
-/* Note: only used for piix4_smbus_register_device */
-static PIIX4PMState *piix4_pm_state;
-
-static uint32_t get_pmtmr(PIIX4PMState *s)
-{
- uint32_t d;
- d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
- return d & 0xffffff;
-}
-
-static int get_pmsts(PIIX4PMState *s)
-{
- int64_t d;
- int pmsts;
- pmsts = s->pmsts;
- d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
- if (d >= s->tmr_overflow_time)
- s->pmsts |= TMROF_EN;
- return pmsts;
-}
-
-static void pm_update_sci(PIIX4PMState *s)
-{
- int sci_level, pmsts;
- int64_t expire_time;
-
- pmsts = get_pmsts(s);
- sci_level = (((pmsts & s->pmen) &
- (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
- pci_set_irq(&s->dev, 0, sci_level);
- /* schedule a timer interruption if needed */
- if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
- expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ);
- qemu_mod_timer(s->tmr_timer, expire_time);
- } else {
- qemu_del_timer(s->tmr_timer);
- }
-}
-
-static void pm_tmr_timer(void *opaque)
-{
- PIIX4PMState *s = opaque;
- pm_update_sci(s);
-}
-
-static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- PIIX4PMState *s = opaque;
- addr &= 0x3f;
- switch(addr) {
- case 0x00:
- {
- int64_t d;
- int pmsts;
- pmsts = get_pmsts(s);
- if (pmsts & val & TMROF_EN) {
- /* if TMRSTS is reset, then compute the new overflow time */
- d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
- s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
- }
- s->pmsts &= ~val;
- pm_update_sci(s);
- }
- break;
- case 0x02:
- s->pmen = val;
- pm_update_sci(s);
- break;
- case 0x04:
- {
- int sus_typ;
- s->pmcntrl = val & ~(SUS_EN);
- if (val & SUS_EN) {
- /* change suspend type */
- sus_typ = (val >> 10) & 3;
- switch(sus_typ) {
- case 0: /* soft power off */
- qemu_system_shutdown_request();
- break;
- default:
- break;
- }
- }
- }
- break;
- default:
- break;
- }
-#ifdef DEBUG
- printf("PM writew port=0x%04x val=0x%04x\n", addr, val);
-#endif
-}
-
-static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
-{
- PIIX4PMState *s = opaque;
- uint32_t val;
-
- addr &= 0x3f;
- switch(addr) {
- case 0x00:
- val = get_pmsts(s);
- break;
- case 0x02:
- val = s->pmen;
- break;
- case 0x04:
- val = s->pmcntrl;
- break;
- default:
- val = 0;
- break;
- }
-#ifdef DEBUG
- printf("PM readw port=0x%04x val=0x%04x\n", addr, val);
-#endif
- return val;
-}
-
-static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- // PIIX4PMState *s = opaque;
- addr &= 0x3f;
-#ifdef DEBUG
- printf("PM writel port=0x%04x val=0x%08x\n", addr, val);
-#endif
-}
-
-static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
-{
- PIIX4PMState *s = opaque;
- uint32_t val;
-
- addr &= 0x3f;
- switch(addr) {
- case 0x08:
- val = get_pmtmr(s);
- break;
- default:
- val = 0;
- break;
- }
-#ifdef DEBUG
- printf("PM readl port=0x%04x val=0x%08x\n", addr, val);
-#endif
- return val;
-}
-
-static void pm_smi_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PIIX4PMState *s = opaque;
- addr &= 1;
-#ifdef DEBUG
- printf("pm_smi_writeb addr=0x%x val=0x%02x\n", addr, val);
-#endif
- if (addr == 0) {
- s->apmc = val;
- if (s->dev.config[0x5b] & (1 << 1)) {
- cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
- }
- } else {
- s->apms = val;
- }
-}
-
-static uint32_t pm_smi_readb(void *opaque, uint32_t addr)
-{
- PIIX4PMState *s = opaque;
- uint32_t val;
-
- addr &= 1;
- if (addr == 0) {
- val = s->apmc;
- } else {
- val = s->apms;
- }
-#ifdef DEBUG
- printf("pm_smi_readb addr=0x%x val=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-#if defined(DEBUG)
- printf("ACPI: DBG: 0x%08x\n", val);
-#endif
-}
-
-static void smb_transaction(PIIX4PMState *s)
-{
- uint8_t prot = (s->smb_ctl >> 2) & 0x07;
- uint8_t read = s->smb_addr & 0x01;
- uint8_t cmd = s->smb_cmd;
- uint8_t addr = s->smb_addr >> 1;
- SMBusDevice *dev = s->smb_dev[addr];
-
-#ifdef DEBUG
- printf("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
-#endif
- if (!dev) goto error;
-
- switch(prot) {
- case 0x0:
- if (!dev->quick_cmd) goto error;
- (*dev->quick_cmd)(dev, read);
- break;
- case 0x1:
- if (read) {
- if (!dev->receive_byte) goto error;
- s->smb_data0 = (*dev->receive_byte)(dev);
- }
- else {
- if (!dev->send_byte) goto error;
- (*dev->send_byte)(dev, cmd);
- }
- break;
- case 0x2:
- if (read) {
- if (!dev->read_byte) goto error;
- s->smb_data0 = (*dev->read_byte)(dev, cmd);
- }
- else {
- if (!dev->write_byte) goto error;
- (*dev->write_byte)(dev, cmd, s->smb_data0);
- }
- break;
- case 0x3:
- if (read) {
- uint16_t val;
- if (!dev->read_word) goto error;
- val = (*dev->read_word)(dev, cmd);
- s->smb_data0 = val;
- s->smb_data1 = val >> 8;
- }
- else {
- if (!dev->write_word) goto error;
- (*dev->write_word)(dev, cmd, (s->smb_data1 << 8) | s->smb_data0);
- }
- break;
- case 0x5:
- if (read) {
- if (!dev->read_block) goto error;
- s->smb_data0 = (*dev->read_block)(dev, cmd, s->smb_data);
- }
- else {
- if (!dev->write_block) goto error;
- (*dev->write_block)(dev, cmd, s->smb_data0, s->smb_data);
- }
- break;
- default:
- goto error;
- }
- return;
-
- error:
- s->smb_stat |= 0x04;
-}
-
-static void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PIIX4PMState *s = opaque;
- addr &= 0x3f;
-#ifdef DEBUG
- printf("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
-#endif
- switch(addr) {
- case SMBHSTSTS:
- s->smb_stat = 0;
- s->smb_index = 0;
- break;
- case SMBHSTCNT:
- s->smb_ctl = val;
- if (val & 0x40)
- smb_transaction(s);
- break;
- case SMBHSTCMD:
- s->smb_cmd = val;
- break;
- case SMBHSTADD:
- s->smb_addr = val;
- break;
- case SMBHSTDAT0:
- s->smb_data0 = val;
- break;
- case SMBHSTDAT1:
- s->smb_data1 = val;
- break;
- case SMBBLKDAT:
- s->smb_data[s->smb_index++] = val;
- if (s->smb_index > 31)
- s->smb_index = 0;
- break;
- default:
- break;
- }
-}
-
-static uint32_t smb_ioport_readb(void *opaque, uint32_t addr)
-{
- PIIX4PMState *s = opaque;
- uint32_t val;
-
- addr &= 0x3f;
- switch(addr) {
- case SMBHSTSTS:
- val = s->smb_stat;
- break;
- case SMBHSTCNT:
- s->smb_index = 0;
- val = s->smb_ctl & 0x1f;
- break;
- case SMBHSTCMD:
- val = s->smb_cmd;
- break;
- case SMBHSTADD:
- val = s->smb_addr;
- break;
- case SMBHSTDAT0:
- val = s->smb_data0;
- break;
- case SMBHSTDAT1:
- val = s->smb_data1;
- break;
- case SMBBLKDAT:
- val = s->smb_data[s->smb_index++];
- if (s->smb_index > 31)
- s->smb_index = 0;
- break;
- default:
- val = 0;
- break;
- }
-#ifdef DEBUG
- printf("SMB readb port=0x%04x val=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void pm_io_space_update(PIIX4PMState *s)
-{
- uint32_t pm_io_base;
-
- if (s->dev.config[0x80] & 1) {
- pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
- pm_io_base &= 0xfffe;
-
- /* XXX: need to improve memory and ioport allocation */
-#if defined(DEBUG)
- printf("PM: mapping to 0x%x\n", pm_io_base);
-#endif
- register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
- register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
- register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
- register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
- }
-}
-
-static void pm_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- pci_default_write_config(d, address, val, len);
- if (address == 0x80)
- pm_io_space_update((PIIX4PMState *)d);
-}
-
-static void pm_save(QEMUFile* f,void *opaque)
-{
- PIIX4PMState *s = opaque;
-
- pci_device_save(&s->dev, f);
-
- qemu_put_be16s(f, &s->pmsts);
- qemu_put_be16s(f, &s->pmen);
- qemu_put_be16s(f, &s->pmcntrl);
- qemu_put_8s(f, &s->apmc);
- qemu_put_8s(f, &s->apms);
- qemu_put_timer(f, s->tmr_timer);
- qemu_put_be64s(f, &s->tmr_overflow_time);
-}
-
-static int pm_load(QEMUFile* f,void* opaque,int version_id)
-{
- PIIX4PMState *s = opaque;
- int ret;
-
- if (version_id > 1)
- return -EINVAL;
-
- ret = pci_device_load(&s->dev, f);
- if (ret < 0)
- return ret;
-
- qemu_get_be16s(f, &s->pmsts);
- qemu_get_be16s(f, &s->pmen);
- qemu_get_be16s(f, &s->pmcntrl);
- qemu_get_8s(f, &s->apmc);
- qemu_get_8s(f, &s->apms);
- qemu_get_timer(f, s->tmr_timer);
- qemu_get_be64s(f, &s->tmr_overflow_time);
-
- pm_io_space_update(s);
-
- return 0;
-}
-
-void piix4_pm_init(PCIBus *bus, int devfn)
-{
- PIIX4PMState *s;
- uint8_t *pci_conf;
- uint32_t pm_io_base, smb_io_base;
-
- s = (PIIX4PMState *)pci_register_device(bus,
- "PM", sizeof(PIIX4PMState),
- devfn, NULL, pm_write_config);
- pci_conf = s->dev.config;
- pci_conf[0x00] = 0x86;
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x13;
- pci_conf[0x03] = 0x71;
- pci_conf[0x08] = 0x00; // revision number
- pci_conf[0x09] = 0x00;
- pci_conf[0x0a] = 0x80; // other bridge device
- pci_conf[0x0b] = 0x06; // bridge device
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x3d] = 0x01; // interrupt pin 1
-
- pci_conf[0x40] = 0x01; /* PM io base read only bit */
-
- register_ioport_write(0xb2, 2, 1, pm_smi_writeb, s);
- register_ioport_read(0xb2, 2, 1, pm_smi_readb, s);
-
- register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
-
- /* XXX: which specification is used ? The i82731AB has different
- mappings */
- pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;
- pci_conf[0x63] = 0x60;
- pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
- (serial_hds[1] != NULL ? 0x90 : 0);
-
- smb_io_base = SMB_IO_BASE;
- pci_conf[0x90] = smb_io_base | 1;
- pci_conf[0x91] = smb_io_base >> 8;
- pci_conf[0xd2] = 0x09;
- register_ioport_write(smb_io_base, 64, 1, smb_ioport_writeb, s);
- register_ioport_read(smb_io_base, 64, 1, smb_ioport_readb, s);
-
- s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
-
- register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s);
- piix4_pm_state = s;
-}
-
-void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr)
-{
- piix4_pm_state->smb_dev[addr] = dev;
-}
diff --git a/tools/ioemu/hw/adb.c b/tools/ioemu/hw/adb.c
deleted file mode 100644
index 3f664a9c5e..0000000000
--- a/tools/ioemu/hw/adb.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * QEMU ADB support
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* ADB commands */
-#define ADB_BUSRESET 0x00
-#define ADB_FLUSH 0x01
-#define ADB_WRITEREG 0x08
-#define ADB_READREG 0x0c
-
-/* ADB device commands */
-#define ADB_CMD_SELF_TEST 0xff
-#define ADB_CMD_CHANGE_ID 0xfe
-#define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
-#define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
-
-/* ADB default device IDs (upper 4 bits of ADB command byte) */
-#define ADB_DONGLE 1
-#define ADB_KEYBOARD 2
-#define ADB_MOUSE 3
-#define ADB_TABLET 4
-#define ADB_MODEM 5
-#define ADB_MISC 7
-
-/* error codes */
-#define ADB_RET_NOTPRESENT (-2)
-
-int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
-{
- ADBDevice *d;
- int devaddr, cmd, i;
-
- cmd = buf[0] & 0xf;
- if (cmd == ADB_BUSRESET) {
- for(i = 0; i < s->nb_devices; i++) {
- d = &s->devices[i];
- if (d->devreset) {
- d->devreset(d);
- }
- }
- return 0;
- }
- devaddr = buf[0] >> 4;
- for(i = 0; i < s->nb_devices; i++) {
- d = &s->devices[i];
- if (d->devaddr == devaddr) {
- return d->devreq(d, obuf, buf, len);
- }
- }
- return ADB_RET_NOTPRESENT;
-}
-
-/* XXX: move that to cuda ? */
-int adb_poll(ADBBusState *s, uint8_t *obuf)
-{
- ADBDevice *d;
- int olen, i;
- uint8_t buf[1];
-
- olen = 0;
- for(i = 0; i < s->nb_devices; i++) {
- if (s->poll_index >= s->nb_devices)
- s->poll_index = 0;
- d = &s->devices[s->poll_index];
- buf[0] = ADB_READREG | (d->devaddr << 4);
- olen = adb_request(s, obuf + 1, buf, 1);
- /* if there is data, we poll again the same device */
- if (olen > 0) {
- obuf[0] = buf[0];
- olen++;
- break;
- }
- s->poll_index++;
- }
- return olen;
-}
-
-ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
- ADBDeviceRequest *devreq,
- ADBDeviceReset *devreset,
- void *opaque)
-{
- ADBDevice *d;
- if (s->nb_devices >= MAX_ADB_DEVICES)
- return NULL;
- d = &s->devices[s->nb_devices++];
- d->bus = s;
- d->devaddr = devaddr;
- d->devreq = devreq;
- d->devreset = devreset;
- d->opaque = opaque;
- return d;
-}
-
-/***************************************************************/
-/* Keyboard ADB device */
-
-typedef struct KBDState {
- uint8_t data[128];
- int rptr, wptr, count;
-} KBDState;
-
-static const uint8_t pc_to_adb_keycode[256] = {
- 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
- 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
- 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
- 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
- 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
- 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
- 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-static void adb_kbd_put_keycode(void *opaque, int keycode)
-{
- ADBDevice *d = opaque;
- KBDState *s = d->opaque;
-
- if (s->count < sizeof(s->data)) {
- s->data[s->wptr] = keycode;
- if (++s->wptr == sizeof(s->data))
- s->wptr = 0;
- s->count++;
- }
-}
-
-static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
-{
- static int ext_keycode;
- KBDState *s = d->opaque;
- int adb_keycode, keycode;
- int olen;
-
- olen = 0;
- for(;;) {
- if (s->count == 0)
- break;
- keycode = s->data[s->rptr];
- if (++s->rptr == sizeof(s->data))
- s->rptr = 0;
- s->count--;
-
- if (keycode == 0xe0) {
- ext_keycode = 1;
- } else {
- if (ext_keycode)
- adb_keycode = pc_to_adb_keycode[keycode | 0x80];
- else
- adb_keycode = pc_to_adb_keycode[keycode & 0x7f];
- obuf[0] = adb_keycode | (keycode & 0x80);
- /* NOTE: could put a second keycode if needed */
- obuf[1] = 0xff;
- olen = 2;
- ext_keycode = 0;
- break;
- }
- }
- return olen;
-}
-
-static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
- const uint8_t *buf, int len)
-{
- KBDState *s = d->opaque;
- int cmd, reg, olen;
-
- if ((buf[0] & 0x0f) == ADB_FLUSH) {
- /* flush keyboard fifo */
- s->wptr = s->rptr = s->count = 0;
- return 0;
- }
-
- cmd = buf[0] & 0xc;
- reg = buf[0] & 0x3;
- olen = 0;
- switch(cmd) {
- case ADB_WRITEREG:
- switch(reg) {
- case 2:
- /* LED status */
- break;
- case 3:
- switch(buf[2]) {
- case ADB_CMD_SELF_TEST:
- break;
- case ADB_CMD_CHANGE_ID:
- case ADB_CMD_CHANGE_ID_AND_ACT:
- case ADB_CMD_CHANGE_ID_AND_ENABLE:
- d->devaddr = buf[1] & 0xf;
- break;
- default:
- /* XXX: check this */
- d->devaddr = buf[1] & 0xf;
- d->handler = buf[2];
- break;
- }
- }
- break;
- case ADB_READREG:
- switch(reg) {
- case 0:
- olen = adb_kbd_poll(d, obuf);
- break;
- case 1:
- break;
- case 2:
- obuf[0] = 0x00; /* XXX: check this */
- obuf[1] = 0x07; /* led status */
- olen = 2;
- break;
- case 3:
- obuf[0] = d->handler;
- obuf[1] = d->devaddr;
- olen = 2;
- break;
- }
- break;
- }
- return olen;
-}
-
-static int adb_kbd_reset(ADBDevice *d)
-{
- KBDState *s = d->opaque;
-
- d->handler = 1;
- d->devaddr = ADB_KEYBOARD;
- memset(s, 0, sizeof(KBDState));
-
- return 0;
-}
-
-void adb_kbd_init(ADBBusState *bus)
-{
- ADBDevice *d;
- KBDState *s;
- s = qemu_mallocz(sizeof(KBDState));
- d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
- adb_kbd_reset, s);
- adb_kbd_reset(d);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
-}
-
-/***************************************************************/
-/* Mouse ADB device */
-
-typedef struct MouseState {
- int buttons_state, last_buttons_state;
- int dx, dy, dz;
-} MouseState;
-
-static void adb_mouse_event(void *opaque,
- int dx1, int dy1, int dz1, int buttons_state)
-{
- ADBDevice *d = opaque;
- MouseState *s = d->opaque;
-
- s->dx += dx1;
- s->dy += dy1;
- s->dz += dz1;
- s->buttons_state = buttons_state;
-}
-
-
-static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
-{
- MouseState *s = d->opaque;
- int dx, dy;
-
- if (s->last_buttons_state == s->buttons_state &&
- s->dx == 0 && s->dy == 0)
- return 0;
-
- dx = s->dx;
- if (dx < -63)
- dx = -63;
- else if (dx > 63)
- dx = 63;
-
- dy = s->dy;
- if (dy < -63)
- dy = -63;
- else if (dy > 63)
- dy = 63;
-
- s->dx -= dx;
- s->dy -= dy;
- s->last_buttons_state = s->buttons_state;
-
- dx &= 0x7f;
- dy &= 0x7f;
-
- if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
- dy |= 0x80;
- if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
- dx |= 0x80;
-
- obuf[0] = dy;
- obuf[1] = dx;
- return 2;
-}
-
-static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
- const uint8_t *buf, int len)
-{
- MouseState *s = d->opaque;
- int cmd, reg, olen;
-
- if ((buf[0] & 0x0f) == ADB_FLUSH) {
- /* flush mouse fifo */
- s->buttons_state = s->last_buttons_state;
- s->dx = 0;
- s->dy = 0;
- s->dz = 0;
- return 0;
- }
-
- cmd = buf[0] & 0xc;
- reg = buf[0] & 0x3;
- olen = 0;
- switch(cmd) {
- case ADB_WRITEREG:
- switch(reg) {
- case 2:
- break;
- case 3:
- switch(buf[2]) {
- case ADB_CMD_SELF_TEST:
- break;
- case ADB_CMD_CHANGE_ID:
- case ADB_CMD_CHANGE_ID_AND_ACT:
- case ADB_CMD_CHANGE_ID_AND_ENABLE:
- d->devaddr = buf[1] & 0xf;
- break;
- default:
- /* XXX: check this */
- d->devaddr = buf[1] & 0xf;
- break;
- }
- }
- break;
- case ADB_READREG:
- switch(reg) {
- case 0:
- olen = adb_mouse_poll(d, obuf);
- break;
- case 1:
- break;
- case 3:
- obuf[0] = d->handler;
- obuf[1] = d->devaddr;
- olen = 2;
- break;
- }
- break;
- }
- return olen;
-}
-
-static int adb_mouse_reset(ADBDevice *d)
-{
- MouseState *s = d->opaque;
-
- d->handler = 2;
- d->devaddr = ADB_MOUSE;
- memset(s, 0, sizeof(MouseState));
-
- return 0;
-}
-
-void adb_mouse_init(ADBBusState *bus)
-{
- ADBDevice *d;
- MouseState *s;
-
- s = qemu_mallocz(sizeof(MouseState));
- d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
- adb_mouse_reset, s);
- adb_mouse_reset(d);
- qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
-}
diff --git a/tools/ioemu/hw/adlib.c b/tools/ioemu/hw/adlib.c
deleted file mode 100644
index b47bc3eece..0000000000
--- a/tools/ioemu/hw/adlib.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * QEMU Proxy for OPL2/3 emulation by MAME team
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <assert.h>
-#include "vl.h"
-
-#define ADLIB_KILL_TIMERS 1
-
-#define dolog(...) AUD_log ("adlib", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#ifdef HAS_YMF262
-#include "ymf262.h"
-void YMF262UpdateOneQEMU (int which, INT16 *dst, int length);
-#define SHIFT 2
-#else
-#include "fmopl.h"
-#define SHIFT 1
-#endif
-
-#define IO_READ_PROTO(name) \
- uint32_t name (void *opaque, uint32_t nport)
-#define IO_WRITE_PROTO(name) \
- void name (void *opaque, uint32_t nport, uint32_t val)
-
-static struct {
- int port;
- int freq;
-} conf = {0x220, 44100};
-
-typedef struct {
- QEMUSoundCard card;
- int ticking[2];
- int enabled;
- int active;
- int bufpos;
-#ifdef DEBUG
- int64_t exp[2];
-#endif
- int16_t *mixbuf;
- uint64_t dexp[2];
- SWVoiceOut *voice;
- int left, pos, samples;
- QEMUAudioTimeStamp ats;
-#ifndef HAS_YMF262
- FM_OPL *opl;
-#endif
-} AdlibState;
-
-static AdlibState glob_adlib;
-
-static void adlib_stop_opl_timer (AdlibState *s, size_t n)
-{
-#ifdef HAS_YMF262
- YMF262TimerOver (0, n);
-#else
- OPLTimerOver (s->opl, n);
-#endif
- s->ticking[n] = 0;
-}
-
-static void adlib_kill_timers (AdlibState *s)
-{
- size_t i;
-
- for (i = 0; i < 2; ++i) {
- if (s->ticking[i]) {
- uint64_t delta;
-
- delta = AUD_get_elapsed_usec_out (s->voice, &s->ats);
- ldebug (
- "delta = %f dexp = %f expired => %d\n",
- delta / 1000000.0,
- s->dexp[i] / 1000000.0,
- delta >= s->dexp[i]
- );
- if (ADLIB_KILL_TIMERS || delta >= s->dexp[i]) {
- adlib_stop_opl_timer (s, i);
- AUD_init_time_stamp_out (s->voice, &s->ats);
- }
- }
- }
-}
-
-static IO_WRITE_PROTO(adlib_write)
-{
- AdlibState *s = opaque;
- int a = nport & 3;
- int status;
-
- s->active = 1;
- AUD_set_active_out (s->voice, 1);
-
- adlib_kill_timers (s);
-
-#ifdef HAS_YMF262
- status = YMF262Write (0, a, val);
-#else
- status = OPLWrite (s->opl, a, val);
-#endif
-}
-
-static IO_READ_PROTO(adlib_read)
-{
- AdlibState *s = opaque;
- uint8_t data;
- int a = nport & 3;
-
- adlib_kill_timers (s);
-
-#ifdef HAS_YMF262
- data = YMF262Read (0, a);
-#else
- data = OPLRead (s->opl, a);
-#endif
- return data;
-}
-
-static void timer_handler (int c, double interval_Sec)
-{
- AdlibState *s = &glob_adlib;
- unsigned n = c & 1;
-#ifdef DEBUG
- double interval;
- int64_t exp;
-#endif
-
- if (interval_Sec == 0.0) {
- s->ticking[n] = 0;
- return;
- }
-
- s->ticking[n] = 1;
-#ifdef DEBUG
- interval = ticks_per_sec * interval_Sec;
- exp = qemu_get_clock (vm_clock) + interval;
- s->exp[n] = exp;
-#endif
-
- s->dexp[n] = interval_Sec * 1000000.0;
- AUD_init_time_stamp_out (s->voice, &s->ats);
-}
-
-static int write_audio (AdlibState *s, int samples)
-{
- int net = 0;
- int pos = s->pos;
-
- while (samples) {
- int nbytes, wbytes, wsampl;
-
- nbytes = samples << SHIFT;
- wbytes = AUD_write (
- s->voice,
- s->mixbuf + (pos << (SHIFT - 1)),
- nbytes
- );
-
- if (wbytes) {
- wsampl = wbytes >> SHIFT;
-
- samples -= wsampl;
- pos = (pos + wsampl) % s->samples;
-
- net += wsampl;
- }
- else {
- break;
- }
- }
-
- return net;
-}
-
-static void adlib_callback (void *opaque, int free)
-{
- AdlibState *s = opaque;
- int samples, net = 0, to_play, written;
-
- samples = free >> SHIFT;
- if (!(s->active && s->enabled) || !samples) {
- return;
- }
-
- to_play = audio_MIN (s->left, samples);
- while (to_play) {
- written = write_audio (s, to_play);
-
- if (written) {
- s->left -= written;
- samples -= written;
- to_play -= written;
- s->pos = (s->pos + written) % s->samples;
- }
- else {
- return;
- }
- }
-
- samples = audio_MIN (samples, s->samples - s->pos);
- if (!samples) {
- return;
- }
-
-#ifdef HAS_YMF262
- YMF262UpdateOneQEMU (0, s->mixbuf + s->pos * 2, samples);
-#else
- YM3812UpdateOne (s->opl, s->mixbuf + s->pos, samples);
-#endif
-
- while (samples) {
- written = write_audio (s, samples);
-
- if (written) {
- net += written;
- samples -= written;
- s->pos = (s->pos + written) % s->samples;
- }
- else {
- s->left = samples;
- return;
- }
- }
-}
-
-static void Adlib_fini (AdlibState *s)
-{
-#ifdef HAS_YMF262
- YMF262Shutdown ();
-#else
- if (s->opl) {
- OPLDestroy (s->opl);
- s->opl = NULL;
- }
-#endif
-
- if (s->mixbuf) {
- qemu_free (s->mixbuf);
- }
-
- s->active = 0;
- s->enabled = 0;
- AUD_remove_card (&s->card);
-}
-
-int Adlib_init (AudioState *audio)
-{
- AdlibState *s = &glob_adlib;
- audsettings_t as;
-
- if (!audio) {
- dolog ("No audio state\n");
- return -1;
- }
-
-#ifdef HAS_YMF262
- if (YMF262Init (1, 14318180, conf.freq)) {
- dolog ("YMF262Init %d failed\n", conf.freq);
- return -1;
- }
- else {
- YMF262SetTimerHandler (0, timer_handler, 0);
- s->enabled = 1;
- }
-#else
- s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq);
- if (!s->opl) {
- dolog ("OPLCreate %d failed\n", conf.freq);
- return -1;
- }
- else {
- OPLSetTimerHandler (s->opl, timer_handler, 0);
- s->enabled = 1;
- }
-#endif
-
- as.freq = conf.freq;
- as.nchannels = SHIFT;
- as.fmt = AUD_FMT_S16;
- as.endianness = AUDIO_HOST_ENDIANNESS;
-
- AUD_register_card (audio, "adlib", &s->card);
-
- s->voice = AUD_open_out (
- &s->card,
- s->voice,
- "adlib",
- s,
- adlib_callback,
- &as
- );
- if (!s->voice) {
- Adlib_fini (s);
- return -1;
- }
-
- s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT;
- s->mixbuf = qemu_mallocz (s->samples << SHIFT);
-
- if (!s->mixbuf) {
- dolog ("Could not allocate mixing buffer, %d samples (each %d bytes)\n",
- s->samples, 1 << SHIFT);
- Adlib_fini (s);
- return -1;
- }
-
- register_ioport_read (0x388, 4, 1, adlib_read, s);
- register_ioport_write (0x388, 4, 1, adlib_write, s);
-
- register_ioport_read (conf.port, 4, 1, adlib_read, s);
- register_ioport_write (conf.port, 4, 1, adlib_write, s);
-
- register_ioport_read (conf.port + 8, 2, 1, adlib_read, s);
- register_ioport_write (conf.port + 8, 2, 1, adlib_write, s);
-
- return 0;
-}
diff --git a/tools/ioemu/hw/apb_pci.c b/tools/ioemu/hw/apb_pci.c
deleted file mode 100644
index a5fe9b989e..0000000000
--- a/tools/ioemu/hw/apb_pci.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * QEMU Ultrasparc APB PCI host
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* XXX This file and most of its contests are somewhat misnamed. The
- Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
- the secondary PCI bridge. */
-
-#include "vl.h"
-typedef target_phys_addr_t pci_addr_t;
-#include "pci_host.h"
-
-typedef PCIHostState APBState;
-
-static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- APBState *s = opaque;
- int i;
-
- for (i = 11; i < 32; i++) {
- if ((val & (1 << i)) != 0)
- break;
- }
- s->config_reg = (1 << 16) | (val & 0x7FC) | (i << 11);
-}
-
-static uint32_t pci_apb_config_readl (void *opaque,
- target_phys_addr_t addr)
-{
- APBState *s = opaque;
- uint32_t val;
- int devfn;
-
- devfn = (s->config_reg >> 8) & 0xFF;
- val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_apb_config_write[] = {
- &pci_apb_config_writel,
- &pci_apb_config_writel,
- &pci_apb_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_apb_config_read[] = {
- &pci_apb_config_readl,
- &pci_apb_config_readl,
- &pci_apb_config_readl,
-};
-
-static void apb_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- //PCIBus *s = opaque;
-
- switch (addr & 0x3f) {
- case 0x00: // Control/Status
- case 0x10: // AFSR
- case 0x18: // AFAR
- case 0x20: // Diagnostic
- case 0x28: // Target address space
- // XXX
- default:
- break;
- }
-}
-
-static uint32_t apb_config_readl (void *opaque,
- target_phys_addr_t addr)
-{
- //PCIBus *s = opaque;
- uint32_t val;
-
- switch (addr & 0x3f) {
- case 0x00: // Control/Status
- case 0x10: // AFSR
- case 0x18: // AFAR
- case 0x20: // Diagnostic
- case 0x28: // Target address space
- // XXX
- default:
- val = 0;
- break;
- }
- return val;
-}
-
-static CPUWriteMemoryFunc *apb_config_write[] = {
- &apb_config_writel,
- &apb_config_writel,
- &apb_config_writel,
-};
-
-static CPUReadMemoryFunc *apb_config_read[] = {
- &apb_config_readl,
- &apb_config_readl,
- &apb_config_readl,
-};
-
-static CPUWriteMemoryFunc *pci_apb_write[] = {
- &pci_host_data_writeb,
- &pci_host_data_writew,
- &pci_host_data_writel,
-};
-
-static CPUReadMemoryFunc *pci_apb_read[] = {
- &pci_host_data_readb,
- &pci_host_data_readw,
- &pci_host_data_readl,
-};
-
-static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cpu_outb(NULL, addr & 0xffff, val);
-}
-
-static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cpu_outw(NULL, addr & 0xffff, val);
-}
-
-static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cpu_outl(NULL, addr & 0xffff, val);
-}
-
-static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
-
- val = cpu_inb(NULL, addr & 0xffff);
- return val;
-}
-
-static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
-
- val = cpu_inw(NULL, addr & 0xffff);
- return val;
-}
-
-static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
-
- val = cpu_inl(NULL, addr & 0xffff);
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
- &pci_apb_iowriteb,
- &pci_apb_iowritew,
- &pci_apb_iowritel,
-};
-
-static CPUReadMemoryFunc *pci_apb_ioread[] = {
- &pci_apb_ioreadb,
- &pci_apb_ioreadw,
- &pci_apb_ioreadl,
-};
-
-/* The APB host has an IRQ line for each IRQ line of each slot. */
-static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
-{
- return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
-}
-
-static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
-{
- int bus_offset;
- if (pci_dev->devfn & 1)
- bus_offset = 16;
- else
- bus_offset = 0;
- return bus_offset + irq_num;
-}
-
-static void pci_apb_set_irq(void *pic, int irq_num, int level)
-{
- /* PCI IRQ map onto the first 32 INO. */
- pic_set_irq_new(pic, irq_num, level);
-}
-
-PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
- void *pic)
-{
- APBState *s;
- PCIDevice *d;
- int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
- PCIDevice *apb;
- PCIBus *secondary;
-
- s = qemu_mallocz(sizeof(APBState));
- /* Ultrasparc PBM main bus */
- s->bus = pci_register_bus(pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32);
-
- pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
- pci_apb_config_write, s);
- apb_config = cpu_register_io_memory(0, apb_config_read,
- apb_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
- pci_apb_write, s);
- pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
- pci_apb_iowrite, s);
-
- cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
- cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
- cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
- cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
-
- d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
- 0, NULL, NULL);
- d->config[0x00] = 0x8e; // vendor_id : Sun
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x00; // device_id
- d->config[0x03] = 0xa0;
- d->config[0x04] = 0x06; // command = bus master, pci mem
- d->config[0x05] = 0x00;
- d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
- d->config[0x07] = 0x03; // status = medium devsel
- d->config[0x08] = 0x00; // revision
- d->config[0x09] = 0x00; // programming i/f
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
-
- /* APB secondary busses */
- secondary = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 1");
- pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 2");
- return secondary;
-}
-
-
diff --git a/tools/ioemu/hw/apic.c b/tools/ioemu/hw/apic.c
deleted file mode 100644
index 8c9776195e..0000000000
--- a/tools/ioemu/hw/apic.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-/*
- * APIC support
- *
- * Copyright (c) 2004-2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "vl.h"
-
-//#define DEBUG_APIC
-//#define DEBUG_IOAPIC
-
-/* APIC Local Vector Table */
-#define APIC_LVT_TIMER 0
-#define APIC_LVT_THERMAL 1
-#define APIC_LVT_PERFORM 2
-#define APIC_LVT_LINT0 3
-#define APIC_LVT_LINT1 4
-#define APIC_LVT_ERROR 5
-#define APIC_LVT_NB 6
-
-/* APIC delivery modes */
-#define APIC_DM_FIXED 0
-#define APIC_DM_LOWPRI 1
-#define APIC_DM_SMI 2
-#define APIC_DM_NMI 4
-#define APIC_DM_INIT 5
-#define APIC_DM_SIPI 6
-#define APIC_DM_EXTINT 7
-
-/* APIC destination mode */
-#define APIC_DESTMODE_FLAT 0xf
-#define APIC_DESTMODE_CLUSTER 1
-
-#define APIC_TRIGGER_EDGE 0
-#define APIC_TRIGGER_LEVEL 1
-
-#define APIC_LVT_TIMER_PERIODIC (1<<17)
-#define APIC_LVT_MASKED (1<<16)
-#define APIC_LVT_LEVEL_TRIGGER (1<<15)
-#define APIC_LVT_REMOTE_IRR (1<<14)
-#define APIC_INPUT_POLARITY (1<<13)
-#define APIC_SEND_PENDING (1<<12)
-
-#define IOAPIC_NUM_PINS 0x18
-
-#define ESR_ILLEGAL_ADDRESS (1 << 7)
-
-#define APIC_SV_ENABLE (1 << 8)
-
-#define MAX_APICS 255
-#define MAX_APIC_WORDS 8
-
-typedef struct APICState {
- CPUState *cpu_env;
- uint32_t apicbase;
- uint8_t id;
- uint8_t arb_id;
- uint8_t tpr;
- uint32_t spurious_vec;
- uint8_t log_dest;
- uint8_t dest_mode;
- uint32_t isr[8]; /* in service register */
- uint32_t tmr[8]; /* trigger mode register */
- uint32_t irr[8]; /* interrupt request register */
- uint32_t lvt[APIC_LVT_NB];
- uint32_t esr; /* error register */
- uint32_t icr[2];
-
- uint32_t divide_conf;
- int count_shift;
- uint32_t initial_count;
- int64_t initial_count_load_time, next_time;
- QEMUTimer *timer;
-} APICState;
-
-struct IOAPICState {
- uint8_t id;
- uint8_t ioregsel;
-
- uint32_t irr;
- uint64_t ioredtbl[IOAPIC_NUM_PINS];
-};
-
-static int apic_io_memory;
-static APICState *local_apics[MAX_APICS + 1];
-static int last_apic_id = 0;
-
-static void apic_init_ipi(APICState *s);
-static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
-static void apic_update_irq(APICState *s);
-
-/* Find first bit starting from msb. Return 0 if value = 0 */
-static int fls_bit(uint32_t value)
-{
- unsigned int ret = 0;
-
-#if defined(HOST_I386)
- __asm__ __volatile__ ("bsr %1, %0\n" : "+r" (ret) : "rm" (value));
- return ret;
-#else
- if (value > 0xffff)
- value >>= 16, ret = 16;
- if (value > 0xff)
- value >>= 8, ret += 8;
- if (value > 0xf)
- value >>= 4, ret += 4;
- if (value > 0x3)
- value >>= 2, ret += 2;
- return ret + (value >> 1);
-#endif
-}
-
-/* Find first bit starting from lsb. Return 0 if value = 0 */
-static int ffs_bit(uint32_t value)
-{
- unsigned int ret = 0;
-
-#if defined(HOST_I386)
- __asm__ __volatile__ ("bsf %1, %0\n" : "+r" (ret) : "rm" (value));
- return ret;
-#else
- if (!value)
- return 0;
- if (!(value & 0xffff))
- value >>= 16, ret = 16;
- if (!(value & 0xff))
- value >>= 8, ret += 8;
- if (!(value & 0xf))
- value >>= 4, ret += 4;
- if (!(value & 0x3))
- value >>= 2, ret += 2;
- if (!(value & 0x1))
- ret++;
- return ret;
-#endif
-}
-
-static inline void set_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- tab[i] |= mask;
-}
-
-static inline void reset_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- tab[i] &= ~mask;
-}
-
-#define foreach_apic(apic, deliver_bitmask, code) \
-{\
- int __i, __j, __mask;\
- for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
- __mask = deliver_bitmask[__i];\
- if (__mask) {\
- for(__j = 0; __j < 32; __j++) {\
- if (__mask & (1 << __j)) {\
- apic = local_apics[__i * 32 + __j];\
- if (apic) {\
- code;\
- }\
- }\
- }\
- }\
- }\
-}
-
-static void apic_bus_deliver(const uint32_t *deliver_bitmask,
- uint8_t delivery_mode,
- uint8_t vector_num, uint8_t polarity,
- uint8_t trigger_mode)
-{
- APICState *apic_iter;
-
- switch (delivery_mode) {
- case APIC_DM_LOWPRI:
- /* XXX: search for focus processor, arbitration */
- {
- int i, d;
- d = -1;
- for(i = 0; i < MAX_APIC_WORDS; i++) {
- if (deliver_bitmask[i]) {
- d = i * 32 + ffs_bit(deliver_bitmask[i]);
- break;
- }
- }
- if (d >= 0) {
- apic_iter = local_apics[d];
- if (apic_iter) {
- apic_set_irq(apic_iter, vector_num, trigger_mode);
- }
- }
- }
- return;
-
- case APIC_DM_FIXED:
- break;
-
- case APIC_DM_SMI:
- case APIC_DM_NMI:
- break;
-
- case APIC_DM_INIT:
- /* normal INIT IPI sent to processors */
- foreach_apic(apic_iter, deliver_bitmask,
- apic_init_ipi(apic_iter) );
- return;
-
- case APIC_DM_EXTINT:
- /* handled in I/O APIC code */
- break;
-
- default:
- return;
- }
-
- foreach_apic(apic_iter, deliver_bitmask,
- apic_set_irq(apic_iter, vector_num, trigger_mode) );
-}
-
-void cpu_set_apic_base(CPUState *env, uint64_t val)
-{
- APICState *s = env->apic_state;
-#ifdef DEBUG_APIC
- printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
-#endif
- s->apicbase = (val & 0xfffff000) |
- (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
- /* if disabled, cannot be enabled again */
- if (!(val & MSR_IA32_APICBASE_ENABLE)) {
- s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
- env->cpuid_features &= ~CPUID_APIC;
- s->spurious_vec &= ~APIC_SV_ENABLE;
- }
-}
-
-uint64_t cpu_get_apic_base(CPUState *env)
-{
- APICState *s = env->apic_state;
-#ifdef DEBUG_APIC
- printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
-#endif
- return s->apicbase;
-}
-
-void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
-{
- APICState *s = env->apic_state;
- s->tpr = (val & 0x0f) << 4;
- apic_update_irq(s);
-}
-
-uint8_t cpu_get_apic_tpr(CPUX86State *env)
-{
- APICState *s = env->apic_state;
- return s->tpr >> 4;
-}
-
-/* return -1 if no bit is set */
-static int get_highest_priority_int(uint32_t *tab)
-{
- int i;
- for(i = 7; i >= 0; i--) {
- if (tab[i] != 0) {
- return i * 32 + fls_bit(tab[i]);
- }
- }
- return -1;
-}
-
-static int apic_get_ppr(APICState *s)
-{
- int tpr, isrv, ppr;
-
- tpr = (s->tpr >> 4);
- isrv = get_highest_priority_int(s->isr);
- if (isrv < 0)
- isrv = 0;
- isrv >>= 4;
- if (tpr >= isrv)
- ppr = s->tpr;
- else
- ppr = isrv << 4;
- return ppr;
-}
-
-static int apic_get_arb_pri(APICState *s)
-{
- /* XXX: arbitration */
- return 0;
-}
-
-/* signal the CPU if an irq is pending */
-static void apic_update_irq(APICState *s)
-{
- int irrv, ppr;
- if (!(s->spurious_vec & APIC_SV_ENABLE))
- return;
- irrv = get_highest_priority_int(s->irr);
- if (irrv < 0)
- return;
- ppr = apic_get_ppr(s);
- if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
- return;
- cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
-}
-
-static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
-{
- set_bit(s->irr, vector_num);
- if (trigger_mode)
- set_bit(s->tmr, vector_num);
- else
- reset_bit(s->tmr, vector_num);
- apic_update_irq(s);
-}
-
-static void apic_eoi(APICState *s)
-{
- int isrv;
- isrv = get_highest_priority_int(s->isr);
- if (isrv < 0)
- return;
- reset_bit(s->isr, isrv);
- /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
- set the remote IRR bit for level triggered interrupts. */
- apic_update_irq(s);
-}
-
-static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
- uint8_t dest, uint8_t dest_mode)
-{
- APICState *apic_iter;
- int i;
-
- if (dest_mode == 0) {
- if (dest == 0xff) {
- memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
- } else {
- memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
- set_bit(deliver_bitmask, dest);
- }
- } else {
- /* XXX: cluster mode */
- memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
- for(i = 0; i < MAX_APICS; i++) {
- apic_iter = local_apics[i];
- if (apic_iter) {
- if (apic_iter->dest_mode == 0xf) {
- if (dest & apic_iter->log_dest)
- set_bit(deliver_bitmask, i);
- } else if (apic_iter->dest_mode == 0x0) {
- if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
- (dest & apic_iter->log_dest & 0x0f)) {
- set_bit(deliver_bitmask, i);
- }
- }
- }
- }
- }
-}
-
-
-static void apic_init_ipi(APICState *s)
-{
- int i;
-
- s->tpr = 0;
- s->spurious_vec = 0xff;
- s->log_dest = 0;
- s->dest_mode = 0xf;
- memset(s->isr, 0, sizeof(s->isr));
- memset(s->tmr, 0, sizeof(s->tmr));
- memset(s->irr, 0, sizeof(s->irr));
- for(i = 0; i < APIC_LVT_NB; i++)
- s->lvt[i] = 1 << 16; /* mask LVT */
- s->esr = 0;
- memset(s->icr, 0, sizeof(s->icr));
- s->divide_conf = 0;
- s->count_shift = 0;
- s->initial_count = 0;
- s->initial_count_load_time = 0;
- s->next_time = 0;
-}
-
-/* send a SIPI message to the CPU to start it */
-static void apic_startup(APICState *s, int vector_num)
-{
- CPUState *env = s->cpu_env;
- if (!(env->hflags & HF_HALTED_MASK))
- return;
- env->eip = 0;
- cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
- 0xffff, 0);
- env->hflags &= ~HF_HALTED_MASK;
-}
-
-static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
- uint8_t delivery_mode, uint8_t vector_num,
- uint8_t polarity, uint8_t trigger_mode)
-{
- uint32_t deliver_bitmask[MAX_APIC_WORDS];
- int dest_shorthand = (s->icr[0] >> 18) & 3;
- APICState *apic_iter;
-
- switch (dest_shorthand) {
- case 0:
- apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
- break;
- case 1:
- memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
- set_bit(deliver_bitmask, s->id);
- break;
- case 2:
- memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
- break;
- case 3:
- memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
- reset_bit(deliver_bitmask, s->id);
- break;
- }
-
- switch (delivery_mode) {
- case APIC_DM_INIT:
- {
- int trig_mode = (s->icr[0] >> 15) & 1;
- int level = (s->icr[0] >> 14) & 1;
- if (level == 0 && trig_mode == 1) {
- foreach_apic(apic_iter, deliver_bitmask,
- apic_iter->arb_id = apic_iter->id );
- return;
- }
- }
- break;
-
- case APIC_DM_SIPI:
- foreach_apic(apic_iter, deliver_bitmask,
- apic_startup(apic_iter, vector_num) );
- return;
- }
-
- apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
- trigger_mode);
-}
-
-int apic_get_interrupt(CPUState *env)
-{
- APICState *s = env->apic_state;
- int intno;
-
- /* if the APIC is installed or enabled, we let the 8259 handle the
- IRQs */
- if (!s)
- return -1;
- if (!(s->spurious_vec & APIC_SV_ENABLE))
- return -1;
-
- /* XXX: spurious IRQ handling */
- intno = get_highest_priority_int(s->irr);
- if (intno < 0)
- return -1;
- if (s->tpr && intno <= s->tpr)
- return s->spurious_vec & 0xff;
- reset_bit(s->irr, intno);
- set_bit(s->isr, intno);
- apic_update_irq(s);
- return intno;
-}
-
-static uint32_t apic_get_current_count(APICState *s)
-{
- int64_t d;
- uint32_t val;
- d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
- s->count_shift;
- if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
- /* periodic */
- val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
- } else {
- if (d >= s->initial_count)
- val = 0;
- else
- val = s->initial_count - d;
- }
- return val;
-}
-
-static void apic_timer_update(APICState *s, int64_t current_time)
-{
- int64_t next_time, d;
-
- if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
- d = (current_time - s->initial_count_load_time) >>
- s->count_shift;
- if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
- d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
- } else {
- if (d >= s->initial_count)
- goto no_timer;
- d = (uint64_t)s->initial_count + 1;
- }
- next_time = s->initial_count_load_time + (d << s->count_shift);
- qemu_mod_timer(s->timer, next_time);
- s->next_time = next_time;
- } else {
- no_timer:
- qemu_del_timer(s->timer);
- }
-}
-
-static void apic_timer(void *opaque)
-{
- APICState *s = opaque;
-
- if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
- apic_set_irq(s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
- }
- apic_timer_update(s, s->next_time);
-}
-
-static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-}
-
-static void apic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-}
-
-static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- CPUState *env;
- APICState *s;
- uint32_t val;
- int index;
-
- env = cpu_single_env;
- if (!env)
- return 0;
- s = env->apic_state;
-
- index = (addr >> 4) & 0xff;
- switch(index) {
- case 0x02: /* id */
- val = s->id << 24;
- break;
- case 0x03: /* version */
- val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
- break;
- case 0x08:
- val = s->tpr;
- break;
- case 0x09:
- val = apic_get_arb_pri(s);
- break;
- case 0x0a:
- /* ppr */
- val = apic_get_ppr(s);
- break;
- case 0x0d:
- val = s->log_dest << 24;
- break;
- case 0x0e:
- val = s->dest_mode << 28;
- break;
- case 0x0f:
- val = s->spurious_vec;
- break;
- case 0x10 ... 0x17:
- val = s->isr[index & 7];
- break;
- case 0x18 ... 0x1f:
- val = s->tmr[index & 7];
- break;
- case 0x20 ... 0x27:
- val = s->irr[index & 7];
- break;
- case 0x28:
- val = s->esr;
- break;
- case 0x30:
- case 0x31:
- val = s->icr[index & 1];
- break;
- case 0x32 ... 0x37:
- val = s->lvt[index - 0x32];
- break;
- case 0x38:
- val = s->initial_count;
- break;
- case 0x39:
- val = apic_get_current_count(s);
- break;
- case 0x3e:
- val = s->divide_conf;
- break;
- default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
- val = 0;
- break;
- }
-#ifdef DEBUG_APIC
- printf("APIC read: %08x = %08x\n", (uint32_t)addr, val);
-#endif
- return val;
-}
-
-static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- CPUState *env;
- APICState *s;
- int index;
-
- env = cpu_single_env;
- if (!env)
- return;
- s = env->apic_state;
-
-#ifdef DEBUG_APIC
- printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
-#endif
-
- index = (addr >> 4) & 0xff;
- switch(index) {
- case 0x02:
- s->id = (val >> 24);
- break;
- case 0x03:
- break;
- case 0x08:
- s->tpr = val;
- apic_update_irq(s);
- break;
- case 0x09:
- case 0x0a:
- break;
- case 0x0b: /* EOI */
- apic_eoi(s);
- break;
- case 0x0d:
- s->log_dest = val >> 24;
- break;
- case 0x0e:
- s->dest_mode = val >> 28;
- break;
- case 0x0f:
- s->spurious_vec = val & 0x1ff;
- apic_update_irq(s);
- break;
- case 0x10 ... 0x17:
- case 0x18 ... 0x1f:
- case 0x20 ... 0x27:
- case 0x28:
- break;
- case 0x30:
- s->icr[0] = val;
- apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
- (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
- (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
- break;
- case 0x31:
- s->icr[1] = val;
- break;
- case 0x32 ... 0x37:
- {
- int n = index - 0x32;
- s->lvt[n] = val;
- if (n == APIC_LVT_TIMER)
- apic_timer_update(s, qemu_get_clock(vm_clock));
- }
- break;
- case 0x38:
- s->initial_count = val;
- s->initial_count_load_time = qemu_get_clock(vm_clock);
- apic_timer_update(s, s->initial_count_load_time);
- break;
- case 0x39:
- break;
- case 0x3e:
- {
- int v;
- s->divide_conf = val & 0xb;
- v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
- s->count_shift = (v + 1) & 7;
- }
- break;
- default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
- break;
- }
-}
-
-static void apic_save(QEMUFile *f, void *opaque)
-{
- APICState *s = opaque;
- int i;
-
- qemu_put_be32s(f, &s->apicbase);
- qemu_put_8s(f, &s->id);
- qemu_put_8s(f, &s->arb_id);
- qemu_put_8s(f, &s->tpr);
- qemu_put_be32s(f, &s->spurious_vec);
- qemu_put_8s(f, &s->log_dest);
- qemu_put_8s(f, &s->dest_mode);
- for (i = 0; i < 8; i++) {
- qemu_put_be32s(f, &s->isr[i]);
- qemu_put_be32s(f, &s->tmr[i]);
- qemu_put_be32s(f, &s->irr[i]);
- }
- for (i = 0; i < APIC_LVT_NB; i++) {
- qemu_put_be32s(f, &s->lvt[i]);
- }
- qemu_put_be32s(f, &s->esr);
- qemu_put_be32s(f, &s->icr[0]);
- qemu_put_be32s(f, &s->icr[1]);
- qemu_put_be32s(f, &s->divide_conf);
- qemu_put_be32s(f, &s->count_shift);
- qemu_put_be32s(f, &s->initial_count);
- qemu_put_be64s(f, &s->initial_count_load_time);
- qemu_put_be64s(f, &s->next_time);
-
- qemu_put_timer(f, s->timer);
-}
-
-static int apic_load(QEMUFile *f, void *opaque, int version_id)
-{
- APICState *s = opaque;
- int i;
-
- if (version_id > 2)
- return -EINVAL;
-
- /* XXX: what if the base changes? (registered memory regions) */
- qemu_get_be32s(f, &s->apicbase);
- qemu_get_8s(f, &s->id);
- qemu_get_8s(f, &s->arb_id);
- qemu_get_8s(f, &s->tpr);
- qemu_get_be32s(f, &s->spurious_vec);
- qemu_get_8s(f, &s->log_dest);
- qemu_get_8s(f, &s->dest_mode);
- for (i = 0; i < 8; i++) {
- qemu_get_be32s(f, &s->isr[i]);
- qemu_get_be32s(f, &s->tmr[i]);
- qemu_get_be32s(f, &s->irr[i]);
- }
- for (i = 0; i < APIC_LVT_NB; i++) {
- qemu_get_be32s(f, &s->lvt[i]);
- }
- qemu_get_be32s(f, &s->esr);
- qemu_get_be32s(f, &s->icr[0]);
- qemu_get_be32s(f, &s->icr[1]);
- qemu_get_be32s(f, &s->divide_conf);
- qemu_get_be32s(f, &s->count_shift);
- qemu_get_be32s(f, &s->initial_count);
- qemu_get_be64s(f, &s->initial_count_load_time);
- qemu_get_be64s(f, &s->next_time);
-
- if (version_id >= 2)
- qemu_get_timer(f, s->timer);
- return 0;
-}
-
-static void apic_reset(void *opaque)
-{
- APICState *s = opaque;
- apic_init_ipi(s);
-}
-
-static CPUReadMemoryFunc *apic_mem_read[3] = {
- apic_mem_readb,
- apic_mem_readw,
- apic_mem_readl,
-};
-
-static CPUWriteMemoryFunc *apic_mem_write[3] = {
- apic_mem_writeb,
- apic_mem_writew,
- apic_mem_writel,
-};
-
-int apic_init(CPUState *env)
-{
- APICState *s;
-
- if (last_apic_id >= MAX_APICS)
- return -1;
- s = qemu_mallocz(sizeof(APICState));
- if (!s)
- return -1;
- env->apic_state = s;
- apic_init_ipi(s);
- s->id = last_apic_id++;
- s->cpu_env = env;
- s->apicbase = 0xfee00000 |
- (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
-
- /* XXX: mapping more APICs at the same memory location */
- if (apic_io_memory == 0) {
- /* NOTE: the APIC is directly connected to the CPU - it is not
- on the global memory bus. */
- apic_io_memory = cpu_register_io_memory(0, apic_mem_read,
- apic_mem_write, NULL);
- cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
- apic_io_memory);
- }
- s->timer = qemu_new_timer(vm_clock, apic_timer, s);
-
- register_savevm("apic", 0, 2, apic_save, apic_load, s);
- qemu_register_reset(apic_reset, s);
-
- local_apics[s->id] = s;
- return 0;
-}
-
-static void ioapic_service(IOAPICState *s)
-{
- uint8_t i;
- uint8_t trig_mode;
- uint8_t vector;
- uint8_t delivery_mode;
- uint32_t mask;
- uint64_t entry;
- uint8_t dest;
- uint8_t dest_mode;
- uint8_t polarity;
- uint32_t deliver_bitmask[MAX_APIC_WORDS];
-
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- mask = 1 << i;
- if (s->irr & mask) {
- entry = s->ioredtbl[i];
- if (!(entry & APIC_LVT_MASKED)) {
- trig_mode = ((entry >> 15) & 1);
- dest = entry >> 56;
- dest_mode = (entry >> 11) & 1;
- delivery_mode = (entry >> 8) & 7;
- polarity = (entry >> 13) & 1;
- if (trig_mode == APIC_TRIGGER_EDGE)
- s->irr &= ~mask;
- if (delivery_mode == APIC_DM_EXTINT)
- vector = pic_read_irq(isa_pic);
- else
- vector = entry & 0xff;
-
- apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
- apic_bus_deliver(deliver_bitmask, delivery_mode,
- vector, polarity, trig_mode);
- }
- }
- }
-}
-
-void ioapic_set_irq(void *opaque, int vector, int level)
-{
- IOAPICState *s = opaque;
-
- if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
- uint32_t mask = 1 << vector;
- uint64_t entry = s->ioredtbl[vector];
-
- if ((entry >> 15) & 1) {
- /* level triggered */
- if (level) {
- s->irr |= mask;
- ioapic_service(s);
- } else {
- s->irr &= ~mask;
- }
- } else {
- /* edge triggered */
- if (level) {
- s->irr |= mask;
- ioapic_service(s);
- }
- }
- }
-}
-
-static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- IOAPICState *s = opaque;
- int index;
- uint32_t val = 0;
-
- addr &= 0xff;
- if (addr == 0x00) {
- val = s->ioregsel;
- } else if (addr == 0x10) {
- switch (s->ioregsel) {
- case 0x00:
- val = s->id << 24;
- break;
- case 0x01:
- val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
- break;
- case 0x02:
- val = 0;
- break;
- default:
- index = (s->ioregsel - 0x10) >> 1;
- if (index >= 0 && index < IOAPIC_NUM_PINS) {
- if (s->ioregsel & 1)
- val = s->ioredtbl[index] >> 32;
- else
- val = s->ioredtbl[index] & 0xffffffff;
- }
- }
-#ifdef DEBUG_IOAPIC
- printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
-#endif
- }
- return val;
-}
-
-static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- IOAPICState *s = opaque;
- int index;
-
- addr &= 0xff;
- if (addr == 0x00) {
- s->ioregsel = val;
- return;
- } else if (addr == 0x10) {
-#ifdef DEBUG_IOAPIC
- printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
-#endif
- switch (s->ioregsel) {
- case 0x00:
- s->id = (val >> 24) & 0xff;
- return;
- case 0x01:
- case 0x02:
- return;
- default:
- index = (s->ioregsel - 0x10) >> 1;
- if (index >= 0 && index < IOAPIC_NUM_PINS) {
- if (s->ioregsel & 1) {
- s->ioredtbl[index] &= 0xffffffff;
- s->ioredtbl[index] |= (uint64_t)val << 32;
- } else {
- s->ioredtbl[index] &= ~0xffffffffULL;
- s->ioredtbl[index] |= val;
- }
- ioapic_service(s);
- }
- }
- }
-}
-
-static void ioapic_save(QEMUFile *f, void *opaque)
-{
- IOAPICState *s = opaque;
- int i;
-
- qemu_put_8s(f, &s->id);
- qemu_put_8s(f, &s->ioregsel);
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- qemu_put_be64s(f, &s->ioredtbl[i]);
- }
-}
-
-static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
-{
- IOAPICState *s = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_8s(f, &s->id);
- qemu_get_8s(f, &s->ioregsel);
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- qemu_get_be64s(f, &s->ioredtbl[i]);
- }
- return 0;
-}
-
-static void ioapic_reset(void *opaque)
-{
- IOAPICState *s = opaque;
- int i;
-
- memset(s, 0, sizeof(*s));
- for(i = 0; i < IOAPIC_NUM_PINS; i++)
- s->ioredtbl[i] = 1 << 16; /* mask LVT */
-}
-
-static CPUReadMemoryFunc *ioapic_mem_read[3] = {
- ioapic_mem_readl,
- ioapic_mem_readl,
- ioapic_mem_readl,
-};
-
-static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
- ioapic_mem_writel,
- ioapic_mem_writel,
- ioapic_mem_writel,
-};
-
-IOAPICState *ioapic_init(void)
-{
- IOAPICState *s;
- int io_memory;
-
- s = qemu_mallocz(sizeof(IOAPICState));
- if (!s)
- return NULL;
- ioapic_reset(s);
- s->id = last_apic_id++;
-
- io_memory = cpu_register_io_memory(0, ioapic_mem_read,
- ioapic_mem_write, s);
- cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
-
- register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
- qemu_register_reset(ioapic_reset, s);
-
- return s;
-}
diff --git a/tools/ioemu/hw/arm_boot.c b/tools/ioemu/hw/arm_boot.c
deleted file mode 100644
index 28f6a92622..0000000000
--- a/tools/ioemu/hw/arm_boot.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * ARM kernel loader.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
-#define INITRD_LOAD_ADDR 0x00800000
-
-/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
-static uint32_t bootloader[] = {
- 0xe3a00000, /* mov r0, #0 */
- 0xe3a01000, /* mov r1, #0x?? */
- 0xe3811c00, /* orr r1, r1, #0x??00 */
- 0xe59f2000, /* ldr r2, [pc, #0] */
- 0xe59ff000, /* ldr pc, [pc, #0] */
- 0, /* Address of kernel args. Set by integratorcp_init. */
- 0 /* Kernel entry point. Set by integratorcp_init. */
-};
-
-static void set_kernel_args(uint32_t ram_size, int initrd_size,
- const char *kernel_cmdline)
-{
- uint32_t *p;
-
- p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR);
- /* ATAG_CORE */
- stl_raw(p++, 5);
- stl_raw(p++, 0x54410001);
- stl_raw(p++, 1);
- stl_raw(p++, 0x1000);
- stl_raw(p++, 0);
- /* ATAG_MEM */
- stl_raw(p++, 4);
- stl_raw(p++, 0x54410002);
- stl_raw(p++, ram_size);
- stl_raw(p++, 0);
- if (initrd_size) {
- /* ATAG_INITRD2 */
- stl_raw(p++, 4);
- stl_raw(p++, 0x54420005);
- stl_raw(p++, INITRD_LOAD_ADDR);
- stl_raw(p++, initrd_size);
- }
- if (kernel_cmdline && *kernel_cmdline) {
- /* ATAG_CMDLINE */
- int cmdline_size;
-
- cmdline_size = strlen(kernel_cmdline);
- memcpy (p + 2, kernel_cmdline, cmdline_size + 1);
- cmdline_size = (cmdline_size >> 2) + 1;
- stl_raw(p++, cmdline_size + 2);
- stl_raw(p++, 0x54410009);
- p += cmdline_size;
- }
- /* ATAG_END */
- stl_raw(p++, 0);
- stl_raw(p++, 0);
-}
-
-void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
- const char *kernel_cmdline, const char *initrd_filename,
- int board_id)
-{
- int kernel_size;
- int initrd_size;
- int n;
- uint64_t entry;
-
- /* Load the kernel. */
- if (!kernel_filename) {
- fprintf(stderr, "Kernel image must be specified\n");
- exit(1);
- }
-
- kernel_size = load_elf(kernel_filename, 0, &entry);
- if (kernel_size >= 0) {
- /* An ELF image. Jump to the entry point. */
- env->regs[15] = entry & 0xfffffffe;
- env->thumb = entry & 1;
- } else {
- /* Raw binary image. Assume it is a Linux zImage. */
- kernel_size = load_image(kernel_filename,
- phys_ram_base + KERNEL_LOAD_ADDR);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
- exit(1);
- }
- if (initrd_filename) {
- initrd_size = load_image(initrd_filename,
- phys_ram_base + INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initrd '%s'\n",
- initrd_filename);
- exit(1);
- }
- } else {
- initrd_size = 0;
- }
- bootloader[1] |= board_id & 0xff;
- bootloader[2] |= (board_id >> 8) & 0xff;
- bootloader[5] = KERNEL_ARGS_ADDR;
- bootloader[6] = KERNEL_LOAD_ADDR;
- for (n = 0; n < sizeof(bootloader) / 4; n++)
- stl_raw(phys_ram_base + (n * 4), bootloader[n]);
- set_kernel_args(ram_size, initrd_size, kernel_cmdline);
- }
-}
-
diff --git a/tools/ioemu/hw/arm_gic.c b/tools/ioemu/hw/arm_gic.c
deleted file mode 100644
index 2901f3466e..0000000000
--- a/tools/ioemu/hw/arm_gic.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * ARM AMBA Generic/Distributed Interrupt Controller
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-/* TODO: Some variants of this controller can handle multiple CPUs.
- Currently only single CPU operation is implemented. */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-//#define DEBUG_GIC
-
-#ifdef DEBUG_GIC
-#define DPRINTF(fmt, args...) \
-do { printf("arm_gic: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-/* Distributed interrupt controller. */
-
-static const uint8_t gic_id[] =
-{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-
-#define GIC_NIRQ 96
-
-typedef struct gic_irq_state
-{
- unsigned enabled:1;
- unsigned pending:1;
- unsigned active:1;
- unsigned level:1;
- unsigned model:1; /* 0 = 1:N, 1 = N:N */
- unsigned trigger:1; /* nonzero = edge triggered. */
-} gic_irq_state;
-
-#define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1
-#define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0
-#define GIC_TEST_ENABLED(irq) s->irq_state[irq].enabled
-#define GIC_SET_PENDING(irq) s->irq_state[irq].pending = 1
-#define GIC_CLEAR_PENDING(irq) s->irq_state[irq].pending = 0
-#define GIC_TEST_PENDING(irq) s->irq_state[irq].pending
-#define GIC_SET_ACTIVE(irq) s->irq_state[irq].active = 1
-#define GIC_CLEAR_ACTIVE(irq) s->irq_state[irq].active = 0
-#define GIC_TEST_ACTIVE(irq) s->irq_state[irq].active
-#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
-#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
-#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
-#define GIC_SET_LEVEL(irq) s->irq_state[irq].level = 1
-#define GIC_CLEAR_LEVEL(irq) s->irq_state[irq].level = 0
-#define GIC_TEST_LEVEL(irq) s->irq_state[irq].level
-#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
-#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
-#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
-
-typedef struct gic_state
-{
- arm_pic_handler handler;
- uint32_t base;
- void *parent;
- int parent_irq;
- int enabled;
- int cpu_enabled;
-
- gic_irq_state irq_state[GIC_NIRQ];
- int irq_target[GIC_NIRQ];
- int priority[GIC_NIRQ];
- int last_active[GIC_NIRQ];
-
- int priority_mask;
- int running_irq;
- int running_priority;
- int current_pending;
-} gic_state;
-
-/* TODO: Many places that call this routine could be optimized. */
-/* Update interrupt status after enabled or pending bits have been changed. */
-static void gic_update(gic_state *s)
-{
- int best_irq;
- int best_prio;
- int irq;
-
- s->current_pending = 1023;
- if (!s->enabled || !s->cpu_enabled) {
- pic_set_irq_new(s->parent, s->parent_irq, 0);
- return;
- }
- best_prio = 0x100;
- best_irq = 1023;
- for (irq = 0; irq < 96; irq++) {
- if (GIC_TEST_ENABLED(irq) && GIC_TEST_PENDING(irq)) {
- if (s->priority[irq] < best_prio) {
- best_prio = s->priority[irq];
- best_irq = irq;
- }
- }
- }
- if (best_prio > s->priority_mask) {
- pic_set_irq_new(s->parent, s->parent_irq, 0);
- } else {
- s->current_pending = best_irq;
- if (best_prio < s->running_priority) {
- DPRINTF("Raised pending IRQ %d\n", best_irq);
- pic_set_irq_new(s->parent, s->parent_irq, 1);
- }
- }
-}
-
-static void gic_set_irq(void *opaque, int irq, int level)
-{
- gic_state *s = (gic_state *)opaque;
- /* The first external input line is internal interrupt 32. */
- irq += 32;
- if (level == GIC_TEST_LEVEL(irq))
- return;
-
- if (level) {
- GIC_SET_LEVEL(irq);
- if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq)) {
- DPRINTF("Set %d pending\n", irq);
- GIC_SET_PENDING(irq);
- }
- } else {
- GIC_CLEAR_LEVEL(irq);
- }
- gic_update(s);
-}
-
-static void gic_set_running_irq(gic_state *s, int irq)
-{
- s->running_irq = irq;
- if (irq == 1023)
- s->running_priority = 0x100;
- else
- s->running_priority = s->priority[irq];
- gic_update(s);
-}
-
-static uint32_t gic_acknowledge_irq(gic_state *s)
-{
- int new_irq;
- new_irq = s->current_pending;
- if (new_irq == 1023 || s->priority[new_irq] >= s->running_priority) {
- DPRINTF("ACK no pending IRQ\n");
- return 1023;
- }
- pic_set_irq_new(s->parent, s->parent_irq, 0);
- s->last_active[new_irq] = s->running_irq;
- /* For level triggered interrupts we clear the pending bit while
- the interrupt is active. */
- GIC_CLEAR_PENDING(new_irq);
- gic_set_running_irq(s, new_irq);
- DPRINTF("ACK %d\n", new_irq);
- return new_irq;
-}
-
-static void gic_complete_irq(gic_state * s, int irq)
-{
- int update = 0;
- DPRINTF("EOI %d\n", irq);
- if (s->running_irq == 1023)
- return; /* No active IRQ. */
- if (irq != 1023) {
- /* Mark level triggered interrupts as pending if they are still
- raised. */
- if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq)
- && GIC_TEST_LEVEL(irq)) {
- GIC_SET_PENDING(irq);
- update = 1;
- }
- }
- if (irq != s->running_irq) {
- /* Complete an IRQ that is not currently running. */
- int tmp = s->running_irq;
- while (s->last_active[tmp] != 1023) {
- if (s->last_active[tmp] == irq) {
- s->last_active[tmp] = s->last_active[irq];
- break;
- }
- tmp = s->last_active[tmp];
- }
- if (update) {
- gic_update(s);
- }
- } else {
- /* Complete the current running IRQ. */
- gic_set_running_irq(s, s->last_active[s->running_irq]);
- }
-}
-
-static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
-{
- gic_state *s = (gic_state *)opaque;
- uint32_t res;
- int irq;
- int i;
-
- offset -= s->base + 0x1000;
- if (offset < 0x100) {
- if (offset == 0)
- return s->enabled;
- if (offset == 4)
- return (GIC_NIRQ / 32) - 1;
- if (offset < 0x08)
- return 0;
- goto bad_reg;
- } else if (offset < 0x200) {
- /* Interrupt Set/Clear Enable. */
- if (offset < 0x180)
- irq = (offset - 0x100) * 8;
- else
- irq = (offset - 0x180) * 8;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_ENABLED(irq + i)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x300) {
- /* Interrupt Set/Clear Pending. */
- if (offset < 0x280)
- irq = (offset - 0x200) * 8;
- else
- irq = (offset - 0x280) * 8;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_PENDING(irq + i)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x400) {
- /* Interrupt Active. */
- irq = (offset - 0x300) * 8;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_ACTIVE(irq + i)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x800) {
- /* Interrupt Priority. */
- irq = offset - 0x400;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = s->priority[irq];
- } else if (offset < 0xc00) {
- /* Interrupt CPU Target. */
- irq = offset - 0x800;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = s->irq_target[irq];
- } else if (offset < 0xf00) {
- /* Interrupt Configuration. */
- irq = (offset - 0xc00) * 2;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 4; i++) {
- if (GIC_TEST_MODEL(irq + i))
- res |= (1 << (i * 2));
- if (GIC_TEST_TRIGGER(irq + i))
- res |= (2 << (i * 2));
- }
- } else if (offset < 0xfe0) {
- goto bad_reg;
- } else /* offset >= 0xfe0 */ {
- if (offset & 3) {
- res = 0;
- } else {
- res = gic_id[(offset - 0xfe0) >> 2];
- }
- }
- return res;
-bad_reg:
- cpu_abort (cpu_single_env, "gic_dist_readb: Bad offset %x\n", offset);
- return 0;
-}
-
-static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = gic_dist_readb(opaque, offset);
- val |= gic_dist_readb(opaque, offset + 1) << 8;
- return val;
-}
-
-static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = gic_dist_readw(opaque, offset);
- val |= gic_dist_readw(opaque, offset + 2) << 16;
- return val;
-}
-
-static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_state *s = (gic_state *)opaque;
- int irq;
- int i;
-
- offset -= s->base + 0x1000;
- if (offset < 0x100) {
- if (offset == 0) {
- s->enabled = (value & 1);
- DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
- } else if (offset < 4) {
- /* ignored. */
- } else {
- goto bad_reg;
- }
- } else if (offset < 0x180) {
- /* Interrupt Set Enable. */
- irq = (offset - 0x100) * 8;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- if (!GIC_TEST_ENABLED(irq + i))
- DPRINTF("Enabled IRQ %d\n", irq + i);
- GIC_SET_ENABLED(irq + i);
- /* If a raised level triggered IRQ enabled then mark
- is as pending. */
- if (GIC_TEST_LEVEL(irq + i) && !GIC_TEST_TRIGGER(irq + i))
- GIC_SET_PENDING(irq + i);
- }
- }
- } else if (offset < 0x200) {
- /* Interrupt Clear Enable. */
- irq = (offset - 0x180) * 8;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- if (GIC_TEST_ENABLED(irq + i))
- DPRINTF("Disabled IRQ %d\n", irq + i);
- GIC_CLEAR_ENABLED(irq + i);
- }
- }
- } else if (offset < 0x280) {
- /* Interrupt Set Pending. */
- irq = (offset - 0x200) * 8;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- GIC_SET_PENDING(irq + i);
- }
- }
- } else if (offset < 0x300) {
- /* Interrupt Clear Pending. */
- irq = (offset - 0x280) * 8;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- GIC_CLEAR_PENDING(irq + i);
- }
- }
- } else if (offset < 0x400) {
- /* Interrupt Active. */
- goto bad_reg;
- } else if (offset < 0x800) {
- /* Interrupt Priority. */
- irq = offset - 0x400;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- s->priority[irq] = value;
- } else if (offset < 0xc00) {
- /* Interrupt CPU Target. */
- irq = offset - 0x800;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- s->irq_target[irq] = value;
- } else if (offset < 0xf00) {
- /* Interrupt Configuration. */
- irq = (offset - 0xc00) * 4;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- for (i = 0; i < 4; i++) {
- if (value & (1 << (i * 2))) {
- GIC_SET_MODEL(irq + i);
- } else {
- GIC_CLEAR_MODEL(irq + i);
- }
- if (value & (2 << (i * 2))) {
- GIC_SET_TRIGGER(irq + i);
- } else {
- GIC_CLEAR_TRIGGER(irq + i);
- }
- }
- } else {
- /* 0xf00 is only handled for word writes. */
- goto bad_reg;
- }
- gic_update(s);
- return;
-bad_reg:
- cpu_abort (cpu_single_env, "gic_dist_writeb: Bad offset %x\n", offset);
-}
-
-static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_state *s = (gic_state *)opaque;
- if (offset - s->base == 0xf00) {
- GIC_SET_PENDING(value & 0x3ff);
- gic_update(s);
- return;
- }
- gic_dist_writeb(opaque, offset, value & 0xff);
- gic_dist_writeb(opaque, offset + 1, value >> 8);
-}
-
-static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_dist_writew(opaque, offset, value & 0xffff);
- gic_dist_writew(opaque, offset + 2, value >> 16);
-}
-
-static CPUReadMemoryFunc *gic_dist_readfn[] = {
- gic_dist_readb,
- gic_dist_readw,
- gic_dist_readl
-};
-
-static CPUWriteMemoryFunc *gic_dist_writefn[] = {
- gic_dist_writeb,
- gic_dist_writew,
- gic_dist_writel
-};
-
-static uint32_t gic_cpu_read(void *opaque, target_phys_addr_t offset)
-{
- gic_state *s = (gic_state *)opaque;
- offset -= s->base;
- switch (offset) {
- case 0x00: /* Control */
- return s->cpu_enabled;
- case 0x04: /* Priority mask */
- return s->priority_mask;
- case 0x08: /* Binary Point */
- /* ??? Not implemented. */
- return 0;
- case 0x0c: /* Acknowledge */
- return gic_acknowledge_irq(s);
- case 0x14: /* Runing Priority */
- return s->running_priority;
- case 0x18: /* Highest Pending Interrupt */
- return s->current_pending;
- default:
- cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void gic_cpu_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_state *s = (gic_state *)opaque;
- offset -= s->base;
- switch (offset) {
- case 0x00: /* Control */
- s->cpu_enabled = (value & 1);
- DPRINTF("CPU %sabled\n", s->cpu_enabled ? "En" : "Dis");
- break;
- case 0x04: /* Priority mask */
- s->priority_mask = (value & 0x3ff);
- break;
- case 0x08: /* Binary Point */
- /* ??? Not implemented. */
- break;
- case 0x10: /* End Of Interrupt */
- return gic_complete_irq(s, value & 0x3ff);
- default:
- cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
- return;
- }
- gic_update(s);
-}
-
-static CPUReadMemoryFunc *gic_cpu_readfn[] = {
- gic_cpu_read,
- gic_cpu_read,
- gic_cpu_read
-};
-
-static CPUWriteMemoryFunc *gic_cpu_writefn[] = {
- gic_cpu_write,
- gic_cpu_write,
- gic_cpu_write
-};
-
-static void gic_reset(gic_state *s)
-{
- int i;
- memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
- s->priority_mask = 0xf0;
- s->current_pending = 1023;
- s->running_irq = 1023;
- s->running_priority = 0x100;
- for (i = 0; i < 15; i++) {
- GIC_SET_ENABLED(i);
- GIC_SET_TRIGGER(i);
- }
- s->enabled = 0;
- s->cpu_enabled = 0;
-}
-
-void *arm_gic_init(uint32_t base, void *parent, int parent_irq)
-{
- gic_state *s;
- int iomemtype;
-
- s = (gic_state *)qemu_mallocz(sizeof(gic_state));
- if (!s)
- return NULL;
- s->handler = gic_set_irq;
- s->parent = parent;
- s->parent_irq = parent_irq;
- if (base != 0xffffffff) {
- iomemtype = cpu_register_io_memory(0, gic_cpu_readfn,
- gic_cpu_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
- gic_dist_writefn, s);
- cpu_register_physical_memory(base + 0x1000, 0x00000fff, iomemtype);
- s->base = base;
- } else {
- s->base = 0;
- }
- gic_reset(s);
- return s;
-}
diff --git a/tools/ioemu/hw/arm_pic.c b/tools/ioemu/hw/arm_pic.c
deleted file mode 100644
index fbc2d67d0a..0000000000
--- a/tools/ioemu/hw/arm_pic.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Generic ARM Programmable Interrupt Controller support.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL
- */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-/* Stub functions for hardware that doesn't exist. */
-void pic_set_irq(int irq, int level)
-{
- cpu_abort(cpu_single_env, "pic_set_irq");
-}
-
-void pic_info(void)
-{
-}
-
-void irq_info(void)
-{
-}
-
-
-void pic_set_irq_new(void *opaque, int irq, int level)
-{
- arm_pic_handler *p = (arm_pic_handler *)opaque;
- /* Call the real handler. */
- (*p)(opaque, irq, level);
-}
-
-/* Model the IRQ/FIQ CPU interrupt lines as a two input interrupt controller.
- Input 0 is IRQ and input 1 is FIQ. */
-typedef struct
-{
- arm_pic_handler handler;
- CPUState *cpu_env;
-} arm_pic_cpu_state;
-
-static void arm_pic_cpu_handler(void *opaque, int irq, int level)
-{
- arm_pic_cpu_state *s = (arm_pic_cpu_state *)opaque;
- switch (irq) {
- case ARM_PIC_CPU_IRQ:
- if (level)
- cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
- else
- cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
- break;
- case ARM_PIC_CPU_FIQ:
- if (level)
- cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
- else
- cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
- break;
- default:
- cpu_abort(s->cpu_env, "arm_pic_cpu_handler: Bad interrput line %d\n",
- irq);
- }
-}
-
-void *arm_pic_init_cpu(CPUState *env)
-{
- arm_pic_cpu_state *s;
-
- s = (arm_pic_cpu_state *)malloc(sizeof(arm_pic_cpu_state));
- s->handler = arm_pic_cpu_handler;
- s->cpu_env = env;
- return s;
-}
diff --git a/tools/ioemu/hw/arm_pic.h b/tools/ioemu/hw/arm_pic.h
deleted file mode 100644
index b29914985a..0000000000
--- a/tools/ioemu/hw/arm_pic.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Generic ARM Programmable Interrupt Controller support.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- * Arm hardware uses a wide variety of interrupt handling hardware.
- * This provides a generic framework for connecting interrupt sources and
- * inputs.
- */
-
-#ifndef ARM_INTERRUPT_H
-#define ARM_INTERRUPT_H 1
-
-/* The first element of an individual PIC state structures should
- be a pointer to the handler routine. */
-typedef void (*arm_pic_handler)(void *opaque, int irq, int level);
-
-/* The CPU is also modeled as an interrupt controller. */
-#define ARM_PIC_CPU_IRQ 0
-#define ARM_PIC_CPU_FIQ 1
-void *arm_pic_init_cpu(CPUState *env);
-
-#endif /* !ARM_INTERRUPT_H */
-
diff --git a/tools/ioemu/hw/arm_sysctl.c b/tools/ioemu/hw/arm_sysctl.c
deleted file mode 100644
index e9de998a2a..0000000000
--- a/tools/ioemu/hw/arm_sysctl.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Status and system control registers for ARM RealView/Versatile boards.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-#define LOCK_VALUE 0xa05f
-
-typedef struct {
- uint32_t base;
- uint32_t sys_id;
- uint32_t leds;
- uint16_t lockval;
- uint32_t cfgdata1;
- uint32_t cfgdata2;
- uint32_t flags;
- uint32_t nvflags;
- uint32_t resetlevel;
-} arm_sysctl_state;
-
-static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
-{
- arm_sysctl_state *s = (arm_sysctl_state *)opaque;
-
- offset -= s->base;
- switch (offset) {
- case 0x00: /* ID */
- return s->sys_id;
- case 0x04: /* SW */
- /* General purpose hardware switches.
- We don't have a useful way of exposing these to the user. */
- return 0;
- case 0x08: /* LED */
- return s->leds;
- case 0x20: /* LOCK */
- return s->lockval;
- case 0x0c: /* OSC0 */
- case 0x10: /* OSC1 */
- case 0x14: /* OSC2 */
- case 0x18: /* OSC3 */
- case 0x1c: /* OSC4 */
- case 0x24: /* 100HZ */
- /* ??? Implement these. */
- return 0;
- case 0x28: /* CFGDATA1 */
- return s->cfgdata1;
- case 0x2c: /* CFGDATA2 */
- return s->cfgdata2;
- case 0x30: /* FLAGS */
- return s->flags;
- case 0x38: /* NVFLAGS */
- return s->nvflags;
- case 0x40: /* RESETCTL */
- return s->resetlevel;
- case 0x44: /* PCICTL */
- return 1;
- case 0x48: /* MCI */
- return 0;
- case 0x4c: /* FLASH */
- return 0;
- case 0x50: /* CLCD */
- return 0x1000;
- case 0x54: /* CLCDSER */
- return 0;
- case 0x58: /* BOOTCS */
- return 0;
- case 0x5c: /* 24MHz */
- /* ??? not implemented. */
- return 0;
- case 0x60: /* MISC */
- return 0;
- case 0x84: /* PROCID0 */
- /* ??? Don't know what the proper value for the core tile ID is. */
- return 0x02000000;
- case 0x88: /* PROCID1 */
- return 0xff000000;
- case 0x64: /* DMAPSR0 */
- case 0x68: /* DMAPSR1 */
- case 0x6c: /* DMAPSR2 */
- case 0x70: /* IOSEL */
- case 0x74: /* PLDCTL */
- case 0x80: /* BUSID */
- case 0x8c: /* OSCRESET0 */
- case 0x90: /* OSCRESET1 */
- case 0x94: /* OSCRESET2 */
- case 0x98: /* OSCRESET3 */
- case 0x9c: /* OSCRESET4 */
- case 0xc0: /* SYS_TEST_OSC0 */
- case 0xc4: /* SYS_TEST_OSC1 */
- case 0xc8: /* SYS_TEST_OSC2 */
- case 0xcc: /* SYS_TEST_OSC3 */
- case 0xd0: /* SYS_TEST_OSC4 */
- return 0;
- default:
- printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
- uint32_t val)
-{
- arm_sysctl_state *s = (arm_sysctl_state *)opaque;
- offset -= s->base;
-
- switch (offset) {
- case 0x08: /* LED */
- s->leds = val;
- case 0x0c: /* OSC0 */
- case 0x10: /* OSC1 */
- case 0x14: /* OSC2 */
- case 0x18: /* OSC3 */
- case 0x1c: /* OSC4 */
- /* ??? */
- break;
- case 0x20: /* LOCK */
- if (val == LOCK_VALUE)
- s->lockval = val;
- else
- s->lockval = val & 0x7fff;
- break;
- case 0x28: /* CFGDATA1 */
- /* ??? Need to implement this. */
- s->cfgdata1 = val;
- break;
- case 0x2c: /* CFGDATA2 */
- /* ??? Need to implement this. */
- s->cfgdata2 = val;
- break;
- case 0x30: /* FLAGSSET */
- s->flags |= val;
- break;
- case 0x34: /* FLAGSCLR */
- s->flags &= ~val;
- break;
- case 0x38: /* NVFLAGSSET */
- s->nvflags |= val;
- break;
- case 0x3c: /* NVFLAGSCLR */
- s->nvflags &= ~val;
- break;
- case 0x40: /* RESETCTL */
- if (s->lockval == LOCK_VALUE) {
- s->resetlevel = val;
- if (val & 0x100)
- cpu_abort(cpu_single_env, "Board reset\n");
- }
- break;
- case 0x44: /* PCICTL */
- /* nothing to do. */
- break;
- case 0x4c: /* FLASH */
- case 0x50: /* CLCD */
- case 0x54: /* CLCDSER */
- case 0x64: /* DMAPSR0 */
- case 0x68: /* DMAPSR1 */
- case 0x6c: /* DMAPSR2 */
- case 0x70: /* IOSEL */
- case 0x74: /* PLDCTL */
- case 0x80: /* BUSID */
- case 0x84: /* PROCID0 */
- case 0x88: /* PROCID1 */
- case 0x8c: /* OSCRESET0 */
- case 0x90: /* OSCRESET1 */
- case 0x94: /* OSCRESET2 */
- case 0x98: /* OSCRESET3 */
- case 0x9c: /* OSCRESET4 */
- break;
- default:
- printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset);
- return;
- }
-}
-
-static CPUReadMemoryFunc *arm_sysctl_readfn[] = {
- arm_sysctl_read,
- arm_sysctl_read,
- arm_sysctl_read
-};
-
-static CPUWriteMemoryFunc *arm_sysctl_writefn[] = {
- arm_sysctl_write,
- arm_sysctl_write,
- arm_sysctl_write
-};
-
-void arm_sysctl_init(uint32_t base, uint32_t sys_id)
-{
- arm_sysctl_state *s;
- int iomemtype;
-
- s = (arm_sysctl_state *)qemu_mallocz(sizeof(arm_sysctl_state));
- if (!s)
- return;
- s->base = base;
- s->sys_id = sys_id;
- iomemtype = cpu_register_io_memory(0, arm_sysctl_readfn,
- arm_sysctl_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- /* ??? Save/restore. */
-}
-
diff --git a/tools/ioemu/hw/arm_timer.c b/tools/ioemu/hw/arm_timer.c
deleted file mode 100644
index c8864f13ce..0000000000
--- a/tools/ioemu/hw/arm_timer.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * ARM PrimeCell Timer modules.
- *
- * Copyright (c) 2005-2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-/* Common timer implementation. */
-
-#define TIMER_CTRL_ONESHOT (1 << 0)
-#define TIMER_CTRL_32BIT (1 << 1)
-#define TIMER_CTRL_DIV1 (0 << 2)
-#define TIMER_CTRL_DIV16 (1 << 2)
-#define TIMER_CTRL_DIV256 (2 << 2)
-#define TIMER_CTRL_IE (1 << 5)
-#define TIMER_CTRL_PERIODIC (1 << 6)
-#define TIMER_CTRL_ENABLE (1 << 7)
-
-typedef struct {
- int64_t next_time;
- int64_t expires;
- int64_t loaded;
- QEMUTimer *timer;
- uint32_t control;
- uint32_t count;
- uint32_t limit;
- int raw_freq;
- int freq;
- int int_level;
- void *pic;
- int irq;
-} arm_timer_state;
-
-/* Calculate the new expiry time of the given timer. */
-
-static void arm_timer_reload(arm_timer_state *s)
-{
- int64_t delay;
-
- s->loaded = s->expires;
- delay = muldiv64(s->count, ticks_per_sec, s->freq);
- if (delay == 0)
- delay = 1;
- s->expires += delay;
-}
-
-/* Check all active timers, and schedule the next timer interrupt. */
-
-static void arm_timer_update(arm_timer_state *s, int64_t now)
-{
- int64_t next;
-
- /* Ignore disabled timers. */
- if ((s->control & TIMER_CTRL_ENABLE) == 0)
- return;
- /* Ignore expired one-shot timers. */
- if (s->count == 0 && (s->control & TIMER_CTRL_ONESHOT))
- return;
- if (s->expires - now <= 0) {
- /* Timer has expired. */
- s->int_level = 1;
- if (s->control & TIMER_CTRL_ONESHOT) {
- /* One-shot. */
- s->count = 0;
- } else {
- if ((s->control & TIMER_CTRL_PERIODIC) == 0) {
- /* Free running. */
- if (s->control & TIMER_CTRL_32BIT)
- s->count = 0xffffffff;
- else
- s->count = 0xffff;
- } else {
- /* Periodic. */
- s->count = s->limit;
- }
- }
- }
- while (s->expires - now <= 0) {
- arm_timer_reload(s);
- }
- /* Update interrupts. */
- if (s->int_level && (s->control & TIMER_CTRL_IE)) {
- pic_set_irq_new(s->pic, s->irq, 1);
- } else {
- pic_set_irq_new(s->pic, s->irq, 0);
- }
-
- next = now;
- if (next - s->expires < 0)
- next = s->expires;
-
- /* Schedule the next timer interrupt. */
- if (next == now) {
- qemu_del_timer(s->timer);
- s->next_time = 0;
- } else if (next != s->next_time) {
- qemu_mod_timer(s->timer, next);
- s->next_time = next;
- }
-}
-
-/* Return the current value of the timer. */
-static uint32_t arm_timer_getcount(arm_timer_state *s, int64_t now)
-{
- int64_t left;
- int64_t period;
-
- if (s->count == 0)
- return 0;
- if ((s->control & TIMER_CTRL_ENABLE) == 0)
- return s->count;
- left = s->expires - now;
- period = s->expires - s->loaded;
- /* If the timer should have expired then return 0. This can happen
- when the host timer signal doesnt occur immediately. It's better to
- have a timer appear to sit at zero for a while than have it wrap
- around before the guest interrupt is raised. */
- /* ??? Could we trigger the interrupt here? */
- if (left < 0)
- return 0;
- /* We need to calculate count * elapsed / period without overfowing.
- Scale both elapsed and period so they fit in a 32-bit int. */
- while (period != (int32_t)period) {
- period >>= 1;
- left >>= 1;
- }
- return ((uint64_t)s->count * (uint64_t)(int32_t)left)
- / (int32_t)period;
-}
-
-uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset)
-{
- arm_timer_state *s = (arm_timer_state *)opaque;
-
- switch (offset >> 2) {
- case 0: /* TimerLoad */
- case 6: /* TimerBGLoad */
- return s->limit;
- case 1: /* TimerValue */
- return arm_timer_getcount(s, qemu_get_clock(vm_clock));
- case 2: /* TimerControl */
- return s->control;
- case 4: /* TimerRIS */
- return s->int_level;
- case 5: /* TimerMIS */
- if ((s->control & TIMER_CTRL_IE) == 0)
- return 0;
- return s->int_level;
- default:
- cpu_abort (cpu_single_env, "arm_timer_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void arm_timer_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- arm_timer_state *s = (arm_timer_state *)opaque;
- int64_t now;
-
- now = qemu_get_clock(vm_clock);
- switch (offset >> 2) {
- case 0: /* TimerLoad */
- s->limit = value;
- s->count = value;
- s->expires = now;
- arm_timer_reload(s);
- break;
- case 1: /* TimerValue */
- /* ??? Linux seems to want to write to this readonly register.
- Ignore it. */
- break;
- case 2: /* TimerControl */
- if (s->control & TIMER_CTRL_ENABLE) {
- /* Pause the timer if it is running. This may cause some
- inaccuracy dure to rounding, but avoids a whole lot of other
- messyness. */
- s->count = arm_timer_getcount(s, now);
- }
- s->control = value;
- s->freq = s->raw_freq;
- /* ??? Need to recalculate expiry time after changing divisor. */
- switch ((value >> 2) & 3) {
- case 1: s->freq >>= 4; break;
- case 2: s->freq >>= 8; break;
- }
- if (s->control & TIMER_CTRL_ENABLE) {
- /* Restart the timer if still enabled. */
- s->expires = now;
- arm_timer_reload(s);
- }
- break;
- case 3: /* TimerIntClr */
- s->int_level = 0;
- break;
- case 6: /* TimerBGLoad */
- s->limit = value;
- break;
- default:
- cpu_abort (cpu_single_env, "arm_timer_write: Bad offset %x\n", offset);
- }
- arm_timer_update(s, now);
-}
-
-static void arm_timer_tick(void *opaque)
-{
- int64_t now;
-
- now = qemu_get_clock(vm_clock);
- arm_timer_update((arm_timer_state *)opaque, now);
-}
-
-static void *arm_timer_init(uint32_t freq, void *pic, int irq)
-{
- arm_timer_state *s;
-
- s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state));
- s->pic = pic;
- s->irq = irq;
- s->raw_freq = s->freq = 1000000;
- s->control = TIMER_CTRL_IE;
- s->count = 0xffffffff;
-
- s->timer = qemu_new_timer(vm_clock, arm_timer_tick, s);
- /* ??? Save/restore. */
- return s;
-}
-
-/* ARM PrimeCell SP804 dual timer module.
- Docs for this device don't seem to be publicly available. This
- implementation is based on gueswork, the linux kernel sources and the
- Integrator/CP timer modules. */
-
-typedef struct {
- /* Include a pseudo-PIC device to merge the two interrupt sources. */
- arm_pic_handler handler;
- void *timer[2];
- int level[2];
- uint32_t base;
- /* The output PIC device. */
- void *pic;
- int irq;
-} sp804_state;
-
-static void sp804_set_irq(void *opaque, int irq, int level)
-{
- sp804_state *s = (sp804_state *)opaque;
-
- s->level[irq] = level;
- pic_set_irq_new(s->pic, s->irq, s->level[0] || s->level[1]);
-}
-
-static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
-{
- sp804_state *s = (sp804_state *)opaque;
-
- /* ??? Don't know the PrimeCell ID for this device. */
- offset -= s->base;
- if (offset < 0x20) {
- return arm_timer_read(s->timer[0], offset);
- } else {
- return arm_timer_read(s->timer[1], offset - 0x20);
- }
-}
-
-static void sp804_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- sp804_state *s = (sp804_state *)opaque;
-
- offset -= s->base;
- if (offset < 0x20) {
- arm_timer_write(s->timer[0], offset, value);
- } else {
- arm_timer_write(s->timer[1], offset - 0x20, value);
- }
-}
-
-static CPUReadMemoryFunc *sp804_readfn[] = {
- sp804_read,
- sp804_read,
- sp804_read
-};
-
-static CPUWriteMemoryFunc *sp804_writefn[] = {
- sp804_write,
- sp804_write,
- sp804_write
-};
-
-void sp804_init(uint32_t base, void *pic, int irq)
-{
- int iomemtype;
- sp804_state *s;
-
- s = (sp804_state *)qemu_mallocz(sizeof(sp804_state));
- s->handler = sp804_set_irq;
- s->base = base;
- s->pic = pic;
- s->irq = irq;
- /* ??? The timers are actually configurable between 32kHz and 1MHz, but
- we don't implement that. */
- s->timer[0] = arm_timer_init(1000000, s, 0);
- s->timer[1] = arm_timer_init(1000000, s, 1);
- iomemtype = cpu_register_io_memory(0, sp804_readfn,
- sp804_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- /* ??? Save/restore. */
-}
-
-
-/* Integrator/CP timer module. */
-
-typedef struct {
- void *timer[3];
- uint32_t base;
-} icp_pit_state;
-
-static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
-{
- icp_pit_state *s = (icp_pit_state *)opaque;
- int n;
-
- /* ??? Don't know the PrimeCell ID for this device. */
- offset -= s->base;
- n = offset >> 8;
- if (n > 3)
- cpu_abort(cpu_single_env, "sp804_read: Bad timer %d\n", n);
-
- return arm_timer_read(s->timer[n], offset & 0xff);
-}
-
-static void icp_pit_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- icp_pit_state *s = (icp_pit_state *)opaque;
- int n;
-
- offset -= s->base;
- n = offset >> 8;
- if (n > 3)
- cpu_abort(cpu_single_env, "sp804_write: Bad timer %d\n", n);
-
- arm_timer_write(s->timer[n], offset & 0xff, value);
-}
-
-
-static CPUReadMemoryFunc *icp_pit_readfn[] = {
- icp_pit_read,
- icp_pit_read,
- icp_pit_read
-};
-
-static CPUWriteMemoryFunc *icp_pit_writefn[] = {
- icp_pit_write,
- icp_pit_write,
- icp_pit_write
-};
-
-void icp_pit_init(uint32_t base, void *pic, int irq)
-{
- int iomemtype;
- icp_pit_state *s;
-
- s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state));
- s->base = base;
- /* Timer 0 runs at the system clock speed (40MHz). */
- s->timer[0] = arm_timer_init(40000000, pic, irq);
- /* The other two timers run at 1MHz. */
- s->timer[1] = arm_timer_init(1000000, pic, irq + 1);
- s->timer[2] = arm_timer_init(1000000, pic, irq + 2);
-
- iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
- icp_pit_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- /* ??? Save/restore. */
-}
-
diff --git a/tools/ioemu/hw/cdrom.c b/tools/ioemu/hw/cdrom.c
deleted file mode 100644
index a43b417902..0000000000
--- a/tools/ioemu/hw/cdrom.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * QEMU ATAPI CD-ROM Emulator
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* ??? Most of the ATAPI emulation is still in ide.c. It should be moved
- here. */
-
-#include <vl.h>
-
-static void lba_to_msf(uint8_t *buf, int lba)
-{
- lba += 150;
- buf[0] = (lba / 75) / 60;
- buf[1] = (lba / 75) % 60;
- buf[2] = lba % 75;
-}
-
-/* same toc as bochs. Return -1 if error or the toc length */
-/* XXX: check this */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
-{
- uint8_t *q;
- int len;
-
- if (start_track > 1 && start_track != 0xaa)
- return -1;
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
- if (start_track <= 1) {
- *q++ = 0; /* reserved */
- *q++ = 0x14; /* ADR, control */
- *q++ = 1; /* track number */
- *q++ = 0; /* reserved */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, 0);
- q += 3;
- } else {
- /* sector 0 */
- cpu_to_be32wu((uint32_t *)q, 0);
- q += 4;
- }
- }
- /* lead out track */
- *q++ = 0; /* reserved */
- *q++ = 0x16; /* ADR, control */
- *q++ = 0xaa; /* track number */
- *q++ = 0; /* reserved */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_be32wu((uint32_t *)q, nb_sectors);
- q += 4;
- }
- len = q - buf;
- cpu_to_be16wu((uint16_t *)buf, len - 2);
- return len;
-}
-
-/* mostly same info as PearPc */
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
-{
- uint8_t *q;
- int len;
-
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa0; /* lead-in */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* first track */
- *q++ = 0x00; /* disk type */
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa1;
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* last track */
- *q++ = 0x00;
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa2; /* lead-out */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_be32wu((uint32_t *)q, nb_sectors);
- q += 4;
- }
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* ADR, control */
- *q++ = 0; /* track number */
- *q++ = 1; /* point */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- if (msf) {
- *q++ = 0;
- lba_to_msf(q, 0);
- q += 3;
- } else {
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- }
-
- len = q - buf;
- cpu_to_be16wu((uint16_t *)buf, len - 2);
- return len;
-}
-
-
diff --git a/tools/ioemu/hw/cirrus_vga.c b/tools/ioemu/hw/cirrus_vga.c
deleted file mode 100644
index d41f1ee4e7..0000000000
--- a/tools/ioemu/hw/cirrus_vga.c
+++ /dev/null
@@ -1,3347 +0,0 @@
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- * Copyright (c) 2004 Makoto Suzuki (suzu)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- * Reference: Finn Thogersons' VGADOC4b
- * available at http://home.worldonline.dk/~finth/
- */
-#include "vl.h"
-#include "vga_int.h"
-#ifndef _WIN32
-#include <sys/mman.h>
-#endif
-
-/*
- * TODO:
- * - destination write mask support not complete (bits 5..7)
- * - optimize linear mappings
- * - optimize bitblt functions
- */
-
-//#define DEBUG_CIRRUS
-//#define DEBUG_BITBLT
-
-/***************************************
- *
- * definitions
- *
- ***************************************/
-
-#define qemu_MIN(a,b) ((a) < (b) ? (a) : (b))
-
-// ID
-#define CIRRUS_ID_CLGD5422 (0x23<<2)
-#define CIRRUS_ID_CLGD5426 (0x24<<2)
-#define CIRRUS_ID_CLGD5424 (0x25<<2)
-#define CIRRUS_ID_CLGD5428 (0x26<<2)
-#define CIRRUS_ID_CLGD5430 (0x28<<2)
-#define CIRRUS_ID_CLGD5434 (0x2A<<2)
-#define CIRRUS_ID_CLGD5436 (0x2B<<2)
-#define CIRRUS_ID_CLGD5446 (0x2E<<2)
-
-// sequencer 0x07
-#define CIRRUS_SR7_BPP_VGA 0x00
-#define CIRRUS_SR7_BPP_SVGA 0x01
-#define CIRRUS_SR7_BPP_MASK 0x0e
-#define CIRRUS_SR7_BPP_8 0x00
-#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
-#define CIRRUS_SR7_BPP_24 0x04
-#define CIRRUS_SR7_BPP_16 0x06
-#define CIRRUS_SR7_BPP_32 0x08
-#define CIRRUS_SR7_ISAADDR_MASK 0xe0
-
-// sequencer 0x0f
-#define CIRRUS_MEMSIZE_512k 0x08
-#define CIRRUS_MEMSIZE_1M 0x10
-#define CIRRUS_MEMSIZE_2M 0x18
-#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
-
-// sequencer 0x12
-#define CIRRUS_CURSOR_SHOW 0x01
-#define CIRRUS_CURSOR_HIDDENPEL 0x02
-#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
-
-// sequencer 0x17
-#define CIRRUS_BUSTYPE_VLBFAST 0x10
-#define CIRRUS_BUSTYPE_PCI 0x20
-#define CIRRUS_BUSTYPE_VLBSLOW 0x30
-#define CIRRUS_BUSTYPE_ISA 0x38
-#define CIRRUS_MMIO_ENABLE 0x04
-#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
-#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
-
-// control 0x0b
-#define CIRRUS_BANKING_DUAL 0x01
-#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
-
-// control 0x30
-#define CIRRUS_BLTMODE_BACKWARDS 0x01
-#define CIRRUS_BLTMODE_MEMSYSDEST 0x02
-#define CIRRUS_BLTMODE_MEMSYSSRC 0x04
-#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
-#define CIRRUS_BLTMODE_PATTERNCOPY 0x40
-#define CIRRUS_BLTMODE_COLOREXPAND 0x80
-#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
-#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
-#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
-#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
-#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
-
-// control 0x31
-#define CIRRUS_BLT_BUSY 0x01
-#define CIRRUS_BLT_START 0x02
-#define CIRRUS_BLT_RESET 0x04
-#define CIRRUS_BLT_FIFOUSED 0x10
-#define CIRRUS_BLT_AUTOSTART 0x80
-
-// control 0x32
-#define CIRRUS_ROP_0 0x00
-#define CIRRUS_ROP_SRC_AND_DST 0x05
-#define CIRRUS_ROP_NOP 0x06
-#define CIRRUS_ROP_SRC_AND_NOTDST 0x09
-#define CIRRUS_ROP_NOTDST 0x0b
-#define CIRRUS_ROP_SRC 0x0d
-#define CIRRUS_ROP_1 0x0e
-#define CIRRUS_ROP_NOTSRC_AND_DST 0x50
-#define CIRRUS_ROP_SRC_XOR_DST 0x59
-#define CIRRUS_ROP_SRC_OR_DST 0x6d
-#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
-#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
-#define CIRRUS_ROP_SRC_OR_NOTDST 0xad
-#define CIRRUS_ROP_NOTSRC 0xd0
-#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
-#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
-
-#define CIRRUS_ROP_NOP_INDEX 2
-#define CIRRUS_ROP_SRC_INDEX 5
-
-// control 0x33
-#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
-#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
-#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
-
-// memory-mapped IO
-#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword
-#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword
-#define CIRRUS_MMIO_BLTWIDTH 0x08 // word
-#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word
-#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word
-#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word
-#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword
-#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword
-#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte
-#define CIRRUS_MMIO_BLTMODE 0x18 // byte
-#define CIRRUS_MMIO_BLTROP 0x1a // byte
-#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte
-#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
-#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
-#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word
-#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word
-#define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word
-#define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte
-#define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word
-#define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word
-#define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word
-#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word
-#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte
-#define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte
-#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte
-
-// PCI 0x00: vendor, 0x02: device
-#define PCI_VENDOR_CIRRUS 0x1013
-#define PCI_DEVICE_CLGD5462 0x00d0
-#define PCI_DEVICE_CLGD5465 0x00d6
-
-// PCI 0x04: command(word), 0x06(word): status
-#define PCI_COMMAND_IOACCESS 0x0001
-#define PCI_COMMAND_MEMACCESS 0x0002
-#define PCI_COMMAND_BUSMASTER 0x0004
-#define PCI_COMMAND_SPECIALCYCLE 0x0008
-#define PCI_COMMAND_MEMWRITEINVALID 0x0010
-#define PCI_COMMAND_PALETTESNOOPING 0x0020
-#define PCI_COMMAND_PARITYDETECTION 0x0040
-#define PCI_COMMAND_ADDRESSDATASTEPPING 0x0080
-#define PCI_COMMAND_SERR 0x0100
-#define PCI_COMMAND_BACKTOBACKTRANS 0x0200
-// PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
-#define PCI_CLASS_BASE_DISPLAY 0x03
-// PCI 0x08, 0x00ff0000
-#define PCI_CLASS_SUB_VGA 0x00
-// PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
-#define PCI_CLASS_HEADERTYPE_00h 0x00
-// 0x10-0x3f (headertype 00h)
-// PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
-// 0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
-#define PCI_MAP_MEM 0x0
-#define PCI_MAP_IO 0x1
-#define PCI_MAP_MEM_ADDR_MASK (~0xf)
-#define PCI_MAP_IO_ADDR_MASK (~0x3)
-#define PCI_MAP_MEMFLAGS_32BIT 0x0
-#define PCI_MAP_MEMFLAGS_32BIT_1M 0x1
-#define PCI_MAP_MEMFLAGS_64BIT 0x4
-#define PCI_MAP_MEMFLAGS_CACHEABLE 0x8
-// PCI 0x28: cardbus CIS pointer
-// PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
-// PCI 0x30: expansion ROM base address
-#define PCI_ROMBIOS_ENABLED 0x1
-// PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
-// PCI 0x38: reserved
-// PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
-
-#define CIRRUS_PNPMMIO_SIZE 0x1000
-
-
-/* I/O and memory hook */
-#define CIRRUS_HOOK_NOT_HANDLED 0
-#define CIRRUS_HOOK_HANDLED 1
-
-struct CirrusVGAState;
-typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
- uint8_t * dst, const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight);
-typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
- uint8_t *dst, int dst_pitch, int width, int height);
-
-typedef struct CirrusVGAState {
- VGA_STATE_COMMON
-
- int cirrus_linear_io_addr;
- int cirrus_linear_bitblt_io_addr;
- int cirrus_mmio_io_addr;
- uint32_t cirrus_addr_mask;
- uint32_t linear_mmio_mask;
- uint8_t cirrus_shadow_gr0;
- uint8_t cirrus_shadow_gr1;
- uint8_t cirrus_hidden_dac_lockindex;
- uint8_t cirrus_hidden_dac_data;
- uint32_t cirrus_bank_base[2];
- uint32_t cirrus_bank_limit[2];
- uint8_t cirrus_hidden_palette[48];
- uint32_t hw_cursor_x;
- uint32_t hw_cursor_y;
- int cirrus_blt_pixelwidth;
- int cirrus_blt_width;
- int cirrus_blt_height;
- int cirrus_blt_dstpitch;
- int cirrus_blt_srcpitch;
- uint32_t cirrus_blt_fgcol;
- uint32_t cirrus_blt_bgcol;
- uint32_t cirrus_blt_dstaddr;
- uint32_t cirrus_blt_srcaddr;
- uint8_t cirrus_blt_mode;
- uint8_t cirrus_blt_modeext;
- cirrus_bitblt_rop_t cirrus_rop;
-#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
- uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
- uint8_t *cirrus_srcptr;
- uint8_t *cirrus_srcptr_end;
- uint32_t cirrus_srccounter;
- /* hwcursor display state */
- int last_hw_cursor_size;
- int last_hw_cursor_x;
- int last_hw_cursor_y;
- int last_hw_cursor_y_start;
- int last_hw_cursor_y_end;
- int real_vram_size; /* XXX: suppress that */
- CPUWriteMemoryFunc **cirrus_linear_write;
- unsigned long map_addr;
- unsigned long map_end;
-} CirrusVGAState;
-
-typedef struct PCICirrusVGAState {
- PCIDevice dev;
- CirrusVGAState cirrus_vga;
-} PCICirrusVGAState;
-
-static uint8_t rop_to_index[256];
-
-/***************************************
- *
- * prototypes.
- *
- ***************************************/
-
-
-static void cirrus_bitblt_reset(CirrusVGAState *s);
-static void cirrus_update_memory_access(CirrusVGAState *s);
-static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val);
-
-/***************************************
- *
- * raster operations
- *
- ***************************************/
-
-static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
-}
-
-static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
- uint8_t *dst,
- int dstpitch, int bltwidth,int bltheight)
-{
-}
-
-#define ROP_NAME 0
-#define ROP_OP(d, s) d = 0
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_and_dst
-#define ROP_OP(d, s) d = (s) & (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_and_notdst
-#define ROP_OP(d, s) d = (s) & (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notdst
-#define ROP_OP(d, s) d = ~(d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src
-#define ROP_OP(d, s) d = s
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME 1
-#define ROP_OP(d, s) d = ~0
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_and_dst
-#define ROP_OP(d, s) d = (~(s)) & (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_xor_dst
-#define ROP_OP(d, s) d = (s) ^ (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_or_dst
-#define ROP_OP(d, s) d = (s) | (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_or_notdst
-#define ROP_OP(d, s) d = (~(s)) | (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_notxor_dst
-#define ROP_OP(d, s) d = ~((s) ^ (d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_or_notdst
-#define ROP_OP(d, s) d = (s) | (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc
-#define ROP_OP(d, s) d = (~(s))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_or_dst
-#define ROP_OP(d, s) d = (~(s)) | (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_and_notdst
-#define ROP_OP(d, s) d = (~(s)) & (~(d))
-#include "cirrus_vga_rop.h"
-
-static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
- cirrus_bitblt_rop_fwd_0,
- cirrus_bitblt_rop_fwd_src_and_dst,
- cirrus_bitblt_rop_nop,
- cirrus_bitblt_rop_fwd_src_and_notdst,
- cirrus_bitblt_rop_fwd_notdst,
- cirrus_bitblt_rop_fwd_src,
- cirrus_bitblt_rop_fwd_1,
- cirrus_bitblt_rop_fwd_notsrc_and_dst,
- cirrus_bitblt_rop_fwd_src_xor_dst,
- cirrus_bitblt_rop_fwd_src_or_dst,
- cirrus_bitblt_rop_fwd_notsrc_or_notdst,
- cirrus_bitblt_rop_fwd_src_notxor_dst,
- cirrus_bitblt_rop_fwd_src_or_notdst,
- cirrus_bitblt_rop_fwd_notsrc,
- cirrus_bitblt_rop_fwd_notsrc_or_dst,
- cirrus_bitblt_rop_fwd_notsrc_and_notdst,
-};
-
-static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
- cirrus_bitblt_rop_bkwd_0,
- cirrus_bitblt_rop_bkwd_src_and_dst,
- cirrus_bitblt_rop_nop,
- cirrus_bitblt_rop_bkwd_src_and_notdst,
- cirrus_bitblt_rop_bkwd_notdst,
- cirrus_bitblt_rop_bkwd_src,
- cirrus_bitblt_rop_bkwd_1,
- cirrus_bitblt_rop_bkwd_notsrc_and_dst,
- cirrus_bitblt_rop_bkwd_src_xor_dst,
- cirrus_bitblt_rop_bkwd_src_or_dst,
- cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
- cirrus_bitblt_rop_bkwd_src_notxor_dst,
- cirrus_bitblt_rop_bkwd_src_or_notdst,
- cirrus_bitblt_rop_bkwd_notsrc,
- cirrus_bitblt_rop_bkwd_notsrc_or_dst,
- cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
-};
-
-#define ROP2(name) {\
- name ## _8,\
- name ## _16,\
- name ## _24,\
- name ## _32,\
- }
-
-#define ROP_NOP2(func) {\
- func,\
- func,\
- func,\
- func,\
- }
-
-static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
- ROP2(cirrus_patternfill_0),
- ROP2(cirrus_patternfill_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_patternfill_src_and_notdst),
- ROP2(cirrus_patternfill_notdst),
- ROP2(cirrus_patternfill_src),
- ROP2(cirrus_patternfill_1),
- ROP2(cirrus_patternfill_notsrc_and_dst),
- ROP2(cirrus_patternfill_src_xor_dst),
- ROP2(cirrus_patternfill_src_or_dst),
- ROP2(cirrus_patternfill_notsrc_or_notdst),
- ROP2(cirrus_patternfill_src_notxor_dst),
- ROP2(cirrus_patternfill_src_or_notdst),
- ROP2(cirrus_patternfill_notsrc),
- ROP2(cirrus_patternfill_notsrc_or_dst),
- ROP2(cirrus_patternfill_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
- ROP2(cirrus_colorexpand_transp_0),
- ROP2(cirrus_colorexpand_transp_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_transp_src_and_notdst),
- ROP2(cirrus_colorexpand_transp_notdst),
- ROP2(cirrus_colorexpand_transp_src),
- ROP2(cirrus_colorexpand_transp_1),
- ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
- ROP2(cirrus_colorexpand_transp_src_xor_dst),
- ROP2(cirrus_colorexpand_transp_src_or_dst),
- ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_transp_src_notxor_dst),
- ROP2(cirrus_colorexpand_transp_src_or_notdst),
- ROP2(cirrus_colorexpand_transp_notsrc),
- ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
- ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
- ROP2(cirrus_colorexpand_0),
- ROP2(cirrus_colorexpand_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_src_and_notdst),
- ROP2(cirrus_colorexpand_notdst),
- ROP2(cirrus_colorexpand_src),
- ROP2(cirrus_colorexpand_1),
- ROP2(cirrus_colorexpand_notsrc_and_dst),
- ROP2(cirrus_colorexpand_src_xor_dst),
- ROP2(cirrus_colorexpand_src_or_dst),
- ROP2(cirrus_colorexpand_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_src_notxor_dst),
- ROP2(cirrus_colorexpand_src_or_notdst),
- ROP2(cirrus_colorexpand_notsrc),
- ROP2(cirrus_colorexpand_notsrc_or_dst),
- ROP2(cirrus_colorexpand_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
- ROP2(cirrus_colorexpand_pattern_transp_0),
- ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_src),
- ROP2(cirrus_colorexpand_pattern_transp_1),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
- ROP2(cirrus_colorexpand_pattern_0),
- ROP2(cirrus_colorexpand_pattern_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_pattern_src_and_notdst),
- ROP2(cirrus_colorexpand_pattern_notdst),
- ROP2(cirrus_colorexpand_pattern_src),
- ROP2(cirrus_colorexpand_pattern_1),
- ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
- ROP2(cirrus_colorexpand_pattern_src_xor_dst),
- ROP2(cirrus_colorexpand_pattern_src_or_dst),
- ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
- ROP2(cirrus_colorexpand_pattern_src_or_notdst),
- ROP2(cirrus_colorexpand_pattern_notsrc),
- ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
- ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
-};
-
-static const cirrus_fill_t cirrus_fill[16][4] = {
- ROP2(cirrus_fill_0),
- ROP2(cirrus_fill_src_and_dst),
- ROP_NOP2(cirrus_bitblt_fill_nop),
- ROP2(cirrus_fill_src_and_notdst),
- ROP2(cirrus_fill_notdst),
- ROP2(cirrus_fill_src),
- ROP2(cirrus_fill_1),
- ROP2(cirrus_fill_notsrc_and_dst),
- ROP2(cirrus_fill_src_xor_dst),
- ROP2(cirrus_fill_src_or_dst),
- ROP2(cirrus_fill_notsrc_or_notdst),
- ROP2(cirrus_fill_src_notxor_dst),
- ROP2(cirrus_fill_src_or_notdst),
- ROP2(cirrus_fill_notsrc),
- ROP2(cirrus_fill_notsrc_or_dst),
- ROP2(cirrus_fill_notsrc_and_notdst),
-};
-
-static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
-{
- unsigned int color;
- switch (s->cirrus_blt_pixelwidth) {
- case 1:
- s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
- break;
- case 2:
- color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8);
- s->cirrus_blt_fgcol = le16_to_cpu(color);
- break;
- case 3:
- s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
- (s->gr[0x11] << 8) | (s->gr[0x13] << 16);
- break;
- default:
- case 4:
- color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8) |
- (s->gr[0x13] << 16) | (s->gr[0x15] << 24);
- s->cirrus_blt_fgcol = le32_to_cpu(color);
- break;
- }
-}
-
-static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
-{
- unsigned int color;
- switch (s->cirrus_blt_pixelwidth) {
- case 1:
- s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
- break;
- case 2:
- color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8);
- s->cirrus_blt_bgcol = le16_to_cpu(color);
- break;
- case 3:
- s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
- (s->gr[0x10] << 8) | (s->gr[0x12] << 16);
- break;
- default:
- case 4:
- color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8) |
- (s->gr[0x12] << 16) | (s->gr[0x14] << 24);
- s->cirrus_blt_bgcol = le32_to_cpu(color);
- break;
- }
-}
-
-static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
- int off_pitch, int bytesperline,
- int lines)
-{
- int y;
- int off_cur;
- int off_cur_end;
-
- for (y = 0; y < lines; y++) {
- off_cur = off_begin;
- off_cur_end = off_cur + bytesperline;
- off_cur &= TARGET_PAGE_MASK;
- while (off_cur < off_cur_end) {
- cpu_physical_memory_set_dirty(s->vram_offset +
- (off_cur & s->cirrus_addr_mask));
- off_cur += TARGET_PAGE_SIZE;
- }
- off_begin += off_pitch;
- }
-}
-
-static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
- const uint8_t * src)
-{
- uint8_t *dst;
-
- dst = s->vram_ptr + s->cirrus_blt_dstaddr;
- (*s->cirrus_rop) (s, dst, src,
- s->cirrus_blt_dstpitch, 0,
- s->cirrus_blt_width, s->cirrus_blt_height);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- return 1;
-}
-
-/* fill */
-
-static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
-{
- cirrus_fill_t rop_func;
-
- rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- cirrus_bitblt_reset(s);
- return 1;
-}
-
-/***************************************
- *
- * bitblt (video-to-video)
- *
- ***************************************/
-
-static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
-{
- return cirrus_bitblt_common_patterncopy(s,
- s->vram_ptr +
- (s->cirrus_blt_srcaddr & ~7));
-}
-
-static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
-{
- int sx, sy;
- int dx, dy;
- int width, height;
- int depth;
- int notify = 0;
-
- depth = s->get_bpp((VGAState *)s) / 8;
- s->get_resolution((VGAState *)s, &width, &height);
-
- /* extra x, y */
- sx = (src % (width * depth)) / depth;
- sy = (src / (width * depth));
- dx = (dst % (width *depth)) / depth;
- dy = (dst / (width * depth));
-
- /* normalize width */
- w /= depth;
-
- /* if we're doing a backward copy, we have to adjust
- our x/y to be the upper left corner (instead of the lower
- right corner) */
- if (s->cirrus_blt_dstpitch < 0) {
- sx -= (s->cirrus_blt_width / depth) - 1;
- dx -= (s->cirrus_blt_width / depth) - 1;
- sy -= s->cirrus_blt_height - 1;
- dy -= s->cirrus_blt_height - 1;
- }
-
- /* are we in the visible portion of memory? */
- if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
- (sx + w) <= width && (sy + h) <= height &&
- (dx + w) <= width && (dy + h) <= height) {
- notify = 1;
- }
-
- /* make to sure only copy if it's a plain copy ROP */
- if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src &&
- *s->cirrus_rop != cirrus_bitblt_rop_bkwd_src)
- notify = 0;
-
- /* we have to flush all pending changes so that the copy
- is generated at the appropriate moment in time */
- if (notify)
- vga_hw_update();
-
- (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
- s->vram_ptr + s->cirrus_blt_srcaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
-
- if (notify)
- s->ds->dpy_copy(s->ds,
- sx, sy, dx, dy,
- s->cirrus_blt_width / depth,
- s->cirrus_blt_height);
-
- /* we don't have to notify the display that this portion has
- changed since dpy_copy implies this */
-
- if (!notify)
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
-}
-
-static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
-{
- if (s->ds->dpy_copy) {
- cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
- s->cirrus_blt_srcaddr - s->start_addr,
- s->cirrus_blt_width, s->cirrus_blt_height);
- } else {
- (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
- s->vram_ptr + s->cirrus_blt_srcaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
-
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- }
-
- return 1;
-}
-
-/***************************************
- *
- * bitblt (cpu-to-video)
- *
- ***************************************/
-
-static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
-{
- int copy_count;
- uint8_t *end_ptr;
-
- if (s->cirrus_srccounter > 0) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
- the_end:
- s->cirrus_srccounter = 0;
- cirrus_bitblt_reset(s);
- } else {
- /* at least one scan line */
- do {
- (*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr,
- s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
- s->cirrus_blt_width, 1);
- s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
- s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
- if (s->cirrus_srccounter <= 0)
- goto the_end;
- /* more bytes than needed can be transfered because of
- word alignment, so we keep them for the next line */
- /* XXX: keep alignment to speed up transfer */
- end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- copy_count = s->cirrus_srcptr_end - end_ptr;
- memmove(s->cirrus_bltbuf, end_ptr, copy_count);
- s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
- s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
- }
- }
-}
-
-/***************************************
- *
- * bitblt wrapper
- *
- ***************************************/
-
-static void cirrus_bitblt_reset(CirrusVGAState * s)
-{
- s->gr[0x31] &=
- ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
- s->cirrus_srcptr = &s->cirrus_bltbuf[0];
- s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
- s->cirrus_srccounter = 0;
- cirrus_update_memory_access(s);
-}
-
-static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
-{
- int w;
-
- s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
- s->cirrus_srcptr = &s->cirrus_bltbuf[0];
- s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- s->cirrus_blt_srcpitch = 8;
- } else {
- /* XXX: check for 24 bpp */
- s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
- }
- s->cirrus_srccounter = s->cirrus_blt_srcpitch;
- } else {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
- s->cirrus_blt_srcpitch = ((w + 31) >> 5);
- else
- s->cirrus_blt_srcpitch = ((w + 7) >> 3);
- } else {
- /* always align input size to 32 bits */
- s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
- }
- s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
- }
- s->cirrus_srcptr = s->cirrus_bltbuf;
- s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- cirrus_update_memory_access(s);
- return 1;
-}
-
-static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
-{
- /* XXX */
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
-#endif
- return 0;
-}
-
-static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
-{
- int ret;
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- ret = cirrus_bitblt_videotovideo_patterncopy(s);
- } else {
- ret = cirrus_bitblt_videotovideo_copy(s);
- }
- if (ret)
- cirrus_bitblt_reset(s);
- return ret;
-}
-
-static void cirrus_bitblt_start(CirrusVGAState * s)
-{
- uint8_t blt_rop;
-
- s->gr[0x31] |= CIRRUS_BLT_BUSY;
-
- s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;
- s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;
- s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));
- s->cirrus_blt_srcpitch = (s->gr[0x26] | (s->gr[0x27] << 8));
- s->cirrus_blt_dstaddr =
- (s->gr[0x28] | (s->gr[0x29] << 8) | (s->gr[0x2a] << 16));
- s->cirrus_blt_srcaddr =
- (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));
- s->cirrus_blt_mode = s->gr[0x30];
- s->cirrus_blt_modeext = s->gr[0x33];
- blt_rop = s->gr[0x32];
-
-#ifdef DEBUG_BITBLT
- printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
- blt_rop,
- s->cirrus_blt_mode,
- s->cirrus_blt_modeext,
- s->cirrus_blt_width,
- s->cirrus_blt_height,
- s->cirrus_blt_dstpitch,
- s->cirrus_blt_srcpitch,
- s->cirrus_blt_dstaddr,
- s->cirrus_blt_srcaddr,
- s->gr[0x2f]);
-#endif
-
- switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
- case CIRRUS_BLTMODE_PIXELWIDTH8:
- s->cirrus_blt_pixelwidth = 1;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH16:
- s->cirrus_blt_pixelwidth = 2;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH24:
- s->cirrus_blt_pixelwidth = 3;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH32:
- s->cirrus_blt_pixelwidth = 4;
- break;
- default:
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt - pixel width is unknown\n");
-#endif
- goto bitblt_ignore;
- }
- s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
-
- if ((s->
- cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
- CIRRUS_BLTMODE_MEMSYSDEST))
- == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt - memory-to-memory copy is requested\n");
-#endif
- goto bitblt_ignore;
- }
-
- if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
- (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
- CIRRUS_BLTMODE_TRANSPARENTCOMP |
- CIRRUS_BLTMODE_PATTERNCOPY |
- CIRRUS_BLTMODE_COLOREXPAND)) ==
- (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_solidfill(s, blt_rop);
- } else {
- if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
- CIRRUS_BLTMODE_PATTERNCOPY)) ==
- CIRRUS_BLTMODE_COLOREXPAND) {
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
- cirrus_bitblt_bgcol(s);
- else
- cirrus_bitblt_fgcol(s);
- s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- } else {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_bgcol(s);
- s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
- cirrus_bitblt_bgcol(s);
- else
- cirrus_bitblt_fgcol(s);
- s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- } else {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_bgcol(s);
- s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else {
- s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
- s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
- s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
- s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
- } else {
- s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
- }
- }
-
- // setup bitblt engine.
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
- if (!cirrus_bitblt_cputovideo(s))
- goto bitblt_ignore;
- } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
- if (!cirrus_bitblt_videotocpu(s))
- goto bitblt_ignore;
- } else {
- if (!cirrus_bitblt_videotovideo(s))
- goto bitblt_ignore;
- }
- }
- return;
- bitblt_ignore:;
- cirrus_bitblt_reset(s);
-}
-
-static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
-{
- unsigned old_value;
-
- old_value = s->gr[0x31];
- s->gr[0x31] = reg_value;
-
- if (((old_value & CIRRUS_BLT_RESET) != 0) &&
- ((reg_value & CIRRUS_BLT_RESET) == 0)) {
- cirrus_bitblt_reset(s);
- } else if (((old_value & CIRRUS_BLT_START) == 0) &&
- ((reg_value & CIRRUS_BLT_START) != 0)) {
- cirrus_bitblt_start(s);
- }
-}
-
-
-/***************************************
- *
- * basic parameters
- *
- ***************************************/
-
-static void cirrus_get_offsets(VGAState *s1,
- uint32_t *pline_offset,
- uint32_t *pstart_addr,
- uint32_t *pline_compare)
-{
- CirrusVGAState * s = (CirrusVGAState *)s1;
- uint32_t start_addr, line_offset, line_compare;
-
- line_offset = s->cr[0x13]
- | ((s->cr[0x1b] & 0x10) << 4);
- line_offset <<= 3;
- *pline_offset = line_offset;
-
- start_addr = (s->cr[0x0c] << 8)
- | s->cr[0x0d]
- | ((s->cr[0x1b] & 0x01) << 16)
- | ((s->cr[0x1b] & 0x0c) << 15)
- | ((s->cr[0x1d] & 0x80) << 12);
- *pstart_addr = start_addr;
-
- line_compare = s->cr[0x18] |
- ((s->cr[0x07] & 0x10) << 4) |
- ((s->cr[0x09] & 0x40) << 3);
- *pline_compare = line_compare;
-}
-
-static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
-{
- uint32_t ret = 16;
-
- switch (s->cirrus_hidden_dac_data & 0xf) {
- case 0:
- ret = 15;
- break; /* Sierra HiColor */
- case 1:
- ret = 16;
- break; /* XGA HiColor */
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: invalid DAC value %x in 16bpp\n",
- (s->cirrus_hidden_dac_data & 0xf));
-#endif
- ret = 15; /* XXX */
- break;
- }
- return ret;
-}
-
-static int cirrus_get_bpp(VGAState *s1)
-{
- CirrusVGAState * s = (CirrusVGAState *)s1;
- uint32_t ret = 8;
-
- if ((s->sr[0x07] & 0x01) != 0) {
- /* Cirrus SVGA */
- switch (s->sr[0x07] & CIRRUS_SR7_BPP_MASK) {
- case CIRRUS_SR7_BPP_8:
- ret = 8;
- break;
- case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
- ret = cirrus_get_bpp16_depth(s);
- break;
- case CIRRUS_SR7_BPP_24:
- ret = 24;
- break;
- case CIRRUS_SR7_BPP_16:
- ret = cirrus_get_bpp16_depth(s);
- break;
- case CIRRUS_SR7_BPP_32:
- ret = 32;
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: unknown bpp - sr7=%x\n", s->sr[0x7]);
-#endif
- ret = 8;
- break;
- }
- } else {
- /* VGA */
- ret = 0;
- }
-
- return ret;
-}
-
-static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight)
-{
- int width, height;
-
- width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
- height = (height + 1);
- /* interlace support */
- if (s->cr[0x1a] & 0x01)
- height = height * 2;
- *pwidth = width;
- *pheight = height;
-}
-
-/***************************************
- *
- * bank memory
- *
- ***************************************/
-
-static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
-{
- unsigned offset;
- unsigned limit;
-
- if ((s->gr[0x0b] & 0x01) != 0) /* dual bank */
- offset = s->gr[0x09 + bank_index];
- else /* single bank */
- offset = s->gr[0x09];
-
- if ((s->gr[0x0b] & 0x20) != 0)
- offset <<= 14;
- else
- offset <<= 12;
-
- if (s->real_vram_size <= offset)
- limit = 0;
- else
- limit = s->real_vram_size - offset;
-
- if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
- if (limit > 0x8000) {
- offset += 0x8000;
- limit -= 0x8000;
- } else {
- limit = 0;
- }
- }
-
- if (limit > 0) {
- s->cirrus_bank_base[bank_index] = offset;
- s->cirrus_bank_limit[bank_index] = limit;
- } else {
- s->cirrus_bank_base[bank_index] = 0;
- s->cirrus_bank_limit[bank_index] = 0;
- }
-}
-
-/***************************************
- *
- * I/O access between 0x3c4-0x3c5
- *
- ***************************************/
-
-static int
-cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x06: // Unlock Cirrus extensions
- *reg_value = s->sr[reg_index];
- break;
- case 0x10:
- case 0x30:
- case 0x50:
- case 0x70: // Graphics Cursor X
- case 0x90:
- case 0xb0:
- case 0xd0:
- case 0xf0: // Graphics Cursor X
- *reg_value = s->sr[0x10];
- break;
- case 0x11:
- case 0x31:
- case 0x51:
- case 0x71: // Graphics Cursor Y
- case 0x91:
- case 0xb1:
- case 0xd1:
- case 0xf1: // Graphics Cursor Y
- *reg_value = s->sr[0x11];
- break;
- case 0x05: // ???
- case 0x07: // Extended Sequencer Mode
- case 0x08: // EEPROM Control
- case 0x09: // Scratch Register 0
- case 0x0a: // Scratch Register 1
- case 0x0b: // VCLK 0
- case 0x0c: // VCLK 1
- case 0x0d: // VCLK 2
- case 0x0e: // VCLK 3
- case 0x0f: // DRAM Control
- case 0x12: // Graphics Cursor Attribute
- case 0x13: // Graphics Cursor Pattern Address
- case 0x14: // Scratch Register 2
- case 0x15: // Scratch Register 3
- case 0x16: // Performance Tuning Register
- case 0x17: // Configuration Readback and Extended Control
- case 0x18: // Signature Generator Control
- case 0x19: // Signal Generator Result
- case 0x1a: // Signal Generator Result
- case 0x1b: // VCLK 0 Denominator & Post
- case 0x1c: // VCLK 1 Denominator & Post
- case 0x1d: // VCLK 2 Denominator & Post
- case 0x1e: // VCLK 3 Denominator & Post
- case 0x1f: // BIOS Write Enable and MCLK select
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled inport sr_index %02x\n", reg_index);
-#endif
- *reg_value = s->sr[reg_index];
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport sr_index %02x\n", reg_index);
-#endif
- *reg_value = 0xff;
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int
-cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x06: // Unlock Cirrus extensions
- reg_value &= 0x17;
- if (reg_value == 0x12) {
- s->sr[reg_index] = 0x12;
- } else {
- s->sr[reg_index] = 0x0f;
- }
- break;
- case 0x10:
- case 0x30:
- case 0x50:
- case 0x70: // Graphics Cursor X
- case 0x90:
- case 0xb0:
- case 0xd0:
- case 0xf0: // Graphics Cursor X
- s->sr[0x10] = reg_value;
- s->hw_cursor_x = (reg_value << 3) | (reg_index >> 5);
- break;
- case 0x11:
- case 0x31:
- case 0x51:
- case 0x71: // Graphics Cursor Y
- case 0x91:
- case 0xb1:
- case 0xd1:
- case 0xf1: // Graphics Cursor Y
- s->sr[0x11] = reg_value;
- s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
- break;
- case 0x07: // Extended Sequencer Mode
- case 0x08: // EEPROM Control
- case 0x09: // Scratch Register 0
- case 0x0a: // Scratch Register 1
- case 0x0b: // VCLK 0
- case 0x0c: // VCLK 1
- case 0x0d: // VCLK 2
- case 0x0e: // VCLK 3
- case 0x0f: // DRAM Control
- case 0x12: // Graphics Cursor Attribute
- case 0x13: // Graphics Cursor Pattern Address
- case 0x14: // Scratch Register 2
- case 0x15: // Scratch Register 3
- case 0x16: // Performance Tuning Register
- case 0x18: // Signature Generator Control
- case 0x19: // Signature Generator Result
- case 0x1a: // Signature Generator Result
- case 0x1b: // VCLK 0 Denominator & Post
- case 0x1c: // VCLK 1 Denominator & Post
- case 0x1d: // VCLK 2 Denominator & Post
- case 0x1e: // VCLK 3 Denominator & Post
- case 0x1f: // BIOS Write Enable and MCLK select
- s->sr[reg_index] = reg_value;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
- reg_index, reg_value);
-#endif
- break;
- case 0x17: // Configuration Readback and Extended Control
- s->sr[reg_index] = (s->sr[reg_index] & 0x38) | (reg_value & 0xc7);
- cirrus_update_memory_access(s);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index,
- reg_value);
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * I/O access at 0x3c6
- *
- ***************************************/
-
-static void cirrus_read_hidden_dac(CirrusVGAState * s, int *reg_value)
-{
- *reg_value = 0xff;
- if (++s->cirrus_hidden_dac_lockindex == 5) {
- *reg_value = s->cirrus_hidden_dac_data;
- s->cirrus_hidden_dac_lockindex = 0;
- }
-}
-
-static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
-{
- if (s->cirrus_hidden_dac_lockindex == 4) {
- s->cirrus_hidden_dac_data = reg_value;
-#if defined(DEBUG_CIRRUS)
- printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
-#endif
- }
- s->cirrus_hidden_dac_lockindex = 0;
-}
-
-/***************************************
- *
- * I/O access at 0x3c9
- *
- ***************************************/
-
-static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value)
-{
- if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
- return CIRRUS_HOOK_NOT_HANDLED;
- *reg_value =
- s->cirrus_hidden_palette[(s->dac_read_index & 0x0f) * 3 +
- s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
- }
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value)
-{
- if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
- return CIRRUS_HOOK_NOT_HANDLED;
- s->dac_cache[s->dac_sub_index] = reg_value;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->cirrus_hidden_palette[(s->dac_write_index & 0x0f) * 3],
- s->dac_cache, 3);
- /* XXX update cursor */
- s->dac_sub_index = 0;
- s->dac_write_index++;
- }
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * I/O access between 0x3ce-0x3cf
- *
- ***************************************/
-
-static int
-cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA, BGCOLOR 0x000000ff
- *reg_value = s->cirrus_shadow_gr0;
- return CIRRUS_HOOK_HANDLED;
- case 0x01: // Standard VGA, FGCOLOR 0x000000ff
- *reg_value = s->cirrus_shadow_gr1;
- return CIRRUS_HOOK_HANDLED;
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x05: // Standard VGA, Cirrus extended mode
- default:
- break;
- }
-
- if (reg_index < 0x3a) {
- *reg_value = s->gr[reg_index];
- } else {
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport gr_index %02x\n", reg_index);
-#endif
- *reg_value = 0xff;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int
-cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
-{
-#if defined(DEBUG_BITBLT) && 0
- printf("gr%02x: %02x\n", reg_index, reg_value);
-#endif
- switch (reg_index) {
- case 0x00: // Standard VGA, BGCOLOR 0x000000ff
- s->cirrus_shadow_gr0 = reg_value;
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x01: // Standard VGA, FGCOLOR 0x000000ff
- s->cirrus_shadow_gr1 = reg_value;
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x05: // Standard VGA, Cirrus extended mode
- s->gr[reg_index] = reg_value & 0x7f;
- cirrus_update_memory_access(s);
- break;
- case 0x09: // bank offset #0
- case 0x0A: // bank offset #1
- s->gr[reg_index] = reg_value;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- break;
- case 0x0B:
- s->gr[reg_index] = reg_value;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- cirrus_update_memory_access(s);
- break;
- case 0x10: // BGCOLOR 0x0000ff00
- case 0x11: // FGCOLOR 0x0000ff00
- case 0x12: // BGCOLOR 0x00ff0000
- case 0x13: // FGCOLOR 0x00ff0000
- case 0x14: // BGCOLOR 0xff000000
- case 0x15: // FGCOLOR 0xff000000
- case 0x20: // BLT WIDTH 0x0000ff
- case 0x22: // BLT HEIGHT 0x0000ff
- case 0x24: // BLT DEST PITCH 0x0000ff
- case 0x26: // BLT SRC PITCH 0x0000ff
- case 0x28: // BLT DEST ADDR 0x0000ff
- case 0x29: // BLT DEST ADDR 0x00ff00
- case 0x2c: // BLT SRC ADDR 0x0000ff
- case 0x2d: // BLT SRC ADDR 0x00ff00
- case 0x2f: // BLT WRITEMASK
- case 0x30: // BLT MODE
- case 0x32: // RASTER OP
- case 0x33: // BLT MODEEXT
- case 0x34: // BLT TRANSPARENT COLOR 0x00ff
- case 0x35: // BLT TRANSPARENT COLOR 0xff00
- case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
- case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
- s->gr[reg_index] = reg_value;
- break;
- case 0x21: // BLT WIDTH 0x001f00
- case 0x23: // BLT HEIGHT 0x001f00
- case 0x25: // BLT DEST PITCH 0x001f00
- case 0x27: // BLT SRC PITCH 0x001f00
- s->gr[reg_index] = reg_value & 0x1f;
- break;
- case 0x2a: // BLT DEST ADDR 0x3f0000
- s->gr[reg_index] = reg_value & 0x3f;
- /* if auto start mode, starts bit blt now */
- if (s->gr[0x31] & CIRRUS_BLT_AUTOSTART) {
- cirrus_bitblt_start(s);
- }
- break;
- case 0x2e: // BLT SRC ADDR 0x3f0000
- s->gr[reg_index] = reg_value & 0x3f;
- break;
- case 0x31: // BLT STATUS/START
- cirrus_write_bitblt(s, reg_value);
- break;
-
- // Extension to allow BIOS to clear 16K VRAM bank in one operation
- case 0xFE:
- s->gr[reg_index] = reg_value; // Lower byte of value to be written
- break;
- case 0xFF: {
- target_phys_addr_t addr;
- for (addr = 0xa0000; addr < 0xa4000; addr += 2)
- cirrus_vga_mem_writew(s, addr, (reg_value << 8) | s->gr[0xFE]);
- }
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
- reg_value);
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * I/O access between 0x3d4-0x3d5
- *
- ***************************************/
-
-static int
-cirrus_hook_read_cr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x05: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- case 0x09: // Standard VGA
- case 0x0a: // Standard VGA
- case 0x0b: // Standard VGA
- case 0x0c: // Standard VGA
- case 0x0d: // Standard VGA
- case 0x0e: // Standard VGA
- case 0x0f: // Standard VGA
- case 0x10: // Standard VGA
- case 0x11: // Standard VGA
- case 0x12: // Standard VGA
- case 0x13: // Standard VGA
- case 0x14: // Standard VGA
- case 0x15: // Standard VGA
- case 0x16: // Standard VGA
- case 0x17: // Standard VGA
- case 0x18: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x19: // Interlace End
- case 0x1a: // Miscellaneous Control
- case 0x1b: // Extended Display Control
- case 0x1c: // Sync Adjust and Genlock
- case 0x1d: // Overlay Extended Control
- case 0x22: // Graphics Data Latches Readback (R)
- case 0x24: // Attribute Controller Toggle Readback (R)
- case 0x25: // Part Status
- case 0x27: // Part ID (R)
- *reg_value = s->cr[reg_index];
- break;
- case 0x26: // Attribute Controller Index Readback (R)
- *reg_value = s->ar_index & 0x3f;
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport cr_index %02x\n", reg_index);
- *reg_value = 0xff;
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int
-cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x05: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- case 0x09: // Standard VGA
- case 0x0a: // Standard VGA
- case 0x0b: // Standard VGA
- case 0x0c: // Standard VGA
- case 0x0d: // Standard VGA
- case 0x0e: // Standard VGA
- case 0x0f: // Standard VGA
- case 0x10: // Standard VGA
- case 0x11: // Standard VGA
- case 0x12: // Standard VGA
- case 0x13: // Standard VGA
- case 0x14: // Standard VGA
- case 0x15: // Standard VGA
- case 0x16: // Standard VGA
- case 0x17: // Standard VGA
- case 0x18: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x19: // Interlace End
- case 0x1a: // Miscellaneous Control
- case 0x1b: // Extended Display Control
- case 0x1c: // Sync Adjust and Genlock
- case 0x1d: // Overlay Extended Control
- s->cr[reg_index] = reg_value;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
- reg_index, reg_value);
-#endif
- break;
- case 0x22: // Graphics Data Latches Readback (R)
- case 0x24: // Attribute Controller Toggle Readback (R)
- case 0x26: // Attribute Controller Index Readback (R)
- case 0x27: // Part ID (R)
- break;
- case 0x25: // Part Status
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: outport cr_index %02x, cr_value %02x\n", reg_index,
- reg_value);
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * memory-mapped I/O (bitblt)
- *
- ***************************************/
-
-static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
-{
- int value = 0xff;
-
- switch (address) {
- case (CIRRUS_MMIO_BLTBGCOLOR + 0):
- cirrus_hook_read_gr(s, 0x00, &value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 1):
- cirrus_hook_read_gr(s, 0x10, &value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 2):
- cirrus_hook_read_gr(s, 0x12, &value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 3):
- cirrus_hook_read_gr(s, 0x14, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 0):
- cirrus_hook_read_gr(s, 0x01, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 1):
- cirrus_hook_read_gr(s, 0x11, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 2):
- cirrus_hook_read_gr(s, 0x13, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 3):
- cirrus_hook_read_gr(s, 0x15, &value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 0):
- cirrus_hook_read_gr(s, 0x20, &value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 1):
- cirrus_hook_read_gr(s, 0x21, &value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 0):
- cirrus_hook_read_gr(s, 0x22, &value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 1):
- cirrus_hook_read_gr(s, 0x23, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 0):
- cirrus_hook_read_gr(s, 0x24, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 1):
- cirrus_hook_read_gr(s, 0x25, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 0):
- cirrus_hook_read_gr(s, 0x26, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 1):
- cirrus_hook_read_gr(s, 0x27, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 0):
- cirrus_hook_read_gr(s, 0x28, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 1):
- cirrus_hook_read_gr(s, 0x29, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 2):
- cirrus_hook_read_gr(s, 0x2a, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 0):
- cirrus_hook_read_gr(s, 0x2c, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 1):
- cirrus_hook_read_gr(s, 0x2d, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 2):
- cirrus_hook_read_gr(s, 0x2e, &value);
- break;
- case CIRRUS_MMIO_BLTWRITEMASK:
- cirrus_hook_read_gr(s, 0x2f, &value);
- break;
- case CIRRUS_MMIO_BLTMODE:
- cirrus_hook_read_gr(s, 0x30, &value);
- break;
- case CIRRUS_MMIO_BLTROP:
- cirrus_hook_read_gr(s, 0x32, &value);
- break;
- case CIRRUS_MMIO_BLTMODEEXT:
- cirrus_hook_read_gr(s, 0x33, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
- cirrus_hook_read_gr(s, 0x34, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
- cirrus_hook_read_gr(s, 0x35, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
- cirrus_hook_read_gr(s, 0x38, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
- cirrus_hook_read_gr(s, 0x39, &value);
- break;
- case CIRRUS_MMIO_BLTSTATUS:
- cirrus_hook_read_gr(s, 0x31, &value);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mmio read - address 0x%04x\n", address);
-#endif
- break;
- }
-
- return (uint8_t) value;
-}
-
-static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
- uint8_t value)
-{
- switch (address) {
- case (CIRRUS_MMIO_BLTBGCOLOR + 0):
- cirrus_hook_write_gr(s, 0x00, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 1):
- cirrus_hook_write_gr(s, 0x10, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 2):
- cirrus_hook_write_gr(s, 0x12, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 3):
- cirrus_hook_write_gr(s, 0x14, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 0):
- cirrus_hook_write_gr(s, 0x01, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 1):
- cirrus_hook_write_gr(s, 0x11, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 2):
- cirrus_hook_write_gr(s, 0x13, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 3):
- cirrus_hook_write_gr(s, 0x15, value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 0):
- cirrus_hook_write_gr(s, 0x20, value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 1):
- cirrus_hook_write_gr(s, 0x21, value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 0):
- cirrus_hook_write_gr(s, 0x22, value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 1):
- cirrus_hook_write_gr(s, 0x23, value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 0):
- cirrus_hook_write_gr(s, 0x24, value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 1):
- cirrus_hook_write_gr(s, 0x25, value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 0):
- cirrus_hook_write_gr(s, 0x26, value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 1):
- cirrus_hook_write_gr(s, 0x27, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 0):
- cirrus_hook_write_gr(s, 0x28, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 1):
- cirrus_hook_write_gr(s, 0x29, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 2):
- cirrus_hook_write_gr(s, 0x2a, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 3):
- /* ignored */
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 0):
- cirrus_hook_write_gr(s, 0x2c, value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 1):
- cirrus_hook_write_gr(s, 0x2d, value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 2):
- cirrus_hook_write_gr(s, 0x2e, value);
- break;
- case CIRRUS_MMIO_BLTWRITEMASK:
- cirrus_hook_write_gr(s, 0x2f, value);
- break;
- case CIRRUS_MMIO_BLTMODE:
- cirrus_hook_write_gr(s, 0x30, value);
- break;
- case CIRRUS_MMIO_BLTROP:
- cirrus_hook_write_gr(s, 0x32, value);
- break;
- case CIRRUS_MMIO_BLTMODEEXT:
- cirrus_hook_write_gr(s, 0x33, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
- cirrus_hook_write_gr(s, 0x34, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
- cirrus_hook_write_gr(s, 0x35, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
- cirrus_hook_write_gr(s, 0x38, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
- cirrus_hook_write_gr(s, 0x39, value);
- break;
- case CIRRUS_MMIO_BLTSTATUS:
- cirrus_hook_write_gr(s, 0x31, value);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
- address, value);
-#endif
- break;
- }
-}
-
-/***************************************
- *
- * write mode 4/5
- *
- * assume TARGET_PAGE_SIZE >= 16
- *
- ***************************************/
-
-static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
- unsigned mode,
- unsigned offset,
- uint32_t mem_value)
-{
- int x;
- unsigned val = mem_value;
- uint8_t *dst;
-
- dst = s->vram_ptr + offset;
- for (x = 0; x < 8; x++) {
- if (val & 0x80) {
- *dst = s->cirrus_shadow_gr1;
- } else if (mode == 5) {
- *dst = s->cirrus_shadow_gr0;
- }
- val <<= 1;
- dst++;
- }
- cpu_physical_memory_set_dirty(s->vram_offset + offset);
- cpu_physical_memory_set_dirty(s->vram_offset + offset + 7);
-}
-
-static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
- unsigned mode,
- unsigned offset,
- uint32_t mem_value)
-{
- int x;
- unsigned val = mem_value;
- uint8_t *dst;
-
- dst = s->vram_ptr + offset;
- for (x = 0; x < 8; x++) {
- if (val & 0x80) {
- *dst = s->cirrus_shadow_gr1;
- *(dst + 1) = s->gr[0x11];
- } else if (mode == 5) {
- *dst = s->cirrus_shadow_gr0;
- *(dst + 1) = s->gr[0x10];
- }
- val <<= 1;
- dst += 2;
- }
- cpu_physical_memory_set_dirty(s->vram_offset + offset);
- cpu_physical_memory_set_dirty(s->vram_offset + offset + 15);
-}
-
-/***************************************
- *
- * memory access between 0xa0000-0xbffff
- *
- ***************************************/
-
-static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- CirrusVGAState *s = opaque;
- unsigned bank_index;
- unsigned bank_offset;
- uint32_t val;
-
- if ((s->sr[0x07] & 0x01) == 0) {
- return vga_mem_readb(s, addr);
- }
-
- addr &= 0x1ffff;
-
- if (addr < 0x10000) {
- /* XXX handle bitblt */
- /* video memory */
- bank_index = addr >> 15;
- bank_offset = addr & 0x7fff;
- if (bank_offset < s->cirrus_bank_limit[bank_index]) {
- bank_offset += s->cirrus_bank_base[bank_index];
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- bank_offset <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- bank_offset <<= 3;
- }
- bank_offset &= s->cirrus_addr_mask;
- val = *(s->vram_ptr + bank_offset);
- } else
- val = 0xff;
- } else if (addr >= 0x18000 && addr < 0x18100) {
- /* memory-mapped I/O */
- val = 0xff;
- if ((s->sr[0x17] & 0x44) == 0x04) {
- val = cirrus_mmio_blt_read(s, addr & 0xff);
- }
- } else {
- val = 0xff;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mem_readb %06x\n", addr);
-#endif
- }
- return val;
-}
-
-static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_vga_mem_readb(opaque, addr) << 8;
- v |= cirrus_vga_mem_readb(opaque, addr + 1);
-#else
- v = cirrus_vga_mem_readb(opaque, addr);
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_vga_mem_readb(opaque, addr) << 24;
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 16;
- v |= cirrus_vga_mem_readb(opaque, addr + 2) << 8;
- v |= cirrus_vga_mem_readb(opaque, addr + 3);
-#else
- v = cirrus_vga_mem_readb(opaque, addr);
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
- v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
- v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t mem_value)
-{
- CirrusVGAState *s = opaque;
- unsigned bank_index;
- unsigned bank_offset;
- unsigned mode;
-
- if ((s->sr[0x07] & 0x01) == 0) {
- vga_mem_writeb(s, addr, mem_value);
- return;
- }
-
- addr &= 0x1ffff;
-
- if (addr < 0x10000) {
- if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) mem_value;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- } else {
- /* video memory */
- bank_index = addr >> 15;
- bank_offset = addr & 0x7fff;
- if (bank_offset < s->cirrus_bank_limit[bank_index]) {
- bank_offset += s->cirrus_bank_base[bank_index];
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- bank_offset <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- bank_offset <<= 3;
- }
- bank_offset &= s->cirrus_addr_mask;
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- *(s->vram_ptr + bank_offset) = mem_value;
- cpu_physical_memory_set_dirty(s->vram_offset +
- bank_offset);
- } else {
- if ((s->gr[0x0B] & 0x14) != 0x14) {
- cirrus_mem_writeb_mode4and5_8bpp(s, mode,
- bank_offset,
- mem_value);
- } else {
- cirrus_mem_writeb_mode4and5_16bpp(s, mode,
- bank_offset,
- mem_value);
- }
- }
- }
- }
- } else if (addr >= 0x18000 && addr < 0x18100) {
- /* memory-mapped I/O */
- if ((s->sr[0x17] & 0x44) == 0x04) {
- cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
- }
- } else {
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mem_writeb %06x value %02x\n", addr, mem_value);
-#endif
- }
-}
-
-static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-static CPUReadMemoryFunc *cirrus_vga_mem_read[3] = {
- cirrus_vga_mem_readb,
- cirrus_vga_mem_readw,
- cirrus_vga_mem_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = {
- cirrus_vga_mem_writeb,
- cirrus_vga_mem_writew,
- cirrus_vga_mem_writel,
-};
-
-/***************************************
- *
- * hardware cursor
- *
- ***************************************/
-
-static inline void invalidate_cursor1(CirrusVGAState *s)
-{
- if (s->last_hw_cursor_size) {
- vga_invalidate_scanlines((VGAState *)s,
- s->last_hw_cursor_y + s->last_hw_cursor_y_start,
- s->last_hw_cursor_y + s->last_hw_cursor_y_end);
- }
-}
-
-static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
-{
- const uint8_t *src;
- uint32_t content;
- int y, y_min, y_max;
-
- src = s->vram_ptr + s->real_vram_size - 16 * 1024;
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
- src += (s->sr[0x13] & 0x3c) * 256;
- y_min = 64;
- y_max = -1;
- for(y = 0; y < 64; y++) {
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)src)[1] |
- ((uint32_t *)src)[2] |
- ((uint32_t *)src)[3];
- if (content) {
- if (y < y_min)
- y_min = y;
- if (y > y_max)
- y_max = y;
- }
- src += 16;
- }
- } else {
- src += (s->sr[0x13] & 0x3f) * 256;
- y_min = 32;
- y_max = -1;
- for(y = 0; y < 32; y++) {
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)(src + 128))[0];
- if (content) {
- if (y < y_min)
- y_min = y;
- if (y > y_max)
- y_max = y;
- }
- src += 4;
- }
- }
- if (y_min > y_max) {
- s->last_hw_cursor_y_start = 0;
- s->last_hw_cursor_y_end = 0;
- } else {
- s->last_hw_cursor_y_start = y_min;
- s->last_hw_cursor_y_end = y_max + 1;
- }
-}
-
-/* NOTE: we do not currently handle the cursor bitmap change, so we
- update the cursor only if it moves. */
-static void cirrus_cursor_invalidate(VGAState *s1)
-{
- CirrusVGAState *s = (CirrusVGAState *)s1;
- int size;
-
- if (!s->sr[0x12] & CIRRUS_CURSOR_SHOW) {
- size = 0;
- } else {
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE)
- size = 64;
- else
- size = 32;
- }
- /* invalidate last cursor and new cursor if any change */
- if (s->last_hw_cursor_size != size ||
- s->last_hw_cursor_x != s->hw_cursor_x ||
- s->last_hw_cursor_y != s->hw_cursor_y) {
-
- invalidate_cursor1(s);
-
- s->last_hw_cursor_size = size;
- s->last_hw_cursor_x = s->hw_cursor_x;
- s->last_hw_cursor_y = s->hw_cursor_y;
- /* compute the real cursor min and max y */
- cirrus_cursor_compute_yrange(s);
- invalidate_cursor1(s);
- }
-}
-
-static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y)
-{
- CirrusVGAState *s = (CirrusVGAState *)s1;
- int w, h, bpp, x1, x2, poffset;
- unsigned int color0, color1;
- const uint8_t *palette, *src;
- uint32_t content;
-
- if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW))
- return;
- /* fast test to see if the cursor intersects with the scan line */
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
- h = 64;
- } else {
- h = 32;
- }
- if (scr_y < s->hw_cursor_y ||
- scr_y >= (s->hw_cursor_y + h))
- return;
-
- src = s->vram_ptr + s->real_vram_size - 16 * 1024;
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
- src += (s->sr[0x13] & 0x3c) * 256;
- src += (scr_y - s->hw_cursor_y) * 16;
- poffset = 8;
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)src)[1] |
- ((uint32_t *)src)[2] |
- ((uint32_t *)src)[3];
- } else {
- src += (s->sr[0x13] & 0x3f) * 256;
- src += (scr_y - s->hw_cursor_y) * 4;
- poffset = 128;
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)(src + 128))[0];
- }
- /* if nothing to draw, no need to continue */
- if (!content)
- return;
- w = h;
-
- x1 = s->hw_cursor_x;
- if (x1 >= s->last_scr_width)
- return;
- x2 = s->hw_cursor_x + w;
- if (x2 > s->last_scr_width)
- x2 = s->last_scr_width;
- w = x2 - x1;
- palette = s->cirrus_hidden_palette;
- color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
- c6_to_8(palette[0x0 * 3 + 1]),
- c6_to_8(palette[0x0 * 3 + 2]));
- color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]),
- c6_to_8(palette[0xf * 3 + 1]),
- c6_to_8(palette[0xf * 3 + 2]));
- bpp = ((s->ds->depth + 7) >> 3);
- d1 += x1 * bpp;
- switch(s->ds->depth) {
- default:
- break;
- case 8:
- vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
- break;
- case 15:
- vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
- break;
- case 16:
- vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
- break;
- case 32:
- vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
- break;
- }
-}
-
-/***************************************
- *
- * LFB memory access
- *
- ***************************************/
-
-static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
- uint32_t ret;
-
- addr &= s->cirrus_addr_mask;
-
- if (((s->sr[0x17] & 0x44) == 0x44) &&
- ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
- /* memory-mapped I/O */
- ret = cirrus_mmio_blt_read(s, addr & 0xff);
- } else if (0) {
- /* XXX handle bitblt */
- ret = 0xff;
- } else {
- /* video memory */
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- addr <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- addr <<= 3;
- }
- addr &= s->cirrus_addr_mask;
- ret = *(s->vram_ptr + addr);
- }
-
- return ret;
-}
-
-static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_readb(opaque, addr) << 8;
- v |= cirrus_linear_readb(opaque, addr + 1);
-#else
- v = cirrus_linear_readb(opaque, addr);
- v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_readb(opaque, addr) << 24;
- v |= cirrus_linear_readb(opaque, addr + 1) << 16;
- v |= cirrus_linear_readb(opaque, addr + 2) << 8;
- v |= cirrus_linear_readb(opaque, addr + 3);
-#else
- v = cirrus_linear_readb(opaque, addr);
- v |= cirrus_linear_readb(opaque, addr + 1) << 8;
- v |= cirrus_linear_readb(opaque, addr + 2) << 16;
- v |= cirrus_linear_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
- unsigned mode;
-
- addr &= s->cirrus_addr_mask;
-
- if (((s->sr[0x17] & 0x44) == 0x44) &&
- ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
- /* memory-mapped I/O */
- cirrus_mmio_blt_write(s, addr & 0xff, val);
- } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) val;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- } else {
- /* video memory */
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- addr <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- addr <<= 3;
- }
- addr &= s->cirrus_addr_mask;
-
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- *(s->vram_ptr + addr) = (uint8_t) val;
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
- } else {
- if ((s->gr[0x0B] & 0x14) != 0x14) {
- cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
- } else {
- cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
- }
- }
- }
-}
-
-static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_linear_writeb(opaque, addr, val & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_linear_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_linear_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_linear_writeb(opaque, addr, val & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-
-static CPUReadMemoryFunc *cirrus_linear_read[3] = {
- cirrus_linear_readb,
- cirrus_linear_readw,
- cirrus_linear_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
- cirrus_linear_writeb,
- cirrus_linear_writew,
- cirrus_linear_writel,
-};
-
-static void cirrus_linear_mem_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= s->cirrus_addr_mask;
- *(s->vram_ptr + addr) = val;
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
-}
-
-static void cirrus_linear_mem_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= s->cirrus_addr_mask;
- cpu_to_le16w((uint16_t *)(s->vram_ptr + addr), val);
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
-}
-
-static void cirrus_linear_mem_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= s->cirrus_addr_mask;
- cpu_to_le32w((uint32_t *)(s->vram_ptr + addr), val);
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
-}
-
-/***************************************
- *
- * system to screen memory access
- *
- ***************************************/
-
-
-static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
-{
- uint32_t ret;
-
- /* XXX handle bitblt */
- ret = 0xff;
- return ret;
-}
-
-static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_bitblt_readb(opaque, addr) << 8;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1);
-#else
- v = cirrus_linear_bitblt_readb(opaque, addr);
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_bitblt_readb(opaque, addr) << 24;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 16;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 8;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 3);
-#else
- v = cirrus_linear_bitblt_readb(opaque, addr);
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) val;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- }
-}
-
-static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_bitblt_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_bitblt_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-
-static CPUReadMemoryFunc *cirrus_linear_bitblt_read[3] = {
- cirrus_linear_bitblt_readb,
- cirrus_linear_bitblt_readw,
- cirrus_linear_bitblt_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = {
- cirrus_linear_bitblt_writeb,
- cirrus_linear_bitblt_writew,
- cirrus_linear_bitblt_writel,
-};
-
-static void set_vram_mapping(CirrusVGAState *s, unsigned long begin, unsigned long end)
-{
- unsigned long i;
- struct xen_add_to_physmap xatp;
- int rc;
-
- if (end > begin + VGA_RAM_SIZE)
- end = begin + VGA_RAM_SIZE;
-
- fprintf(logfile,"mapping vram to %lx - %lx\n", begin, end);
-
- if (!s->vram_mfns)
- return;
-
- xatp.domid = domid;
- xatp.space = XENMAPSPACE_mfn;
-
- for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) {
- xatp.idx = s->vram_mfns[i];
- xatp.gpfn = (begin >> TARGET_PAGE_BITS) + i;
- rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
- if (rc) {
- fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, rc);
- return;
- }
- }
-
- (void)xc_domain_pin_memory_cacheattr(
- xc_handle, domid,
- begin >> TARGET_PAGE_BITS,
- end >> TARGET_PAGE_BITS,
- XEN_DOMCTL_MEM_CACHEATTR_WB);
-}
-
-static void unset_vram_mapping(CirrusVGAState *s, unsigned long begin, unsigned long end)
-{
- if (s->stolen_vram_addr) {
- /* We can put it there for xend to save it efficiently */
- set_vram_mapping(s, s->stolen_vram_addr, s->stolen_vram_addr + VGA_RAM_SIZE);
- } else {
- /* Old image, we have to unmap them completely */
- struct xen_remove_from_physmap xrfp;
- unsigned long i;
- int rc;
-
- if (end > begin + VGA_RAM_SIZE)
- end = begin + VGA_RAM_SIZE;
-
- fprintf(logfile,"unmapping vram from %lx - %lx\n", begin, end);
-
- xrfp.domid = domid;
-
- for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) {
- xrfp.gpfn = (begin >> TARGET_PAGE_BITS) + i;
- rc = xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp);
- if (rc) {
- fprintf(stderr, "remove_from_physmap PFN %"PRI_xen_pfn" failed: %d\n", xrfp.gpfn, rc);
- return;
- }
- }
- }
-}
-
-void cirrus_restart_acc(CirrusVGAState *s)
-{
- set_vram_mapping(s, s->lfb_addr, s->lfb_end);
- s->map_addr = s->lfb_addr;
- s->map_end = s->lfb_end;
-}
-
-/* Compute the memory access functions */
-static void cirrus_update_memory_access(CirrusVGAState *s)
-{
- unsigned mode;
-
- if ((s->sr[0x17] & 0x44) == 0x44) {
- goto generic_io;
- } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- goto generic_io;
- } else {
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- goto generic_io;
- } else if (s->gr[0x0B] & 0x02) {
- goto generic_io;
- }
-
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- if (s->lfb_addr && s->lfb_end && !s->map_addr) {
- set_vram_mapping(s, s->lfb_addr, s->lfb_end);
- s->map_addr = s->lfb_addr;
- s->map_end = s->lfb_end;
- }
- s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
- s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
- s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
- } else {
- generic_io:
- if (s->lfb_addr && s->lfb_end && s->map_addr) {
- unset_vram_mapping(s, s->map_addr, s->map_end);
- s->map_addr = s->map_end = 0;
- }
- s->cirrus_linear_write[0] = cirrus_linear_writeb;
- s->cirrus_linear_write[1] = cirrus_linear_writew;
- s->cirrus_linear_write[2] = cirrus_linear_writel;
- }
- }
-}
-
-
-/* I/O ports */
-
-static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
-{
- CirrusVGAState *s = opaque;
- int val, index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
- || (addr >= 0x3d0 && addr <= 0x3df
- && !(s->msr & MSR_COLOR_EMULATION))) {
- val = 0xff;
- } else {
- switch (addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val = s->ar_index;
- } else {
- val = 0;
- }
- break;
- case 0x3c1:
- index = s->ar_index & 0x1f;
- if (index < 21)
- val = s->ar[index];
- else
- val = 0;
- break;
- case 0x3c2:
- val = s->st00;
- break;
- case 0x3c4:
- val = s->sr_index;
- break;
- case 0x3c5:
- if (cirrus_hook_read_sr(s, s->sr_index, &val))
- break;
- val = s->sr[s->sr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- break;
- case 0x3c6:
- cirrus_read_hidden_dac(s, &val);
- break;
- case 0x3c7:
- val = s->dac_state;
- break;
- case 0x3c8:
- val = s->dac_write_index;
- s->cirrus_hidden_dac_lockindex = 0;
- break;
- case 0x3c9:
- if (cirrus_hook_read_palette(s, &val))
- break;
- val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
- }
- break;
- case 0x3ca:
- val = s->fcr;
- break;
- case 0x3cc:
- val = s->msr;
- break;
- case 0x3ce:
- val = s->gr_index;
- break;
- case 0x3cf:
- if (cirrus_hook_read_gr(s, s->gr_index, &val))
- break;
- val = s->gr[s->gr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- break;
- case 0x3b4:
- case 0x3d4:
- val = s->cr_index;
- break;
- case 0x3b5:
- case 0x3d5:
- if (cirrus_hook_read_cr(s, s->cr_index, &val))
- break;
- val = s->cr[s->cr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- break;
- case 0x3ba:
- case 0x3da:
- /* just toggle to fool polling */
- s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
- val = s->st01;
- s->ar_flip_flop = 0;
- break;
- default:
- val = 0x00;
- break;
- }
- }
-#if defined(DEBUG_VGA)
- printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- CirrusVGAState *s = opaque;
- int index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
- || (addr >= 0x3d0 && addr <= 0x3df
- && !(s->msr & MSR_COLOR_EMULATION)))
- return;
-
-#ifdef DEBUG_VGA
- printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
-#endif
-
- switch (addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val &= 0x3f;
- s->ar_index = val;
- } else {
- index = s->ar_index & 0x1f;
- switch (index) {
- case 0x00 ... 0x0f:
- s->ar[index] = val & 0x3f;
- break;
- case 0x10:
- s->ar[index] = val & ~0x10;
- break;
- case 0x11:
- s->ar[index] = val;
- break;
- case 0x12:
- s->ar[index] = val & ~0xc0;
- break;
- case 0x13:
- s->ar[index] = val & ~0xf0;
- break;
- case 0x14:
- s->ar[index] = val & ~0xf0;
- break;
- default:
- break;
- }
- }
- s->ar_flip_flop ^= 1;
- break;
- case 0x3c2:
- s->msr = val & ~0x10;
- break;
- case 0x3c4:
- s->sr_index = val;
- break;
- case 0x3c5:
- if (cirrus_hook_write_sr(s, s->sr_index, val))
- break;
-#ifdef DEBUG_VGA_REG
- printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- s->sr[s->sr_index] = val & sr_mask[s->sr_index];
- break;
- case 0x3c6:
- cirrus_write_hidden_dac(s, val);
- break;
- case 0x3c7:
- s->dac_read_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 3;
- break;
- case 0x3c8:
- s->dac_write_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 0;
- break;
- case 0x3c9:
- if (cirrus_hook_write_palette(s, val))
- break;
- s->dac_cache[s->dac_sub_index] = val;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
- s->dac_sub_index = 0;
- s->dac_write_index++;
- }
- break;
- case 0x3ce:
- s->gr_index = val;
- break;
- case 0x3cf:
- if (cirrus_hook_write_gr(s, s->gr_index, val))
- break;
-#ifdef DEBUG_VGA_REG
- printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- s->gr[s->gr_index] = val & gr_mask[s->gr_index];
- break;
- case 0x3b4:
- case 0x3d4:
- s->cr_index = val;
- break;
- case 0x3b5:
- case 0x3d5:
- if (cirrus_hook_write_cr(s, s->cr_index, val))
- break;
-#ifdef DEBUG_VGA_REG
- printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- /* handle CR0-7 protection */
- if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
- /* can always write bit 4 of CR7 */
- if (s->cr_index == 7)
- s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
- return;
- }
- switch (s->cr_index) {
- case 0x01: /* horizontal display end */
- case 0x07:
- case 0x09:
- case 0x0c:
- case 0x0d:
- case 0x12: /* veritcal display end */
- s->cr[s->cr_index] = val;
- break;
-
- default:
- s->cr[s->cr_index] = val;
- break;
- }
- break;
- case 0x3ba:
- case 0x3da:
- s->fcr = val & 0x10;
- break;
- }
-}
-
-/***************************************
- *
- * memory-mapped I/O access
- *
- ***************************************/
-
-static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
- if (addr >= 0x100) {
- return cirrus_mmio_blt_read(s, addr - 0x100);
- } else {
- return vga_ioport_read(s, addr + 0x3c0);
- }
-}
-
-static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_mmio_readb(opaque, addr) << 8;
- v |= cirrus_mmio_readb(opaque, addr + 1);
-#else
- v = cirrus_mmio_readb(opaque, addr);
- v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_mmio_readb(opaque, addr) << 24;
- v |= cirrus_mmio_readb(opaque, addr + 1) << 16;
- v |= cirrus_mmio_readb(opaque, addr + 2) << 8;
- v |= cirrus_mmio_readb(opaque, addr + 3);
-#else
- v = cirrus_mmio_readb(opaque, addr);
- v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
- v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
- v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
- if (addr >= 0x100) {
- cirrus_mmio_blt_write(s, addr - 0x100, val);
- } else {
- vga_ioport_write(s, addr + 0x3c0, val);
- }
-}
-
-static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_mmio_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_mmio_writeb(opaque, addr, val & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_mmio_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_mmio_writeb(opaque, addr, val & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-
-static CPUReadMemoryFunc *cirrus_mmio_read[3] = {
- cirrus_mmio_readb,
- cirrus_mmio_readw,
- cirrus_mmio_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_mmio_write[3] = {
- cirrus_mmio_writeb,
- cirrus_mmio_writew,
- cirrus_mmio_writel,
-};
-
-/* load/save state */
-
-static void cirrus_vga_save(QEMUFile *f, void *opaque)
-{
- CirrusVGAState *s = opaque;
- uint8_t vga_acc;
-
- if (s->pci_dev)
- pci_device_save(s->pci_dev, f);
-
- qemu_put_be32s(f, &s->latch);
- qemu_put_8s(f, &s->sr_index);
- qemu_put_buffer(f, s->sr, 256);
- qemu_put_8s(f, &s->gr_index);
- qemu_put_8s(f, &s->cirrus_shadow_gr0);
- qemu_put_8s(f, &s->cirrus_shadow_gr1);
- qemu_put_buffer(f, s->gr + 2, 254);
- qemu_put_8s(f, &s->ar_index);
- qemu_put_buffer(f, s->ar, 21);
- qemu_put_be32s(f, &s->ar_flip_flop);
- qemu_put_8s(f, &s->cr_index);
- qemu_put_buffer(f, s->cr, 256);
- qemu_put_8s(f, &s->msr);
- qemu_put_8s(f, &s->fcr);
- qemu_put_8s(f, &s->st00);
- qemu_put_8s(f, &s->st01);
-
- qemu_put_8s(f, &s->dac_state);
- qemu_put_8s(f, &s->dac_sub_index);
- qemu_put_8s(f, &s->dac_read_index);
- qemu_put_8s(f, &s->dac_write_index);
- qemu_put_buffer(f, s->dac_cache, 3);
- qemu_put_buffer(f, s->palette, 768);
-
- qemu_put_be32s(f, &s->bank_offset);
-
- qemu_put_8s(f, &s->cirrus_hidden_dac_lockindex);
- qemu_put_8s(f, &s->cirrus_hidden_dac_data);
-
- qemu_put_be32s(f, &s->hw_cursor_x);
- qemu_put_be32s(f, &s->hw_cursor_y);
- /* XXX: we do not save the bitblt state - we assume we do not save
- the state when the blitter is active */
-
- vga_acc = (!!s->map_addr);
- qemu_put_8s(f, &vga_acc);
- qemu_put_be64s(f, (uint64_t*)&s->lfb_addr);
- qemu_put_be64s(f, (uint64_t*)&s->lfb_end);
- qemu_put_be64s(f, &s->stolen_vram_addr);
- if (!s->stolen_vram_addr && !vga_acc)
- /* Old guest: VRAM is not mapped, we have to save it ourselves */
- qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
-}
-
-static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
-{
- CirrusVGAState *s = opaque;
- uint8_t vga_acc = 0;
- int ret;
-
- if (version_id > 3)
- return -EINVAL;
-
- if (s->pci_dev && version_id >= 2) {
- ret = pci_device_load(s->pci_dev, f);
- if (ret < 0)
- return ret;
- }
-
- qemu_get_be32s(f, &s->latch);
- qemu_get_8s(f, &s->sr_index);
- qemu_get_buffer(f, s->sr, 256);
- qemu_get_8s(f, &s->gr_index);
- qemu_get_8s(f, &s->cirrus_shadow_gr0);
- qemu_get_8s(f, &s->cirrus_shadow_gr1);
- s->gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
- s->gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
- qemu_get_buffer(f, s->gr + 2, 254);
- qemu_get_8s(f, &s->ar_index);
- qemu_get_buffer(f, s->ar, 21);
- qemu_get_be32s(f, &s->ar_flip_flop);
- qemu_get_8s(f, &s->cr_index);
- qemu_get_buffer(f, s->cr, 256);
- qemu_get_8s(f, &s->msr);
- qemu_get_8s(f, &s->fcr);
- qemu_get_8s(f, &s->st00);
- qemu_get_8s(f, &s->st01);
-
- qemu_get_8s(f, &s->dac_state);
- qemu_get_8s(f, &s->dac_sub_index);
- qemu_get_8s(f, &s->dac_read_index);
- qemu_get_8s(f, &s->dac_write_index);
- qemu_get_buffer(f, s->dac_cache, 3);
- qemu_get_buffer(f, s->palette, 768);
-
- qemu_get_be32s(f, &s->bank_offset);
-
- qemu_get_8s(f, &s->cirrus_hidden_dac_lockindex);
- qemu_get_8s(f, &s->cirrus_hidden_dac_data);
-
- qemu_get_be32s(f, &s->hw_cursor_x);
- qemu_get_be32s(f, &s->hw_cursor_y);
-
- qemu_get_8s(f, &vga_acc);
- qemu_get_be64s(f, (uint64_t*)&s->lfb_addr);
- qemu_get_be64s(f, (uint64_t*)&s->lfb_end);
- if (version_id >= 3) {
- qemu_get_be64s(f, &s->stolen_vram_addr);
- if (!s->stolen_vram_addr && !vga_acc) {
- /* Old guest, VRAM is not mapped, we have to restore it ourselves */
- qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
- xen_vga_populate_vram(s->lfb_addr);
- } else
- xen_vga_vram_map(vga_acc ? s->lfb_addr : s->stolen_vram_addr, 0);
- } else {
- /* Old image, we have to populate and restore VRAM ourselves */
- xen_vga_populate_vram(s->lfb_addr);
- qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
- if (vga_acc)
- cirrus_restart_acc(s);
- }
-
- /* force refresh */
- s->graphic_mode = -1;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- return 0;
-}
-
-/***************************************
- *
- * initialize
- *
- ***************************************/
-
-static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
-{
- int vga_io_memory, i;
- static int inited;
-
- if (!inited) {
- inited = 1;
- for(i = 0;i < 256; i++)
- rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
- rop_to_index[CIRRUS_ROP_0] = 0;
- rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
- rop_to_index[CIRRUS_ROP_NOP] = 2;
- rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
- rop_to_index[CIRRUS_ROP_NOTDST] = 4;
- rop_to_index[CIRRUS_ROP_SRC] = 5;
- rop_to_index[CIRRUS_ROP_1] = 6;
- rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
- rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
- rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
- rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
- rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
- rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
- rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
- rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
- rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
- }
-
- register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
-
- register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
- register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
- register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
- register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
- register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
-
- vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
- cirrus_vga_mem_write, s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- vga_io_memory);
-
- s->sr[0x06] = 0x0f;
- if (device_id == CIRRUS_ID_CLGD5446) {
- /* 4MB 64 bit memory config, always PCI */
- s->sr[0x1F] = 0x2d; // MemClock
- s->gr[0x18] = 0x0f; // fastest memory configuration
-#if 1
- s->sr[0x0f] = 0x98;
- s->sr[0x17] = 0x20;
- s->sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
- s->real_vram_size = 4096 * 1024;
-#else
- s->sr[0x0f] = 0x18;
- s->sr[0x17] = 0x20;
- s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
- s->real_vram_size = 2048 * 1024;
-#endif
- } else {
- s->sr[0x1F] = 0x22; // MemClock
- s->sr[0x0F] = CIRRUS_MEMSIZE_2M;
- if (is_pci)
- s->sr[0x17] = CIRRUS_BUSTYPE_PCI;
- else
- s->sr[0x17] = CIRRUS_BUSTYPE_ISA;
- s->real_vram_size = 2048 * 1024;
- s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
- }
- s->cr[0x27] = device_id;
-
- /* Win2K seems to assume that the pattern buffer is at 0xff
- initially ! */
- memset(s->vram_ptr, 0xff, s->real_vram_size);
-
- s->cirrus_hidden_dac_lockindex = 5;
- s->cirrus_hidden_dac_data = 0;
-
- /* I/O handler for LFB */
- s->cirrus_linear_io_addr =
- cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
- s);
- s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr);
-
- /* I/O handler for LFB */
- s->cirrus_linear_bitblt_io_addr =
- cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write,
- s);
-
- /* I/O handler for memory-mapped I/O */
- s->cirrus_mmio_io_addr =
- cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
-
- /* XXX: s->vram_size must be a power of two */
- s->cirrus_addr_mask = s->real_vram_size - 1;
- s->linear_mmio_mask = s->real_vram_size - 256;
-
- s->get_bpp = cirrus_get_bpp;
- s->get_offsets = cirrus_get_offsets;
- s->get_resolution = cirrus_get_resolution;
- s->cursor_invalidate = cirrus_cursor_invalidate;
- s->cursor_draw_line = cirrus_cursor_draw_line;
-
- register_savevm("cirrus_vga", 0, 3, cirrus_vga_save, cirrus_vga_load, s);
-}
-
-/***************************************
- *
- * ISA bus support
- *
- ***************************************/
-
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- CirrusVGAState *s;
-
- s = qemu_mallocz(sizeof(CirrusVGAState));
-
- vga_common_init((VGAState *)s,
- ds, vga_ram_base, vga_ram_offset, vga_ram_size);
- cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
- /* XXX ISA-LFB support */
-}
-
-/***************************************
- *
- * PCI bus support
- *
- ***************************************/
-
-static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
-
- /* XXX: add byte swapping apertures */
- cpu_register_physical_memory(addr, s->vram_size,
- s->cirrus_linear_io_addr);
- s->lfb_addr = addr;
- s->lfb_end = addr + VGA_RAM_SIZE;
-
- if (s->map_addr && (s->lfb_addr != s->map_addr) &&
- (s->lfb_end != s->map_end))
- fprintf(logfile, "cirrus vga map change while on lfb mode\n");
-
- cpu_register_physical_memory(addr + 0x1000000, 0x400000,
- s->cirrus_linear_bitblt_io_addr);
-}
-
-static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
-
- cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
- s->cirrus_mmio_io_addr);
-}
-
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- PCICirrusVGAState *d;
- uint8_t *pci_conf;
- CirrusVGAState *s;
- int device_id;
-
- device_id = CIRRUS_ID_CLGD5446;
-
- /* setup PCI configuration registers */
- d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA",
- sizeof(PCICirrusVGAState),
- -1, NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = (uint8_t) (PCI_VENDOR_CIRRUS & 0xff);
- pci_conf[0x01] = (uint8_t) (PCI_VENDOR_CIRRUS >> 8);
- pci_conf[0x02] = (uint8_t) (device_id & 0xff);
- pci_conf[0x03] = (uint8_t) (device_id >> 8);
- pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
- pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
- pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
- pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
- pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
- pci_conf[0x2d] = 0x58;
- pci_conf[0x2e] = 0x01; /* subsystem device */
- pci_conf[0x2f] = 0x00;
-
- /* setup VGA */
- s = &d->cirrus_vga;
- vga_common_init((VGAState *)s,
- ds, vga_ram_base, vga_ram_offset, vga_ram_size);
- cirrus_init_common(s, device_id, 1);
- s->pci_dev = (PCIDevice *)d;
-
- /* setup memory space */
- /* memory #0 LFB */
- /* memory #1 memory-mapped I/O */
- /* XXX: s->vram_size must be a power of two */
- pci_register_io_region((PCIDevice *)d, 0, 0x2000000,
- PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map);
- if (device_id == CIRRUS_ID_CLGD5446) {
- pci_register_io_region((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
- PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map);
- }
- /* XXX: ROM BIOS */
-}
diff --git a/tools/ioemu/hw/cirrus_vga_rop.h b/tools/ioemu/hw/cirrus_vga_rop.h
deleted file mode 100644
index e8eef2fe7e..0000000000
--- a/tools/ioemu/hw/cirrus_vga_rop.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#define get_base(p, s, b) do { \
- if ((p) >= (s)->vram_ptr && (p) < (s)->vram_ptr + (s)->vram_size) \
- (b) = (s)->vram_ptr; \
- else if ((p) >= &(s)->cirrus_bltbuf[0] && \
- (p) < &(s)->cirrus_bltbuf[CIRRUS_BLTBUFSIZE]) \
- (b) = &(s)->cirrus_bltbuf[0]; \
- else \
- return; \
-} while(0)
-
-#define m(x) ((x) & s->cirrus_addr_mask)
-
-static void
-glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
- uint8_t *dst_,const uint8_t *src_,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- uint32_t dst, src;
- uint8_t *dst_base, *src_base;
- get_base(dst_, s, dst_base);
- get_base(src_, s, src_base);
- dst = dst_ - dst_base;
- src = src_ - src_base;
- dstpitch -= bltwidth;
- srcpitch -= bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- ROP_OP(*(dst_base + m(dst)), *(src_base + m(src)));
- dst++;
- src++;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-static void
-glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
- uint8_t *dst_,const uint8_t *src_,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- uint32_t dst, src;
- uint8_t *dst_base, *src_base;
- get_base(dst_, s, dst_base);
- get_base(src_, s, src_base);
- dst = dst_ - dst_base;
- src = src_ - src_base;
- dstpitch += bltwidth;
- srcpitch += bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- ROP_OP(*(dst_base + m(dst)), *(src_base + m(src)));
- dst--;
- src--;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-#define DEPTH 8
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 16
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 24
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 32
-#include "cirrus_vga_rop2.h"
-
-#undef ROP_NAME
-#undef ROP_OP
-
-#undef get_base
-#undef m
diff --git a/tools/ioemu/hw/cirrus_vga_rop2.h b/tools/ioemu/hw/cirrus_vga_rop2.h
deleted file mode 100644
index 7775c683e8..0000000000
--- a/tools/ioemu/hw/cirrus_vga_rop2.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if DEPTH == 8
-#define PUTPIXEL() ROP_OP((dst_base + m(d))[0], col)
-#elif DEPTH == 16
-#define PUTPIXEL() ROP_OP(((uint16_t *)(dst_base + m(d)))[0], col);
-#elif DEPTH == 24
-#define PUTPIXEL() ROP_OP((dst_base + m(d))[0], col); \
- ROP_OP((dst_base + m(d))[1], (col >> 8)); \
- ROP_OP((dst_base + m(d))[2], (col >> 16))
-#elif DEPTH == 32
-#define PUTPIXEL() ROP_OP(((uint32_t *)(dst_base + m(d)))[0], col)
-#else
-#error unsupported DEPTH
-#endif
-
-static void
-glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *dst_base, *src_base;
- uint32_t src, dst;
- uint32_t d;
- int x, y, pattern_y, pattern_pitch, pattern_x;
- unsigned int col;
- uint32_t src1;
-#if DEPTH == 24
- int skipleft = s->gr[0x2f] & 0x1f;
-#else
- int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8);
-#endif
-
- get_base(dst_, s, dst_base);
- get_base(src_, s, src_base);
- dst = dst_ - dst_base;
- src = src_ - src_base;
-#if DEPTH == 8
- pattern_pitch = 8;
-#elif DEPTH == 16
- pattern_pitch = 16;
-#else
- pattern_pitch = 32;
-#endif
- pattern_y = s->cirrus_blt_srcaddr & 7;
- for(y = 0; y < bltheight; y++) {
- pattern_x = skipleft;
- d = dst + skipleft;
- src1 = src + pattern_y * pattern_pitch;
- for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
-#if DEPTH == 8
- col = *(src_base + m(src1 + pattern_x));
- pattern_x = (pattern_x + 1) & 7;
-#elif DEPTH == 16
- col = *(uint16_t *)(src_base + m(src1 + pattern_x));
- pattern_x = (pattern_x + 2) & 15;
-#elif DEPTH == 24
- {
- const uint8_t *src2 = src_base + m(src1 + pattern_x * 3);
- col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
- pattern_x = (pattern_x + 1) & 7;
- }
-#else
- col = *(uint32_t *)(src_base + m(src1 + pattern_x));
- pattern_x = (pattern_x + 4) & 31;
-#endif
- PUTPIXEL();
- d += (DEPTH / 8);
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-/* NOTE: srcpitch is ignored */
-static void
-glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *dst_base, *src_base;
- uint32_t src, dst;
- uint32_t d;
- int x, y;
- unsigned bits, bits_xor;
- unsigned int col;
- unsigned bitmask;
- unsigned index;
-#if DEPTH == 24
- int dstskipleft = s->gr[0x2f] & 0x1f;
- int srcskipleft = dstskipleft / 3;
-#else
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-#endif
-
- get_base(dst_, s, dst_base);
- get_base(src_, s, src_base);
- dst = dst_ - dst_base;
- src = src_ - src_base;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
- } else {
- bits_xor = 0x00;
- col = s->cirrus_blt_fgcol;
- }
-
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
- bits = *(src_base + m(src++)) ^ bits_xor;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
- bits = *(src_base + m(src++)) ^ bits_xor;
- }
- index = (bits & bitmask);
- if (index) {
- PUTPIXEL();
- }
- d += (DEPTH / 8);
- bitmask >>= 1;
- }
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *dst_base, *src_base;
- uint32_t src, dst;
- uint32_t colors[2];
- uint32_t d;
- int x, y;
- unsigned bits;
- unsigned int col;
- unsigned bitmask;
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
- get_base(dst_, s, dst_base);
- get_base(src_, s, src_base);
- dst = dst_ - dst_base;
- src = src_ - src_base;
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
- bits = *(src_base + m(src++));
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
- bits = *(src_base + m(src++));
- }
- col = colors[!!(bits & bitmask)];
- PUTPIXEL();
- d += (DEPTH / 8);
- bitmask >>= 1;
- }
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *dst_base, *src_base;
- uint32_t src, dst;
- uint32_t d;
- int x, y, bitpos, pattern_y;
- unsigned int bits, bits_xor;
- unsigned int col;
-#if DEPTH == 24
- int dstskipleft = s->gr[0x2f] & 0x1f;
- int srcskipleft = dstskipleft / 3;
-#else
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-#endif
-
- get_base(dst_, s, dst_base);
- get_base(src_, s, src_base);
- dst = dst_ - dst_base;
- src = src_ - src_base;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
- } else {
- bits_xor = 0x00;
- col = s->cirrus_blt_fgcol;
- }
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
- bits = *(src_base + m(src + pattern_y)) ^ bits_xor;
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bits >> bitpos) & 1) {
- PUTPIXEL();
- }
- d += (DEPTH / 8);
- bitpos = (bitpos - 1) & 7;
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *dst_base, *src_base;
- uint32_t src, dst;
- uint32_t colors[2];
- uint32_t d;
- int x, y, bitpos, pattern_y;
- unsigned int bits;
- unsigned int col;
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
- get_base(dst_, s, dst_base);
- get_base(src_, s, src_base);
- dst = dst_ - dst_base;
- src = src_ - src_base;
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
- bits = *(src_base + m(src + pattern_y));
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- col = colors[(bits >> bitpos) & 1];
- PUTPIXEL();
- d += (DEPTH / 8);
- bitpos = (bitpos - 1) & 7;
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
- (CirrusVGAState *s,
- uint8_t *dst_, int dst_pitch,
- int width, int height)
-{
- uint8_t *dst_base;
- uint32_t dst;
- uint32_t d, d1;
- uint32_t col;
- int x, y;
-
- get_base(dst_, s, dst_base);
- dst = dst_ - dst_base;
- col = s->cirrus_blt_fgcol;
-
- d1 = dst;
- for(y = 0; y < height; y++) {
- d = d1;
- for(x = 0; x < width; x += (DEPTH / 8)) {
- PUTPIXEL();
- d += (DEPTH / 8);
- }
- d1 += dst_pitch;
- }
-}
-
-#undef DEPTH
-#undef PUTPIXEL
diff --git a/tools/ioemu/hw/cs4231.c b/tools/ioemu/hw/cs4231.c
deleted file mode 100644
index a154685569..0000000000
--- a/tools/ioemu/hw/cs4231.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * QEMU Crystal CS4231 audio chip emulation
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug CS4231 */
-//#define DEBUG_CS
-
-/*
- * In addition to Crystal CS4231 there is a DMA controller on Sparc.
- */
-#define CS_MAXADDR 0x3f
-#define CS_REGS 16
-#define CS_DREGS 32
-#define CS_MAXDREG (CS_DREGS - 1)
-
-typedef struct CSState {
- uint32_t regs[CS_REGS];
- uint8_t dregs[CS_DREGS];
- void *intctl;
-} CSState;
-
-#define CS_RAP(s) ((s)->regs[0] & CS_MAXDREG)
-#define CS_VER 0xa0
-#define CS_CDC_VER 0x8a
-
-#ifdef DEBUG_CS
-#define DPRINTF(fmt, args...) \
- do { printf("CS: " fmt , ##args); } while (0)
-#define pic_set_irq_new(intctl, irq, level) \
- do { printf("CS: set_irq(%d): %d\n", (irq), (level)); \
- pic_set_irq_new((intctl), (irq),(level));} while (0)
-#else
-#define DPRINTF(fmt, args...)
-#endif
-
-static void cs_reset(void *opaque)
-{
- CSState *s = opaque;
-
- memset(s->regs, 0, CS_REGS * 4);
- memset(s->dregs, 0, CS_DREGS);
- s->dregs[12] = CS_CDC_VER;
- s->dregs[25] = CS_VER;
-}
-
-static uint32_t cs_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- CSState *s = opaque;
- uint32_t saddr, ret;
-
- saddr = (addr & CS_MAXADDR) >> 2;
- switch (saddr) {
- case 1:
- switch (CS_RAP(s)) {
- case 3: // Write only
- ret = 0;
- break;
- default:
- ret = s->dregs[CS_RAP(s)];
- break;
- }
- DPRINTF("read dreg[%d]: 0x%8.8x\n", CS_RAP(s), ret);
- break;
- default:
- ret = s->regs[saddr];
- DPRINTF("read reg[%d]: 0x%8.8x\n", saddr, ret);
- break;
- }
- return ret;
-}
-
-static void cs_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- CSState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & CS_MAXADDR) >> 2;
- DPRINTF("write reg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->regs[saddr], val);
- switch (saddr) {
- case 1:
- DPRINTF("write dreg[%d]: 0x%2.2x -> 0x%2.2x\n", CS_RAP(s), s->dregs[CS_RAP(s)], val);
- switch(CS_RAP(s)) {
- case 11:
- case 25: // Read only
- break;
- case 12:
- val &= 0x40;
- val |= CS_CDC_VER; // Codec version
- s->dregs[CS_RAP(s)] = val;
- break;
- default:
- s->dregs[CS_RAP(s)] = val;
- break;
- }
- break;
- case 2: // Read only
- break;
- case 4:
- if (val & 1)
- cs_reset(s);
- val &= 0x7f;
- s->regs[saddr] = val;
- break;
- default:
- s->regs[saddr] = val;
- break;
- }
-}
-
-static CPUReadMemoryFunc *cs_mem_read[3] = {
- cs_mem_readl,
- cs_mem_readl,
- cs_mem_readl,
-};
-
-static CPUWriteMemoryFunc *cs_mem_write[3] = {
- cs_mem_writel,
- cs_mem_writel,
- cs_mem_writel,
-};
-
-static void cs_save(QEMUFile *f, void *opaque)
-{
- CSState *s = opaque;
- unsigned int i;
-
- for (i = 0; i < CS_REGS; i++)
- qemu_put_be32s(f, &s->regs[i]);
-
- qemu_put_buffer(f, s->dregs, CS_DREGS);
-}
-
-static int cs_load(QEMUFile *f, void *opaque, int version_id)
-{
- CSState *s = opaque;
- unsigned int i;
-
- if (version_id > 1)
- return -EINVAL;
-
- for (i = 0; i < CS_REGS; i++)
- qemu_get_be32s(f, &s->regs[i]);
-
- qemu_get_buffer(f, s->dregs, CS_DREGS);
- return 0;
-}
-
-void cs_init(target_phys_addr_t base, int irq, void *intctl)
-{
- int cs_io_memory;
- CSState *s;
-
- s = qemu_mallocz(sizeof(CSState));
- if (!s)
- return;
-
- cs_io_memory = cpu_register_io_memory(0, cs_mem_read, cs_mem_write, s);
- cpu_register_physical_memory(base, CS_MAXADDR, cs_io_memory);
- register_savevm("cs4231", base, 1, cs_save, cs_load, s);
- qemu_register_reset(cs_reset, s);
- cs_reset(s);
-}
diff --git a/tools/ioemu/hw/cuda.c b/tools/ioemu/hw/cuda.c
deleted file mode 100644
index f3c2b56010..0000000000
--- a/tools/ioemu/hw/cuda.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * QEMU CUDA support
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* XXX: implement all timer modes */
-
-//#define DEBUG_CUDA
-//#define DEBUG_CUDA_PACKET
-
-/* Bits in B data register: all active low */
-#define TREQ 0x08 /* Transfer request (input) */
-#define TACK 0x10 /* Transfer acknowledge (output) */
-#define TIP 0x20 /* Transfer in progress (output) */
-
-/* Bits in ACR */
-#define SR_CTRL 0x1c /* Shift register control bits */
-#define SR_EXT 0x0c /* Shift on external clock */
-#define SR_OUT 0x10 /* Shift out if 1 */
-
-/* Bits in IFR and IER */
-#define IER_SET 0x80 /* set bits in IER */
-#define IER_CLR 0 /* clear bits in IER */
-#define SR_INT 0x04 /* Shift register full/empty */
-#define T1_INT 0x40 /* Timer 1 interrupt */
-#define T2_INT 0x20 /* Timer 2 interrupt */
-
-/* Bits in ACR */
-#define T1MODE 0xc0 /* Timer 1 mode */
-#define T1MODE_CONT 0x40 /* continuous interrupts */
-
-/* commands (1st byte) */
-#define ADB_PACKET 0
-#define CUDA_PACKET 1
-#define ERROR_PACKET 2
-#define TIMER_PACKET 3
-#define POWER_PACKET 4
-#define MACIIC_PACKET 5
-#define PMU_PACKET 6
-
-
-/* CUDA commands (2nd byte) */
-#define CUDA_WARM_START 0x0
-#define CUDA_AUTOPOLL 0x1
-#define CUDA_GET_6805_ADDR 0x2
-#define CUDA_GET_TIME 0x3
-#define CUDA_GET_PRAM 0x7
-#define CUDA_SET_6805_ADDR 0x8
-#define CUDA_SET_TIME 0x9
-#define CUDA_POWERDOWN 0xa
-#define CUDA_POWERUP_TIME 0xb
-#define CUDA_SET_PRAM 0xc
-#define CUDA_MS_RESET 0xd
-#define CUDA_SEND_DFAC 0xe
-#define CUDA_BATTERY_SWAP_SENSE 0x10
-#define CUDA_RESET_SYSTEM 0x11
-#define CUDA_SET_IPL 0x12
-#define CUDA_FILE_SERVER_FLAG 0x13
-#define CUDA_SET_AUTO_RATE 0x14
-#define CUDA_GET_AUTO_RATE 0x16
-#define CUDA_SET_DEVICE_LIST 0x19
-#define CUDA_GET_DEVICE_LIST 0x1a
-#define CUDA_SET_ONE_SECOND_MODE 0x1b
-#define CUDA_SET_POWER_MESSAGES 0x21
-#define CUDA_GET_SET_IIC 0x22
-#define CUDA_WAKEUP 0x23
-#define CUDA_TIMER_TICKLE 0x24
-#define CUDA_COMBINED_FORMAT_IIC 0x25
-
-#define CUDA_TIMER_FREQ (4700000 / 6)
-#define CUDA_ADB_POLL_FREQ 50
-
-/* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
-#define RTC_OFFSET 2082844800
-
-typedef struct CUDATimer {
- int index;
- uint16_t latch;
- uint16_t counter_value; /* counter value at load time */
- int64_t load_time;
- int64_t next_irq_time;
- QEMUTimer *timer;
-} CUDATimer;
-
-typedef struct CUDAState {
- /* cuda registers */
- uint8_t b; /* B-side data */
- uint8_t a; /* A-side data */
- uint8_t dirb; /* B-side direction (1=output) */
- uint8_t dira; /* A-side direction (1=output) */
- uint8_t sr; /* Shift register */
- uint8_t acr; /* Auxiliary control register */
- uint8_t pcr; /* Peripheral control register */
- uint8_t ifr; /* Interrupt flag register */
- uint8_t ier; /* Interrupt enable register */
- uint8_t anh; /* A-side data, no handshake */
-
- CUDATimer timers[2];
-
- uint8_t last_b; /* last value of B register */
- uint8_t last_acr; /* last value of B register */
-
- int data_in_size;
- int data_in_index;
- int data_out_index;
-
- SetIRQFunc *set_irq;
- int irq;
- void *irq_opaque;
- uint8_t autopoll;
- uint8_t data_in[128];
- uint8_t data_out[16];
- QEMUTimer *adb_poll_timer;
-} CUDAState;
-
-static CUDAState cuda_state;
-ADBBusState adb_bus;
-
-static void cuda_update(CUDAState *s);
-static void cuda_receive_packet_from_host(CUDAState *s,
- const uint8_t *data, int len);
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
- int64_t current_time);
-
-static void cuda_update_irq(CUDAState *s)
-{
- if (s->ifr & s->ier & (SR_INT | T1_INT)) {
- s->set_irq(s->irq_opaque, s->irq, 1);
- } else {
- s->set_irq(s->irq_opaque, s->irq, 0);
- }
-}
-
-static unsigned int get_counter(CUDATimer *s)
-{
- int64_t d;
- unsigned int counter;
-
- d = muldiv64(qemu_get_clock(vm_clock) - s->load_time,
- CUDA_TIMER_FREQ, ticks_per_sec);
- if (s->index == 0) {
- /* the timer goes down from latch to -1 (period of latch + 2) */
- if (d <= (s->counter_value + 1)) {
- counter = (s->counter_value - d) & 0xffff;
- } else {
- counter = (d - (s->counter_value + 1)) % (s->latch + 2);
- counter = (s->latch - counter) & 0xffff;
- }
- } else {
- counter = (s->counter_value - d) & 0xffff;
- }
- return counter;
-}
-
-static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
-{
-#ifdef DEBUG_CUDA
- printf("cuda: T%d.counter=%d\n",
- 1 + (ti->timer == NULL), val);
-#endif
- ti->load_time = qemu_get_clock(vm_clock);
- ti->counter_value = val;
- cuda_timer_update(s, ti, ti->load_time);
-}
-
-static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
-{
- int64_t d, next_time;
- unsigned int counter;
-
- /* current counter value */
- d = muldiv64(current_time - s->load_time,
- CUDA_TIMER_FREQ, ticks_per_sec);
- /* the timer goes down from latch to -1 (period of latch + 2) */
- if (d <= (s->counter_value + 1)) {
- counter = (s->counter_value - d) & 0xffff;
- } else {
- counter = (d - (s->counter_value + 1)) % (s->latch + 2);
- counter = (s->latch - counter) & 0xffff;
- }
-
- /* Note: we consider the irq is raised on 0 */
- if (counter == 0xffff) {
- next_time = d + s->latch + 1;
- } else if (counter == 0) {
- next_time = d + s->latch + 2;
- } else {
- next_time = d + counter;
- }
-#if 0
-#ifdef DEBUG_CUDA
- printf("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n",
- s->latch, d, next_time - d);
-#endif
-#endif
- next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) +
- s->load_time;
- if (next_time <= current_time)
- next_time = current_time + 1;
- return next_time;
-}
-
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
- int64_t current_time)
-{
- if (!ti->timer)
- return;
- if ((s->acr & T1MODE) != T1MODE_CONT) {
- qemu_del_timer(ti->timer);
- } else {
- ti->next_irq_time = get_next_irq_time(ti, current_time);
- qemu_mod_timer(ti->timer, ti->next_irq_time);
- }
-}
-
-static void cuda_timer1(void *opaque)
-{
- CUDAState *s = opaque;
- CUDATimer *ti = &s->timers[0];
-
- cuda_timer_update(s, ti, ti->next_irq_time);
- s->ifr |= T1_INT;
- cuda_update_irq(s);
-}
-
-static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr)
-{
- CUDAState *s = opaque;
- uint32_t val;
-
- addr = (addr >> 9) & 0xf;
- switch(addr) {
- case 0:
- val = s->b;
- break;
- case 1:
- val = s->a;
- break;
- case 2:
- val = s->dirb;
- break;
- case 3:
- val = s->dira;
- break;
- case 4:
- val = get_counter(&s->timers[0]) & 0xff;
- s->ifr &= ~T1_INT;
- cuda_update_irq(s);
- break;
- case 5:
- val = get_counter(&s->timers[0]) >> 8;
- cuda_update_irq(s);
- break;
- case 6:
- val = s->timers[0].latch & 0xff;
- break;
- case 7:
- /* XXX: check this */
- val = (s->timers[0].latch >> 8) & 0xff;
- break;
- case 8:
- val = get_counter(&s->timers[1]) & 0xff;
- s->ifr &= ~T2_INT;
- break;
- case 9:
- val = get_counter(&s->timers[1]) >> 8;
- break;
- case 10:
- val = s->sr;
- s->ifr &= ~SR_INT;
- cuda_update_irq(s);
- break;
- case 11:
- val = s->acr;
- break;
- case 12:
- val = s->pcr;
- break;
- case 13:
- val = s->ifr;
- if (s->ifr & s->ier)
- val |= 0x80;
- break;
- case 14:
- val = s->ier | 0x80;
- break;
- default:
- case 15:
- val = s->anh;
- break;
- }
-#ifdef DEBUG_CUDA
- if (addr != 13 || val != 0)
- printf("cuda: read: reg=0x%x val=%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- CUDAState *s = opaque;
-
- addr = (addr >> 9) & 0xf;
-#ifdef DEBUG_CUDA
- printf("cuda: write: reg=0x%x val=%02x\n", addr, val);
-#endif
-
- switch(addr) {
- case 0:
- s->b = val;
- cuda_update(s);
- break;
- case 1:
- s->a = val;
- break;
- case 2:
- s->dirb = val;
- break;
- case 3:
- s->dira = val;
- break;
- case 4:
- s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
- break;
- case 5:
- s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
- s->ifr &= ~T1_INT;
- set_counter(s, &s->timers[0], s->timers[0].latch);
- break;
- case 6:
- s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
- break;
- case 7:
- s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
- s->ifr &= ~T1_INT;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
- break;
- case 8:
- s->timers[1].latch = val;
- set_counter(s, &s->timers[1], val);
- break;
- case 9:
- set_counter(s, &s->timers[1], (val << 8) | s->timers[1].latch);
- break;
- case 10:
- s->sr = val;
- break;
- case 11:
- s->acr = val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
- cuda_update(s);
- break;
- case 12:
- s->pcr = val;
- break;
- case 13:
- /* reset bits */
- s->ifr &= ~val;
- cuda_update_irq(s);
- break;
- case 14:
- if (val & IER_SET) {
- /* set bits */
- s->ier |= val & 0x7f;
- } else {
- /* reset bits */
- s->ier &= ~val;
- }
- cuda_update_irq(s);
- break;
- default:
- case 15:
- s->anh = val;
- break;
- }
-}
-
-/* NOTE: TIP and TREQ are negated */
-static void cuda_update(CUDAState *s)
-{
- int packet_received, len;
-
- packet_received = 0;
- if (!(s->b & TIP)) {
- /* transfer requested from host */
-
- if (s->acr & SR_OUT) {
- /* data output */
- if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
- if (s->data_out_index < sizeof(s->data_out)) {
-#ifdef DEBUG_CUDA
- printf("cuda: send: %02x\n", s->sr);
-#endif
- s->data_out[s->data_out_index++] = s->sr;
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- }
- }
- } else {
- if (s->data_in_index < s->data_in_size) {
- /* data input */
- if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
- s->sr = s->data_in[s->data_in_index++];
-#ifdef DEBUG_CUDA
- printf("cuda: recv: %02x\n", s->sr);
-#endif
- /* indicate end of transfer */
- if (s->data_in_index >= s->data_in_size) {
- s->b = (s->b | TREQ);
- }
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- }
- }
- }
- } else {
- /* no transfer requested: handle sync case */
- if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) {
- /* update TREQ state each time TACK change state */
- if (s->b & TACK)
- s->b = (s->b | TREQ);
- else
- s->b = (s->b & ~TREQ);
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- } else {
- if (!(s->last_b & TIP)) {
- /* handle end of host to cuda transfert */
- packet_received = (s->data_out_index > 0);
- /* always an IRQ at the end of transfert */
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- }
- /* signal if there is data to read */
- if (s->data_in_index < s->data_in_size) {
- s->b = (s->b & ~TREQ);
- }
- }
- }
-
- s->last_acr = s->acr;
- s->last_b = s->b;
-
- /* NOTE: cuda_receive_packet_from_host() can call cuda_update()
- recursively */
- if (packet_received) {
- len = s->data_out_index;
- s->data_out_index = 0;
- cuda_receive_packet_from_host(s, s->data_out, len);
- }
-}
-
-static void cuda_send_packet_to_host(CUDAState *s,
- const uint8_t *data, int len)
-{
-#ifdef DEBUG_CUDA_PACKET
- {
- int i;
- printf("cuda_send_packet_to_host:\n");
- for(i = 0; i < len; i++)
- printf(" %02x", data[i]);
- printf("\n");
- }
-#endif
- memcpy(s->data_in, data, len);
- s->data_in_size = len;
- s->data_in_index = 0;
- cuda_update(s);
- s->ifr |= SR_INT;
- cuda_update_irq(s);
-}
-
-static void cuda_adb_poll(void *opaque)
-{
- CUDAState *s = opaque;
- uint8_t obuf[ADB_MAX_OUT_LEN + 2];
- int olen;
-
- olen = adb_poll(&adb_bus, obuf + 2);
- if (olen > 0) {
- obuf[0] = ADB_PACKET;
- obuf[1] = 0x40; /* polled data */
- cuda_send_packet_to_host(s, obuf, olen + 2);
- }
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock(vm_clock) +
- (ticks_per_sec / CUDA_ADB_POLL_FREQ));
-}
-
-static void cuda_receive_packet(CUDAState *s,
- const uint8_t *data, int len)
-{
- uint8_t obuf[16];
- int ti, autopoll;
-
- switch(data[0]) {
- case CUDA_AUTOPOLL:
- autopoll = (data[1] != 0);
- if (autopoll != s->autopoll) {
- s->autopoll = autopoll;
- if (autopoll) {
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock(vm_clock) +
- (ticks_per_sec / CUDA_ADB_POLL_FREQ));
- } else {
- qemu_del_timer(s->adb_poll_timer);
- }
- }
- obuf[0] = CUDA_PACKET;
- obuf[1] = data[1];
- cuda_send_packet_to_host(s, obuf, 2);
- break;
- case CUDA_GET_TIME:
- case CUDA_SET_TIME:
- /* XXX: add time support ? */
- ti = time(NULL) + RTC_OFFSET;
- obuf[0] = CUDA_PACKET;
- obuf[1] = 0;
- obuf[2] = 0;
- obuf[3] = ti >> 24;
- obuf[4] = ti >> 16;
- obuf[5] = ti >> 8;
- obuf[6] = ti;
- cuda_send_packet_to_host(s, obuf, 7);
- break;
- case CUDA_FILE_SERVER_FLAG:
- case CUDA_SET_DEVICE_LIST:
- case CUDA_SET_AUTO_RATE:
- case CUDA_SET_POWER_MESSAGES:
- obuf[0] = CUDA_PACKET;
- obuf[1] = 0;
- cuda_send_packet_to_host(s, obuf, 2);
- break;
- case CUDA_POWERDOWN:
- obuf[0] = CUDA_PACKET;
- obuf[1] = 0;
- cuda_send_packet_to_host(s, obuf, 2);
- qemu_system_shutdown_request();
- break;
- default:
- break;
- }
-}
-
-static void cuda_receive_packet_from_host(CUDAState *s,
- const uint8_t *data, int len)
-{
-#ifdef DEBUG_CUDA_PACKET
- {
- int i;
- printf("cuda_receive_packet_from_host:\n");
- for(i = 0; i < len; i++)
- printf(" %02x", data[i]);
- printf("\n");
- }
-#endif
- switch(data[0]) {
- case ADB_PACKET:
- {
- uint8_t obuf[ADB_MAX_OUT_LEN + 2];
- int olen;
- olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1);
- if (olen > 0) {
- obuf[0] = ADB_PACKET;
- obuf[1] = 0x00;
- } else {
- /* error */
- obuf[0] = ADB_PACKET;
- obuf[1] = -olen;
- olen = 0;
- }
- cuda_send_packet_to_host(s, obuf, olen + 2);
- }
- break;
- case CUDA_PACKET:
- cuda_receive_packet(s, data + 1, len - 1);
- break;
- }
-}
-
-static void cuda_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static void cuda_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static uint32_t cuda_readw (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static uint32_t cuda_readl (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static CPUWriteMemoryFunc *cuda_write[] = {
- &cuda_writeb,
- &cuda_writew,
- &cuda_writel,
-};
-
-static CPUReadMemoryFunc *cuda_read[] = {
- &cuda_readb,
- &cuda_readw,
- &cuda_readl,
-};
-
-int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq)
-{
- CUDAState *s = &cuda_state;
- int cuda_mem_index;
-
- s->set_irq = set_irq;
- s->irq_opaque = irq_opaque;
- s->irq = irq;
-
- s->timers[0].index = 0;
- s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s);
- s->timers[0].latch = 0xffff;
- set_counter(s, &s->timers[0], 0xffff);
-
- s->timers[1].index = 1;
- s->timers[1].latch = 0;
- // s->ier = T1_INT | SR_INT;
- s->ier = 0;
- set_counter(s, &s->timers[1], 0xffff);
-
- s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
- cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
- return cuda_mem_index;
-}
diff --git a/tools/ioemu/hw/dma.c b/tools/ioemu/hw/dma.c
deleted file mode 100644
index 69fdf49f8d..0000000000
--- a/tools/ioemu/hw/dma.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * QEMU DMA emulation
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* #define DEBUG_DMA */
-
-#define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#ifdef DEBUG_DMA
-#define lwarn(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define linfo(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define ldebug(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#else
-#define lwarn(...)
-#define linfo(...)
-#define ldebug(...)
-#endif
-
-#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-struct dma_regs {
- int now[2];
- uint16_t base[2];
- uint8_t mode;
- uint8_t page;
- uint8_t pageh;
- uint8_t dack;
- uint8_t eop;
- DMA_transfer_handler transfer_handler;
- void *opaque;
-};
-
-#define ADDR 0
-#define COUNT 1
-
-static struct dma_cont {
- uint8_t status;
- uint8_t command;
- uint8_t mask;
- uint8_t flip_flop;
- int dshift;
- struct dma_regs regs[4];
-} dma_controllers[2];
-
-enum {
- CMD_MEMORY_TO_MEMORY = 0x01,
- CMD_FIXED_ADDRESS = 0x02,
- CMD_BLOCK_CONTROLLER = 0x04,
- CMD_COMPRESSED_TIME = 0x08,
- CMD_CYCLIC_PRIORITY = 0x10,
- CMD_EXTENDED_WRITE = 0x20,
- CMD_LOW_DREQ = 0x40,
- CMD_LOW_DACK = 0x80,
- CMD_NOT_SUPPORTED = CMD_MEMORY_TO_MEMORY | CMD_FIXED_ADDRESS
- | CMD_COMPRESSED_TIME | CMD_CYCLIC_PRIORITY | CMD_EXTENDED_WRITE
- | CMD_LOW_DREQ | CMD_LOW_DACK
-
-};
-
-static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
-
-static void write_page (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].page = data;
-}
-
-static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].pageh = data;
-}
-
-static uint32_t read_page (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].page;
-}
-
-static uint32_t read_pageh (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].pageh;
-}
-
-static inline void init_chan (struct dma_cont *d, int ichan)
-{
- struct dma_regs *r;
-
- r = d->regs + ichan;
- r->now[ADDR] = r->base[ADDR] << d->dshift;
- r->now[COUNT] = 0;
-}
-
-static inline int getff (struct dma_cont *d)
-{
- int ff;
-
- ff = d->flip_flop;
- d->flip_flop = !ff;
- return ff;
-}
-
-static uint32_t read_chan (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan, nreg, iport, ff, val, dir;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
-
- dir = ((r->mode >> 5) & 1) ? -1 : 1;
- ff = getff (d);
- if (nreg)
- val = (r->base[COUNT] << d->dshift) - r->now[COUNT];
- else
- val = r->now[ADDR] + r->now[COUNT] * dir;
-
- ldebug ("read_chan %#x -> %d\n", iport, val);
- return (val >> (d->dshift + (ff << 3))) & 0xff;
-}
-
-static void write_chan (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan, nreg;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
- if (getff (d)) {
- r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00);
- init_chan (d, ichan);
- } else {
- r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff);
- }
-}
-
-static void write_cont (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan = 0;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* command */
- if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
- dolog ("command %#x not supported\n", data);
- return;
- }
- d->command = data;
- break;
-
- case 0x09:
- ichan = data & 3;
- if (data & 4) {
- d->status |= 1 << (ichan + 4);
- }
- else {
- d->status &= ~(1 << (ichan + 4));
- }
- d->status &= ~(1 << ichan);
- break;
-
- case 0x0a: /* single mask */
- if (data & 4)
- d->mask |= 1 << (data & 3);
- else
- d->mask &= ~(1 << (data & 3));
- break;
-
- case 0x0b: /* mode */
- {
- ichan = data & 3;
-#ifdef DEBUG_DMA
- {
- int op, ai, dir, opmode;
- op = (data >> 2) & 3;
- ai = (data >> 4) & 1;
- dir = (data >> 5) & 1;
- opmode = (data >> 6) & 3;
-
- linfo ("ichan %d, op %d, ai %d, dir %d, opmode %d\n",
- ichan, op, ai, dir, opmode);
- }
-#endif
- d->regs[ichan].mode = data;
- break;
- }
-
- case 0x0c: /* clear flip flop */
- d->flip_flop = 0;
- break;
-
- case 0x0d: /* reset */
- d->flip_flop = 0;
- d->mask = ~0;
- d->status = 0;
- d->command = 0;
- break;
-
- case 0x0e: /* clear mask for all channels */
- d->mask = 0;
- break;
-
- case 0x0f: /* write mask for all channels */
- d->mask = data;
- break;
-
- default:
- dolog ("unknown iport %#x\n", iport);
- break;
- }
-
-#ifdef DEBUG_DMA
- if (0xc != iport) {
- linfo ("write_cont: nport %#06x, ichan % 2d, val %#06x\n",
- nport, ichan, data);
- }
-#endif
-}
-
-static uint32_t read_cont (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int iport, val;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* status */
- val = d->status;
- d->status &= 0xf0;
- break;
- case 0x0f: /* mask */
- val = d->mask;
- break;
- default:
- val = 0;
- break;
- }
-
- ldebug ("read_cont: nport %#06x, iport %#04x val %#x\n", nport, iport, val);
- return val;
-}
-
-int DMA_get_channel_mode (int nchan)
-{
- return dma_controllers[nchan > 3].regs[nchan & 3].mode;
-}
-
-void DMA_hold_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("held cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status |= 1 << (ichan + 4);
-}
-
-void DMA_release_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("released cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status &= ~(1 << (ichan + 4));
-}
-
-static void channel_run (int ncont, int ichan)
-{
- int n;
- struct dma_regs *r = &dma_controllers[ncont].regs[ichan];
-#ifdef DEBUG_DMA
- int dir, opmode;
-
- dir = (r->mode >> 5) & 1;
- opmode = (r->mode >> 6) & 3;
-
- if (dir) {
- dolog ("DMA in address decrement mode\n");
- }
- if (opmode != 1) {
- dolog ("DMA not in single mode select %#x\n", opmode);
- }
-#endif
-
- r = dma_controllers[ncont].regs + ichan;
- if (r->transfer_handler == NULL)
- return;
- n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
- r->now[COUNT], (r->base[COUNT] + 1) << ncont);
- r->now[COUNT] = n;
- ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
-}
-
-void DMA_run (void)
-{
- struct dma_cont *d;
- int icont, ichan;
-
- d = dma_controllers;
-
- for (icont = 0; icont < 2; icont++, d++) {
- for (ichan = 0; ichan < 4; ichan++) {
- int mask;
-
- mask = 1 << ichan;
-
- if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4))))
- channel_run (icont, ichan);
- }
- }
-}
-
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
-{
- struct dma_regs *r;
- int ichan, ncont;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
-
- r = dma_controllers[ncont].regs + ichan;
- r->transfer_handler = transfer_handler;
- r->opaque = opaque;
-}
-
-int DMA_read_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_read (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len >> 1; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_read (addr + pos, buf, len);
-
- return len;
-}
-
-int DMA_write_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_write (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_write (addr + pos, buf, len);
-
- return len;
-}
-
-/* request the emulator to transfer a new DMA memory block ASAP */
-void DMA_schedule(int nchan)
-{
- CPUState *env = cpu_single_env;
- if (env)
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-}
-
-static void dma_reset(void *opaque)
-{
- struct dma_cont *d = opaque;
- write_cont (d, (0x0d << d->dshift), 0);
-}
-
-static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
-{
- dolog ("unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n",
- nchan, dma_pos, dma_len);
- return dma_pos;
-}
-
-/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
-static void dma_init2(struct dma_cont *d, int base, int dshift,
- int page_base, int pageh_base)
-{
- const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
- int i;
-
- d->dshift = dshift;
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
- register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
- }
- for (i = 0; i < LENOFA (page_port_list); i++) {
- register_ioport_write (page_base + page_port_list[i], 1, 1,
- write_page, d);
- register_ioport_read (page_base + page_port_list[i], 1, 1,
- read_page, d);
- if (pageh_base >= 0) {
- register_ioport_write (pageh_base + page_port_list[i], 1, 1,
- write_pageh, d);
- register_ioport_read (pageh_base + page_port_list[i], 1, 1,
- read_pageh, d);
- }
- }
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + ((i + 8) << dshift), 1, 1,
- write_cont, d);
- register_ioport_read (base + ((i + 8) << dshift), 1, 1,
- read_cont, d);
- }
- qemu_register_reset(dma_reset, d);
- dma_reset(d);
- for (i = 0; i < LENOFA (d->regs); ++i) {
- d->regs[i].transfer_handler = dma_phony_handler;
- }
-}
-
-static void dma_save (QEMUFile *f, void *opaque)
-{
- struct dma_cont *d = opaque;
- int i;
-
- /* qemu_put_8s (f, &d->status); */
- qemu_put_8s (f, &d->command);
- qemu_put_8s (f, &d->mask);
- qemu_put_8s (f, &d->flip_flop);
- qemu_put_be32s (f, &d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_put_be32s (f, &r->now[0]);
- qemu_put_be32s (f, &r->now[1]);
- qemu_put_be16s (f, &r->base[0]);
- qemu_put_be16s (f, &r->base[1]);
- qemu_put_8s (f, &r->mode);
- qemu_put_8s (f, &r->page);
- qemu_put_8s (f, &r->pageh);
- qemu_put_8s (f, &r->dack);
- qemu_put_8s (f, &r->eop);
- }
-}
-
-static int dma_load (QEMUFile *f, void *opaque, int version_id)
-{
- struct dma_cont *d = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- /* qemu_get_8s (f, &d->status); */
- qemu_get_8s (f, &d->command);
- qemu_get_8s (f, &d->mask);
- qemu_get_8s (f, &d->flip_flop);
- qemu_get_be32s (f, &d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_get_be32s (f, &r->now[0]);
- qemu_get_be32s (f, &r->now[1]);
- qemu_get_be16s (f, &r->base[0]);
- qemu_get_be16s (f, &r->base[1]);
- qemu_get_8s (f, &r->mode);
- qemu_get_8s (f, &r->page);
- qemu_get_8s (f, &r->pageh);
- qemu_get_8s (f, &r->dack);
- qemu_get_8s (f, &r->eop);
- }
- return 0;
-}
-
-void DMA_init (int high_page_enable)
-{
- dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
- high_page_enable ? 0x480 : -1);
- dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
- high_page_enable ? 0x488 : -1);
- register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]);
- register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]);
-}
diff --git a/tools/ioemu/hw/e100.c b/tools/ioemu/hw/e100.c
deleted file mode 100644
index 79cd4aa06e..0000000000
--- a/tools/ioemu/hw/e100.c
+++ /dev/null
@@ -1,2605 +0,0 @@
-/*
- * QEMU E100(i82557) ethernet card emulation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Copyright (c) 2006-2007 Stefan Weil
- * Copyright (c) 2006-2007 Zhang Xin(xing.z.zhang@intel.com)
- *
- * Support OS:
- * x86 linux and windows
- * PAE linux and windows
- * x86_64 linux and windows
- * IA64 linux and windows
- *
- * Untested:
- * Big-endian machine
- *
- * References:
- *
- * Intel 8255x 10/100 Mbps Ethernet Controller Family
- * Open Source Software Developer Manual
- */
-
-#include <assert.h>
-#include "vl.h"
-
-enum
-{
- E100_PCI_VENDOR_ID = 0x00, /* 16 bits */
- E100_PCI_DEVICE_ID = 0x02, /* 16 bits */
- E100_PCI_COMMAND = 0x04, /* 16 bits */
- E100_PCI_STATUS = 0x06, /* 16 bits */
- E100_PCI_REVISION_ID = 0x08, /* 8 bits */
- E100_PCI_CLASS_CODE = 0x0b, /* 8 bits */
- E100_PCI_SUBCLASS_CODE = 0x0a, /* 8 bits */
- E100_PCI_HEADER_TYPE = 0x0e, /* 8 bits */
- E100_PCI_BASE_ADDRESS_0 = 0x10, /* 32 bits */
- E100_PCI_BASE_ADDRESS_1 = 0x14, /* 32 bits */
- E100_PCI_BASE_ADDRESS_2 = 0x18, /* 32 bits */
- E100_PCI_BASE_ADDRESS_3 = 0x1c, /* 32 bits */
- E100_PCI_BASE_ADDRESS_4 = 0x20, /* 32 bits */
- E100_PCI_BASE_ADDRESS_5 = 0x24 /* 32 bits */
-}PCI_CONFIGURE_SPACE;
-
-#define PCI_CONFIG_8(offset, value) \
- (*(uint8_t *)&pci_conf[offset] = (value))
-#define PCI_CONFIG_16(offset, value) \
- (*(uint16_t *)&pci_conf[offset] = cpu_to_le16(value))
-#define PCI_CONFIG_32(offset, value) \
- (*(uint32_t *)&pci_conf[offset] = cpu_to_le32(value))
-
-// Alias for Control/Status register read/write
-#define CSR_STATUS scb_status
-#define CSR_CMD scb_cmd
-#define CSR_POINTER scb_pointer
-#define CSR_PORT port
-#define CSR_EEPROM eeprom_ctrl
-#define CSR_MDI mdi_ctrl
-#define CSR_PM pm_reg
-
-#define CSR(class, field) \
- (s->pci_mem.csr.class.u.field)
-#define CSR_VAL(class) \
- (s->pci_mem.csr.class.val)
-
-#define CSR_READ(x, type) \
- ({ \
- type t; \
- memcpy(&t, &s->pci_mem.mem[x], sizeof(type)); \
- t; \
- })
-
-#define CSR_WRITE(x, val, type) \
- ({ \
- type t = val; \
- memcpy(&s->pci_mem.mem[x], &t, sizeof(type)); \
- })
-
-#define SET_CU_STATE(val) \
- (CSR(CSR_STATUS, cus) = val)
-#define GET_CU_STATE \
- (CSR(CSR_STATUS, cus))
-
-#define SET_RU_STATE(val) \
- (CSR(CSR_STATUS, rus) = val)
-#define GET_RU_STATE \
- (CSR(CSR_STATUS, rus))
-
-#define KiB 1024
-
-#define EEPROM_SIZE 64
-
-#define BIT(n) (1U << (n))
-
-/* debug E100 card */
-//#define DEBUG_E100
-
-#ifdef DEBUG_E100
-#define logout(fmt, args...) fprintf(stderr, "EE100\t%-28s" fmt, __func__, ##args)
-#else
-#define logout(fmt, args...) ((void)0)
-#endif
-
-#define MAX_ETH_FRAME_SIZE 1514
-
-/* This driver supports several different devices which are declared here. */
-#define i82551 0x82551
-#define i82557B 0x82557b
-#define i82557C 0x82557c
-#define i82558B 0x82558b
-#define i82559C 0x82559c
-#define i82559ER 0x82559e
-#define i82562 0x82562
-
-#define PCI_MEM_SIZE (4 * KiB)
-#define PCI_IO_SIZE (64)
-#define PCI_FLASH_SIZE (128 * KiB)
-
-enum
-{
- OP_READ,
- OP_WRITE,
-} OPERTAION_DIRECTION;
-
-/* The SCB accepts the following controls for the Tx and Rx units: */
-enum
-{
- CU_NOP = 0x0000, /* No operation */
- CU_START = 0x0010, /* CU start */
- CU_RESUME = 0x0020, /* CU resume */
- CU_STATSADDR = 0x0040, /* Load dump counters address */
- CU_SHOWSTATS = 0x0050, /* Dump statistical counters */
- CU_CMD_BASE = 0x0060, /* Load CU base address */
- CU_DUMPSTATS = 0x0070, /* Dump and reset statistical counters */
- CU_S_RESUME = 0x00a0 /* CU static resume */
-}CONTROL_UNIT_COMMAND;
-
-enum
-{
- RU_NOP = 0x0000,
- RU_START = 0x0001,
- RU_RESUME = 0x0002,
- RU_DMA_REDIRECT = 0x0003,
- RU_ABORT = 0x0004,
- RU_LOAD_HDS = 0x0005,
- RU_ADDR_LOAD = 0x0006,
- RU_RESUMENR = 0x0007,
-}RECEIVE_UNIT_COMMAND;
-
-/* SCB status word descriptions */
-enum
-{
- CU_IDLE = 0,
- CU_SUSPENDED = 1,
- CU_LPQ_ACTIVE = 2,
- CU_HQP_ACTIVE = 3
-} CONTROL_UINT_STATE;
-
-enum
-{
- RU_IDLE = 0,
- RU_SUSPENDED = 1,
- RU_NO_RESOURCES =2,
- RU_READY = 4
-} RECEIVE_UNIT_STATE;
-
-enum
-{
- PORT_SOFTWARE_RESET = 0,
- PORT_SELF_TEST = 1,
- PORT_SELECTIVE_RESET = 2,
- PORT_DUMP = 3,
- PORT_DUMP_WAKE_UP = 7,
-}SCB_PORT_SELECTION_FUNCTION;
-
-enum
-{
- CBL_NOP = 0,
- CBL_IASETUP = 1,
- CBL_CONFIGURE = 2,
- CBL_MULTCAST_ADDR_SETUP = 3,
- CBL_TRANSMIT = 4,
- CBL_LOAD_MICROCODE = 5,
- CBL_DUMP = 6,
- CBL_DIAGNOSE = 7,
-}CBL_COMMAND;
-
-enum
-{
- SCB_STATUS = 0, /* SCB base + 0x00h, RU states + CU states + STAT/ACK */
- SCB_ACK = 1, /* SCB ack/stat */
- SCB_CMD = 2, /* RU command + CU command + S bit + M bit */
- SCB_INTERRUPT_MASK = 3, /* Interrupts mask bits */
- SCB_POINTER = 4, /* SCB general pointer, depending on command type */
- SCB_PORT = 8, /* SCB port register */
- SCB_EEPROM = 0xe, /* SCB eeprom control register */
- SCB_MDI =0x10, /* SCB MDI control register */
-} CSR_OFFSETS;
-
-enum
-{
- EEPROM_SK = 0x01,
- EEPROM_CS = 0x02,
- EEPROM_DI = 0x04,
- EEPROM_DO = 0x08,
-} EEPROM_CONTROL_REGISTER;
-
-enum
-{
- EEPROM_READ = 0x2,
- EEPROM_WRITE = 0x1,
- EEPROM_ERASE = 0x3,
-} EEPROM_OPCODE;
-
-enum
-{
- MDI_WRITE = 0x1,
- MDI_READ = 0x2,
-} MDI_OPCODE;
-
-enum
-{
- INT_FCP = BIT(8),
- INT_SWI = BIT(10),
- INT_MDI = BIT(11),
- INT_RNR = BIT(12),
- INT_CNA = BIT(13),
- INT_FR = BIT(14),
- INT_CX_TNO = BIT(15),
-} E100_INTERRUPT;
-
-enum
-{
- CSR_MEMORY_BASE,
- CSR_IO_BASE,
- FLASH_MEMORY_BASE,
- REGION_NUM
-}E100_PCI_MEMORY_REGION;
-
-typedef struct {
- uint32_t tx_good_frames, // Good frames transmitted
- tx_max_collisions, // Fatal frames -- had max collisions
- tx_late_collisions, // Fatal frames -- had a late coll.
- tx_underruns, // Transmit underruns (fatal or re-transmit)
- tx_lost_crs, // Frames transmitted without CRS
- tx_deferred, // Deferred transmits
- tx_single_collisions, // Transmits that had 1 and only 1 coll.
- tx_multiple_collisions,// Transmits that had multiple coll.
- tx_total_collisions, // Transmits that had 1+ collisions.
-
- rx_good_frames, // Good frames received
- rx_crc_errors, // Aligned frames that had a CRC error
- rx_alignment_errors, // Receives that had alignment errors
- rx_resource_errors, // Good frame dropped due to lack of resources
- rx_overrun_errors, // Overrun errors - bus was busy
- rx_cdt_errors, // Received frames that encountered coll.
- rx_short_frame_errors, // Received frames that were to short
-
- complete_word; // A005h indicates dump cmd completion,
- // A007h indicates dump and reset cmd completion.
-
-// TODO: Add specific field for i82558, i82559
-} __attribute__ ((packed)) e100_stats_t;
-
-#define EEPROM_I82557_ADDRBIT 6
-/* Below data is dumped from a real I82557 card */
-static const uint16_t eeprom_i82557[] =
-{
- 0x300, 0xe147, 0x2fa4, 0x203, 0x0, 0x201, 0x4701, 0x0, 0x7414, 0x6207,
- 0x4082, 0xb, 0x8086, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x128, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc374,
-};
-
-static const uint8_t e100_pci_configure[] =
-{
- 0x86, 0x80, 0x29, 0x12, 0x17, 0x00, 0x90, 0x02, 0x08, 0x00, 0x00, 0x02, 0x10, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x50, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x80, 0x0b, 0x00,
- 0x00, 0x00, 0xf0, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x08, 0x38,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x22, 0xfe,
- 0x00, 0x40, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-typedef struct
-{
-#define OPCODE 0xb
-#define ADDR 0xc
-#define DATA 0xd
-#define NOP 0xe
-
-#define EEPROM_RESET_ALL 0xfe
-#define EEPROM_SELECT_RESET 0xff
- uint8_t start_bit;
- uint8_t opcode;
- uint8_t address;
- uint16_t data; //This must be 16 bit represents a register in eeprom
-
- uint32_t val;
- uint32_t val_len;
- uint8_t val_type; // What data type is in DI. opcode?address?data?
-
- uint8_t cs;
- uint8_t sk;
-
- // This two fileds only be reset when device init
- uint16_t addr_len;
- uint16_t contents[256]; // 256 is enough to all device(i82557 ... i82559)
-} eeprom_t;
-
-// Control/Status register structure
-typedef struct
-{
- /* SCB status word */
- union
- {
- uint16_t val;
- struct
- {
- uint8_t rs1:2; // Reserved
- uint8_t rus:4; // RU status
- uint8_t cus:2; // CU status
- uint8_t stat_ack; // Stat/ACK
- }u;
- }scb_status;
-
- /* SCB command word */
- union
- {
- uint16_t val;
- struct
- {
- uint8_t ru_cmd:3; // RU command
- uint8_t rs1:1; // Reserved
- uint8_t cu_cmd:4; // CU command
- uint8_t m:1; // Interrup mask bit(1:mask all interrupt)
- uint8_t si:1; // Use for software cause interrupt
- uint8_t simb:6; // Specific interrupt mask bit
- }u;
- }scb_cmd;
-
- /* SCB general pointer */
- union
- {
- uint32_t val;
- struct
- {
- uint32_t scb_ptr;
- }u;
- }scb_pointer;
-
- /* Port interface */
- union
- {
- uint32_t val;
- struct
- {
- uint8_t opcode:4; // Op code for function selection
- uint32_t ptr:28; // Result pointer
- }u;
- }port;
-
- uint16_t rs1; // Reserved
-
- /* EEPROM control register */
- union
- {
- uint16_t val;
- struct
- {
- uint8_t eesk:1; // Serial clock
- uint8_t eecs:1; // Chip select
- uint8_t eedi:1; // Serial data in
- uint8_t eedo:1; // Serial data out
- uint8_t rs1:4; // Reserved
- uint8_t data;
- }u;
- }eeprom_ctrl;
-
- /* MDI control register */
- union
- {
- uint32_t val;
- struct
- {
- uint16_t data; // Data
- uint8_t regaddr:5; // PHY register address
- uint8_t phyaddr:5; // PHY address
- uint8_t opcode:2; // Opcode
- uint8_t r:1; // Ready
- uint8_t ie:1; // Interrup enable
- uint8_t rs1:2; // Reserved
- }u;
- } mdi_ctrl;
-
- /* Receive byte counter register */
- uint32_t rx_byte_counter;
-
- /* Early receive interrupt register */
- uint8_t early_interrupt;
-
- /* Flow control register */
- union
- {
- uint16_t val;
- }flow_ctrl;
-
- /* Power management driver register */
- union
- {
- uint8_t val;
- struct
- {
- uint8_t pme_s:1; // PME status
- uint8_t tco_r:1; // TCO request
- uint8_t f_tco_i:1; // Force TCO indication
- uint8_t tco_re:1; // TCO ready
- uint8_t rs1:1; // Reserved
- uint8_t isp:1; // Intersting packet
- uint8_t mg:1; // Magic packet
- uint8_t lsci:1; // Link status change indication
- }u;
- }pm_reg;
-
- /* General control register */
- uint8_t gen_ctrl;
-
- /* General status register */
- uint8_t gen_status;
-
- /* These are reserved or we don't support register */
- uint8_t others[30];
-} __attribute__ ((packed)) csr_t;
-
-typedef struct
-{
- uint8_t byte_count;
- uint8_t rx_fifo_limit:4;
- uint8_t tx_fifo_limit:4;
- uint8_t adpt_inf_spacing;
- uint8_t rs1;
- uint8_t rx_dma_max_bytes;
- uint8_t tx_dma_max_bytes:7;
- uint8_t dmbc_en:1;
- uint8_t late_scb:1,
- rs2:1,
- tno_intr:1,
- ci_intr:1,
- rs3:1,
- rs4:1,
- dis_overrun_rx:1,
- save_bad_frame:1;
- uint8_t dis_short_rx:1,
- underrun_retry:2,
- rs5:5;
- uint8_t mii:1,
- rs6:7;
- uint8_t rs7;
- uint8_t rs8:3,
- nsai:1,
- preamble_len:2,
- loopback:2;
- uint8_t linear_prio:3,
- rs9:5;
- uint8_t pri_mode:1,
- rs10:3,
- interframe_spacing:4;
- uint16_t rs11;
- uint8_t promiscuous:1,
- broadcast_dis:1,
- rs12:5,
- crs_cdt:1;
- uint16_t rs13;
- uint8_t strip:1,
- padding:1,
- rx_crc:1,
- rs14:5;
- uint8_t rs15:6,
- force_fdx:1,
- fdx_en:1;
- uint8_t rs16:6,
- mul_ia:2;
- uint8_t rs17:3,
- mul_all:1,
- rs18:4;
-} __attribute__ ((packed)) i82557_cfg_t;
-
-typedef struct {
- VLANClientState *vc;
- PCIDevice *pci_dev;
- int mmio_index;
- uint8_t scb_stat; /* SCB stat/ack byte */
- uint32_t region_base_addr[REGION_NUM]; /* PCI region addresses */
- uint8_t macaddr[6];
- uint16_t mdimem[32];
- eeprom_t eeprom;
- uint32_t device; /* device variant */
-
- uint8_t mult_list[8]; /* Multicast address list */
- int is_multcast_enable;
-
- /* (cu_base + cu_offset) address the next command block in the command block list. */
- uint32_t cu_base; /* CU base address */
- uint32_t cu_offset; /* CU address offset */
- uint32_t cu_next; /* Point to next command when CU go to suspend */
-
- /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */
- uint32_t ru_base; /* RU base address */
- uint32_t ru_offset; /* RU address offset */
-
- uint32_t statsaddr; /* pointer to e100_stats_t */
-
- e100_stats_t statistics; /* statistical counters */
-
- /* Configuration bytes. */
- i82557_cfg_t config;
-
- /* FIFO buffer of card. The packet that need to be sent buffered in it */
- uint8_t pkt_buf[MAX_ETH_FRAME_SIZE+4];
- /* Data length in FIFO buffer */
- int pkt_buf_len;
-
- /* Data in mem is always in the byte order of the controller (le). */
- union
- {
- csr_t csr;
- uint8_t mem[PCI_MEM_SIZE];
- }pci_mem;
-
-} E100State;
-
-/* CB structure, filled by device driver
- * This is a common structure of CB. In some
- * special case such as TRANSMIT command, the
- * reserved field will be used.
- */
-struct control_block
-{
- uint16_t rs1:13; /* reserved */
- uint8_t ok:1; /* 1:command executed without error, otherwise 0 */
- uint8_t rs2:1;
- uint8_t c:1; /* execution status. set by device, clean by software */
- uint8_t cmd:3; /* command */
- uint16_t rs3:10; /* most time equal to 0 */
- uint8_t i:1; /* whether trigger interrupt after execution. 1:yes; 0:no */
- uint8_t s:1; /* suspend */
- uint8_t el:1; /* end flag */
- uint32_t link_addr;
-} __attribute__ ((packed));
-
-typedef struct
-{
- uint32_t tx_desc_addr; /* transmit buffer decsriptor array address. */
- uint16_t tcb_bytes:14; /* transmit command block byte count (in lower 14 bits)*/
- uint8_t rs1:1;
- uint8_t eof:1;
- uint8_t tx_threshold; /* transmit threshold */
- uint8_t tbd_num; /* TBD number */
-} __attribute__ ((packed)) tbd_t;
-
-/* Receive frame descriptore structure */
-typedef struct
-{
- uint16_t status:13; // Result of receive opration
- uint8_t ok:1; // 1:receive without error, otherwise 0
- uint8_t rs1:1;
- uint8_t c:1; // 1:receive complete
- uint8_t rs2:3;
- uint8_t sf:1; // 0:simplified mode
- uint8_t h:1; // 1:header RFD
- uint16_t rs3:9;
- uint8_t s:1; // 1:go to suspend
- uint8_t el:1; // 1:last RFD
- uint32_t link_addr; // Add on RU base point to next RFD
- uint32_t rs4;
- uint16_t count:14; // Number of bytes written into data area
- uint8_t f:1; // Set by device when count field update
- uint8_t eof:1; // Set by device when placing data into data area complete
- uint16_t size:14; // Buffer size (even number)
- uint8_t rs5:2;
-} __attribute__ ((packed)) rfd_t;
-
-enum
-{
- RX_COLLISION = BIT(0), // 1:Receive collision detected
- RX_IA_MATCH = BIT(1), // 0:Receive frame match individual address
- RX_NO_MATCH = BIT(2), // 1:Receive frame match no address
- RX_ERR = BIT(4), // 1:Receive frame error
- RX_TYPE = BIT(5), // 1:Receive frame is a type frame
- RX_SHORT = BIT(7), // 1:Receive frame is too short
- RX_DMA_ERR = BIT(8),
- RX_LARGE = BIT(9), // 1:Receive frame is too large
- RX_CRC_ERR = BIT(10),
-} RFD_STATUS;
-
-typedef struct PCIE100State {
- PCIDevice dev;
- E100State e100;
-} PCIE100State;
-
-/* Default values for MDI (PHY) registers */
-static const uint16_t e100_mdi_default[] = {
- /* MDI Registers 0 - 6, 7 */
- 0x3000, 0x780d, 0x02a8, 0x0154, 0x05e1, 0x0000, 0x0000, 0x0000,
- /* MDI Registers 8 - 15 */
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- /* MDI Registers 16 - 31 */
- 0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-};
-
-static const uint8_t broadcast_macaddr[6] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-/* Debugging codes */
-#ifdef DEBUG_E100
-
-static void e100_dump(char *comment, uint8_t *info, int len)
-{
- int i;
-
- if ( !comment || !info )
- return;
-
- fprintf(stderr, "EE100\t%-24s%s", __func__, comment);
- for ( i=0; i<len; i++ )
- fprintf(stderr, "%x ", info[i]);
-
- fprintf(stderr, "\n");
-}
-
-static const char *regname[] =
-{
- [0] = "SCB Status", [1] = "SCB Ack",
- [2] = "SCB Cmd", [3] = "SCB Interrupt Mask",
- [4] = "SCB Pointer", [8] = "SCB Port",
- [0xc] = "SCB Flash", [0xe] = "SCB Eeprom",
- [0x10] = "SCB Ctrl MDI", [0x14] = "SCB Early RX",
-};
-#define SCBNAME(x) \
- ( (x) < (sizeof(regname) / sizeof(regname[0])) ? regname[(x)] : "Unknown SCB Register" )
-
-static const char *cb_cmd_name[] =
-{
- [CBL_NOP] = "NOP", [CBL_IASETUP] = "Individual address setup",
- [CBL_CONFIGURE] = "Configure", [CBL_MULTCAST_ADDR_SETUP] = "Set Multcast address list",
- [CBL_TRANSMIT] = "Transmit", [CBL_LOAD_MICROCODE] = "Load microcode",
- [CBL_DUMP] = "Dump", [CBL_DIAGNOSE] = "Diagnose",
-};
-#define CB_CMD_NAME(x) \
- ( (x) < (sizeof(cb_cmd_name) / sizeof(cb_cmd_name[0])) ? cb_cmd_name[(x)] : "Unknown CB command" )
-
-static const char *eeprom_opcode_name[] =
-{
- [0] = "Unknow", [EEPROM_WRITE] = "Write",
- [EEPROM_READ] = "Read", [EEPROM_ERASE] = "Erase",
-};
-#define EEPROM_OPCODE_NAME(x) \
- ( (x) < (sizeof(eeprom_opcode_name) / sizeof(eeprom_opcode_name[0])) ? \
- eeprom_opcode_name[(x)] : "Unknown" )
-
-static struct eeprom_trace_data
-{
- uint8_t eedo[256];
- uint8_t di[256];
- int op;
- int i;
- uint32_t data;
-}etd = {.op = NOP};
-
-static void eeprom_trace(int eedo, int di, int dir, int next_op, int clr)
-{
- int i;
-
- if ( clr )
- {
- char *opname = NULL;
-
- switch ( etd.op )
- {
- case NOP:
- break;
- case OPCODE:
- opname = "opcode";
- break;
- case ADDR:
- opname = "address";
- break;
- case DATA:
- opname = "data transfer";
- break;
- default:
- opname = "Unknown";
- }
-
- if ( opname )
- {
- logout("EEPROM trace:\n");
- fprintf(stderr, "\toperation: %s\n", opname);
- fprintf(stderr, "\tDI track:");
- for ( i=0; i<etd.i; i++ )
- fprintf(stderr, "%x ", etd.di[i]);
- fprintf(stderr, "\n\tDO track:");
- for ( i=0; i<etd.i; i++ )
- fprintf(stderr, "%x ", etd.eedo[i]);
- fprintf(stderr, "\n\tData:%#x\n", etd.data);
- }
-
-
- memset(&etd, 0x0, sizeof(etd));
- etd.op = next_op;
-
- return;
- }
-
- etd.eedo[etd.i] = eedo;
- etd.di[etd.i] = di;
- etd.i ++;
- if ( dir == EEPROM_READ && etd.op == DATA )
- etd.data = (etd.data << 1) | eedo;
- else
- etd.data = (etd.data << 1) | di;
-}
-
-#define INT_NAME(x) \
- ({ \
- char *name = NULL; \
- switch (x) \
- { \
- case INT_FCP: \
- name = "FCP"; \
- break; \
- case INT_SWI: \
- name = "SWI"; \
- break; \
- case INT_MDI: \
- name = "MDI"; \
- break; \
- case INT_RNR: \
- name = "RNR"; \
- break; \
- case INT_CNA: \
- name = "CNA"; \
- break; \
- case INT_FR: \
- name = "FR"; \
- break; \
- case INT_CX_TNO: \
- name ="CX/TNO"; \
- break; \
- default: \
- name ="Unknown"; \
- } \
- name; \
- })
-
-#else
-static void e100_dump(char *comment, uint8_t *info, int len) {}
-static void eeprom_trace(int eedo, int di, int dir, int next_op, int clr) {}
-#endif
-
-static void pci_reset(E100State * s)
-{
- uint8_t *pci_conf = s->pci_dev->config;
-
- memcpy(pci_conf, &e100_pci_configure[0], sizeof(e100_pci_configure));
- logout("%p\n", s);
-
- /* I82557 */
- PCI_CONFIG_8(E100_PCI_REVISION_ID, 0x01);
-
- PCI_CONFIG_8(0x3c, 0x0);
-
-}
-
-static void e100_selective_reset(E100State * s)
-{
-
- memset(s->pci_mem.mem, 0x0, sizeof(s->pci_mem.mem));
- // Set RU/CU to idle, maintain the register mentioned in spec,
- SET_CU_STATE(CU_IDLE);
- SET_RU_STATE(RU_IDLE);
- logout("CU and RU go to idle\n");
-
- s->ru_offset = 0;
- s->cu_offset = 0;
- s->cu_next = 0;
-
- // For 82557, special interrupt bits are all 1
- CSR(CSR_CMD, simb) = 0x3f;
- // Set PHY to 1
- CSR_VAL(CSR_MDI) |= BIT(21);
-
- /* Initialize EEDO bit to 1. Due to driver would detect dummy 0 at
- * EEDO bit, so initialize it to 1 is safety a way.
- */
- CSR(CSR_EEPROM, eedo) = 1;
- // no pending interrupts
- s->scb_stat = 0;
-
- return;
-}
-
-static void e100_software_reset(E100State *s)
-{
- memset(s->pci_mem.mem, 0x0, sizeof(s->pci_mem.mem));
- // Clear multicast list
- memset(s->mult_list, 0x0, sizeof(s->mult_list));
- // Set MDI register to default value
- memcpy(&s->mdimem[0], &e100_mdi_default[0], sizeof(s->mdimem));
- s->is_multcast_enable = 1;
- /* Clean FIFO buffer */
- memset(s->pkt_buf, 0x0, sizeof(s->pkt_buf));
- s->pkt_buf_len = 0;
-
- memset(&s->statistics, 0x0, sizeof(s->statistics));
- e100_selective_reset(s);
- return;
-}
-
-static void e100_reset(void *opaque)
-{
- E100State *s = (E100State *) opaque;
- logout("%p\n", s);
- e100_software_reset(s);
-}
-
-
-static void e100_save(QEMUFile * f, void *opaque)
-{
- E100State *s = (E100State *)opaque;
- int i;
-
- pci_device_save(s->pci_dev, f);
-
- qemu_put_be32s(f, &s->mmio_index);
- qemu_put_8s(f, &s->scb_stat);
- for(i = 0; i < REGION_NUM; i++) {
- qemu_put_be32s(f, &s->region_base_addr[i]);
- }
- qemu_put_buffer(f, s->macaddr, 6);
- for(i = 0; i < 32; i++) {
- qemu_put_be16s(f, &s->mdimem[i]);
- }
-
- /* Save eeprom. */
- qemu_put_8s(f, &s->eeprom.start_bit);
- qemu_put_8s(f, &s->eeprom.opcode);
- qemu_put_8s(f, &s->eeprom.address);
- qemu_put_be16s(f, &s->eeprom.data);
- qemu_put_be32s(f, &s->eeprom.val);
- qemu_put_be32s(f, &s->eeprom.val);
- qemu_put_be32s(f, &s->eeprom.val_len);
- qemu_put_be32s(f, &s->eeprom.val_type);
- qemu_put_8s(f, &s->eeprom.cs);
- qemu_put_8s(f, &s->eeprom.sk);
- qemu_put_be16s(f, &s->eeprom.addr_len);
- for(i = 0; i < 256; i++) {
- qemu_put_be16s(f, &s->eeprom.contents[i]);
- }
-
- qemu_put_be32s(f, &s->device);
-
- qemu_put_buffer(f, s->mult_list, 8);
- qemu_put_be32s(f, &s->is_multcast_enable);
-
- qemu_put_be32s(f, &s->cu_base);
- qemu_put_be32s(f, &s->cu_offset);
- qemu_put_be32s(f, &s->cu_next);
-
- qemu_put_be32s(f, &s->ru_base);
- qemu_put_be32s(f, &s->ru_offset);
-
- qemu_put_be32s(f, &s->statsaddr);
-
- /* Save statistics. */
- qemu_put_be32s(f, &s->statistics.tx_good_frames);
- qemu_put_be32s(f, &s->statistics.tx_max_collisions);
- qemu_put_be32s(f, &s->statistics.tx_late_collisions);
- qemu_put_be32s(f, &s->statistics.tx_underruns);
- qemu_put_be32s(f, &s->statistics.tx_lost_crs);
- qemu_put_be32s(f, &s->statistics.tx_deferred);
- qemu_put_be32s(f, &s->statistics.tx_single_collisions);
- qemu_put_be32s(f, &s->statistics.tx_multiple_collisions);
- qemu_put_be32s(f, &s->statistics.tx_total_collisions);
- qemu_put_be32s(f, &s->statistics.rx_good_frames);
- qemu_put_be32s(f, &s->statistics.rx_crc_errors);
- qemu_put_be32s(f, &s->statistics.rx_alignment_errors);
- qemu_put_be32s(f, &s->statistics.rx_resource_errors);
- qemu_put_be32s(f, &s->statistics.rx_overrun_errors);
- qemu_put_be32s(f, &s->statistics.rx_short_frame_errors);
- qemu_put_be32s(f, &s->statistics.complete_word);
-
- qemu_put_buffer(f, (uint8_t*)(&s->config), sizeof(s->config));
-
- qemu_put_buffer(f, s->pkt_buf, MAX_ETH_FRAME_SIZE+4);
- qemu_put_be32s(f, &s->pkt_buf_len);
-
- qemu_put_buffer(f, (uint8_t*)(&s->pci_mem), sizeof(s->pci_mem));
-}
-
-static int e100_load(QEMUFile * f, void *opaque, int version_id)
-{
- E100State *s = (E100State *)opaque;
- int i, ret;
-
- if (version_id > 3)
- return -EINVAL;
-
- ret = pci_device_load(s->pci_dev, f);
- if (ret < 0)
- return ret;
-
- qemu_get_be32s(f, &s->mmio_index);
- qemu_get_8s(f, &s->scb_stat);
- for(i = 0; i < REGION_NUM; i++) {
- qemu_get_be32s(f, &s->region_base_addr[i]);
- }
- qemu_get_buffer(f, s->macaddr, 6);
- for(i = 0; i < 32; i++) {
- qemu_get_be16s(f, &s->mdimem[i]);
- }
-
- /* Load eeprom. */
- qemu_get_8s(f, &s->eeprom.start_bit);
- qemu_get_8s(f, &s->eeprom.opcode);
- qemu_get_8s(f, &s->eeprom.address);
- qemu_get_be16s(f, &s->eeprom.data);
- qemu_get_be32s(f, &s->eeprom.val);
- qemu_get_be32s(f, &s->eeprom.val);
- qemu_get_be32s(f, &s->eeprom.val_len);
- qemu_get_be32s(f, &s->eeprom.val_type);
- qemu_get_8s(f, &s->eeprom.cs);
- qemu_get_8s(f, &s->eeprom.sk);
- qemu_get_be16s(f, &s->eeprom.addr_len);
- for(i = 0; i < 256; i++) {
- qemu_get_be16s(f, &s->eeprom.contents[i]);
- }
-
- qemu_get_be32s(f, &s->device);
-
- qemu_get_buffer(f, s->mult_list, 8);
- qemu_get_be32s(f, &s->is_multcast_enable);
-
- qemu_get_be32s(f, &s->cu_base);
- qemu_get_be32s(f, &s->cu_offset);
- qemu_get_be32s(f, &s->cu_next);
-
- qemu_get_be32s(f, &s->ru_base);
- qemu_get_be32s(f, &s->ru_offset);
-
- qemu_get_be32s(f, &s->statsaddr);
-
- /* Load statistics. */
- qemu_get_be32s(f, &s->statistics.tx_good_frames);
- qemu_get_be32s(f, &s->statistics.tx_max_collisions);
- qemu_get_be32s(f, &s->statistics.tx_late_collisions);
- qemu_get_be32s(f, &s->statistics.tx_underruns);
- qemu_get_be32s(f, &s->statistics.tx_lost_crs);
- qemu_get_be32s(f, &s->statistics.tx_deferred);
- qemu_get_be32s(f, &s->statistics.tx_single_collisions);
- qemu_get_be32s(f, &s->statistics.tx_multiple_collisions);
- qemu_get_be32s(f, &s->statistics.tx_total_collisions);
- qemu_get_be32s(f, &s->statistics.rx_good_frames);
- qemu_get_be32s(f, &s->statistics.rx_crc_errors);
- qemu_get_be32s(f, &s->statistics.rx_alignment_errors);
- qemu_get_be32s(f, &s->statistics.rx_resource_errors);
- qemu_get_be32s(f, &s->statistics.rx_overrun_errors);
- qemu_get_be32s(f, &s->statistics.rx_short_frame_errors);
- qemu_get_be32s(f, &s->statistics.complete_word);
-
- qemu_put_buffer(f, (uint8_t*)(&s->config), sizeof(s->config));
-
- qemu_get_buffer(f, s->pkt_buf, MAX_ETH_FRAME_SIZE+4);
- qemu_get_be32s(f, &s->pkt_buf_len);
-
- qemu_get_buffer(f, (uint8_t*)(&s->pci_mem), sizeof(s->pci_mem));
-
- return 0;
-}
-
-/* Interrupt functions */
-static void e100_interrupt(E100State *s, uint16_t int_type)
-{
-
- //TODO: Add another i8255x card supported mask bit
- if ( !CSR(CSR_CMD,m) )
- {
- //Set bit in stat/ack, so driver can no what interrupt happen
- CSR_VAL(CSR_STATUS) |= int_type;
- s->scb_stat = CSR(CSR_STATUS, stat_ack);
-
- /* SCB maske and SCB Bit M do not disable interrupt. */
- logout("Trigger an interrupt(type = %s(%#x), SCB Status = %#x)\n",
- INT_NAME(int_type), int_type, CSR_VAL(CSR_STATUS));
- pci_set_irq(s->pci_dev, 0, 1);
- }
-}
-
-static void e100_interrupt_ack(E100State * s, uint8_t ack)
-{
-
- /* Ignore acknowledege if driver write 0 to ack or
- * according interrupt bit is not set
- */
- if ( !ack || !(s->scb_stat & ack) )
- {
- logout("Illegal interrupt ack(ack=%#x, SCB Stat/Ack=%#x), ignore it\n",
- ack, s->scb_stat);
- // Due to we do write operation before e100_execute(), so
- // we must restore value of ack field here
- CSR(CSR_STATUS, stat_ack) = s->scb_stat;
- return;
- }
-
- s->scb_stat &= ~ack;
- CSR(CSR_STATUS, stat_ack) = s->scb_stat;
-
- logout("Interrupt ack(name=%s,val=%#x)\n", INT_NAME(({uint16_t bit = ack<<8;bit;})),ack);
- if ( !s->scb_stat )
- {
- logout("All interrupts are acknowledeged, de-assert interrupt line\n");
- pci_set_irq(s->pci_dev, 0, 0);
- }
-}
-
-static void e100_self_test(uint32_t res_addr)
-{
- struct
- {
- uint32_t st_sign; /* Self Test Signature */
- uint32_t st_result; /* Self Test Results */
- } test_res;
-
- test_res.st_sign = (uint32_t)-1;
- test_res.st_result = 0; // Our self test always success
- cpu_physical_memory_write(res_addr, (uint8_t *)&test_res, sizeof(test_res));
-
- logout("Write self test result to %#x\n", res_addr);
-}
-
-static void scb_port_func(E100State *s, uint32_t val, int dir)
-{
-#define PORT_SELECTION_MASK 0xfU
-
- uint32_t sel = val & PORT_SELECTION_MASK;
-
- switch ( sel )
- {
- case PORT_SOFTWARE_RESET:
- logout("do PORT_SOFTWARE_RESET!\n");
- e100_software_reset(s);
- break;
- case PORT_SELF_TEST:
- e100_self_test(val & ~PORT_SELECTION_MASK);
- logout("do PORT_SELF_TEST!\n");
- break;
- case PORT_SELECTIVE_RESET:
- logout("do PORT_SELECTIVE_RESET!\n");
- e100_selective_reset(s);
- break;
- case PORT_DUMP:
- logout("do PORT_SOFTWARE_RESET!\n");
- break;
- case PORT_DUMP_WAKE_UP:
- logout("do PORT_SOFTWARE_RESET!\n");
- break;
- default:
- logout("Unkonw SCB port command(selection function = %#x)\n", sel);
- }
-}
-
-static void e100_write_mdi(E100State *s, uint32_t val)
-{
- uint32_t ie = (val & 0x20000000) >> 29;
- uint32_t opcode = (val & 0x0c000000) >> 26;
- uint32_t phyaddr = (val & 0x03e00000) >> 21;
- uint32_t regaddr = (val & 0x001f0000) >> 16;
- uint32_t data = val & 0x0000ffff;
-
- logout("Write MDI:\n"
- "\topcode:%#x\n"
- "\tphy address:%#x\n"
- "\treg address:%#x\n"
- "\tie:%#x\n"
- "\tdata:%#x\n",
- opcode, phyaddr, regaddr, ie, data);
-
- /* We use default value --- PHY1
- * If driver operate on other PHYs, do nothing and
- * deceive it that the operation is finished
- */
- if ( phyaddr != 1 )
- {
- logout("Unsupport PHY address(phy = %#x)\n", phyaddr);
- goto done;
- }
-
- // 1: MDI write
- // 2: MDI read
- if ( opcode != MDI_WRITE && opcode != MDI_READ )
- {
- logout("Invalid Opcode(opcode = %#x)\n", opcode);
- return;
- }
-
- // Current only support MDI generic registers.
- if ( regaddr > 6 )
- {
- logout("Invalid phy register index( phy register addr = %#x)\n", regaddr);
- }
-
- if ( opcode == MDI_WRITE )
- {
- // MDI write
- switch ( regaddr )
- {
- case 0: // Control Register
- if ( data & 0x8000 ) // Reset
- {
- /* Reset status and control registers to default. */
- s->mdimem[0] = e100_mdi_default[0];
- s->mdimem[1] = e100_mdi_default[1];
- data = s->mdimem[regaddr];
- }
- else
- {
- /* Restart Auto Configuration = Normal Operation */
- data &= ~0x0200;
- }
- break;
- case 1: // Status Register
- logout("Invalid write on readonly register(opcode = %#x)\n", opcode);
- data = s->mdimem[regaddr];
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- break;
- }
- s->mdimem[regaddr] = data;
- logout("MDI WRITE: reg = %#x, data = %#x\n", regaddr, data);
- }
- else if ( opcode == MDI_READ )
- {
- // MDI read
- switch ( regaddr )
- {
- case 0: // Control Register
- if ( data & 0x8000 ) // Reset
- {
- /* Reset status and control registers to default. */
- s->mdimem[0] = e100_mdi_default[0];
- s->mdimem[1] = e100_mdi_default[1];
- }
- break;
- case 1: // Status Register
- // Auto Negotiation complete, set sticky bit to 1
- s->mdimem[regaddr] |= 0x0026;
- break;
- case 2: // PHY Identification Register (Word 1)
- case 3: // PHY Identification Register (Word 2)
- break;
- case 5: // Auto-Negotiation Link Partner Ability Register
- s->mdimem[regaddr] = 0x41fe;
- break;
- case 6: // Auto-Negotiation Expansion Register
- s->mdimem[regaddr] = 0x0001;
- break;
- }
- data = s->mdimem[regaddr];
- logout("MDI READ: reg = %#x, data = %#x\n", regaddr, data);
- }
-
- /* Emulation takes no time to finish MDI transaction.
- * Set MDI bit in SCB status register. */
-done:
- val |= BIT(28);
- val = (val & 0xffff0000) + data;
- CSR_WRITE(SCB_MDI, val, uint32_t);
-
- if ( ie )
- e100_interrupt(s, (uint16_t)INT_MDI);
-}
-
-static void scb_mdi_func(E100State *s, uint32_t val, int dir)
-{
- if ( dir == OP_READ )
- // Do nothing, just tell driver we are ready
- CSR_VAL(CSR_MDI) |= BIT(28);
- else if ( dir == OP_WRITE )
- e100_write_mdi(s, val);
- else
- logout("Invalid operation direction(dir=%x)\n", dir);
-
-}
-
-static void eeprom_reset(E100State *s, int type)
-{
- eeprom_t *e = &s->eeprom;
-
- if ( type == EEPROM_RESET_ALL )
- {
- memset(e, 0x0, sizeof(eeprom_t));
- e->val_type = NOP;
- logout("EEPROM reset all\n");
- return;
- }
-
- CSR(CSR_EEPROM, eedo) = 1;
- e->start_bit = 0;
- e->opcode = 0;
- e->address = 0;
- e->data = 0;
-
- e->val = 0;
- e->val_len = 0;
- e->val_type = NOP;
-
- e->cs = 0;
- e->sk = 0;
- logout("EEPROM select reset\n");
-}
-
-static void do_eeprom_op(E100State *s, eeprom_t *e, int cs, int sk, int di, int dir)
-{
- int assert_cs = (cs == 1 && e->cs == 0);
- int de_assert_cs = (cs == 0 && e->cs == 1);
- int de_assert_sk = (sk == 0 && e->sk == 1);
-
- // Chip select is not be enabled
- if ( cs == 0 && e->cs == 0 )
- {
- logout("Invalid EECS signal\n");
- return;
- }
-
- // update state
- e->cs = cs;
- e->sk = sk;
-
- // Do nothing
- if ( assert_cs )
- {
- logout("EECS assert\n");
- return;
- }
-
- // Complete one command
- if ( de_assert_cs )
- {
- if ( e->val_type == DATA && e->opcode == EEPROM_WRITE )
- {
- e->data = e->val;
- memcpy((void *)((unsigned long)e->contents + e->address),
- &e->data, sizeof(e->data));
- logout("EEPROM write complete(data=%#x)\n", e->data);
- }
- eeprom_trace(0,0,0,NOP,1);
- eeprom_reset(s, EEPROM_SELECT_RESET);
- logout("EECS de-asserted\n");
- return;
- }
-
- // Chip is selected and serial clock is change, so the operation is vaild
- if ( cs == 1 && de_assert_sk == 1)
- {
- // Set start bit
- if ( e->start_bit == 0 && di == 1 )
- {
- e->start_bit = di;
- e->val_len = 0;
- e->val = 0;
- e->val_type = OPCODE;
-
- eeprom_trace(0,0,0,OPCODE,1);
- logout("EEPROM start bit set\n");
- return;
- }
- // Data in DI is vaild
- else if ( e->start_bit == 1 )
- {
- // If current operation is eeprom read, ignore DI
- if ( !(e->val_type == DATA && e->opcode == EEPROM_READ) )
- {
- e->val = (e->val << 1) | di;
- e->val_len ++;
- }
-
- switch ( e->val_type )
- {
- // Get the opcode.
- case OPCODE:
- eeprom_trace(CSR(CSR_EEPROM, eedo), di, e->opcode, 0, 0);
- if ( e->val_len == 2 )
- {
- e->opcode = e->val;
- e->val = 0;
- e->val_len = 0;
- e->val_type = ADDR;
-
- eeprom_trace(0,0,0,ADDR,1);
- logout("EEPROM get opcode(opcode name=%s,opcode=%#x )\n",
- EEPROM_OPCODE_NAME(e->opcode), e->opcode);
- }
- break;
- // Get address
- case ADDR:
- eeprom_trace(CSR(CSR_EEPROM, eedo), di, e->opcode, 0, 0);
- if ( e->val_len == e->addr_len )
- {
- e->address = e->val;
- e->val = 0;
- e->val_len = 0;
- e->val_type = DATA;
-
- // We prepare data eary for later read operation
- if ( e->opcode == EEPROM_READ )
- {
- memcpy(&e->data, (void *)(e->contents + e->address),
- sizeof(e->data));
- logout("EEPROM prepare data to read(addr=%#x,data=%#x)\n",
- e->address, e->data);
- }
-
- // Write dummy 0 to response to driver the address is written complete
- CSR(CSR_EEPROM, eedo) = 0;
- eeprom_trace(0,0,0,DATA,1);
- logout("EEPROM get address(addr=%#x)\n", e->address);
- }
- break;
- // Only do data out operation
- case DATA:
- if ( e->opcode == EEPROM_READ )
- {
- // Start from the most significant bit
- //uint16_t t = ((e->data & (1<<(sizeof(e->data)*8 - e->val_len - 1))) != 0);
- uint16_t t = !!(e->data & (0x8000U >> e->val_len));
-
- CSR(CSR_EEPROM, eedo) = t;
-
- logout("EEPROM read(reg address=%#x, reg val=%#x, do=%#x, len=%#x)\n",
- e->address, e->data, t, e->val_len);
-
- if ( e->val_len > sizeof(e->data)*8 )
- {
- /* Driver may do more write op to de-assert EESK,
- * So we let EEPROM go to idle after a register be
- * read complete
- */
- e->val_type = NOP;
- logout("Read complete\n");
-
- break;
- }
-
- e->val_len ++;
- }
- eeprom_trace(CSR(CSR_EEPROM, eedo), di, e->opcode, 0, 0);
- // Do eerpom write when CS de-assert
- break;
- default:
- break;
- }
- }
- }
-
- return;
-}
-
-
-static void scb_eeprom_func(E100State *s, uint32_t val, int dir)
-{
- int eecs = ((val & EEPROM_CS) != 0);
- int eesk = ((val & EEPROM_SK) != 0);
- int eedi = ((val & EEPROM_DI) != 0);
-
- logout("EEPROM: Old(cs=%#x, sk=%#x), New(cs=%#x, sk=%#x, di=%#x)\n",
- s->eeprom.cs, s->eeprom.sk, eecs, eesk, eedi);
-
- do_eeprom_op(s, &s->eeprom, eecs, eesk, eedi, dir);
-
- return;
-}
-
-static void e100_ru_command(E100State *s, uint8_t val)
-{
- switch ( val )
- {
- case RU_NOP:
- /* Will not be here */
- break;
- case RU_START:
- /* RU start */
-
- SET_RU_STATE(RU_READY);
- logout("RU is set to ready\n");
- s->ru_offset = CSR_VAL(CSR_POINTER);
- logout("RFD offset is at %#x\n", s->ru_offset);
- break;
- case RU_RESUME:
- /* RU Resume */
- if ( GET_RU_STATE == RU_SUSPENDED )
- SET_RU_STATE(RU_READY);
- logout("RU resume to ready\n");
- break;
- case RU_ADDR_LOAD:
- /* Load RU base */
- s->ru_base = CSR_VAL(CSR_POINTER);
- logout("Load RU base address at %#x\n", s->ru_base);
- break;
- case RU_DMA_REDIRECT:
- logout("RU DMA redirect not implemented\n");
- break;
- case RU_ABORT:
- e100_interrupt(s, INT_RNR);
- SET_RU_STATE(RU_IDLE);
- logout("RU abort, go to idle\n");
- break;
- case RU_LOAD_HDS:
- logout("RU load header data size(HDS) not implemented\n");
- default:
- break;
- }
-}
-
-// This function will change CU's state, so CU start and
-// CU resume must set CU's state before it
-static void e100_execute_cb_list(E100State *s, int is_resume)
-{
-
- struct control_block cb = {0};
- uint32_t cb_addr;
-
- if ( !is_resume )
- s->cu_offset = CSR_VAL(CSR_POINTER);
-
- /* If call from CU resume, cu_offset has been set */
-
- while (1)
- {
- cb_addr = s->cu_base + s->cu_offset;
- cpu_physical_memory_read(cb_addr, (uint8_t *)&cb, sizeof(cb));
-
-
- switch ( cb.cmd )
- {
- case CBL_NOP:
- /* Do nothing */
- break;
- case CBL_IASETUP:
- cpu_physical_memory_read(cb_addr + 8, &s->macaddr[0], sizeof(s->macaddr));
- e100_dump("Setup Individual Address:", &s->macaddr[0], 6);
- break;
- case CBL_CONFIGURE:
- {
- i82557_cfg_t *cfg = &s->config;
-
- assert(sizeof(s->config) == 22);
- cpu_physical_memory_read(cb_addr + 8, (uint8_t *)cfg, sizeof(s->config));
- logout("Setup card configuration:"
- "\tbyte count:%d\n"
- "\tRx FIFO limit:%d\n"
- "\tTx FIFO limit:%d\n"
- "\tAdaptive interframe spacing:%d\n"
- "\tRx DMA max:%d\n"
- "\tTX DMA max:%d\n"
- "\tDMBC enable:%d\n"
- "\tLate SCB:%d\n"
- "\tTNO:%d\n"
- "\tCI:%d\n"
- "\tDiscard overrun RX:%d\n"
- "\tSave bad frame:%d\n"
- "\tDiscard short RX:%d\n"
- "\tunderrun retry:%d\n"
- "\tMII:%d\n"
- "\tNSAI:%d\n"
- "\tPreamble len:%d\n"
- "\tloopback:%d\n"
- "\tliner pro:%d\n"
- "\tPRI mode:%d\n"
- "\tinterframe spacing:%d\n"
- "\tpromiscuous:%d\n"
- "\tbroadcast dis:%d\n"
- "\tCRS CDT:%d\n"
- "\tstripping:%d\n"
- "\tpadding:%d\n"
- "\tRX crc:%d\n"
- "\tforce fdx:%d\n"
- "\tfdx enable:%d\n"
- "\tmultiple IA:%d\n"
- "\tmulticast all:%d\n",
- cfg->byte_count, cfg->rx_fifo_limit, cfg->tx_fifo_limit,
- cfg->adpt_inf_spacing, cfg->rx_dma_max_bytes, cfg->tx_dma_max_bytes,
- cfg->dmbc_en, cfg->late_scb, cfg->tno_intr, cfg->ci_intr,
- cfg->dis_overrun_rx, cfg->save_bad_frame, cfg->dis_short_rx,
- cfg->underrun_retry, cfg->mii, cfg->nsai, cfg->preamble_len,
- cfg->loopback, cfg->linear_prio, cfg->pri_mode, cfg->interframe_spacing,
- cfg->promiscuous, cfg->broadcast_dis, cfg->crs_cdt, cfg->strip,
- cfg->padding, cfg->rx_crc, cfg->force_fdx, cfg->fdx_en,
- cfg->mul_ia, cfg->mul_all);
- }
- break;
- case CBL_MULTCAST_ADDR_SETUP:
- {
- uint16_t mult_list_count = 0;
- uint16_t size = 0;
-
- cpu_physical_memory_read(cb_addr + 8, (uint8_t *)&mult_list_count, 2);
- mult_list_count = (mult_list_count << 2) >> 2;
-
- if ( !mult_list_count )
- {
- logout("Multcast disabled(multicast count=0)\n");
- s->is_multcast_enable = 0;
- memset(s->mult_list, 0x0, sizeof(s->mult_list));
- break;
- }
- size = mult_list_count > sizeof(s->mult_list) ?
- sizeof(s->mult_list) : mult_list_count;
- cpu_physical_memory_read(cb_addr + 12, &s->mult_list[0], size);
-
- e100_dump("Setup Multicast list: ", &s->mult_list[0], size);
- break;
- }
- case CBL_TRANSMIT:
- {
- struct
- {
- struct control_block cb;
- tbd_t tbd;
- } __attribute__ ((packed)) tx;
-
- struct
- {
- uint32_t addr;
- uint16_t size;
- uint16_t is_el_set;
- } tx_buf = {0};
-
- uint32_t tbd_array;
- uint16_t tcb_bytes;
- uint8_t sf;
- int len = s->pkt_buf_len;
-
- assert( len < sizeof(s->pkt_buf));
-
- cpu_physical_memory_read(cb_addr, (uint8_t *)&tx, sizeof(tx));
- tbd_array = le32_to_cpu(tx.tbd.tx_desc_addr);
- tcb_bytes = le16_to_cpu(tx.tbd.tcb_bytes);
- // Indicate use what mode to transmit(simple or flexible)
- sf = tx.cb.rs3 & 0x1;
-
- logout("Get a TBD:\n"
- "\tTBD array address:%#x\n"
- "\tTCB byte count:%#x\n"
- "\tEOF:%#x\n"
- "\tTransmit Threshold:%#x\n"
- "\tTBD number:%#x\n"
- "\tUse %s mode to send frame\n",
- tbd_array, tcb_bytes, tx.tbd.eof,
- tx.tbd.tx_threshold, tx.tbd.tbd_num,
- sf ? "Flexible" : "Simple");
-
- if ( !sf || tbd_array == (uint32_t)-1 )
- {
- /* Simple mode */
-
- /* For simple mode, TCB bytes should not be zero.
- * But we still check here for safety
- */
- if ( !tcb_bytes || tcb_bytes > sizeof(s->pkt_buf) )
- break;
-
- cpu_physical_memory_read(cb_addr+16, &s->pkt_buf[0], tcb_bytes);
- len = tcb_bytes;
- logout("simple mode(size=%d)\n", len);
-
- }
- else
- {
- /* Flexible mode */
-
- /* For flexible mode, TBD num should not be zero.
- * But we still check here for safety
- */
- if ( !tx.tbd.tbd_num )
- break;
-
- // I82557 don't support extend TCB
- if ( s->device == i82557C || s->device == i82557B )
- {
- /* Standard TCB mode */
-
- int i;
-
- for ( i=0; i<tx.tbd.tbd_num; i++ )
- {
-
- cpu_physical_memory_read(tbd_array, (uint8_t *)&tx_buf,
- sizeof(tx_buf));
- tx_buf.is_el_set &= 0x1;
- tx_buf.size &= 0x7fff;
- tbd_array += 8;
-
- if ( tx_buf.size > sizeof(s->pkt_buf) - len )
- {
- logout("Warning: Get a too big TBD, ignore it"
- "(buf addr %#x, size %d, el:%#x)\n",
- tx_buf.addr, tx_buf.size, tx_buf.is_el_set);
- continue;
- }
-
- cpu_physical_memory_read(tx_buf.addr, &s->pkt_buf[len],
- tx_buf.size);
-
- logout("TBD (standard mode): buf addr %#x, size %d, el:%#x\n",
- tx_buf.addr, tx_buf.size, tx_buf.is_el_set);
- len += tx_buf.size;
-
- if ( tx_buf.is_el_set )
- break;
- }
-
- }
- //FIXME: Extend mode is not be tested
- else
- {
- /* Extend TCB mode */
-
- /* A strandard TCB followed by two TBDs */
- uint32_t tbd_addr = cb_addr+16;
- int i = 0;
-
-
- for ( ; i<2 && i<tx.tbd.tbd_num; i++ )
- {
-
- cpu_physical_memory_read(tbd_array, (uint8_t *)&tx_buf,
- sizeof(tx_buf));
- tx_buf.is_el_set &= 0x1;
- tbd_addr += 8;
-
- /* From Intel's spec, size of TBD equal to zero
- * has same effect with EL bit set
- */
- if ( tx_buf.size == 0 )
- {
- tx_buf.is_el_set = 1;
- break;
- }
-
- if ( tx_buf.size + len > sizeof(s->pkt_buf) )
- {
- logout("TX frame is too large, discarding it"
- "(buf addr=%#x, size=%#x)\n", tx_buf.addr,
- tx_buf.size);
- //continue;
- break;
- }
-
- logout("TBD (extended mode): buf addr %#08x, size %#04x, el:%#x\n",
- tx_buf.addr, tx_buf.size, tx_buf.is_el_set);
- cpu_physical_memory_read(tx_buf.addr, &s->pkt_buf[len],
- tx_buf.size);
-
- len += tx_buf.size;
-
- if ( tx_buf.is_el_set )
- break;
- }
-
- /* In extend TCB mode, TDB array point to the thrid TBD
- * if it is not NULL(0xffffffff) and EL bit of before
- * two TBDs is not set
- */
- if ( tbd_array != (uint32_t)-1 && !tx_buf.is_el_set )
- {
- tbd_addr = tbd_array;
-
- /* TBD number includes first two TBDs, so don't
- * initialize i here
- */
- for ( ; i<tx.tbd.tbd_num; i++ )
- {
- cpu_physical_memory_read(tbd_addr, (uint8_t *)&tx_buf,
- sizeof(tx_buf));
- tx_buf.is_el_set &= 0x1;
- tbd_addr += 8;
-
- cpu_physical_memory_read(tx_buf.addr, &s->pkt_buf[len],
- tx_buf.size);
- logout("TBD (extended mode): buf addr 0x%#08x, size 0x%#04x\n",
- tx_buf.addr, tx_buf.size);
-
- len += tx_buf.size;
-
- if ( tx_buf.is_el_set )
- break;
- }
- }
- }
- }
-
-
- s->pkt_buf_len = len;
-
-/* Below codes are used for Threshold. But with these logic, network of guest
- * getting bad performance. So I comment it and leave codes here to hope anyone
- * fix it
- */
-#if 0
- /* If threshold is set, only send packet when threshold
- * bytes are read
- */
- if ( tx.tbd.tx_threshold && s->pkt_buf_len < tx.tbd.tx_threshold * 8 )
- {
- logout("Current data length in FIFO buffer:%d\n", s->pkt_buf_len);
- break;
- }
-#endif
-
- if ( s->pkt_buf_len )
- {
- qemu_send_packet(s->vc, s->pkt_buf, s->pkt_buf_len);
- s->statistics.tx_good_frames ++;
- logout("Send out frame successful(size=%d,"
- "already sent %d frames)\n", s->pkt_buf_len,
- s->statistics.tx_good_frames);
- s->pkt_buf_len = 0;
- }
-
- e100_dump("Dest addr:", (uint8_t *)s->pkt_buf, 6);
- e100_dump("Src addr:", (uint8_t *)(s->pkt_buf+6), 6);
- e100_dump("type:", (uint8_t *)(s->pkt_buf+8), 2);
-
- break;
- }
- case CBL_LOAD_MICROCODE:
-#ifdef DEBUG_E100
- {
- /* Don't support load marco code, just dump it */
- #define MICRO_CODE_LEN 256
- uint8_t micro_code[MICRO_CODE_LEN] = {0};
- cpu_physical_memory_read(cb_addr+8, micro_code, MICRO_CODE_LEN);
- e100_dump("Load micro code:", micro_code, MICRO_CODE_LEN);
- }
-#endif
- break;
- case CBL_DUMP:
- logout("Control block dump\n");
- break;
- case CBL_DIAGNOSE:
- logout("Control block diagnose\n");
- break;
- default:
- logout("Unknown Control block command(val=%#x)\n", cb.cmd);
- break;
- }
-
- /* Now, we finished executing a command, update status of CB.
- * We always success
- */
- cb.c = 1;
- cb.ok = 1;
- // Only update C bit and OK bit field in TCB
- cpu_physical_memory_write(cb_addr, (uint8_t *)&cb, 2);
-
- logout("Finished a command from CB list:\n"
- "\tok:%d\n"
- "\tc:%d\n"
- "\tcommand name:%s(cmd=%#x)\n"
- "\ti:%d\n"
- "\ts:%d\n"
- "\tel:%d\n"
- "\tlink address:%#x\n",
- cb.ok, cb.c, CB_CMD_NAME(cb.cmd), cb.cmd,
- cb.i, cb.s, cb.el, cb.link_addr);
-
- if ( cb.i )
- e100_interrupt(s, (uint16_t)INT_CX_TNO);
-
- // Suspend CU
- if ( cb.s )
- {
- logout("CU go to suspend\n");
- SET_CU_STATE(CU_SUSPENDED);
- s->cu_next = cb.link_addr; // Save it for go on executing when resume
-
- // Trigger CNA interrupt only when CNA mode is configured
- if ( !(s->config.ci_intr) && cb.i )
- e100_interrupt(s, (uint16_t)INT_CNA);
-
- return;
- }
-
- // This is last command in CB list, CU go back to IDLE
- if ( cb.el )
- {
- logout("Command block list is empty, CU go to idle\n");
- SET_CU_STATE(CU_IDLE);
- /* Either in CNA mode or CI mode, interrupt need be triggered
- * when CU go to idle.
- */
- if ( cb.i )
- e100_interrupt(s, (uint16_t)INT_CNA);
-
- return;
- }
-
- s->cu_offset = le32_to_cpu(cb.link_addr); // get next CB offset
- }
-}
-
-static void dump_statistics(E100State * s, uint32_t complete_word)
-{
- /* Dump statistical data. Most data is never changed by the emulation
- * and always 0.
- */
- s->statistics.complete_word = complete_word;
- cpu_physical_memory_write(s->statsaddr, (uint8_t *)&s->statistics, sizeof(s->statistics));
-
-}
-
-static void e100_cu_command(E100State *s, uint8_t val)
-{
-
- switch ( val )
- {
- case CU_NOP:
- /* Will not be here */
- break;
- case CU_START:
- /* This strictly follow Intel's spec */
- if ( GET_CU_STATE != CU_IDLE && GET_CU_STATE != CU_SUSPENDED )
- {
- logout("Illegal CU start command. Device is not idle or suspend\n");
- return;
- }
-
- SET_CU_STATE(CU_LPQ_ACTIVE);
- logout("CU start\n");
-
- e100_execute_cb_list(s, 0);
- break;
- case CU_RESUME:
- {
- uint32_t previous_cb = s->cu_base + s->cu_offset;
- struct control_block cb;
-
- /* Resume from suspend */
-
- /* FIXME:From Intel's spec, CU resume from idle is
- * forbidden, but e100 drive in linux
- * indeed do this.
- */
- if ( GET_CU_STATE == CU_IDLE )
- {
- logout("Illegal resume form IDLE\n");
- }
-
- cpu_physical_memory_read(previous_cb, (uint8_t *)&cb,
- sizeof(cb));
-
- //FIXME: Need any speical handle when CU is active ?
-
- /* Driver must clean S bit in previous CB when
- * it issue CU resume command
- */
- if ( cb.s )
- {
- logout("CU still in suspend\n");
- break;
- }
-
- SET_CU_STATE(CU_LPQ_ACTIVE);
- if ( cb.el )
- {
- logout("CB list is empty, CU just go to active\n");
- break;
- }
-
- // Continue next command
- s->cu_offset = s->cu_next;
-
- e100_execute_cb_list(s, 1);
-
- logout("CU resume\n");
- }
- break;
- case CU_STATSADDR:
- /* Load dump counters address */
- s->statsaddr = CSR_VAL(CSR_POINTER);
- logout("Load Stats address at %#x\n", s->statsaddr);
- break;
- case CU_SHOWSTATS:
- /* Dump statistical counters */
- dump_statistics(s, 0xa005);
- logout("Execute dump statistics\n");
- break;
- case CU_CMD_BASE:
- /* Load CU base */
- s->cu_base = CSR_VAL(CSR_POINTER);
- logout("Load CU base at %x\n", s->cu_base);
- break;
- case CU_DUMPSTATS:
- /* Dump statistical counters and reset counters. */
- dump_statistics(s, 0xa007);
- memset(&s->statistics, 0x0, sizeof(s->statistics));
- logout("Execute dump and reset statistics\n");
- break;
- case CU_S_RESUME:
- /* CU static resume */
- logout("CU static resume is not implemented\n");
- break;
- default:
- logout("Unknown CU command(val=%#x)\n", val);
- break;
- }
-
-}
-
-static void scb_cmd_func(E100State *s, uint16_t val, int dir)
-{
- /* ignore NOP operation */
- if ( val & 0x0f )
- {
- e100_ru_command(s, val & 0x0f);
- CSR(CSR_CMD, ru_cmd) = 0;
- }
- else if ( val & 0xf0 )
- {
- e100_cu_command(s, val & 0xf0);
- CSR(CSR_CMD, cu_cmd) = 0;
- }
-
-}
-
-enum
-{
- WRITEB,
- WRITEW,
- WRITEL,
- OP_IS_READ,
-} WRITE_BYTES;
-
-/* Driver may issue a command by writting one 32bit-entry,
- * two 16bit-entries or four 8bit-entries. In late two case, we
- * must wait until driver finish writting to the highest byte. The parameter
- * 'bytes' means write action of driver(writeb, wirtew, wirtel)
- */
-static void e100_execute(E100State *s, uint32_t addr_offset,
- uint32_t val, int dir, int bytes)
-{
-
- switch ( addr_offset )
- {
- case SCB_STATUS:
- if ( bytes == WRITEB )
- break;
- case SCB_ACK:
- if ( dir == OP_WRITE )
- {
- uint8_t _val = 0;
- if ( bytes == WRITEB )
- _val = (uint8_t)val;
- else if ( bytes == WRITEW )
- _val = ((uint16_t)val) >> 8;
- else if ( bytes == WRITEL)
- {
- // This should not be happen
- _val = ((uint16_t)val) >> 8;
- logout("WARNNING: Drvier write 4 bytes to CSR register at offset %d,"
- "emulator may do things wrong!!!\n", addr_offset);
- }
-
- e100_interrupt_ack(s, _val);
- }
- break;
- case SCB_CMD:
- if ( dir == OP_WRITE )
- scb_cmd_func(s, val, dir);
-
-/* I don't know whether there is any driver writes command words and
- * interrupt mask at same time by two bytes. This is not a regular operation.
- * but if we meet the case, below codes could copy with it. As far
- * as I know. windows's and linux's driver don't do this thing.
- */
-#if 0
- if ( bytes == WRITEW && (val&0xff00) != 0 )
- ;
- else
- break;
-#endif
- break;
- case SCB_INTERRUPT_MASK:
- if ( dir == OP_WRITE )
- {
- uint8_t _val = 0;
- if ( bytes == WRITEB )
- _val = (uint8_t)val;
- else if ( bytes == WRITEW )
- _val = (val & 0xff00) >> 8;
- else
- logout("WARNNING: Drvier write 4 bytes to CSR register at offset %d,"
- "emulator may do things wrong!!!\n", addr_offset);
-
- // Driver generates a software interrupt
- if ( _val & BIT(1) )
- e100_interrupt(s, INT_SWI);
- }
- break;
- case SCB_PORT ... SCB_PORT + 3:
- if ( dir == OP_WRITE )
- {
- // Waitting for driver write to the highest byte
- if ( (bytes == WRITEB && addr_offset != SCB_PORT + 3) ||
- (bytes == WRITEW && addr_offset != SCB_PORT + 2) )
- break;
-
- scb_port_func(s, CSR_VAL(CSR_PORT), dir);
- }
- break;
- case SCB_MDI ... SCB_MDI + 3:
- if ( dir == OP_WRITE )
- {
- // Waitting for driver write to the highest byte
- if ( (bytes == WRITEB && addr_offset != SCB_MDI + 3) ||
- (bytes == WRITEW && addr_offset != SCB_MDI + 2) )
- break;
- }
-
- scb_mdi_func(s, CSR_VAL(CSR_MDI), dir);
- break;
- case SCB_EEPROM:
- if ( dir == OP_WRITE )
- scb_eeprom_func(s, val, dir);
- // Nothing need do when driver read EEPROM registers of CSR
- break;
- case SCB_POINTER:
- break;
- default:
- logout("Driver operate on CSR reg(offset=%#x,dir=%s,val=%#x)\n",
- addr_offset, dir==OP_WRITE?"write":"read", val);
- }
-
-}
-
-/* MMIO access functions */
-static uint8_t e100_read1(E100State * s, uint32_t addr_offset)
-{
- uint8_t val = -1;
-
- if ( addr_offset + sizeof(val) >= sizeof(s->pci_mem.mem) )
- {
- logout("Invaild read, beyond memory boundary(addr:%#x)\n", addr_offset
- + s->region_base_addr[CSR_MEMORY_BASE]);
- return val;
- }
-
-
- e100_execute(s, addr_offset, val, OP_READ, OP_IS_READ);
- val = CSR_READ(addr_offset, uint8_t);
- logout("READ1: Register name = %s, addr_offset = %#x, val=%#x\n", SCBNAME(addr_offset), addr_offset, val);
-
- return val;
-}
-
-static uint16_t e100_read2(E100State * s, uint32_t addr_offset)
-{
- uint16_t val = -1;
-
- if ( addr_offset + sizeof(val) >= sizeof(s->pci_mem.mem) )
- {
- logout("Invaild read, beyond memory boundary(addr:%#x)\n", addr_offset
- + s->region_base_addr[CSR_MEMORY_BASE]);
- return val;
- }
-
- e100_execute(s, addr_offset, val, OP_READ, OP_IS_READ);
- val = CSR_READ(addr_offset, uint16_t);
- logout("READ2: Register name = %s, addr_offset = %#x, val=%#x\n", SCBNAME(addr_offset), addr_offset, val);
-
- return val;
-
-}
-
-static uint32_t e100_read4(E100State * s, uint32_t addr_offset)
-{
- uint32_t val = -1;
-
- if ( addr_offset + sizeof(val) >= sizeof(s->pci_mem.mem) )
- {
- logout("Invaild read, beyond memory boundary(addr:%#x)\n", addr_offset
- + s->region_base_addr[CSR_MEMORY_BASE]);
- return val;
- }
-
- e100_execute(s, addr_offset, val, OP_READ, OP_IS_READ);
- val = CSR_READ(addr_offset, uint32_t);
- logout("READ4: Register name = %s, addr_offset = %#x, val=%#x\n", SCBNAME(addr_offset), addr_offset, val);
-
- return val;
-
-}
-
-static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_MEMORY_BASE];
- return e100_read1(s, addr);
-}
-
-static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_MEMORY_BASE];
- return e100_read2(s, addr);
-}
-
-static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_MEMORY_BASE];
- return e100_read4(s, addr);
-}
-
-static CPUReadMemoryFunc *pci_mmio_read[] = {
- pci_mmio_readb,
- pci_mmio_readw,
- pci_mmio_readl
-};
-
-static void e100_write1(E100State * s, uint32_t addr_offset, uint8_t val)
-{
- if ( addr_offset + sizeof(val) >= sizeof(s->pci_mem.mem) )
- {
- logout("Invaild write, beyond memory boundary(addr = %#x, val = %#x\n", addr_offset
- + s->region_base_addr[CSR_MEMORY_BASE], val);
- return;
- }
-
- // SCB stauts is read-only word, can not be directly write
- if ( addr_offset == SCB_STATUS )
- {
- return;
- }
- // EEDO bit of eeprom register is read-only, can not be written;
- else if ( addr_offset == SCB_EEPROM )
- {
- int eedo = BIT(3) & CSR_VAL(CSR_EEPROM);
- CSR_WRITE(addr_offset, val, uint8_t);
- CSR(CSR_EEPROM, eedo) = !!(eedo & EEPROM_DO);
-
- logout("WRITE1: Register name = %s, addr_offset = %#x, val = %#x\n", SCBNAME(addr_offset),addr_offset, (uint8_t)CSR_VAL(CSR_EEPROM));
- return;
- }
- else
- {
- CSR_WRITE(addr_offset, val, uint8_t);
- }
-
- logout("WRITE1: Register name = %s, addr_offset = %#x, val = %#x\n", SCBNAME(addr_offset),addr_offset, val);
- return;
-}
-
-static void e100_write2(E100State * s, uint32_t addr_offset, uint16_t val)
-{
- if ( addr_offset + sizeof(val) >= sizeof(s->pci_mem.mem) )
- {
- logout("Invaild write, beyond memory boundary(addr = %#x, val = %#x\n", addr_offset
- + s->region_base_addr[CSR_MEMORY_BASE], val);
- return;
- }
-
- // SCB stauts is readonly word, can not be directly write
- if ( addr_offset == SCB_STATUS )
- {
- uint8_t __val = val >> 8;
- CSR_WRITE(addr_offset+1, __val, uint8_t);
- }
- // EEDO bit of eeprom register is read-only, can not be written;
- else if ( addr_offset == SCB_EEPROM )
- {
- int eedo = BIT(3) & CSR_VAL(CSR_EEPROM);
- CSR_WRITE(addr_offset, val, uint16_t);
- CSR(CSR_EEPROM, eedo) = !!(eedo & EEPROM_DO);
-
- logout("WRITE1: Register name = %s, addr_offset = %#x, val = %#x\n", SCBNAME(addr_offset),addr_offset, CSR_VAL(CSR_EEPROM));
- return;
- }
- else
- {
- CSR_WRITE(addr_offset, val, uint16_t);
- }
-
- logout("WRITE2: Register name = %s, addr_offset = %#x, val = %#x\n", SCBNAME(addr_offset),addr_offset, val);
- return;
-}
-
-static void e100_write4(E100State * s, uint32_t addr_offset, uint32_t val)
-{
- if ( addr_offset + sizeof(val) >= sizeof(s->pci_mem.mem) )
- {
- logout("Invaild write, beyond memory boundary(addr = %#x, val = %#x\n", addr_offset
- + s->region_base_addr[CSR_MEMORY_BASE], val);
- return;
- }
-
- // SCB stauts is readonly word, can not be directly write
- if ( addr_offset == SCB_STATUS )
- {
- uint8_t __val[4] = {0};
-
- //FIXME: any un-aligned reference ?
- *(uint32_t *)&__val = val;
-
- CSR_WRITE(addr_offset+1, __val[1], uint8_t);
- CSR_WRITE(addr_offset+2, __val[2], uint8_t);
- CSR_WRITE(addr_offset+3, __val[3], uint8_t);
- }
- /* No write4 opertaion on EEPROM register */
- else
- {
- CSR_WRITE(addr_offset, val, uint32_t);
- }
-
- logout("WRITE4: Register name = %s, addr_offset = %#x, val = %#x\n", SCBNAME(addr_offset),addr_offset, val);
- return;
-}
-
-static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_MEMORY_BASE];
- e100_write1(s, addr, val);
- e100_execute(s, addr, val, OP_WRITE, WRITEB);
-}
-
-static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_MEMORY_BASE];
- e100_write2(s, addr, val);
- e100_execute(s, addr, val, OP_WRITE, WRITEW);
-}
-
-static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_MEMORY_BASE];
- e100_write4(s, addr, val);
- (void)e100_execute(s, addr, val, OP_WRITE, WRITEL);
-}
-
-static CPUWriteMemoryFunc *pci_mmio_write[] = {
- pci_mmio_writeb,
- pci_mmio_writew,
- pci_mmio_writel
-};
-
-static void pci_mmio_map(PCIDevice * pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIE100State *d = (PCIE100State *) pci_dev;
-
- logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",
- region_num, addr, size, type);
-
- if ( region_num == CSR_MEMORY_BASE ) {
- /* Map control / status registers. */
- cpu_register_physical_memory(addr, size, d->e100.mmio_index);
- d->e100.region_base_addr[region_num] = addr;
- }
-}
-
-/* IO access functions */
-static void ioport_write1(void *opaque, uint32_t addr, uint32_t val)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_IO_BASE];
- e100_write1(s, addr, val);
- (void)e100_execute(s, addr, (uint32_t)val, OP_WRITE, WRITEB);
-}
-
-static void ioport_write2(void *opaque, uint32_t addr, uint32_t val)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_IO_BASE];
- e100_write2(s, addr, val);
- (void)e100_execute(s, addr, (uint32_t)val, OP_WRITE, WRITEW);
-}
-
-static void ioport_write4(void *opaque, uint32_t addr, uint32_t val)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_IO_BASE];
- e100_write4(s, addr, val);
- (void)e100_execute(s, addr, (uint32_t)val, OP_WRITE, WRITEL);
-}
-
-static uint32_t ioport_read1(void *opaque, uint32_t addr)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_IO_BASE];
- return e100_read1(s, addr);
-}
-
-static uint32_t ioport_read2(void *opaque, uint32_t addr)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_IO_BASE];
- return e100_read2(s, addr);
-}
-
-static uint32_t ioport_read4(void *opaque, uint32_t addr)
-{
- E100State *s = opaque;
- addr -= s->region_base_addr[CSR_IO_BASE];
- return e100_read4(s, addr);
-}
-
-static void pci_ioport_map(PCIDevice * pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIE100State *d = (PCIE100State *) pci_dev;
- E100State *s = &d->e100;
-
- logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",
- region_num, addr, size, type);
-
- if ( region_num != 1 )
- {
- logout("Invaid region number!\n");
- return;
- }
-
- register_ioport_write(addr, size, 1, ioport_write1, s);
- register_ioport_read(addr, size, 1, ioport_read1, s);
- register_ioport_write(addr, size, 2, ioport_write2, s);
- register_ioport_read(addr, size, 2, ioport_read2, s);
- register_ioport_write(addr, size, 4, ioport_write4, s);
- register_ioport_read(addr, size, 4, ioport_read4, s);
-
- s->region_base_addr[region_num] = addr;
-}
-
-/* From FreeBSD */
-#define POLYNOMIAL 0x04c11db6
-static int compute_mcast_idx(const uint8_t *ep)
-{
- uint32_t crc;
- int carry, i, j;
- uint8_t b;
-
- crc = 0xffffffff;
- for (i = 0; i < 6; i++) {
- b = *ep++;
- for (j = 0; j < 8; j++) {
- carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
- crc <<= 1;
- b >>= 1;
- if (carry)
- crc = ((crc ^ POLYNOMIAL) | carry);
- }
- }
- return (crc >> 26);
-}
-
-/* Eerpro100 receive functions */
-static int e100_can_receive(void *opaque)
-{
- E100State *s = opaque;
-
- int is_ready = (GET_RU_STATE == RU_READY);
- logout("%s\n", is_ready ? "EEPro100 receiver is ready"
- : "EEPro100 receiver is not ready");
- return is_ready;
-}
-
-static void e100_receive(void *opaque, const uint8_t * buf, int size)
-{
- E100State *s = opaque;
- uint32_t rfd_addr = 0;
- rfd_t rfd = {0};
-
-
- if ( GET_RU_STATE != RU_READY )
- {
- //logout("RU is not ready. Begin discarding frame(state=%x)\n", GET_RU_STATE);
- return;
- }
-
- rfd_addr = s->ru_base + s->ru_offset;
- cpu_physical_memory_read(rfd_addr, (uint8_t *)&rfd, sizeof(rfd_t));
-
- if ( (size > MAX_ETH_FRAME_SIZE+4) )
- {
- /* Long frame and configuration byte 18/3 (long receive ok) not set:
- * Long frames are discarded. */
- logout("Discard long frame(size=%d)\n", size);
-
- return;
- }
- else if ( !memcmp(buf, s->macaddr, sizeof(s->macaddr)) )
- {
- /* The frame is for me */
- logout("Receive a frame for me(size=%d)\n", size);
- e100_dump("FRAME:", (uint8_t *)buf, size);
- }
- else if ( !memcmp(buf, broadcast_macaddr, sizeof(broadcast_macaddr)) )
- {
- if ( s->config.broadcast_dis && !s->config.promiscuous )
- {
- logout("Discard a broadcast frame\n");
- return;
- }
-
- /* Broadcast frame */
- rfd.status |= RX_IA_MATCH;
- logout("Receive a broadcast frame(size=%d)\n", size);
- }
- else if ( s->is_multcast_enable && buf[0] & 0x1 )
- {
- int mcast_idx = compute_mcast_idx(buf);
- if ( !(s->mult_list[mcast_idx >> 3] & (1 << (mcast_idx & 7))) )
- {
- logout("Multicast address mismatch, discard\n");
- return;
- }
- logout("Receive a multicast frame(size=%d)\n", size);
- }
- else if ( size < 64 && (s->config.dis_short_rx) )
- {
- /* From Intel's spec, short frame should be discarded
- * when configuration byte 7/0 (discard short receive) set.
- * But this will cause frame lossing such as ICMP frame, ARP frame.
- * So we check is the frame for me before discarding short frame
- */
-
- /* Save Bad Frame bit */
- if ( s->config.save_bad_frame )
- {
- rfd.status |= RX_SHORT;
- s->statistics.rx_short_frame_errors ++;
- }
- logout("Receive a short frame(size=%d), discard it\n", size);
- return;
- }
- else if ( s->config.promiscuous )
- {
- /* Promiscuous: receive all. No address match */
- logout("Received frame in promiscuous mode(size=%d)\n", size);
- rfd.status |= RX_NO_MATCH;
- }
- else
- {
- e100_dump("Unknown frame, MAC = ", (uint8_t *)buf, 6);
- return;
- }
- e100_dump("Get frame, MAC = ", (uint8_t *)buf, 6);
-
- rfd.c = 1;
- rfd.ok = 1;
- rfd.f = 1;
- rfd.eof = 1;
- rfd.status &= ~RX_COLLISION;
- rfd.count = size;
-
- logout("Get a RFD configure:\n"
- "\tstatus:%#x\n"
- "\tok:%#x\n" "\tc:%#x\n" "\tsf:%#x\n"
- "\th:%#x\n" "\ts:%#x\n" "\tel:%#x\n"
- "\tlink add:%#x\n" "\tactual count:%#x\n"
- "\tf:%#x\n" "\teof:%#x\n" "\tsize:%#x\n",
- rfd.status, rfd.ok, rfd.c, rfd.sf, rfd.h,
- rfd.s, rfd.el, rfd.link_addr, rfd.count,
- rfd.f, rfd.eof, rfd.size);
-
- cpu_physical_memory_write(rfd_addr, (uint8_t *)&rfd, sizeof(rfd));
- cpu_physical_memory_write(rfd_addr + sizeof(rfd_t), buf, size);
- s->statistics.rx_good_frames ++;
- s->ru_offset = le32_to_cpu(rfd.link_addr);
-
- e100_interrupt(s, INT_FR);
-
- if ( rfd.el || rfd.s )
- {
- /* Go to suspend */
- SET_RU_STATE(RU_SUSPENDED);
- e100_interrupt(s, INT_RNR);
- logout("RFD met S or EL bit set, RU go to suspend\n");
- return;
- }
-
- logout("Complete a frame receive(size = %d)\n", size);
- return;
-}
-
-static void eeprom_init(E100State *s)
-{
- int i;
- int chksum = 0;
- /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
- * i82559 and later support 64 or 256 word EEPROM. */
- eeprom_reset(s, EEPROM_RESET_ALL);
- s->eeprom.addr_len = EEPROM_I82557_ADDRBIT;
- memcpy(s->eeprom.contents, eeprom_i82557, sizeof(eeprom_i82557));
- /* Dirver is going to get MAC from eeprom*/
- memcpy((uint8_t *)s->eeprom.contents, s->macaddr, sizeof(s->macaddr));
-
- /* The last word in eeprom saving checksum value.
- * After we update MAC in eeprom, the checksum need be re-calculate
- * and saved at the end of eeprom
- */
- for ( i=0; i<(1<<s->eeprom.addr_len)-1; i++ )
- chksum += s->eeprom.contents[i];
- s->eeprom.contents[i] = 0xBABA - chksum;
-
-}
-
-static void e100_init(PCIBus * bus, NICInfo * nd,
- const char *name, uint32_t device)
-{
- PCIE100State *d;
- E100State *s;
-
- logout("\n");
-
- d = (PCIE100State *) pci_register_device(bus, name,
- sizeof(PCIE100State), -1,
- NULL, NULL);
-
- s = &d->e100;
- s->device = device;
- s->pci_dev = &d->dev;
-
- pci_reset(s);
-
-
- /* Handler for memory-mapped I/O */
- d->e100.mmio_index =
- cpu_register_io_memory(0, pci_mmio_read, pci_mmio_write, s);
-
- //CSR Memory mapped base
- pci_register_io_region(&d->dev, 0, PCI_MEM_SIZE,
- PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_MEM_PREFETCH,
- pci_mmio_map);
- //CSR I/O mapped base
- pci_register_io_region(&d->dev, 1, PCI_IO_SIZE, PCI_ADDRESS_SPACE_IO,
- pci_ioport_map);
- //Flash memory mapped base
- pci_register_io_region(&d->dev, 2, PCI_FLASH_SIZE, PCI_ADDRESS_SPACE_MEM,
- pci_mmio_map);
-
- memcpy(s->macaddr, nd->macaddr, 6);
- e100_dump("MAC ADDR", (uint8_t *)&s->macaddr[0], 6);
-
- eeprom_init(s);
-
- e100_reset(s);
-
- s->vc = qemu_new_vlan_client(nd->vlan, e100_receive, e100_can_receive, s);
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "e100 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- s->macaddr[0],
- s->macaddr[1],
- s->macaddr[2], s->macaddr[3], s->macaddr[4], s->macaddr[5]);
-
- qemu_register_reset(e100_reset, s);
-
- register_savevm(name, 0, 3, e100_save, e100_load, s);
-}
-
-void pci_e100_init(PCIBus * bus, NICInfo * nd)
-{
- e100_init(bus, nd, "e100", i82557C);
-}
-
diff --git a/tools/ioemu/hw/e1000.c b/tools/ioemu/hw/e1000.c
deleted file mode 100644
index 7375cef247..0000000000
--- a/tools/ioemu/hw/e1000.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-/*
- * QEMU e1000 emulation
- *
- * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
- * Copyright (c) 2008 Qumranet
- * Based on work done by:
- * Copyright (c) 2007 Dan Aloni
- * Copyright (c) 2004 Antony T Curtis
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "vl.h"
-
-#include "e1000_hw.h"
-
-#define DEBUG
-
-#ifdef DEBUG
-enum {
- DEBUG_GENERAL, DEBUG_IO, DEBUG_MMIO, DEBUG_INTERRUPT,
- DEBUG_RX, DEBUG_TX, DEBUG_MDIC, DEBUG_EEPROM,
- DEBUG_UNKNOWN, DEBUG_TXSUM, DEBUG_TXERR, DEBUG_RXERR,
- DEBUG_RXFILTER, DEBUG_NOTYET,
-};
-#define DBGBIT(x) (1<<DEBUG_##x)
-static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
-
-#define DBGOUT(what, fmt, params...) do { \
- if (debugflags & DBGBIT(what)) \
- fprintf(stderr, "e1000: " fmt, ##params); \
- } while (0)
-#else
-#define DBGOUT(what, fmt, params...) do {} while (0)
-#endif
-
-#define IOPORT_SIZE 0x40
-#define PNPMMIO_SIZE 0x20000
-
-/*
- * HW models:
- * E1000_DEV_ID_82540EM works with Windows and Linux
- * E1000_DEV_ID_82573L OK with windoze and Linux 2.6.22,
- * appears to perform better than 82540EM, but breaks with Linux 2.6.18
- * E1000_DEV_ID_82544GC_COPPER appears to work; not well tested
- * Others never tested
- */
-enum { E1000_DEVID = E1000_DEV_ID_82540EM };
-
-/*
- * May need to specify additional MAC-to-PHY entries --
- * Intel's Windows driver refuses to initialize unless they match
- */
-enum {
- PHY_ID2_INIT = E1000_DEVID == E1000_DEV_ID_82573L ? 0xcc2 :
- E1000_DEVID == E1000_DEV_ID_82544GC_COPPER ? 0xc30 :
- /* default to E1000_DEV_ID_82540EM */ 0xc20
-};
-
-typedef struct E1000State_st {
- PCIDevice dev;
- VLANClientState *vc;
- NICInfo *nd;
- uint32_t instance;
- uint32_t mmio_base;
- int mmio_index;
-
- uint32_t mac_reg[0x8000];
- uint16_t phy_reg[0x20];
- uint16_t eeprom_data[64];
-
- uint32_t rxbuf_size;
- uint32_t rxbuf_min_shift;
- int check_rxov;
- struct e1000_tx {
- unsigned char header[256];
- unsigned char data[0x10000];
- uint16_t size;
- unsigned char sum_needed;
- uint8_t ipcss;
- uint8_t ipcso;
- uint16_t ipcse;
- uint8_t tucss;
- uint8_t tucso;
- uint16_t tucse;
- uint8_t hdr_len;
- uint16_t mss;
- uint32_t paylen;
- uint16_t tso_frames;
- char tse;
- char ip;
- char tcp;
- char cptse; //current packet tse bit
- } tx;
-
- struct {
- uint32_t val_in; // shifted in from guest driver
- uint16_t bitnum_in;
- uint16_t bitnum_out;
- uint16_t reading;
- uint32_t old_eecd;
- } eecd_state;
-} E1000State;
-
-#define defreg(x) x = (E1000_##x>>2)
-enum {
- defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC),
- defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC),
- defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC),
- defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH),
- defreg(RDBAL), defreg(RDH), defreg(RDLEN), defreg(RDT),
- defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH),
- defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT),
- defreg(TORH), defreg(TORL), defreg(TOTH), defreg(TOTL),
- defreg(TPR), defreg(TPT), defreg(TXDCTL), defreg(WUFC),
- defreg(RA), defreg(MTA), defreg(CRCERRS),
-};
-
-enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W };
-static char phy_regcap[0x20] = {
- [PHY_STATUS] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
- [PHY_ID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW,
- [PHY_CTRL] = PHY_RW, [PHY_1000T_CTRL] = PHY_RW,
- [PHY_LP_ABILITY] = PHY_R, [PHY_1000T_STATUS] = PHY_R,
- [PHY_AUTONEG_ADV] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R,
- [PHY_ID2] = PHY_R,
-};
-
-static void
-ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr,
- uint32_t size, int type)
-{
- DBGOUT(IO, "e1000_ioport_map addr=0x%04x size=0x%08x\n", addr, size);
-}
-
-static void
-set_interrupt_cause(E1000State *s, int index, uint32_t val)
-{
- if (val)
- val |= E1000_ICR_INT_ASSERTED;
- s->mac_reg[ICR] = val;
- pci_set_irq(&s->dev, 0, (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0);
-}
-
-static void
-set_ics(E1000State *s, int index, uint32_t val)
-{
- DBGOUT(INTERRUPT, "set_ics %x, ICR %x, IMR %x\n", val, s->mac_reg[ICR],
- s->mac_reg[IMS]);
- set_interrupt_cause(s, 0, val | s->mac_reg[ICR]);
-}
-
-static int
-rxbufsize(uint32_t v)
-{
- v &= E1000_RCTL_BSEX | E1000_RCTL_SZ_16384 | E1000_RCTL_SZ_8192 |
- E1000_RCTL_SZ_4096 | E1000_RCTL_SZ_2048 | E1000_RCTL_SZ_1024 |
- E1000_RCTL_SZ_512 | E1000_RCTL_SZ_256;
- switch (v) {
- case E1000_RCTL_BSEX | E1000_RCTL_SZ_16384:
- return 16384;
- case E1000_RCTL_BSEX | E1000_RCTL_SZ_8192:
- return 8192;
- case E1000_RCTL_BSEX | E1000_RCTL_SZ_4096:
- return 4096;
- case E1000_RCTL_SZ_1024:
- return 1024;
- case E1000_RCTL_SZ_512:
- return 512;
- case E1000_RCTL_SZ_256:
- return 256;
- }
- return 2048;
-}
-
-static void
-set_rx_control(E1000State *s, int index, uint32_t val)
-{
- s->mac_reg[RCTL] = val;
- s->rxbuf_size = rxbufsize(val);
- s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
- DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
- s->mac_reg[RCTL]);
-}
-
-static void
-set_mdic(E1000State *s, int index, uint32_t val)
-{
- uint32_t data = val & E1000_MDIC_DATA_MASK;
- uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
-
- if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) // phy #
- val = s->mac_reg[MDIC] | E1000_MDIC_ERROR;
- else if (val & E1000_MDIC_OP_READ) {
- DBGOUT(MDIC, "MDIC read reg 0x%x\n", addr);
- if (!(phy_regcap[addr] & PHY_R)) {
- DBGOUT(MDIC, "MDIC read reg %x unhandled\n", addr);
- val |= E1000_MDIC_ERROR;
- } else
- val = (val ^ data) | s->phy_reg[addr];
- } else if (val & E1000_MDIC_OP_WRITE) {
- DBGOUT(MDIC, "MDIC write reg 0x%x, value 0x%x\n", addr, data);
- if (!(phy_regcap[addr] & PHY_W)) {
- DBGOUT(MDIC, "MDIC write reg %x unhandled\n", addr);
- val |= E1000_MDIC_ERROR;
- } else
- s->phy_reg[addr] = data;
- }
- s->mac_reg[MDIC] = val | E1000_MDIC_READY;
- set_ics(s, 0, E1000_ICR_MDAC);
-}
-
-static uint32_t
-get_eecd(E1000State *s, int index)
-{
- uint32_t ret = E1000_EECD_PRES|E1000_EECD_GNT | s->eecd_state.old_eecd;
-
- DBGOUT(EEPROM, "reading eeprom bit %d (reading %d)\n",
- s->eecd_state.bitnum_out, s->eecd_state.reading);
- if (!s->eecd_state.reading ||
- ((s->eeprom_data[(s->eecd_state.bitnum_out >> 4) & 0x3f] >>
- ((s->eecd_state.bitnum_out & 0xf) ^ 0xf))) & 1)
- ret |= E1000_EECD_DO;
- return ret;
-}
-
-static void
-set_eecd(E1000State *s, int index, uint32_t val)
-{
- uint32_t oldval = s->eecd_state.old_eecd;
-
- s->eecd_state.old_eecd = val & (E1000_EECD_SK | E1000_EECD_CS |
- E1000_EECD_DI|E1000_EECD_FWE_MASK|E1000_EECD_REQ);
- if (!(E1000_EECD_SK & (val ^ oldval))) // no clock edge
- return;
- if (!(E1000_EECD_SK & val)) { // falling edge
- s->eecd_state.bitnum_out++;
- return;
- }
- if (!(val & E1000_EECD_CS)) { // rising, no CS (EEPROM reset)
- memset(&s->eecd_state, 0, sizeof s->eecd_state);
- return;
- }
- s->eecd_state.val_in <<= 1;
- if (val & E1000_EECD_DI)
- s->eecd_state.val_in |= 1;
- if (++s->eecd_state.bitnum_in == 9 && !s->eecd_state.reading) {
- s->eecd_state.bitnum_out = ((s->eecd_state.val_in & 0x3f)<<4)-1;
- s->eecd_state.reading = (((s->eecd_state.val_in >> 6) & 7) ==
- EEPROM_READ_OPCODE_MICROWIRE);
- }
- DBGOUT(EEPROM, "eeprom bitnum in %d out %d, reading %d\n",
- s->eecd_state.bitnum_in, s->eecd_state.bitnum_out,
- s->eecd_state.reading);
-}
-
-static uint32_t
-flash_eerd_read(E1000State *s, int x)
-{
- unsigned int index, r = s->mac_reg[EERD] & ~E1000_EEPROM_RW_REG_START;
-
- if ((index = r >> E1000_EEPROM_RW_ADDR_SHIFT) > EEPROM_CHECKSUM_REG)
- return 0;
- return (s->eeprom_data[index] << E1000_EEPROM_RW_REG_DATA) |
- E1000_EEPROM_RW_REG_DONE | r;
-}
-
-static unsigned int
-do_cksum(uint8_t *dp, uint8_t *de)
-{
- unsigned int bsum[2] = {0, 0}, i, sum;
-
- for (i = 1; dp < de; bsum[i^=1] += *dp++)
- ;
- sum = (bsum[0] << 8) + bsum[1];
- sum = (sum >> 16) + (sum & 0xffff);
- return ~(sum + (sum >> 16));
-}
-
-static void
-putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
-{
- if (cse && cse < n)
- n = cse + 1;
- if (sloc < n-1)
- cpu_to_be16wu((uint16_t *)(data + sloc),
- do_cksum(data + css, data + n));
-}
-
-static void
-xmit_seg(E1000State *s)
-{
- uint16_t len, *sp;
- unsigned int frames = s->tx.tso_frames, css, sofar, n;
- struct e1000_tx *tp = &s->tx;
-
- if (tp->tse && tp->cptse) {
- css = tp->ipcss;
- DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",
- frames, tp->size, css);
- if (tp->ip) { // IPv4
- cpu_to_be16wu((uint16_t *)(tp->data+css+2),
- tp->size - css);
- cpu_to_be16wu((uint16_t *)(tp->data+css+4),
- be16_to_cpup((uint16_t *)(tp->data+css+4))+frames);
- } else // IPv6
- cpu_to_be16wu((uint16_t *)(tp->data+css+4),
- tp->size - css);
- css = tp->tucss;
- len = tp->size - css;
- DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);
- if (tp->tcp) {
- sofar = frames * tp->mss;
- cpu_to_be32wu((uint32_t *)(tp->data+css+4), // seq
- be32_to_cpup((uint32_t *)(tp->data+css+4))+sofar);
- if (tp->paylen - sofar > tp->mss)
- tp->data[css + 13] &= ~9; // PSH, FIN
- } else // UDP
- cpu_to_be16wu((uint16_t *)(tp->data+css+4), len);
- if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {
- // add pseudo-header length before checksum calculation
- sp = (uint16_t *)(tp->data + tp->tucso);
- cpu_to_be16wu(sp, be16_to_cpup(sp) + len);
- }
- tp->tso_frames++;
- }
-
- if (tp->sum_needed & E1000_TXD_POPTS_TXSM)
- putsum(tp->data, tp->size, tp->tucso, tp->tucss, tp->tucse);
- if (tp->sum_needed & E1000_TXD_POPTS_IXSM)
- putsum(tp->data, tp->size, tp->ipcso, tp->ipcss, tp->ipcse);
- qemu_send_packet(s->vc, tp->data, tp->size);
- s->mac_reg[TPT]++;
- s->mac_reg[GPTC]++;
- n = s->mac_reg[TOTL];
- if ((s->mac_reg[TOTL] += s->tx.size) < n)
- s->mac_reg[TOTH]++;
-}
-
-static void
-process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
-{
- uint32_t txd_lower = le32_to_cpu(dp->lower.data);
- uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D);
- unsigned int split_size = txd_lower & 0xffff, bytes, sz, op;
- unsigned int msh = 0xfffff, hdr = 0;
- uint64_t addr;
- struct e1000_context_desc *xp = (struct e1000_context_desc *)dp;
- struct e1000_tx *tp = &s->tx;
-
- if (dtype == E1000_TXD_CMD_DEXT) { // context descriptor
- op = le32_to_cpu(xp->cmd_and_length);
- tp->ipcss = xp->lower_setup.ip_fields.ipcss;
- tp->ipcso = xp->lower_setup.ip_fields.ipcso;
- tp->ipcse = le16_to_cpu(xp->lower_setup.ip_fields.ipcse);
- tp->tucss = xp->upper_setup.tcp_fields.tucss;
- tp->tucso = xp->upper_setup.tcp_fields.tucso;
- tp->tucse = le16_to_cpu(xp->upper_setup.tcp_fields.tucse);
- tp->paylen = op & 0xfffff;
- tp->hdr_len = xp->tcp_seg_setup.fields.hdr_len;
- tp->mss = le16_to_cpu(xp->tcp_seg_setup.fields.mss);
- tp->ip = (op & E1000_TXD_CMD_IP) ? 1 : 0;
- tp->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
- tp->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
- tp->tso_frames = 0;
- if (tp->tucso == 0) { // this is probably wrong
- DBGOUT(TXSUM, "TCP/UDP: cso 0!\n");
- tp->tucso = tp->tucss + (tp->tcp ? 16 : 6);
- }
- return;
- } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)){
- // data descriptor
- tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8;
- tp->cptse = ( txd_lower & E1000_TXD_CMD_TSE ) ? 1 : 0;
- } else
- // legacy descriptor
- tp->cptse = 0;
-
- addr = le64_to_cpu(dp->buffer_addr);
- if (tp->tse && tp->cptse) {
- hdr = tp->hdr_len;
- msh = hdr + tp->mss;
- do {
- bytes = split_size;
- if (tp->size + bytes > msh)
- bytes = msh - tp->size;
- cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
- if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
- memmove(tp->header, tp->data, hdr);
- tp->size = sz;
- addr += bytes;
- if (sz == msh) {
- xmit_seg(s);
- memmove(tp->data, tp->header, hdr);
- tp->size = hdr;
- }
- } while (split_size -= bytes);
- } else if (!tp->tse && tp->cptse) {
- // context descriptor TSE is not set, while data descriptor TSE is set
- DBGOUT(TXERR, "TCP segmentaion Error\n");
- } else {
- cpu_physical_memory_read(addr, tp->data + tp->size, split_size);
- tp->size += split_size;
- }
-
- if (!(txd_lower & E1000_TXD_CMD_EOP))
- return;
- if (!(tp->tse && tp->cptse && tp->size < hdr))
- xmit_seg(s);
- tp->tso_frames = 0;
- tp->sum_needed = 0;
- tp->size = 0;
- tp->cptse = 0;
-}
-
-static uint32_t
-txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
-{
- uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data);
-
- if (!(txd_lower & (E1000_TXD_CMD_RS|E1000_TXD_CMD_RPS)))
- return 0;
- txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) &
- ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU);
- dp->upper.data = cpu_to_le32(txd_upper);
- cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp),
- (void *)&dp->upper, sizeof(dp->upper));
- return E1000_ICR_TXDW;
-}
-
-static void
-start_xmit(E1000State *s)
-{
- target_phys_addr_t base;
- struct e1000_tx_desc desc;
- uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE;
-
- if (!(s->mac_reg[TCTL] & E1000_TCTL_EN)) {
- DBGOUT(TX, "tx disabled\n");
- return;
- }
-
- while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
- base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] +
- sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
- cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
-
- DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH],
- (void *)desc.buffer_addr, desc.lower.data,
- desc.upper.data);
-
- process_tx_desc(s, &desc);
- cause |= txdesc_writeback(base, &desc);
-
- if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN])
- s->mac_reg[TDH] = 0;
- /*
- * the following could happen only if guest sw assigns
- * bogus values to TDT/TDLEN.
- * there's nothing too intelligent we could do about this.
- */
- if (s->mac_reg[TDH] == tdh_start) {
- DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
- tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
- break;
- }
- }
- set_ics(s, 0, cause);
-}
-
-static int
-receive_filter(E1000State *s, const uint8_t *buf, int size)
-{
- static uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- static int mta_shift[] = {4, 3, 2, 0};
- uint32_t f, rctl = s->mac_reg[RCTL], ra[2], *rp;
-
- if (rctl & E1000_RCTL_UPE) // promiscuous
- return 1;
-
- if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE)) // promiscuous mcast
- return 1;
-
- if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast))
- return 1;
-
- for (rp = s->mac_reg + RA; rp < s->mac_reg + RA + 32; rp += 2) {
- if (!(rp[1] & E1000_RAH_AV))
- continue;
- ra[0] = cpu_to_le32(rp[0]);
- ra[1] = cpu_to_le32(rp[1]);
- if (!memcmp(buf, (uint8_t *)ra, 6)) {
- DBGOUT(RXFILTER,
- "unicast match[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n",
- (int)(rp - s->mac_reg - RA)/2,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
- return 1;
- }
- }
- DBGOUT(RXFILTER, "unicast mismatch: %02x:%02x:%02x:%02x:%02x:%02x\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
-
- f = mta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
- f = (((buf[5] << 8) | buf[4]) >> f) & 0xfff;
- if (s->mac_reg[MTA + (f >> 5)] & (1 << (f & 0x1f)))
- return 1;
- DBGOUT(RXFILTER,
- "dropping, inexact filter mismatch: %02x:%02x:%02x:%02x:%02x:%02x MO %d MTA[%d] %x\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
- (rctl >> E1000_RCTL_MO_SHIFT) & 3, f >> 5,
- s->mac_reg[MTA + (f >> 5)]);
-
- return 0;
-}
-
-static int
-e1000_can_receive(void *opaque)
-{
- E1000State *s = opaque;
-
- return (!(s->mac_reg[RCTL] & E1000_RCTL_EN) ||
- s->mac_reg[RDH] != s->mac_reg[RDT]);
-}
-
-static void
-e1000_receive(void *opaque, const uint8_t *buf, int size)
-{
- E1000State *s = opaque;
- struct e1000_rx_desc desc;
- target_phys_addr_t base;
- unsigned int n, rdt;
- uint32_t rdh_start;
-
- if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
- return;
-
- if (size > s->rxbuf_size) {
- DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size,
- s->rxbuf_size);
- return;
- }
-
- if (!receive_filter(s, buf, size))
- return;
-
- rdh_start = s->mac_reg[RDH];
- size += 4; // for the header
- do {
- if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
- set_ics(s, 0, E1000_ICS_RXO);
- return;
- }
- base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
- sizeof(desc) * s->mac_reg[RDH];
- cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
- desc.status |= E1000_RXD_STAT_DD;
- if (desc.buffer_addr) {
- cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
- (void *)buf, size);
- desc.length = cpu_to_le16(size);
- desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
- } else // as per intel docs; skip descriptors with null buf addr
- DBGOUT(RX, "Null RX descriptor!!\n");
- cpu_physical_memory_write(base, (void *)&desc, sizeof(desc));
-
- if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
- s->mac_reg[RDH] = 0;
- s->check_rxov = 1;
- /* see comment in start_xmit; same here */
- if (s->mac_reg[RDH] == rdh_start) {
- DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
- rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
- set_ics(s, 0, E1000_ICS_RXO);
- return;
- }
- } while (desc.buffer_addr == 0);
-
- s->mac_reg[GPRC]++;
- s->mac_reg[TPR]++;
- n = s->mac_reg[TORL];
- if ((s->mac_reg[TORL] += size) < n)
- s->mac_reg[TORH]++;
-
- n = E1000_ICS_RXT0;
- if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])
- rdt += s->mac_reg[RDLEN] / sizeof(desc);
- if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >=
- s->mac_reg[RDLEN])
- n |= E1000_ICS_RXDMT0;
-
- set_ics(s, 0, n);
-}
-
-static uint32_t
-mac_readreg(E1000State *s, int index)
-{
- return s->mac_reg[index];
-}
-
-static uint32_t
-mac_icr_read(E1000State *s, int index)
-{
- uint32_t ret = s->mac_reg[ICR];
-
- DBGOUT(INTERRUPT, "ICR read: %x\n", ret);
- set_interrupt_cause(s, 0, 0);
- return ret;
-}
-
-static uint32_t
-mac_read_clr4(E1000State *s, int index)
-{
- uint32_t ret = s->mac_reg[index];
-
- s->mac_reg[index] = 0;
- return ret;
-}
-
-static uint32_t
-mac_read_clr8(E1000State *s, int index)
-{
- uint32_t ret = s->mac_reg[index];
-
- s->mac_reg[index] = 0;
- s->mac_reg[index-1] = 0;
- return ret;
-}
-
-static void
-mac_writereg(E1000State *s, int index, uint32_t val)
-{
- s->mac_reg[index] = val;
-}
-
-static void
-set_rdt(E1000State *s, int index, uint32_t val)
-{
- s->check_rxov = 0;
- s->mac_reg[index] = val & 0xffff;
-}
-
-static void
-set_16bit(E1000State *s, int index, uint32_t val)
-{
- s->mac_reg[index] = val & 0xffff;
-}
-
-static void
-set_dlen(E1000State *s, int index, uint32_t val)
-{
- s->mac_reg[index] = val & 0xfff80;
-}
-
-static void
-set_tctl(E1000State *s, int index, uint32_t val)
-{
- s->mac_reg[index] = val;
- s->mac_reg[TDT] &= 0xffff;
- start_xmit(s);
-}
-
-static void
-set_icr(E1000State *s, int index, uint32_t val)
-{
- DBGOUT(INTERRUPT, "set_icr %x\n", val);
- set_interrupt_cause(s, 0, s->mac_reg[ICR] & ~val);
-}
-
-static void
-set_imc(E1000State *s, int index, uint32_t val)
-{
- s->mac_reg[IMS] &= ~val;
- set_ics(s, 0, 0);
-}
-
-static void
-set_ims(E1000State *s, int index, uint32_t val)
-{
- s->mac_reg[IMS] |= val;
- set_ics(s, 0, 0);
-}
-
-#define getreg(x) [x] = mac_readreg
-static uint32_t (*macreg_readops[])(E1000State *, int) = {
- getreg(PBA), getreg(RCTL), getreg(TDH), getreg(TXDCTL),
- getreg(WUFC), getreg(TDT), getreg(CTRL), getreg(LEDCTL),
- getreg(MANC), getreg(MDIC), getreg(SWSM), getreg(STATUS),
- getreg(TORL), getreg(TOTL), getreg(IMS), getreg(TCTL),
- getreg(RDH), getreg(RDT),
-
- [TOTH] = mac_read_clr8, [TORH] = mac_read_clr8, [GPRC] = mac_read_clr4,
- [GPTC] = mac_read_clr4, [TPR] = mac_read_clr4, [TPT] = mac_read_clr4,
- [ICR] = mac_icr_read, [EECD] = get_eecd, [EERD] = flash_eerd_read,
- [CRCERRS ... MPC] = &mac_readreg,
- [RA ... RA+31] = &mac_readreg,
- [MTA ... MTA+127] = &mac_readreg,
-};
-enum { NREADOPS = sizeof(macreg_readops) / sizeof(*macreg_readops) };
-
-#define putreg(x) [x] = mac_writereg
-static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
- putreg(PBA), putreg(EERD), putreg(SWSM), putreg(WUFC),
- putreg(TDBAL), putreg(TDBAH), putreg(TXDCTL), putreg(RDBAH),
- putreg(RDBAL), putreg(LEDCTL),
- [TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl,
- [TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics,
- [TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt,
- [IMC] = set_imc, [IMS] = set_ims, [ICR] = set_icr,
- [EECD] = set_eecd, [RCTL] = set_rx_control,
- [RA ... RA+31] = &mac_writereg,
- [MTA ... MTA+127] = &mac_writereg,
-};
-enum { NWRITEOPS = sizeof(macreg_writeops) / sizeof(*macreg_writeops) };
-
-static void
-e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- E1000State *s = opaque;
- unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
-
- if (index < NWRITEOPS && macreg_writeops[index])
- macreg_writeops[index](s, index, le32_to_cpu(val));
- else if (index < NREADOPS && macreg_readops[index])
- DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
- else
- DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
- index<<2, val);
-}
-
-static void
-e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- // emulate hw without byte enables: no RMW
- e1000_mmio_writel(opaque, addr & ~3,
- cpu_to_le32(le16_to_cpu(val & 0xffff) << (8*(addr & 3))));
-}
-
-static void
-e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- // emulate hw without byte enables: no RMW
- e1000_mmio_writel(opaque, addr & ~3,
- cpu_to_le32((val & 0xff) << (8*(addr & 3))));
-}
-
-static uint32_t
-e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- E1000State *s = opaque;
- unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
-
- if (index < NREADOPS && macreg_readops[index])
- return cpu_to_le32(macreg_readops[index](s, index));
- DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2);
- return 0;
-}
-
-static uint32_t
-e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- return (le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
- (8 * (addr & 3))) & 0xff;
-}
-
-static uint32_t
-e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- return cpu_to_le16((le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
- (8 * (addr & 3))) & 0xffff);
-}
-
-int mac_regtosave[] = {
- CTRL, EECD, EERD, GPRC, GPTC, ICR, ICS, IMC, IMS,
- LEDCTL, MANC, MDIC, MPC, PBA, RCTL, RDBAH, RDBAL, RDH,
- RDLEN, RDT, STATUS, SWSM, TCTL, TDBAH, TDBAL, TDH, TDLEN,
- TDT, TORH, TORL, TOTH, TOTL, TPR, TPT, TXDCTL, WUFC,
-};
-enum { MAC_NSAVE = sizeof mac_regtosave/sizeof *mac_regtosave };
-
-struct {
- int size;
- int array0;
-} mac_regarraystosave[] = { {32, RA}, {128, MTA} };
-enum { MAC_NARRAYS = sizeof mac_regarraystosave/sizeof *mac_regarraystosave };
-
-static void
-nic_save(QEMUFile *f, void *opaque)
-{
- E1000State *s = (E1000State *)opaque;
- int i, j;
-
- pci_device_save(&s->dev, f);
- qemu_put_be32s(f, &s->instance);
- qemu_put_be32s(f, &s->mmio_base);
- qemu_put_be32s(f, &s->rxbuf_size);
- qemu_put_be32s(f, &s->rxbuf_min_shift);
- qemu_put_be32s(f, &s->eecd_state.val_in);
- qemu_put_be16s(f, &s->eecd_state.bitnum_in);
- qemu_put_be16s(f, &s->eecd_state.bitnum_out);
- qemu_put_be16s(f, &s->eecd_state.reading);
- qemu_put_be32s(f, &s->eecd_state.old_eecd);
- qemu_put_8s(f, &s->tx.ipcss);
- qemu_put_8s(f, &s->tx.ipcso);
- qemu_put_be16s(f, &s->tx.ipcse);
- qemu_put_8s(f, &s->tx.tucss);
- qemu_put_8s(f, &s->tx.tucso);
- qemu_put_be16s(f, &s->tx.tucse);
- qemu_put_be32s(f, &s->tx.paylen);
- qemu_put_8s(f, &s->tx.hdr_len);
- qemu_put_be16s(f, &s->tx.mss);
- qemu_put_be16s(f, &s->tx.size);
- qemu_put_be16s(f, &s->tx.tso_frames);
- qemu_put_8s(f, &s->tx.sum_needed);
- qemu_put_8s(f, &s->tx.ip);
- qemu_put_8s(f, &s->tx.tcp);
- qemu_put_buffer(f, s->tx.header, sizeof s->tx.header);
- qemu_put_buffer(f, s->tx.data, sizeof s->tx.data);
- for (i = 0; i < 64; i++)
- qemu_put_be16s(f, s->eeprom_data + i);
- for (i = 0; i < 0x20; i++)
- qemu_put_be16s(f, s->phy_reg + i);
- for (i = 0; i < MAC_NSAVE; i++)
- qemu_put_be32s(f, s->mac_reg + mac_regtosave[i]);
- for (i = 0; i < MAC_NARRAYS; i++)
- for (j = 0; j < mac_regarraystosave[i].size; j++)
- qemu_put_be32s(f,
- s->mac_reg + mac_regarraystosave[i].array0 + j);
-}
-
-static int
-nic_load(QEMUFile *f, void *opaque, int version_id)
-{
- E1000State *s = (E1000State *)opaque;
- int i, j, ret;
-
- if ((ret = pci_device_load(&s->dev, f)) < 0)
- return ret;
- qemu_get_be32s(f, &s->instance);
- qemu_get_be32s(f, &s->mmio_base);
- qemu_get_be32s(f, &s->rxbuf_size);
- qemu_get_be32s(f, &s->rxbuf_min_shift);
- qemu_get_be32s(f, &s->eecd_state.val_in);
- qemu_get_be16s(f, &s->eecd_state.bitnum_in);
- qemu_get_be16s(f, &s->eecd_state.bitnum_out);
- qemu_get_be16s(f, &s->eecd_state.reading);
- qemu_get_be32s(f, &s->eecd_state.old_eecd);
- qemu_get_8s(f, &s->tx.ipcss);
- qemu_get_8s(f, &s->tx.ipcso);
- qemu_get_be16s(f, &s->tx.ipcse);
- qemu_get_8s(f, &s->tx.tucss);
- qemu_get_8s(f, &s->tx.tucso);
- qemu_get_be16s(f, &s->tx.tucse);
- qemu_get_be32s(f, &s->tx.paylen);
- qemu_get_8s(f, &s->tx.hdr_len);
- qemu_get_be16s(f, &s->tx.mss);
- qemu_get_be16s(f, &s->tx.size);
- qemu_get_be16s(f, &s->tx.tso_frames);
- qemu_get_8s(f, &s->tx.sum_needed);
- qemu_get_8s(f, &s->tx.ip);
- qemu_get_8s(f, &s->tx.tcp);
- qemu_get_buffer(f, s->tx.header, sizeof s->tx.header);
- qemu_get_buffer(f, s->tx.data, sizeof s->tx.data);
- for (i = 0; i < 64; i++)
- qemu_get_be16s(f, s->eeprom_data + i);
- for (i = 0; i < 0x20; i++)
- qemu_get_be16s(f, s->phy_reg + i);
- for (i = 0; i < MAC_NSAVE; i++)
- qemu_get_be32s(f, s->mac_reg + mac_regtosave[i]);
- for (i = 0; i < MAC_NARRAYS; i++)
- for (j = 0; j < mac_regarraystosave[i].size; j++)
- qemu_get_be32s(f,
- s->mac_reg + mac_regarraystosave[i].array0 + j);
- return 0;
-}
-
-static uint16_t e1000_eeprom_template[64] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000,
- 0x3000, 0x1000, 0x6403, E1000_DEVID, 0x8086, E1000_DEVID, 0x8086, 0x3040,
- 0x0008, 0x2000, 0x7e14, 0x0048, 0x1000, 0x00d8, 0x0000, 0x2700,
- 0x6cc9, 0x3150, 0x0722, 0x040b, 0x0984, 0x0000, 0xc000, 0x0706,
- 0x1008, 0x0000, 0x0f04, 0x7fff, 0x4d01, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0x0100, 0x4000, 0x121c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000,
-};
-
-static uint16_t phy_reg_init[] = {
- [PHY_CTRL] = 0x1140, [PHY_STATUS] = 0x796d, // link initially up
- [PHY_ID1] = 0x141, [PHY_ID2] = PHY_ID2_INIT,
- [PHY_1000T_CTRL] = 0x0e00, [M88E1000_PHY_SPEC_CTRL] = 0x360,
- [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60, [PHY_AUTONEG_ADV] = 0xde1,
- [PHY_LP_ABILITY] = 0x1e0, [PHY_1000T_STATUS] = 0x3c00,
-};
-
-static uint32_t mac_reg_init[] = {
- [PBA] = 0x00100030,
- [LEDCTL] = 0x602,
- [CTRL] = E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN0 |
- E1000_CTRL_SPD_1000 | E1000_CTRL_SLU,
- [STATUS] = 0x80000000 | E1000_STATUS_GIO_MASTER_ENABLE |
- E1000_STATUS_ASDV | E1000_STATUS_MTXCKOK |
- E1000_STATUS_SPEED_1000 | E1000_STATUS_FD |
- E1000_STATUS_LU,
- [MANC] = E1000_MANC_EN_MNG2HOST | E1000_MANC_RCV_TCO_EN |
- E1000_MANC_ARP_EN | E1000_MANC_0298_EN |
- E1000_MANC_RMCP_EN,
-};
-
-/* PCI interface */
-
-static CPUWriteMemoryFunc *e1000_mmio_write[] = {
- e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel
-};
-
-static CPUReadMemoryFunc *e1000_mmio_read[] = {
- e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl
-};
-
-static void
-e1000_mmio_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- E1000State *d = (E1000State *)pci_dev;
-
- DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size);
-
- d->mmio_base = addr;
- cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
-}
-
-void
-pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
-{
- E1000State *d;
- uint8_t *pci_conf;
- static int instance;
- uint16_t checksum = 0;
- char *info_str = "e1000";
- int i;
-
- d = (E1000State *)pci_register_device(bus, "e1000",
- sizeof(E1000State), devfn, NULL, NULL);
-
- pci_conf = d->dev.config;
- memset(pci_conf, 0, 256);
-
- *(uint16_t *)(pci_conf+0x00) = cpu_to_le16(0x8086);
- *(uint16_t *)(pci_conf+0x02) = cpu_to_le16(E1000_DEVID);
- *(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407);
- *(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);
- pci_conf[0x08] = 0x03;
- pci_conf[0x0a] = 0x00; // ethernet network controller
- pci_conf[0x0b] = 0x02;
- pci_conf[0x0c] = 0x10;
-
- pci_conf[0x3d] = 1; // interrupt pin 0
-
- d->mmio_index = cpu_register_io_memory(0, e1000_mmio_read,
- e1000_mmio_write, d);
-
- pci_register_io_region((PCIDevice *)d, 0, PNPMMIO_SIZE,
- PCI_ADDRESS_SPACE_MEM, e1000_mmio_map);
-
- pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE,
- PCI_ADDRESS_SPACE_IO, ioport_map);
-
- d->instance = instance++;
-
- d->nd = nd;
- memmove(d->eeprom_data, e1000_eeprom_template,
- sizeof e1000_eeprom_template);
- for (i = 0; i < 3; i++)
- d->eeprom_data[i] = (nd->macaddr[2*i+1]<<8) | nd->macaddr[2*i];
- for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
- checksum += d->eeprom_data[i];
- checksum = (uint16_t) EEPROM_SUM - checksum;
- d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
-
- memset(d->phy_reg, 0, sizeof d->phy_reg);
- memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
- memset(d->mac_reg, 0, sizeof d->mac_reg);
- memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
- d->rxbuf_min_shift = 1;
- memset(&d->tx, 0, sizeof d->tx);
-
- d->vc = qemu_new_vlan_client(nd->vlan, e1000_receive,
- e1000_can_receive, d);
-
- snprintf(d->vc->info_str, sizeof(d->vc->info_str),
- "%s macaddr=%02x:%02x:%02x:%02x:%02x:%02x", info_str,
- d->nd->macaddr[0], d->nd->macaddr[1], d->nd->macaddr[2],
- d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);
-
- register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);
-}
diff --git a/tools/ioemu/hw/e1000_hw.h b/tools/ioemu/hw/e1000_hw.h
deleted file mode 100644
index 6677775f79..0000000000
--- a/tools/ioemu/hw/e1000_hw.h
+++ /dev/null
@@ -1,865 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* e1000_hw.h
- * Structures, enums, and macros for the MAC
- */
-
-#ifndef _E1000_HW_H_
-#define _E1000_HW_H_
-
-
-/* PCI Device IDs */
-#define E1000_DEV_ID_82542 0x1000
-#define E1000_DEV_ID_82543GC_FIBER 0x1001
-#define E1000_DEV_ID_82543GC_COPPER 0x1004
-#define E1000_DEV_ID_82544EI_COPPER 0x1008
-#define E1000_DEV_ID_82544EI_FIBER 0x1009
-#define E1000_DEV_ID_82544GC_COPPER 0x100C
-#define E1000_DEV_ID_82544GC_LOM 0x100D
-#define E1000_DEV_ID_82540EM 0x100E
-#define E1000_DEV_ID_82540EM_LOM 0x1015
-#define E1000_DEV_ID_82540EP_LOM 0x1016
-#define E1000_DEV_ID_82540EP 0x1017
-#define E1000_DEV_ID_82540EP_LP 0x101E
-#define E1000_DEV_ID_82545EM_COPPER 0x100F
-#define E1000_DEV_ID_82545EM_FIBER 0x1011
-#define E1000_DEV_ID_82545GM_COPPER 0x1026
-#define E1000_DEV_ID_82545GM_FIBER 0x1027
-#define E1000_DEV_ID_82545GM_SERDES 0x1028
-#define E1000_DEV_ID_82546EB_COPPER 0x1010
-#define E1000_DEV_ID_82546EB_FIBER 0x1012
-#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
-#define E1000_DEV_ID_82541EI 0x1013
-#define E1000_DEV_ID_82541EI_MOBILE 0x1018
-#define E1000_DEV_ID_82541ER_LOM 0x1014
-#define E1000_DEV_ID_82541ER 0x1078
-#define E1000_DEV_ID_82547GI 0x1075
-#define E1000_DEV_ID_82541GI 0x1076
-#define E1000_DEV_ID_82541GI_MOBILE 0x1077
-#define E1000_DEV_ID_82541GI_LF 0x107C
-#define E1000_DEV_ID_82546GB_COPPER 0x1079
-#define E1000_DEV_ID_82546GB_FIBER 0x107A
-#define E1000_DEV_ID_82546GB_SERDES 0x107B
-#define E1000_DEV_ID_82546GB_PCIE 0x108A
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
-#define E1000_DEV_ID_82547EI 0x1019
-#define E1000_DEV_ID_82547EI_MOBILE 0x101A
-#define E1000_DEV_ID_82571EB_COPPER 0x105E
-#define E1000_DEV_ID_82571EB_FIBER 0x105F
-#define E1000_DEV_ID_82571EB_SERDES 0x1060
-#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
-#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
-#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
-#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC
-#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
-#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
-#define E1000_DEV_ID_82572EI_COPPER 0x107D
-#define E1000_DEV_ID_82572EI_FIBER 0x107E
-#define E1000_DEV_ID_82572EI_SERDES 0x107F
-#define E1000_DEV_ID_82572EI 0x10B9
-#define E1000_DEV_ID_82573E 0x108B
-#define E1000_DEV_ID_82573E_IAMT 0x108C
-#define E1000_DEV_ID_82573L 0x109A
-#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
-#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
-#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
-#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
-#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
-
-#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
-#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
-#define E1000_DEV_ID_ICH8_IGP_C 0x104B
-#define E1000_DEV_ID_ICH8_IFE 0x104C
-#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
-#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
-#define E1000_DEV_ID_ICH8_IGP_M 0x104D
-
-/* Register Set. (82543, 82544)
- *
- * Registers are defined to be 32 bits and should be accessed as 32 bit values.
- * These registers are physically located on the NIC, but are mapped into the
- * host memory address space.
- *
- * RW - register is both readable and writable
- * RO - register is read only
- * WO - register is write only
- * R/clr - register is read only and is cleared when read
- * A - register array
- */
-#define E1000_CTRL 0x00000 /* Device Control - RW */
-#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
-#define E1000_STATUS 0x00008 /* Device Status - RO */
-#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
-#define E1000_EERD 0x00014 /* EEPROM Read - RW */
-#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
-#define E1000_FLA 0x0001C /* Flash Access - RW */
-#define E1000_MDIC 0x00020 /* MDI Control - RW */
-#define E1000_SCTL 0x00024 /* SerDes Control - RW */
-#define E1000_FEXTNVM 0x00028 /* Future Extended NVM register */
-#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
-#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
-#define E1000_FCT 0x00030 /* Flow Control Type - RW */
-#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
-#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
-#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
-#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
-#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
-#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
-#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
-#define E1000_RCTL 0x00100 /* RX Control - RW */
-#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
-#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
-#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
-#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
-#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
-#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
-#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
-#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
-#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
-#define E1000_TCTL 0x00400 /* TX Control - RW */
-#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
-#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
-#define E1000_TBT 0x00448 /* TX Burst Timer - RW */
-#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
-#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
-#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
-#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
-#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
-#define FEXTNVM_SW_CONFIG 0x0001
-#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
-#define E1000_PBS 0x01008 /* Packet Buffer Size */
-#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
-#define E1000_FLASH_UPDATES 1000
-#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
-#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
-#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
-#define E1000_FLSWCTL 0x01030 /* FLASH control register */
-#define E1000_FLSWDATA 0x01034 /* FLASH data register */
-#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
-#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
-#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
-#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
-#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
-#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
-#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
-#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
-#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
-#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
-#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
-#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
-#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
-#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
-#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
-#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
-#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
-#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
-#define E1000_RXDCTL 0x02828 /* RX Descriptor Control queue 0 - RW */
-#define E1000_RXDCTL1 0x02928 /* RX Descriptor Control queue 1 - RW */
-#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
-#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
-#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
-#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
-#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
-#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
-#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
-#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
-#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
-#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
-#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
-#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
-#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
-#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
-#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
-#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */
-#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
-#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
-#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
-#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */
-#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */
-#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */
-#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */
-#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */
-#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
-#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
-#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
-#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
-#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
-#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
-#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
-#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
-#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
-#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
-#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
-#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
-#define E1000_COLC 0x04028 /* Collision Count - R/clr */
-#define E1000_DC 0x04030 /* Defer Count - R/clr */
-#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
-#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
-#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
-#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
-#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
-#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
-#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
-#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
-#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
-#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
-#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
-#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
-#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
-#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
-#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
-#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
-#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
-#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
-#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
-#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
-#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
-#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
-#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
-#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
-#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
-#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
-#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
-#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
-#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
-#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
-#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
-#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
-#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
-#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
-#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
-#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
-#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
-#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
-#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
-#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
-#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
-#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
-#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
-#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
-#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
-#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
-#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
-#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
-#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
-#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
-#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
-#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
-#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
-#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
-#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
-#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
-#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
-#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
-#define E1000_RA 0x05400 /* Receive Address - RW Array */
-#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_WUC 0x05800 /* Wakeup Control - RW */
-#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
-#define E1000_WUS 0x05810 /* Wakeup Status - RO */
-#define E1000_MANC 0x05820 /* Management Control - RW */
-#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
-#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
-#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
-#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
-#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
-#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
-#define E1000_HOST_IF 0x08800 /* Host Interface */
-#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
-#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
-
-#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
-#define E1000_MDPHYA 0x0003C /* PHY address - RW */
-#define E1000_MANC2H 0x05860 /* Managment Control To Host - RW */
-#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
-
-#define E1000_GCR 0x05B00 /* PCI-Ex Control */
-#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
-#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
-#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
-#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
-#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
-#define E1000_SWSM 0x05B50 /* SW Semaphore */
-#define E1000_FWSM 0x05B54 /* FW Semaphore */
-#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
-#define E1000_HICR 0x08F00 /* Host Inteface Control */
-
-/* RSS registers */
-#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
-#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
-#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
-#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
-#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
-#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
-
-/* PHY 1000 MII Register/Bit Definitions */
-/* PHY Registers defined by IEEE */
-#define PHY_CTRL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Regiser */
-#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
-#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
-#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
-#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
-#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */
-#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
-#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
-#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
-#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
-#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
-
-#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
-#define MAX_PHY_MULTI_PAGE_REG 0xF /* Registers equal on all pages */
-
-/* M88E1000 Specific Registers */
-#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
-#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
-#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */
-#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */
-#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
-#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
-
-#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */
-#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
-#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
-#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
-#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
-
-/* Interrupt Cause Read */
-#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
-#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
-#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
-#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO 0x00000040 /* rx overrun */
-#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
-#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_SRPD 0x00010000
-#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
-#define E1000_ICR_MNG 0x00040000 /* Manageability event */
-#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
-#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
-#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity error */
-#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
-#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
-#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */
-#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */
-#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
-
-/* Interrupt Cause Set */
-#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_ICS_SRPD E1000_ICR_SRPD
-#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICS_DSW E1000_ICR_DSW
-#define E1000_ICS_PHYINT E1000_ICR_PHYINT
-#define E1000_ICS_EPRST E1000_ICR_EPRST
-
-/* Interrupt Mask Set */
-#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMS_SRPD E1000_ICR_SRPD
-#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_IMS_DSW E1000_ICR_DSW
-#define E1000_IMS_PHYINT E1000_ICR_PHYINT
-#define E1000_IMS_EPRST E1000_ICR_EPRST
-
-/* Interrupt Mask Clear */
-#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMC_SRPD E1000_ICR_SRPD
-#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */
-#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_IMC_DSW E1000_ICR_DSW
-#define E1000_IMC_PHYINT E1000_ICR_PHYINT
-#define E1000_IMC_EPRST E1000_ICR_EPRST
-
-/* Receive Control */
-#define E1000_RCTL_RST 0x00000001 /* Software reset */
-#define E1000_RCTL_EN 0x00000002 /* enable */
-#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
-#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
-#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
-#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
-#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
-#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
-#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
-#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
-#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
-#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
-#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
-#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
-#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
-#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
-#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
-#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
-#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
-#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
-#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
-#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
-#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
-#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
-#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
-#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
-#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
-#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
-#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
-#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
-#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
-#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
-#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */
-#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */
-
-
-#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
-#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
-#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */
-#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
-#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */
-#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
-#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */
-#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */
-/* Register Bit Masks */
-/* Device Control */
-#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
-#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
-#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
-#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
-#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
-#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
-#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
-#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
-#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
-#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
-#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
-#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
-#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
-#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
-#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
-#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
-#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
-#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
-#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
-#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */
-#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
-#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
-#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
-#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
-#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
-#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */
-#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
-#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
-#define E1000_CTRL_RST 0x04000000 /* Global reset */
-#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
-#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
-#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
-#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
-#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
-#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manageability engine */
-
-/* Device Status */
-#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
-#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
-#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
-#define E1000_STATUS_FUNC_SHIFT 2
-#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
-#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
-#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
-#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */
-#define E1000_STATUS_SPEED_MASK 0x000000C0
-#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
-#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
-#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
-#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion
- by EEPROM/Flash */
-#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
-#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */
-#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
-#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
-#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
-#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
-#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
-#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */
-#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disabled */
-#define E1000_STATUS_BMC_SKU_1 0x00200000 /* BMC SRAM disabled */
-#define E1000_STATUS_BMC_SKU_2 0x00400000 /* BMC SDRAM disabled */
-#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */
-#define E1000_STATUS_BMC_LITE 0x01000000 /* BMC external code execution disabled */
-#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */
-#define E1000_STATUS_FUSE_8 0x04000000
-#define E1000_STATUS_FUSE_9 0x08000000
-#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */
-#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */
-
-/* EEPROM/Flash Control */
-#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */
-#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
-#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
-#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
-#define E1000_EECD_FWE_MASK 0x00000030
-#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
-#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
-#define E1000_EECD_FWE_SHIFT 4
-#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
-#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
-#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
-#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
-#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
- * (0-small, 1-large) */
-#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
-#ifndef E1000_EEPROM_GRANT_ATTEMPTS
-#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
-#endif
-#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
-#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
-#define E1000_EECD_SIZE_EX_SHIFT 11
-#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */
-#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
-#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
-#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
-#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
-#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
-#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
-#define E1000_EECD_SECVAL_SHIFT 22
-#define E1000_STM_OPCODE 0xDB00
-#define E1000_HICR_FW_RESET 0xC0
-
-#define E1000_SHADOW_RAM_WORDS 2048
-#define E1000_ICH_NVM_SIG_WORD 0x13
-#define E1000_ICH_NVM_SIG_MASK 0xC0
-
-/* MDI Control */
-#define E1000_MDIC_DATA_MASK 0x0000FFFF
-#define E1000_MDIC_REG_MASK 0x001F0000
-#define E1000_MDIC_REG_SHIFT 16
-#define E1000_MDIC_PHY_MASK 0x03E00000
-#define E1000_MDIC_PHY_SHIFT 21
-#define E1000_MDIC_OP_WRITE 0x04000000
-#define E1000_MDIC_OP_READ 0x08000000
-#define E1000_MDIC_READY 0x10000000
-#define E1000_MDIC_INT_EN 0x20000000
-#define E1000_MDIC_ERROR 0x40000000
-
-/* EEPROM Commands - Microwire */
-#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
-#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
-#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
-#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
-#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
-
-/* EEPROM Word Offsets */
-#define EEPROM_COMPAT 0x0003
-#define EEPROM_ID_LED_SETTINGS 0x0004
-#define EEPROM_VERSION 0x0005
-#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
-#define EEPROM_PHY_CLASS_WORD 0x0007
-#define EEPROM_INIT_CONTROL1_REG 0x000A
-#define EEPROM_INIT_CONTROL2_REG 0x000F
-#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
-#define EEPROM_INIT_CONTROL3_PORT_B 0x0014
-#define EEPROM_INIT_3GIO_3 0x001A
-#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
-#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
-#define EEPROM_CFG 0x0012
-#define EEPROM_FLASH_VERSION 0x0032
-#define EEPROM_CHECKSUM_REG 0x003F
-
-#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
-#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
- uint64_t buffer_addr; /* Address of the descriptor's data buffer */
- union {
- uint32_t data;
- struct {
- uint16_t length; /* Data buffer length */
- uint8_t cso; /* Checksum offset */
- uint8_t cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- uint32_t data;
- struct {
- uint8_t status; /* Descriptor status */
- uint8_t css; /* Checksum start */
- uint16_t special;
- } fields;
- } upper;
-};
-
-/* Transmit Descriptor bit definitions */
-#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
-#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
-#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
-#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
-#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
-#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
-#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
-#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
-#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
-#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
-#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
-#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
-#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
-#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
-#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
-#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
-#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
-#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
-#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
-#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
-
-/* Transmit Control */
-#define E1000_TCTL_RST 0x00000001 /* software reset */
-#define E1000_TCTL_EN 0x00000002 /* enable tx */
-#define E1000_TCTL_BCE 0x00000004 /* busy check enable */
-#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
-#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
-#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
-#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
-#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
-#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
-#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
-#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
-
-/* Receive Descriptor */
-struct e1000_rx_desc {
- uint64_t buffer_addr; /* Address of the descriptor's data buffer */
- uint16_t length; /* Length of data DMAed into data buffer */
- uint16_t csum; /* Packet checksum */
- uint8_t status; /* Descriptor status */
- uint8_t errors; /* Descriptor Errors */
- uint16_t special;
-};
-
-/* Receive Decriptor bit definitions */
-#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
-#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
-#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
-#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
-#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
-#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
-#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
-#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
-#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
-#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
-#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
-#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
-#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
-#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
-#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
-#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
-#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
-#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
-#define E1000_RXD_SPC_PRI_SHIFT 13
-#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
-#define E1000_RXD_SPC_CFI_SHIFT 12
-
-#define E1000_RXDEXT_STATERR_CE 0x01000000
-#define E1000_RXDEXT_STATERR_SE 0x02000000
-#define E1000_RXDEXT_STATERR_SEQ 0x04000000
-#define E1000_RXDEXT_STATERR_CXE 0x10000000
-#define E1000_RXDEXT_STATERR_TCPE 0x20000000
-#define E1000_RXDEXT_STATERR_IPE 0x40000000
-#define E1000_RXDEXT_STATERR_RXE 0x80000000
-
-#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
-#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
-
-/* Receive Address */
-#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
- union {
- uint32_t ip_config;
- struct {
- uint8_t ipcss; /* IP checksum start */
- uint8_t ipcso; /* IP checksum offset */
- uint16_t ipcse; /* IP checksum end */
- } ip_fields;
- } lower_setup;
- union {
- uint32_t tcp_config;
- struct {
- uint8_t tucss; /* TCP checksum start */
- uint8_t tucso; /* TCP checksum offset */
- uint16_t tucse; /* TCP checksum end */
- } tcp_fields;
- } upper_setup;
- uint32_t cmd_and_length; /* */
- union {
- uint32_t data;
- struct {
- uint8_t status; /* Descriptor status */
- uint8_t hdr_len; /* Header length */
- uint16_t mss; /* Maximum segment size */
- } fields;
- } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
- uint64_t buffer_addr; /* Address of the descriptor's buffer address */
- union {
- uint32_t data;
- struct {
- uint16_t length; /* Data buffer length */
- uint8_t typ_len_ext; /* */
- uint8_t cmd; /* */
- } flags;
- } lower;
- union {
- uint32_t data;
- struct {
- uint8_t status; /* Descriptor status */
- uint8_t popts; /* Packet Options */
- uint16_t special; /* */
- } fields;
- } upper;
-};
-
-/* Management Control */
-#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
-#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
-#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */
-#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */
-#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */
-#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */
-#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */
-#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */
-#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
-#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
- * Filtering */
-#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */
-#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
-#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
-#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
-#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */
-#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
-#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address
- * filtering */
-#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host
- * memory */
-#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address
- * filtering */
-#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
-#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
-#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
-#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
-#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
-#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */
-#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
-#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
-
-#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
-#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
-
-/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
-#define EEPROM_SUM 0xBABA
-
-#endif /* _E1000_HW_H_ */
diff --git a/tools/ioemu/hw/es1370.c b/tools/ioemu/hw/es1370.c
deleted file mode 100644
index 0d2d861166..0000000000
--- a/tools/ioemu/hw/es1370.c
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- * QEMU ES1370 emulation
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* #define DEBUG_ES1370 */
-/* #define VERBOSE_ES1370 */
-#define SILENT_ES1370
-
-#include "vl.h"
-
-/* Missing stuff:
- SCTRL_P[12](END|ST)INC
- SCTRL_P1SCTRLD
- SCTRL_P2DACSEN
- CTRL_DAC_SYNC
- MIDI
- non looped mode
- surely more
-*/
-
-/*
- Following macros and samplerate array were copied verbatim from
- Linux kernel 2.4.30: drivers/sound/es1370.c
-
- Copyright (C) 1998-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch)
-*/
-
-/* Start blatant GPL violation */
-
-#define ES1370_REG_CONTROL 0x00
-#define ES1370_REG_STATUS 0x04
-#define ES1370_REG_UART_DATA 0x08
-#define ES1370_REG_UART_STATUS 0x09
-#define ES1370_REG_UART_CONTROL 0x09
-#define ES1370_REG_UART_TEST 0x0a
-#define ES1370_REG_MEMPAGE 0x0c
-#define ES1370_REG_CODEC 0x10
-#define ES1370_REG_SERIAL_CONTROL 0x20
-#define ES1370_REG_DAC1_SCOUNT 0x24
-#define ES1370_REG_DAC2_SCOUNT 0x28
-#define ES1370_REG_ADC_SCOUNT 0x2c
-
-#define ES1370_REG_DAC1_FRAMEADR 0xc30
-#define ES1370_REG_DAC1_FRAMECNT 0xc34
-#define ES1370_REG_DAC2_FRAMEADR 0xc38
-#define ES1370_REG_DAC2_FRAMECNT 0xc3c
-#define ES1370_REG_ADC_FRAMEADR 0xd30
-#define ES1370_REG_ADC_FRAMECNT 0xd34
-#define ES1370_REG_PHANTOM_FRAMEADR 0xd38
-#define ES1370_REG_PHANTOM_FRAMECNT 0xd3c
-
-static const unsigned dac1_samplerate[] = { 5512, 11025, 22050, 44100 };
-
-#define DAC2_SRTODIV(x) (((1411200+(x)/2)/(x))-2)
-#define DAC2_DIVTOSR(x) (1411200/((x)+2))
-
-#define CTRL_ADC_STOP 0x80000000 /* 1 = ADC stopped */
-#define CTRL_XCTL1 0x40000000 /* electret mic bias */
-#define CTRL_OPEN 0x20000000 /* no function, can be read and written */
-#define CTRL_PCLKDIV 0x1fff0000 /* ADC/DAC2 clock divider */
-#define CTRL_SH_PCLKDIV 16
-#define CTRL_MSFMTSEL 0x00008000 /* MPEG serial data fmt: 0 = Sony, 1 = I2S */
-#define CTRL_M_SBB 0x00004000 /* DAC2 clock: 0 = PCLKDIV, 1 = MPEG */
-#define CTRL_WTSRSEL 0x00003000 /* DAC1 clock freq: 0=5512, 1=11025, 2=22050, 3=44100 */
-#define CTRL_SH_WTSRSEL 12
-#define CTRL_DAC_SYNC 0x00000800 /* 1 = DAC2 runs off DAC1 clock */
-#define CTRL_CCB_INTRM 0x00000400 /* 1 = CCB "voice" ints enabled */
-#define CTRL_M_CB 0x00000200 /* recording source: 0 = ADC, 1 = MPEG */
-#define CTRL_XCTL0 0x00000100 /* 0 = Line in, 1 = Line out */
-#define CTRL_BREQ 0x00000080 /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN 0x00000040 /* enable DAC1 */
-#define CTRL_DAC2_EN 0x00000020 /* enable DAC2 */
-#define CTRL_ADC_EN 0x00000010 /* enable ADC */
-#define CTRL_UART_EN 0x00000008 /* enable MIDI uart */
-#define CTRL_JYSTK_EN 0x00000004 /* enable Joystick port (presumably at address 0x200) */
-#define CTRL_CDC_EN 0x00000002 /* enable serial (CODEC) interface */
-#define CTRL_SERR_DIS 0x00000001 /* 1 = disable PCI SERR signal */
-
-#define STAT_INTR 0x80000000 /* wired or of all interrupt bits */
-#define STAT_CSTAT 0x00000400 /* 1 = codec busy or codec write in progress */
-#define STAT_CBUSY 0x00000200 /* 1 = codec busy */
-#define STAT_CWRIP 0x00000100 /* 1 = codec write in progress */
-#define STAT_VC 0x00000060 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
-#define STAT_SH_VC 5
-#define STAT_MCCB 0x00000010 /* CCB int pending */
-#define STAT_UART 0x00000008 /* UART int pending */
-#define STAT_DAC1 0x00000004 /* DAC1 int pending */
-#define STAT_DAC2 0x00000002 /* DAC2 int pending */
-#define STAT_ADC 0x00000001 /* ADC int pending */
-
-#define USTAT_RXINT 0x80 /* UART rx int pending */
-#define USTAT_TXINT 0x04 /* UART tx int pending */
-#define USTAT_TXRDY 0x02 /* UART tx ready */
-#define USTAT_RXRDY 0x01 /* UART rx ready */
-
-#define UCTRL_RXINTEN 0x80 /* 1 = enable RX ints */
-#define UCTRL_TXINTEN 0x60 /* TX int enable field mask */
-#define UCTRL_ENA_TXINT 0x20 /* enable TX int */
-#define UCTRL_CNTRL 0x03 /* control field */
-#define UCTRL_CNTRL_SWR 0x03 /* software reset command */
-
-#define SCTRL_P2ENDINC 0x00380000 /* */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC 0x00070000 /* */
-#define SCTRL_SH_P2STINC 16
-#define SCTRL_R1LOOPSEL 0x00008000 /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL 0x00004000 /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL 0x00002000 /* 0 = loop mode */
-#define SCTRL_P2PAUSE 0x00001000 /* 1 = pause mode */
-#define SCTRL_P1PAUSE 0x00000800 /* 1 = pause mode */
-#define SCTRL_R1INTEN 0x00000400 /* enable interrupt */
-#define SCTRL_P2INTEN 0x00000200 /* enable interrupt */
-#define SCTRL_P1INTEN 0x00000100 /* enable interrupt */
-#define SCTRL_P1SCTRLD 0x00000080 /* reload sample count register for DAC1 */
-#define SCTRL_P2DACSEN 0x00000040 /* 1 = DAC2 play back last sample when disabled */
-#define SCTRL_R1SEB 0x00000020 /* 1 = 16bit */
-#define SCTRL_R1SMB 0x00000010 /* 1 = stereo */
-#define SCTRL_R1FMT 0x00000030 /* format mask */
-#define SCTRL_SH_R1FMT 4
-#define SCTRL_P2SEB 0x00000008 /* 1 = 16bit */
-#define SCTRL_P2SMB 0x00000004 /* 1 = stereo */
-#define SCTRL_P2FMT 0x0000000c /* format mask */
-#define SCTRL_SH_P2FMT 2
-#define SCTRL_P1SEB 0x00000002 /* 1 = 16bit */
-#define SCTRL_P1SMB 0x00000001 /* 1 = stereo */
-#define SCTRL_P1FMT 0x00000003 /* format mask */
-#define SCTRL_SH_P1FMT 0
-
-/* End blatant GPL violation */
-
-#define NB_CHANNELS 3
-#define DAC1_CHANNEL 0
-#define DAC2_CHANNEL 1
-#define ADC_CHANNEL 2
-
-#define IO_READ_PROTO(n) \
-static uint32_t n (void *opaque, uint32_t addr)
-#define IO_WRITE_PROTO(n) \
-static void n (void *opaque, uint32_t addr, uint32_t val)
-
-static void es1370_dac1_callback (void *opaque, int free);
-static void es1370_dac2_callback (void *opaque, int free);
-static void es1370_adc_callback (void *opaque, int avail);
-
-#ifdef DEBUG_ES1370
-
-#define ldebug(...) AUD_log ("es1370", __VA_ARGS__)
-
-static void print_ctl (uint32_t val)
-{
- char buf[1024];
-
- buf[0] = '\0';
-#define a(n) if (val & CTRL_##n) strcat (buf, " "#n)
- a (ADC_STOP);
- a (XCTL1);
- a (OPEN);
- a (MSFMTSEL);
- a (M_SBB);
- a (DAC_SYNC);
- a (CCB_INTRM);
- a (M_CB);
- a (XCTL0);
- a (BREQ);
- a (DAC1_EN);
- a (DAC2_EN);
- a (ADC_EN);
- a (UART_EN);
- a (JYSTK_EN);
- a (CDC_EN);
- a (SERR_DIS);
-#undef a
- AUD_log ("es1370", "ctl - PCLKDIV %d(DAC2 freq %d), freq %d,%s\n",
- (val & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV,
- DAC2_DIVTOSR ((val & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV),
- dac1_samplerate[(val & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL],
- buf);
-}
-
-static void print_sctl (uint32_t val)
-{
- static const char *fmt_names[] = {"8M", "8S", "16M", "16S"};
- char buf[1024];
-
- buf[0] = '\0';
-
-#define a(n) if (val & SCTRL_##n) strcat (buf, " "#n)
-#define b(n) if (!(val & SCTRL_##n)) strcat (buf, " "#n)
- b (R1LOOPSEL);
- b (P2LOOPSEL);
- b (P1LOOPSEL);
- a (P2PAUSE);
- a (P1PAUSE);
- a (R1INTEN);
- a (P2INTEN);
- a (P1INTEN);
- a (P1SCTRLD);
- a (P2DACSEN);
- if (buf[0]) {
- strcat (buf, "\n ");
- }
- else {
- buf[0] = ' ';
- buf[1] = '\0';
- }
-#undef b
-#undef a
- AUD_log ("es1370",
- "%s"
- "p2_end_inc %d, p2_st_inc %d, r1_fmt %s, p2_fmt %s, p1_fmt %s\n",
- buf,
- (val & SCTRL_P2ENDINC) >> SCTRL_SH_P2ENDINC,
- (val & SCTRL_P2STINC) >> SCTRL_SH_P2STINC,
- fmt_names [(val >> SCTRL_SH_R1FMT) & 3],
- fmt_names [(val >> SCTRL_SH_P2FMT) & 3],
- fmt_names [(val >> SCTRL_SH_P1FMT) & 3]
- );
-}
-#else
-#define ldebug(...)
-#define print_ctl(...)
-#define print_sctl(...)
-#endif
-
-#ifdef VERBOSE_ES1370
-#define dolog(...) AUD_log ("es1370", __VA_ARGS__)
-#else
-#define dolog(...)
-#endif
-
-#ifndef SILENT_ES1370
-#define lwarn(...) AUD_log ("es1370: warning", __VA_ARGS__)
-#else
-#define lwarn(...)
-#endif
-
-struct chan {
- uint32_t shift;
- uint32_t leftover;
- uint32_t scount;
- uint32_t frame_addr;
- uint32_t frame_cnt;
-};
-
-typedef struct ES1370State {
- PCIDevice *pci_dev;
-
- QEMUSoundCard card;
- struct chan chan[NB_CHANNELS];
- SWVoiceOut *dac_voice[2];
- SWVoiceIn *adc_voice;
-
- uint32_t ctl;
- uint32_t status;
- uint32_t mempage;
- uint32_t codec;
- uint32_t sctl;
-} ES1370State;
-
-typedef struct PCIES1370State {
- PCIDevice dev;
- ES1370State es1370;
-} PCIES1370State;
-
-struct chan_bits {
- uint32_t ctl_en;
- uint32_t stat_int;
- uint32_t sctl_pause;
- uint32_t sctl_inten;
- uint32_t sctl_fmt;
- uint32_t sctl_sh_fmt;
- uint32_t sctl_loopsel;
- void (*calc_freq) (ES1370State *s, uint32_t ctl,
- uint32_t *old_freq, uint32_t *new_freq);
-};
-
-static void es1370_dac1_calc_freq (ES1370State *s, uint32_t ctl,
- uint32_t *old_freq, uint32_t *new_freq);
-static void es1370_dac2_and_adc_calc_freq (ES1370State *s, uint32_t ctl,
- uint32_t *old_freq,
- uint32_t *new_freq);
-
-static const struct chan_bits es1370_chan_bits[] = {
- {CTRL_DAC1_EN, STAT_DAC1, SCTRL_P1PAUSE, SCTRL_P1INTEN,
- SCTRL_P1FMT, SCTRL_SH_P1FMT, SCTRL_P1LOOPSEL,
- es1370_dac1_calc_freq},
-
- {CTRL_DAC2_EN, STAT_DAC2, SCTRL_P2PAUSE, SCTRL_P2INTEN,
- SCTRL_P2FMT, SCTRL_SH_P2FMT, SCTRL_P2LOOPSEL,
- es1370_dac2_and_adc_calc_freq},
-
- {CTRL_ADC_EN, STAT_ADC, 0, SCTRL_R1INTEN,
- SCTRL_R1FMT, SCTRL_SH_R1FMT, SCTRL_R1LOOPSEL,
- es1370_dac2_and_adc_calc_freq}
-};
-
-static void es1370_update_status (ES1370State *s, uint32_t new_status)
-{
- uint32_t level = new_status & (STAT_DAC1 | STAT_DAC2 | STAT_ADC);
-
- if (level) {
- s->status = new_status | STAT_INTR;
- }
- else {
- s->status = new_status & ~STAT_INTR;
- }
- pci_set_irq (s->pci_dev, 0, !!level);
-}
-
-static void es1370_reset (ES1370State *s)
-{
- size_t i;
-
- s->ctl = 1;
- s->status = 0x60;
- s->mempage = 0;
- s->codec = 0;
- s->sctl = 0;
-
- for (i = 0; i < NB_CHANNELS; ++i) {
- struct chan *d = &s->chan[i];
- d->scount = 0;
- d->leftover = 0;
- if (i == ADC_CHANNEL) {
- AUD_close_in (&s->card, s->adc_voice);
- s->adc_voice = NULL;
- }
- else {
- AUD_close_out (&s->card, s->dac_voice[i]);
- s->dac_voice[i] = NULL;
- }
- }
- pci_set_irq (s->pci_dev, 0, 0);
-}
-
-static void es1370_maybe_lower_irq (ES1370State *s, uint32_t sctl)
-{
- uint32_t new_status = s->status;
-
- if (!(sctl & SCTRL_P1INTEN) && (s->sctl & SCTRL_P1INTEN)) {
- new_status &= ~STAT_DAC1;
- }
-
- if (!(sctl & SCTRL_P2INTEN) && (s->sctl & SCTRL_P2INTEN)) {
- new_status &= ~STAT_DAC2;
- }
-
- if (!(sctl & SCTRL_R1INTEN) && (s->sctl & SCTRL_R1INTEN)) {
- new_status &= ~STAT_ADC;
- }
-
- if (new_status != s->status) {
- es1370_update_status (s, new_status);
- }
-}
-
-static void es1370_dac1_calc_freq (ES1370State *s, uint32_t ctl,
- uint32_t *old_freq, uint32_t *new_freq)
-
-{
- *old_freq = dac1_samplerate[(s->ctl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL];
- *new_freq = dac1_samplerate[(ctl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL];
-}
-
-static void es1370_dac2_and_adc_calc_freq (ES1370State *s, uint32_t ctl,
- uint32_t *old_freq,
- uint32_t *new_freq)
-
-{
- uint32_t old_pclkdiv, new_pclkdiv;
-
- new_pclkdiv = (ctl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV;
- old_pclkdiv = (s->ctl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV;
- *new_freq = DAC2_DIVTOSR (new_pclkdiv);
- *old_freq = DAC2_DIVTOSR (old_pclkdiv);
-}
-
-static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl)
-{
- size_t i;
- uint32_t old_freq, new_freq, old_fmt, new_fmt;
-
- for (i = 0; i < NB_CHANNELS; ++i) {
- struct chan *d = &s->chan[i];
- const struct chan_bits *b = &es1370_chan_bits[i];
-
- new_fmt = (sctl & b->sctl_fmt) >> b->sctl_sh_fmt;
- old_fmt = (s->sctl & b->sctl_fmt) >> b->sctl_sh_fmt;
-
- b->calc_freq (s, ctl, &old_freq, &new_freq);
-
- if ((old_fmt != new_fmt) || (old_freq != new_freq)) {
- d->shift = (new_fmt & 1) + (new_fmt >> 1);
- ldebug ("channel %d, freq = %d, nchannels %d, fmt %d, shift %d\n",
- i,
- new_freq,
- 1 << (new_fmt & 1),
- (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8,
- d->shift);
- if (new_freq) {
- audsettings_t as;
-
- as.freq = new_freq;
- as.nchannels = 1 << (new_fmt & 1);
- as.fmt = (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8;
- as.endianness = 0;
-
- if (i == ADC_CHANNEL) {
- s->adc_voice =
- AUD_open_in (
- &s->card,
- s->adc_voice,
- "es1370.adc",
- s,
- es1370_adc_callback,
- &as
- );
- }
- else {
- s->dac_voice[i] =
- AUD_open_out (
- &s->card,
- s->dac_voice[i],
- i ? "es1370.dac2" : "es1370.dac1",
- s,
- i ? es1370_dac2_callback : es1370_dac1_callback,
- &as
- );
- }
- }
- }
-
- if (((ctl ^ s->ctl) & b->ctl_en)
- || ((sctl ^ s->sctl) & b->sctl_pause)) {
- int on = (ctl & b->ctl_en) && !(sctl & b->sctl_pause);
-
- if (i == ADC_CHANNEL) {
- AUD_set_active_in (s->adc_voice, on);
- }
- else {
- AUD_set_active_out (s->dac_voice[i], on);
- }
- }
- }
-
- s->ctl = ctl;
- s->sctl = sctl;
-}
-
-static inline uint32_t es1370_fixup (ES1370State *s, uint32_t addr)
-{
- addr &= 0xff;
- if (addr >= 0x30 && addr <= 0x3f)
- addr |= s->mempage << 8;
- return addr;
-}
-
-IO_WRITE_PROTO (es1370_writeb)
-{
- ES1370State *s = opaque;
- uint32_t shift, mask;
-
- addr = es1370_fixup (s, addr);
-
- switch (addr) {
- case ES1370_REG_CONTROL:
- case ES1370_REG_CONTROL + 1:
- case ES1370_REG_CONTROL + 2:
- case ES1370_REG_CONTROL + 3:
- shift = (addr - ES1370_REG_CONTROL) << 3;
- mask = 0xff << shift;
- val = (s->ctl & ~mask) | ((val & 0xff) << shift);
- es1370_update_voices (s, val, s->sctl);
- print_ctl (val);
- break;
- case ES1370_REG_MEMPAGE:
- s->mempage = val;
- break;
- case ES1370_REG_SERIAL_CONTROL:
- case ES1370_REG_SERIAL_CONTROL + 1:
- case ES1370_REG_SERIAL_CONTROL + 2:
- case ES1370_REG_SERIAL_CONTROL + 3:
- shift = (addr - ES1370_REG_SERIAL_CONTROL) << 3;
- mask = 0xff << shift;
- val = (s->sctl & ~mask) | ((val & 0xff) << shift);
- es1370_maybe_lower_irq (s, val);
- es1370_update_voices (s, s->ctl, val);
- print_sctl (val);
- break;
- default:
- lwarn ("writeb %#x <- %#x\n", addr, val);
- break;
- }
-}
-
-IO_WRITE_PROTO (es1370_writew)
-{
- ES1370State *s = opaque;
- addr = es1370_fixup (s, addr);
- uint32_t shift, mask;
- struct chan *d = &s->chan[0];
-
- switch (addr) {
- case ES1370_REG_CODEC:
- dolog ("ignored codec write address %#x, data %#x\n",
- (val >> 8) & 0xff, val & 0xff);
- s->codec = val;
- break;
-
- case ES1370_REG_CONTROL:
- case ES1370_REG_CONTROL + 2:
- shift = (addr != ES1370_REG_CONTROL) << 4;
- mask = 0xffff << shift;
- val = (s->ctl & ~mask) | ((val & 0xffff) << shift);
- es1370_update_voices (s, val, s->sctl);
- print_ctl (val);
- break;
-
- case ES1370_REG_ADC_SCOUNT:
- d++;
- case ES1370_REG_DAC2_SCOUNT:
- d++;
- case ES1370_REG_DAC1_SCOUNT:
- d->scount = (d->scount & ~0xffff) | (val & 0xffff);
- break;
-
- default:
- lwarn ("writew %#x <- %#x\n", addr, val);
- break;
- }
-}
-
-IO_WRITE_PROTO (es1370_writel)
-{
- ES1370State *s = opaque;
- struct chan *d = &s->chan[0];
-
- addr = es1370_fixup (s, addr);
-
- switch (addr) {
- case ES1370_REG_CONTROL:
- es1370_update_voices (s, val, s->sctl);
- print_ctl (val);
- break;
-
- case ES1370_REG_MEMPAGE:
- s->mempage = val & 0xf;
- break;
-
- case ES1370_REG_SERIAL_CONTROL:
- es1370_maybe_lower_irq (s, val);
- es1370_update_voices (s, s->ctl, val);
- print_sctl (val);
- break;
-
- case ES1370_REG_ADC_SCOUNT:
- d++;
- case ES1370_REG_DAC2_SCOUNT:
- d++;
- case ES1370_REG_DAC1_SCOUNT:
- d->scount = (val & 0xffff) | (d->scount & ~0xffff);
- ldebug ("chan %d CURR_SAMP_CT %d, SAMP_CT %d\n",
- d - &s->chan[0], val >> 16, (val & 0xffff));
- break;
-
- case ES1370_REG_ADC_FRAMEADR:
- d++;
- case ES1370_REG_DAC2_FRAMEADR:
- d++;
- case ES1370_REG_DAC1_FRAMEADR:
- d->frame_addr = val;
- ldebug ("chan %d frame address %#x\n", d - &s->chan[0], val);
- break;
-
- case ES1370_REG_PHANTOM_FRAMECNT:
- lwarn ("writing to phantom frame count %#x\n", val);
- break;
- case ES1370_REG_PHANTOM_FRAMEADR:
- lwarn ("writing to phantom frame address %#x\n", val);
- break;
-
- case ES1370_REG_ADC_FRAMECNT:
- d++;
- case ES1370_REG_DAC2_FRAMECNT:
- d++;
- case ES1370_REG_DAC1_FRAMECNT:
- d->frame_cnt = val;
- d->leftover = 0;
- ldebug ("chan %d frame count %d, buffer size %d\n",
- d - &s->chan[0], val >> 16, val & 0xffff);
- break;
-
- default:
- lwarn ("writel %#x <- %#x\n", addr, val);
- break;
- }
-}
-
-IO_READ_PROTO (es1370_readb)
-{
- ES1370State *s = opaque;
- uint32_t val;
-
- addr = es1370_fixup (s, addr);
-
- switch (addr) {
- case 0x1b: /* Legacy */
- lwarn ("Attempt to read from legacy register\n");
- val = 5;
- break;
- case ES1370_REG_MEMPAGE:
- val = s->mempage;
- break;
- case ES1370_REG_CONTROL + 0:
- case ES1370_REG_CONTROL + 1:
- case ES1370_REG_CONTROL + 2:
- case ES1370_REG_CONTROL + 3:
- val = s->ctl >> ((addr - ES1370_REG_CONTROL) << 3);
- break;
- case ES1370_REG_STATUS + 0:
- case ES1370_REG_STATUS + 1:
- case ES1370_REG_STATUS + 2:
- case ES1370_REG_STATUS + 3:
- val = s->status >> ((addr - ES1370_REG_STATUS) << 3);
- break;
- default:
- val = ~0;
- lwarn ("readb %#x -> %#x\n", addr, val);
- break;
- }
- return val;
-}
-
-IO_READ_PROTO (es1370_readw)
-{
- ES1370State *s = opaque;
- struct chan *d = &s->chan[0];
- uint32_t val;
-
- addr = es1370_fixup (s, addr);
-
- switch (addr) {
- case ES1370_REG_ADC_SCOUNT + 2:
- d++;
- case ES1370_REG_DAC2_SCOUNT + 2:
- d++;
- case ES1370_REG_DAC1_SCOUNT + 2:
- val = d->scount >> 16;
- break;
-
- case ES1370_REG_ADC_FRAMECNT:
- d++;
- case ES1370_REG_DAC2_FRAMECNT:
- d++;
- case ES1370_REG_DAC1_FRAMECNT:
- val = d->frame_cnt & 0xffff;
- break;
-
- case ES1370_REG_ADC_FRAMECNT + 2:
- d++;
- case ES1370_REG_DAC2_FRAMECNT + 2:
- d++;
- case ES1370_REG_DAC1_FRAMECNT + 2:
- val = d->frame_cnt >> 16;
- break;
-
- default:
- val = ~0;
- lwarn ("readw %#x -> %#x\n", addr, val);
- break;
- }
-
- return val;
-}
-
-IO_READ_PROTO (es1370_readl)
-{
- ES1370State *s = opaque;
- uint32_t val;
- struct chan *d = &s->chan[0];
-
- addr = es1370_fixup (s, addr);
-
- switch (addr) {
- case ES1370_REG_CONTROL:
- val = s->ctl;
- break;
- case ES1370_REG_STATUS:
- val = s->status;
- break;
- case ES1370_REG_MEMPAGE:
- val = s->mempage;
- break;
- case ES1370_REG_CODEC:
- val = s->codec;
- break;
- case ES1370_REG_SERIAL_CONTROL:
- val = s->sctl;
- break;
-
- case ES1370_REG_ADC_SCOUNT:
- d++;
- case ES1370_REG_DAC2_SCOUNT:
- d++;
- case ES1370_REG_DAC1_SCOUNT:
- val = d->scount;
-#ifdef DEBUG_ES1370
- {
- uint32_t curr_count = d->scount >> 16;
- uint32_t count = d->scount & 0xffff;
-
- curr_count <<= d->shift;
- count <<= d->shift;
- dolog ("read scount curr %d, total %d\n", curr_count, count);
- }
-#endif
- break;
-
- case ES1370_REG_ADC_FRAMECNT:
- d++;
- case ES1370_REG_DAC2_FRAMECNT:
- d++;
- case ES1370_REG_DAC1_FRAMECNT:
- val = d->frame_cnt;
-#ifdef DEBUG_ES1370
- {
- uint32_t size = ((d->frame_cnt & 0xffff) + 1) << 2;
- uint32_t curr = ((d->frame_cnt >> 16) + 1) << 2;
- if (curr > size)
- dolog ("read framecnt curr %d, size %d %d\n", curr, size,
- curr > size);
- }
-#endif
- break;
-
- case ES1370_REG_ADC_FRAMEADR:
- d++;
- case ES1370_REG_DAC2_FRAMEADR:
- d++;
- case ES1370_REG_DAC1_FRAMEADR:
- val = d->frame_addr;
- break;
-
- case ES1370_REG_PHANTOM_FRAMECNT:
- val = ~0U;
- lwarn ("reading from phantom frame count\n");
- break;
- case ES1370_REG_PHANTOM_FRAMEADR:
- val = ~0U;
- lwarn ("reading from phantom frame address\n");
- break;
-
- default:
- val = ~0U;
- lwarn ("readl %#x -> %#x\n", addr, val);
- break;
- }
- return val;
-}
-
-
-static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
- int max, int *irq)
-{
- uint8_t tmpbuf[4096];
- uint32_t addr = d->frame_addr;
- int sc = d->scount & 0xffff;
- int csc = d->scount >> 16;
- int csc_bytes = (csc + 1) << d->shift;
- int cnt = d->frame_cnt >> 16;
- int size = d->frame_cnt & 0xffff;
- int left = ((size - cnt + 1) << 2) + d->leftover;
- int transfered = 0;
- int temp = audio_MIN (max, audio_MIN (left, csc_bytes));
- int index = d - &s->chan[0];
-
- addr += (cnt << 2) + d->leftover;
-
- if (index == ADC_CHANNEL) {
- while (temp) {
- int acquired, to_copy;
-
- to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf));
- acquired = AUD_read (s->adc_voice, tmpbuf, to_copy);
- if (!acquired)
- break;
-
- cpu_physical_memory_write (addr, tmpbuf, acquired);
-
- temp -= acquired;
- addr += acquired;
- transfered += acquired;
- }
- }
- else {
- SWVoiceOut *voice = s->dac_voice[index];
-
- while (temp) {
- int copied, to_copy;
-
- to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf));
- cpu_physical_memory_read (addr, tmpbuf, to_copy);
- copied = AUD_write (voice, tmpbuf, to_copy);
- if (!copied)
- break;
- temp -= copied;
- addr += copied;
- transfered += copied;
- }
- }
-
- if (csc_bytes == transfered) {
- *irq = 1;
- d->scount = sc | (sc << 16);
- ldebug ("sc = %d, rate = %f\n",
- (sc + 1) << d->shift,
- (sc + 1) / (double) 44100);
- }
- else {
- *irq = 0;
- d->scount = sc | (((csc_bytes - transfered - 1) >> d->shift) << 16);
- }
-
- cnt += (transfered + d->leftover) >> 2;
-
- if (s->sctl & loop_sel) {
- /* Bah, how stupid is that having a 0 represent true value?
- i just spent few hours on this shit */
- AUD_log ("es1370: warning", "non looping mode\n");
- }
- else {
- d->frame_cnt = size;
-
- if ((uint32_t) cnt <= d->frame_cnt)
- d->frame_cnt |= cnt << 16;
- }
-
- d->leftover = (transfered + d->leftover) & 3;
-}
-
-static void es1370_run_channel (ES1370State *s, size_t chan, int free_or_avail)
-{
- uint32_t new_status = s->status;
- int max_bytes, irq;
- struct chan *d = &s->chan[chan];
- const struct chan_bits *b = &es1370_chan_bits[chan];
-
- if (!(s->ctl & b->ctl_en) || (s->sctl & b->sctl_pause)) {
- return;
- }
-
- max_bytes = free_or_avail;
- max_bytes &= ~((1 << d->shift) - 1);
- if (!max_bytes) {
- return;
- }
-
- es1370_transfer_audio (s, d, b->sctl_loopsel, max_bytes, &irq);
-
- if (irq) {
- if (s->sctl & b->sctl_inten) {
- new_status |= b->stat_int;
- }
- }
-
- if (new_status != s->status) {
- es1370_update_status (s, new_status);
- }
-}
-
-static void es1370_dac1_callback (void *opaque, int free)
-{
- ES1370State *s = opaque;
-
- es1370_run_channel (s, DAC1_CHANNEL, free);
-}
-
-static void es1370_dac2_callback (void *opaque, int free)
-{
- ES1370State *s = opaque;
-
- es1370_run_channel (s, DAC2_CHANNEL, free);
-}
-
-static void es1370_adc_callback (void *opaque, int avail)
-{
- ES1370State *s = opaque;
-
- es1370_run_channel (s, ADC_CHANNEL, avail);
-}
-
-static void es1370_map (PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIES1370State *d = (PCIES1370State *) pci_dev;
- ES1370State *s = &d->es1370;
-
- (void) region_num;
- (void) size;
- (void) type;
-
- register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s);
- register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s);
- register_ioport_write (addr, 0x40, 4, es1370_writel, s);
-
- register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s);
- register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s);
- register_ioport_read (addr, 0x40, 4, es1370_readl, s);
-}
-
-static void es1370_save (QEMUFile *f, void *opaque)
-{
- ES1370State *s = opaque;
- size_t i;
-
- for (i = 0; i < NB_CHANNELS; ++i) {
- struct chan *d = &s->chan[i];
- qemu_put_be32s (f, &d->shift);
- qemu_put_be32s (f, &d->leftover);
- qemu_put_be32s (f, &d->scount);
- qemu_put_be32s (f, &d->frame_addr);
- qemu_put_be32s (f, &d->frame_cnt);
- }
- qemu_put_be32s (f, &s->ctl);
- qemu_put_be32s (f, &s->status);
- qemu_put_be32s (f, &s->mempage);
- qemu_put_be32s (f, &s->codec);
- qemu_put_be32s (f, &s->sctl);
-}
-
-static int es1370_load (QEMUFile *f, void *opaque, int version_id)
-{
- uint32_t ctl, sctl;
- ES1370State *s = opaque;
- size_t i;
-
- if (version_id != 1)
- return -EINVAL;
-
- for (i = 0; i < NB_CHANNELS; ++i) {
- struct chan *d = &s->chan[i];
- qemu_get_be32s (f, &d->shift);
- qemu_get_be32s (f, &d->leftover);
- qemu_get_be32s (f, &d->scount);
- qemu_get_be32s (f, &d->frame_addr);
- qemu_get_be32s (f, &d->frame_cnt);
- if (i == ADC_CHANNEL) {
- if (s->adc_voice) {
- AUD_close_in (&s->card, s->adc_voice);
- s->adc_voice = NULL;
- }
- }
- else {
- if (s->dac_voice[i]) {
- AUD_close_out (&s->card, s->dac_voice[i]);
- s->dac_voice[i] = NULL;
- }
- }
- }
-
- qemu_get_be32s (f, &ctl);
- qemu_get_be32s (f, &s->status);
- qemu_get_be32s (f, &s->mempage);
- qemu_get_be32s (f, &s->codec);
- qemu_get_be32s (f, &sctl);
-
- s->ctl = 0;
- s->sctl = 0;
- es1370_update_voices (s, ctl, sctl);
- return 0;
-}
-
-static void es1370_on_reset (void *opaque)
-{
- ES1370State *s = opaque;
- es1370_reset (s);
-}
-
-int es1370_init (PCIBus *bus, AudioState *audio)
-{
- PCIES1370State *d;
- ES1370State *s;
- uint8_t *c;
-
- if (!bus) {
- dolog ("No PCI bus\n");
- return -1;
- }
-
- if (!audio) {
- dolog ("No audio state\n");
- return -1;
- }
-
- d = (PCIES1370State *) pci_register_device (bus, "ES1370",
- sizeof (PCIES1370State),
- -1, NULL, NULL);
-
- if (!d) {
- AUD_log (NULL, "Failed to register PCI device for ES1370\n");
- return -1;
- }
-
- c = d->dev.config;
- c[0x00] = 0x74;
- c[0x01] = 0x12;
- c[0x02] = 0x00;
- c[0x03] = 0x50;
- c[0x07] = 2 << 1;
- c[0x0a] = 0x01;
- c[0x0b] = 0x04;
-
-#if 1
- c[0x2c] = 0x42;
- c[0x2d] = 0x49;
- c[0x2e] = 0x4c;
- c[0x2f] = 0x4c;
-#else
- c[0x2c] = 0x74;
- c[0x2d] = 0x12;
- c[0x2e] = 0x71;
- c[0x2f] = 0x13;
- c[0x34] = 0xdc;
- c[0x3c] = 10;
- c[0xdc] = 0x00;
-#endif
-
- c[0x3d] = 1;
- c[0x3e] = 0x0c;
- c[0x3f] = 0x80;
-
- s = &d->es1370;
- s->pci_dev = &d->dev;
-
- pci_register_io_region (&d->dev, 0, 256, PCI_ADDRESS_SPACE_IO, es1370_map);
- register_savevm ("es1370", 0, 1, es1370_save, es1370_load, s);
- qemu_register_reset (es1370_on_reset, s);
-
- AUD_register_card (audio, "es1370", &s->card);
- es1370_reset (s);
- return 0;
-}
diff --git a/tools/ioemu/hw/esp.c b/tools/ioemu/hw/esp.c
deleted file mode 100644
index fea08d8783..0000000000
--- a/tools/ioemu/hw/esp.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * QEMU ESP/NCR53C9x emulation
- *
- * Copyright (c) 2005-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug ESP card */
-//#define DEBUG_ESP
-
-/*
- * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O), also
- * produced as NCR89C100. See
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
- * and
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
- */
-
-#ifdef DEBUG_ESP
-#define DPRINTF(fmt, args...) \
-do { printf("ESP: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...)
-#endif
-
-#define ESP_MAXREG 0x3f
-#define TI_BUFSZ 32
-/* The HBA is ID 7, so for simplicitly limit to 7 devices. */
-#define ESP_MAX_DEVS 7
-
-typedef struct ESPState ESPState;
-
-struct ESPState {
- BlockDriverState **bd;
- uint8_t rregs[ESP_MAXREG];
- uint8_t wregs[ESP_MAXREG];
- int32_t ti_size;
- uint32_t ti_rptr, ti_wptr;
- uint8_t ti_buf[TI_BUFSZ];
- int sense;
- int dma;
- SCSIDevice *scsi_dev[MAX_DISKS];
- SCSIDevice *current_dev;
- uint8_t cmdbuf[TI_BUFSZ];
- int cmdlen;
- int do_cmd;
-
- /* The amount of data left in the current DMA transfer. */
- uint32_t dma_left;
- /* The size of the current DMA transfer. Zero if no transfer is in
- progress. */
- uint32_t dma_counter;
- uint8_t *async_buf;
- uint32_t async_len;
- void *dma_opaque;
-};
-
-#define STAT_DO 0x00
-#define STAT_DI 0x01
-#define STAT_CD 0x02
-#define STAT_ST 0x03
-#define STAT_MI 0x06
-#define STAT_MO 0x07
-
-#define STAT_TC 0x10
-#define STAT_PE 0x20
-#define STAT_GE 0x40
-#define STAT_IN 0x80
-
-#define INTR_FC 0x08
-#define INTR_BS 0x10
-#define INTR_DC 0x20
-#define INTR_RST 0x80
-
-#define SEQ_0 0x0
-#define SEQ_CD 0x4
-
-static int get_cmd(ESPState *s, uint8_t *buf)
-{
- uint32_t dmalen;
- int target;
-
- dmalen = s->rregs[0] | (s->rregs[1] << 8);
- target = s->wregs[4] & 7;
- DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
- if (s->dma) {
- espdma_memory_read(s->dma_opaque, buf, dmalen);
- } else {
- buf[0] = 0;
- memcpy(&buf[1], s->ti_buf, dmalen);
- dmalen++;
- }
-
- s->ti_size = 0;
- s->ti_rptr = 0;
- s->ti_wptr = 0;
-
- if (s->current_dev) {
- /* Started a new command before the old one finished. Cancel it. */
- scsi_cancel_io(s->current_dev, 0);
- s->async_len = 0;
- }
-
- if (target >= MAX_DISKS || !s->scsi_dev[target]) {
- // No such drive
- s->rregs[4] = STAT_IN;
- s->rregs[5] = INTR_DC;
- s->rregs[6] = SEQ_0;
- espdma_raise_irq(s->dma_opaque);
- return 0;
- }
- s->current_dev = s->scsi_dev[target];
- return dmalen;
-}
-
-static void do_cmd(ESPState *s, uint8_t *buf)
-{
- int32_t datalen;
- int lun;
-
- DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
- lun = buf[0] & 7;
- datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun);
- s->ti_size = datalen;
- if (datalen != 0) {
- s->rregs[4] = STAT_IN | STAT_TC;
- s->dma_left = 0;
- s->dma_counter = 0;
- if (datalen > 0) {
- s->rregs[4] |= STAT_DI;
- scsi_read_data(s->current_dev, 0);
- } else {
- s->rregs[4] |= STAT_DO;
- scsi_write_data(s->current_dev, 0);
- }
- }
- s->rregs[5] = INTR_BS | INTR_FC;
- s->rregs[6] = SEQ_CD;
- espdma_raise_irq(s->dma_opaque);
-}
-
-static void handle_satn(ESPState *s)
-{
- uint8_t buf[32];
- int len;
-
- len = get_cmd(s, buf);
- if (len)
- do_cmd(s, buf);
-}
-
-static void handle_satn_stop(ESPState *s)
-{
- s->cmdlen = get_cmd(s, s->cmdbuf);
- if (s->cmdlen) {
- DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
- s->do_cmd = 1;
- s->rregs[4] = STAT_IN | STAT_TC | STAT_CD;
- s->rregs[5] = INTR_BS | INTR_FC;
- s->rregs[6] = SEQ_CD;
- espdma_raise_irq(s->dma_opaque);
- }
-}
-
-static void write_response(ESPState *s)
-{
- DPRINTF("Transfer status (sense=%d)\n", s->sense);
- s->ti_buf[0] = s->sense;
- s->ti_buf[1] = 0;
- if (s->dma) {
- espdma_memory_write(s->dma_opaque, s->ti_buf, 2);
- s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
- s->rregs[5] = INTR_BS | INTR_FC;
- s->rregs[6] = SEQ_CD;
- } else {
- s->ti_size = 2;
- s->ti_rptr = 0;
- s->ti_wptr = 0;
- s->rregs[7] = 2;
- }
- espdma_raise_irq(s->dma_opaque);
-}
-
-static void esp_dma_done(ESPState *s)
-{
- s->rregs[4] |= STAT_IN | STAT_TC;
- s->rregs[5] = INTR_BS;
- s->rregs[6] = 0;
- s->rregs[7] = 0;
- s->rregs[0] = 0;
- s->rregs[1] = 0;
- espdma_raise_irq(s->dma_opaque);
-}
-
-static void esp_do_dma(ESPState *s)
-{
- uint32_t len;
- int to_device;
-
- to_device = (s->ti_size < 0);
- len = s->dma_left;
- if (s->do_cmd) {
- DPRINTF("command len %d + %d\n", s->cmdlen, len);
- espdma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
- s->ti_size = 0;
- s->cmdlen = 0;
- s->do_cmd = 0;
- do_cmd(s, s->cmdbuf);
- return;
- }
- if (s->async_len == 0) {
- /* Defer until data is available. */
- return;
- }
- if (len > s->async_len) {
- len = s->async_len;
- }
- if (to_device) {
- espdma_memory_read(s->dma_opaque, s->async_buf, len);
- } else {
- espdma_memory_write(s->dma_opaque, s->async_buf, len);
- }
- s->dma_left -= len;
- s->async_buf += len;
- s->async_len -= len;
- if (to_device)
- s->ti_size += len;
- else
- s->ti_size -= len;
- if (s->async_len == 0) {
- if (to_device) {
- // ti_size is negative
- scsi_write_data(s->current_dev, 0);
- } else {
- scsi_read_data(s->current_dev, 0);
- /* If there is still data to be read from the device then
- complete the DMA operation immeriately. Otherwise defer
- until the scsi layer has completed. */
- if (s->dma_left == 0 && s->ti_size > 0) {
- esp_dma_done(s);
- }
- }
- } else {
- /* Partially filled a scsi buffer. Complete immediately. */
- esp_dma_done(s);
- }
-}
-
-static void esp_command_complete(void *opaque, int reason, uint32_t tag,
- uint32_t arg)
-{
- ESPState *s = (ESPState *)opaque;
-
- if (reason == SCSI_REASON_DONE) {
- DPRINTF("SCSI Command complete\n");
- if (s->ti_size != 0)
- DPRINTF("SCSI command completed unexpectedly\n");
- s->ti_size = 0;
- s->dma_left = 0;
- s->async_len = 0;
- if (arg)
- DPRINTF("Command failed\n");
- s->sense = arg;
- s->rregs[4] = STAT_ST;
- esp_dma_done(s);
- s->current_dev = NULL;
- } else {
- DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
- s->async_len = arg;
- s->async_buf = scsi_get_buf(s->current_dev, 0);
- if (s->dma_left) {
- esp_do_dma(s);
- } else if (s->dma_counter != 0 && s->ti_size <= 0) {
- /* If this was the last part of a DMA transfer then the
- completion interrupt is deferred to here. */
- esp_dma_done(s);
- }
- }
-}
-
-static void handle_ti(ESPState *s)
-{
- uint32_t dmalen, minlen;
-
- dmalen = s->rregs[0] | (s->rregs[1] << 8);
- if (dmalen==0) {
- dmalen=0x10000;
- }
- s->dma_counter = dmalen;
-
- if (s->do_cmd)
- minlen = (dmalen < 32) ? dmalen : 32;
- else if (s->ti_size < 0)
- minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
- else
- minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
- DPRINTF("Transfer Information len %d\n", minlen);
- if (s->dma) {
- s->dma_left = minlen;
- s->rregs[4] &= ~STAT_TC;
- esp_do_dma(s);
- } else if (s->do_cmd) {
- DPRINTF("command len %d\n", s->cmdlen);
- s->ti_size = 0;
- s->cmdlen = 0;
- s->do_cmd = 0;
- do_cmd(s, s->cmdbuf);
- return;
- }
-}
-
-void esp_reset(void *opaque)
-{
- ESPState *s = opaque;
-
- memset(s->rregs, 0, ESP_MAXREG);
- memset(s->wregs, 0, ESP_MAXREG);
- s->rregs[0x0e] = 0x4; // Indicate fas100a
- s->ti_size = 0;
- s->ti_rptr = 0;
- s->ti_wptr = 0;
- s->dma = 0;
- s->do_cmd = 0;
-}
-
-static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- ESPState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & ESP_MAXREG) >> 2;
- DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
- switch (saddr) {
- case 2:
- // FIFO
- if (s->ti_size > 0) {
- s->ti_size--;
- if ((s->rregs[4] & 6) == 0) {
- /* Data in/out. */
- fprintf(stderr, "esp: PIO data read not implemented\n");
- s->rregs[2] = 0;
- } else {
- s->rregs[2] = s->ti_buf[s->ti_rptr++];
- }
- espdma_raise_irq(s->dma_opaque);
- }
- if (s->ti_size == 0) {
- s->ti_rptr = 0;
- s->ti_wptr = 0;
- }
- break;
- case 5:
- // interrupt
- // Clear interrupt/error status bits
- s->rregs[4] &= ~(STAT_IN | STAT_GE | STAT_PE);
- espdma_clear_irq(s->dma_opaque);
- break;
- default:
- break;
- }
- return s->rregs[saddr];
-}
-
-static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- ESPState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & ESP_MAXREG) >> 2;
- DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], val);
- switch (saddr) {
- case 0:
- case 1:
- s->rregs[4] &= ~STAT_TC;
- break;
- case 2:
- // FIFO
- if (s->do_cmd) {
- s->cmdbuf[s->cmdlen++] = val & 0xff;
- } else if ((s->rregs[4] & 6) == 0) {
- uint8_t buf;
- buf = val & 0xff;
- s->ti_size--;
- fprintf(stderr, "esp: PIO data write not implemented\n");
- } else {
- s->ti_size++;
- s->ti_buf[s->ti_wptr++] = val & 0xff;
- }
- break;
- case 3:
- s->rregs[saddr] = val;
- // Command
- if (val & 0x80) {
- s->dma = 1;
- /* Reload DMA counter. */
- s->rregs[0] = s->wregs[0];
- s->rregs[1] = s->wregs[1];
- } else {
- s->dma = 0;
- }
- switch(val & 0x7f) {
- case 0:
- DPRINTF("NOP (%2.2x)\n", val);
- break;
- case 1:
- DPRINTF("Flush FIFO (%2.2x)\n", val);
- //s->ti_size = 0;
- s->rregs[5] = INTR_FC;
- s->rregs[6] = 0;
- break;
- case 2:
- DPRINTF("Chip reset (%2.2x)\n", val);
- esp_reset(s);
- break;
- case 3:
- DPRINTF("Bus reset (%2.2x)\n", val);
- s->rregs[5] = INTR_RST;
- if (!(s->wregs[8] & 0x40)) {
- espdma_raise_irq(s->dma_opaque);
- }
- break;
- case 0x10:
- handle_ti(s);
- break;
- case 0x11:
- DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
- write_response(s);
- break;
- case 0x12:
- DPRINTF("Message Accepted (%2.2x)\n", val);
- write_response(s);
- s->rregs[5] = INTR_DC;
- s->rregs[6] = 0;
- break;
- case 0x1a:
- DPRINTF("Set ATN (%2.2x)\n", val);
- break;
- case 0x42:
- DPRINTF("Set ATN (%2.2x)\n", val);
- handle_satn(s);
- break;
- case 0x43:
- DPRINTF("Set ATN & stop (%2.2x)\n", val);
- handle_satn_stop(s);
- break;
- default:
- DPRINTF("Unhandled ESP command (%2.2x)\n", val);
- break;
- }
- break;
- case 4 ... 7:
- break;
- case 8:
- s->rregs[saddr] = val;
- break;
- case 9 ... 10:
- break;
- case 11:
- s->rregs[saddr] = val & 0x15;
- break;
- case 12 ... 15:
- s->rregs[saddr] = val;
- break;
- default:
- break;
- }
- s->wregs[saddr] = val;
-}
-
-static CPUReadMemoryFunc *esp_mem_read[3] = {
- esp_mem_readb,
- esp_mem_readb,
- esp_mem_readb,
-};
-
-static CPUWriteMemoryFunc *esp_mem_write[3] = {
- esp_mem_writeb,
- esp_mem_writeb,
- esp_mem_writeb,
-};
-
-static void esp_save(QEMUFile *f, void *opaque)
-{
- ESPState *s = opaque;
-
- qemu_put_buffer(f, s->rregs, ESP_MAXREG);
- qemu_put_buffer(f, s->wregs, ESP_MAXREG);
- qemu_put_be32s(f, &s->ti_size);
- qemu_put_be32s(f, &s->ti_rptr);
- qemu_put_be32s(f, &s->ti_wptr);
- qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
- qemu_put_be32s(f, &s->dma);
-}
-
-static int esp_load(QEMUFile *f, void *opaque, int version_id)
-{
- ESPState *s = opaque;
-
- if (version_id != 2)
- return -EINVAL; // Cannot emulate 1
-
- qemu_get_buffer(f, s->rregs, ESP_MAXREG);
- qemu_get_buffer(f, s->wregs, ESP_MAXREG);
- qemu_get_be32s(f, &s->ti_size);
- qemu_get_be32s(f, &s->ti_rptr);
- qemu_get_be32s(f, &s->ti_wptr);
- qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
- qemu_get_be32s(f, &s->dma);
-
- return 0;
-}
-
-void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id)
-{
- ESPState *s = (ESPState *)opaque;
-
- if (id < 0) {
- for (id = 0; id < ESP_MAX_DEVS; id++) {
- if (s->scsi_dev[id] == NULL)
- break;
- }
- }
- if (id >= ESP_MAX_DEVS) {
- DPRINTF("Bad Device ID %d\n", id);
- return;
- }
- if (s->scsi_dev[id]) {
- DPRINTF("Destroying device %d\n", id);
- scsi_disk_destroy(s->scsi_dev[id]);
- }
- DPRINTF("Attaching block device %d\n", id);
- /* Command queueing is not implemented. */
- s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
-}
-
-void *esp_init(BlockDriverState **bd, uint32_t espaddr, void *dma_opaque)
-{
- ESPState *s;
- int esp_io_memory;
-
- s = qemu_mallocz(sizeof(ESPState));
- if (!s)
- return NULL;
-
- s->bd = bd;
- s->dma_opaque = dma_opaque;
-
- esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
- cpu_register_physical_memory(espaddr, ESP_MAXREG*4, esp_io_memory);
-
- esp_reset(s);
-
- register_savevm("esp", espaddr, 2, esp_save, esp_load, s);
- qemu_register_reset(esp_reset, s);
-
- return s;
-}
diff --git a/tools/ioemu/hw/extboot.c b/tools/ioemu/hw/extboot.c
deleted file mode 100644
index 6ee4982092..0000000000
--- a/tools/ioemu/hw/extboot.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Extended boot option ROM support.
- *
- * Copyright IBM, Corp. 2007
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "vl.h"
-
-/* Extended Boot ROM suport */
-
-union extboot_cmd
-{
- uint16_t type;
- struct {
- uint16_t type;
- uint16_t cylinders;
- uint16_t heads;
- uint16_t sectors;
- } query_geometry;
- struct {
- uint16_t type;
- uint16_t nb_sectors;
- uint16_t segment;
- uint16_t offset;
- uint64_t sector;
- } xfer;
-};
-
-static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
-{
- bdrv_get_geometry_hint(bs, c, h, s);
-
- if (*c <= 1024) {
- *c >>= 0;
- *h <<= 0;
- } else if (*c <= 2048) {
- *c >>= 1;
- *h <<= 1;
- } else if (*c <= 4096) {
- *c >>= 2;
- *h <<= 2;
- } else if (*c <= 8192) {
- *c >>= 3;
- *h <<= 3;
- } else {
- *c >>= 4;
- *h <<= 4;
- }
-
- /* what is the correct algorithm for this?? */
- if (*h == 256) {
- *h = 255;
- *c = *c + 1;
- }
-}
-
-static uint32_t extboot_read(void *opaque, uint32_t addr)
-{
- int *pcmd = opaque;
- return *pcmd;
-}
-
-static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value)
-{
- union extboot_cmd *cmd = (void *)(phys_ram_base + ((value & 0xFFFF) << 4));
- BlockDriverState *bs = opaque;
- int cylinders, heads, sectors, err;
-
- get_translated_chs(bs, &cylinders, &heads, &sectors);
-
- if (cmd->type == 0x01 || cmd->type == 0x02) {
- target_ulong pa = cmd->xfer.segment * 16 + cmd->xfer.segment;
-
- /* possible buffer overflow */
- if ((pa + cmd->xfer.nb_sectors * 512) > phys_ram_size)
- return;
- }
-
- switch (cmd->type) {
- case 0x00:
- cmd->query_geometry.cylinders = cylinders;
- cmd->query_geometry.heads = heads;
- cmd->query_geometry.sectors = sectors;
- cpu_physical_memory_set_dirty((value & 0xFFFF) << 4);
- break;
- case 0x01:
- err = bdrv_read(bs, cmd->xfer.sector, phys_ram_base +
- cmd->xfer.segment * 16 + cmd->xfer.offset,
- cmd->xfer.nb_sectors);
- if (err)
- printf("Read failed\n");
- break;
- case 0x02:
- err = bdrv_write(bs, cmd->xfer.sector, phys_ram_base +
- cmd->xfer.segment * 16 + cmd->xfer.offset,
- cmd->xfer.nb_sectors);
- if (err)
- printf("Write failed\n");
-
- cpu_physical_memory_set_dirty(cmd->xfer.segment * 16 + cmd->xfer.offset);
- break;
- }
-}
-
-void extboot_init(BlockDriverState *bs, int cmd)
-{
- int *pcmd;
-
- pcmd = qemu_mallocz(sizeof(int));
- if (!pcmd) {
- fprintf(stderr, "Error allocating memory\n");
- exit(1);
- }
-
- *pcmd = cmd;
- register_ioport_read(0x404, 1, 1, extboot_read, pcmd);
- register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);
-}
diff --git a/tools/ioemu/hw/fdc.c b/tools/ioemu/hw/fdc.c
deleted file mode 100644
index 5989afd7d0..0000000000
--- a/tools/ioemu/hw/fdc.c
+++ /dev/null
@@ -1,1758 +0,0 @@
-/*
- * QEMU Floppy disk emulator (Intel 82078)
- *
- * Copyright (c) 2003 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- * The controller is used in Sun4m systems in a slightly different
- * way. There are changes in DOR register and DMA is not available.
- */
-#include "vl.h"
-
-/********************************************************/
-/* debug Floppy devices */
-//#define DEBUG_FLOPPY
-
-#ifdef DEBUG_FLOPPY
-#define FLOPPY_DPRINTF(fmt, args...) \
-do { printf("FLOPPY: " fmt , ##args); } while (0)
-#else
-#define FLOPPY_DPRINTF(fmt, args...)
-#endif
-
-#define FLOPPY_ERROR(fmt, args...) \
-do { printf("FLOPPY ERROR: %s: " fmt, __func__ , ##args); } while (0)
-
-/********************************************************/
-/* Floppy drive emulation */
-
-/* Will always be a fixed parameter for us */
-#define FD_SECTOR_LEN 512
-#define FD_SECTOR_SC 2 /* Sector size code */
-
-/* Floppy disk drive emulation */
-typedef enum fdisk_type_t {
- FDRIVE_DISK_288 = 0x01, /* 2.88 MB disk */
- FDRIVE_DISK_144 = 0x02, /* 1.44 MB disk */
- FDRIVE_DISK_720 = 0x03, /* 720 kB disk */
- FDRIVE_DISK_USER = 0x04, /* User defined geometry */
- FDRIVE_DISK_NONE = 0x05, /* No disk */
-} fdisk_type_t;
-
-typedef enum fdrive_type_t {
- FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */
- FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */
- FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */
- FDRIVE_DRV_NONE = 0x03, /* No drive connected */
-} fdrive_type_t;
-
-typedef enum fdrive_flags_t {
- FDRIVE_MOTOR_ON = 0x01, /* motor on/off */
-} fdrive_flags_t;
-
-typedef enum fdisk_flags_t {
- FDISK_DBL_SIDES = 0x01,
-} fdisk_flags_t;
-
-typedef struct fdrive_t {
- BlockDriverState *bs;
- /* Drive status */
- fdrive_type_t drive;
- fdrive_flags_t drflags;
- uint8_t perpendicular; /* 2.88 MB access mode */
- /* Position */
- uint8_t head;
- uint8_t track;
- uint8_t sect;
- /* Last operation status */
- uint8_t dir; /* Direction */
- uint8_t rw; /* Read/write */
- /* Media */
- fdisk_flags_t flags;
- uint8_t last_sect; /* Nb sector per track */
- uint8_t max_track; /* Nb of tracks */
- uint16_t bps; /* Bytes per sector */
- uint8_t ro; /* Is read-only */
-} fdrive_t;
-
-static void fd_init (fdrive_t *drv, BlockDriverState *bs)
-{
- /* Drive */
- drv->bs = bs;
- drv->drive = FDRIVE_DRV_NONE;
- drv->drflags = 0;
- drv->perpendicular = 0;
- /* Disk */
- drv->last_sect = 0;
- drv->max_track = 0;
-}
-
-static int _fd_sector (uint8_t head, uint8_t track,
- uint8_t sect, uint8_t last_sect)
-{
- return (((track * 2) + head) * last_sect) + sect - 1;
-}
-
-/* Returns current position, in sectors, for given drive */
-static int fd_sector (fdrive_t *drv)
-{
- return _fd_sector(drv->head, drv->track, drv->sect, drv->last_sect);
-}
-
-static int fd_seek (fdrive_t *drv, uint8_t head, uint8_t track, uint8_t sect,
- int enable_seek)
-{
- uint32_t sector;
- int ret;
-
- if (track > drv->max_track ||
- (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
- FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
- head, track, sect, 1,
- (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
- drv->max_track, drv->last_sect);
- return 2;
- }
- if (sect > drv->last_sect) {
- FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
- head, track, sect, 1,
- (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
- drv->max_track, drv->last_sect);
- return 3;
- }
- sector = _fd_sector(head, track, sect, drv->last_sect);
- ret = 0;
- if (sector != fd_sector(drv)) {
-#if 0
- if (!enable_seek) {
- FLOPPY_ERROR("no implicit seek %d %02x %02x (max=%d %02x %02x)\n",
- head, track, sect, 1, drv->max_track, drv->last_sect);
- return 4;
- }
-#endif
- drv->head = head;
- if (drv->track != track)
- ret = 1;
- drv->track = track;
- drv->sect = sect;
- }
-
- return ret;
-}
-
-/* Set drive back to track 0 */
-static void fd_recalibrate (fdrive_t *drv)
-{
- FLOPPY_DPRINTF("recalibrate\n");
- drv->head = 0;
- drv->track = 0;
- drv->sect = 1;
- drv->dir = 1;
- drv->rw = 0;
-}
-
-/* Recognize floppy formats */
-typedef struct fd_format_t {
- fdrive_type_t drive;
- fdisk_type_t disk;
- uint8_t last_sect;
- uint8_t max_track;
- uint8_t max_head;
- const unsigned char *str;
-} fd_format_t;
-
-static fd_format_t fd_formats[] = {
- /* First entry is default format */
- /* 1.44 MB 3"1/2 floppy disks */
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, "1.6 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
- /* 2.88 MB 3"1/2 floppy disks */
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, "3.2 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
- /* 720 kB 3"1/2 floppy disks */
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 1, "720 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, "800 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, "820 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, "830 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
- /* 1.2 MB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1, "1.2 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1, "1.6 MB 5\"1/4", },
- /* 720 kB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 80, 1, "720 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1, "880 kB 5\"1/4", },
- /* 360 kB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 1, "360 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 0, "180 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, "410 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, "420 kB 5\"1/4", },
- /* 320 kB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 1, "320 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 0, "160 kB 5\"1/4", },
- /* 360 kB must match 5"1/4 better than 3"1/2... */
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 0, "360 kB 3\"1/2", },
- /* end */
- { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
-};
-
-/* Revalidate a disk drive after a disk change */
-static void fd_revalidate (fdrive_t *drv)
-{
- fd_format_t *parse;
- int64_t nb_sectors, size;
- int i, first_match, match;
- int nb_heads, max_track, last_sect, ro;
-
- FLOPPY_DPRINTF("revalidate\n");
- if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
- ro = bdrv_is_read_only(drv->bs);
- bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
- if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
- FLOPPY_DPRINTF("User defined disk (%d %d %d)",
- nb_heads - 1, max_track, last_sect);
- } else {
- bdrv_get_geometry(drv->bs, &nb_sectors);
- match = -1;
- first_match = -1;
- for (i = 0;; i++) {
- parse = &fd_formats[i];
- if (parse->drive == FDRIVE_DRV_NONE)
- break;
- if (drv->drive == parse->drive ||
- drv->drive == FDRIVE_DRV_NONE) {
- size = (parse->max_head + 1) * parse->max_track *
- parse->last_sect;
- if (nb_sectors == size) {
- match = i;
- break;
- }
- if (first_match == -1)
- first_match = i;
- }
- }
- if (match == -1) {
- if (first_match == -1)
- match = 1;
- else
- match = first_match;
- parse = &fd_formats[match];
- }
- nb_heads = parse->max_head + 1;
- max_track = parse->max_track;
- last_sect = parse->last_sect;
- drv->drive = parse->drive;
- FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
- nb_heads, max_track, last_sect, ro ? "ro" : "rw");
- }
- if (nb_heads == 1) {
- drv->flags &= ~FDISK_DBL_SIDES;
- } else {
- drv->flags |= FDISK_DBL_SIDES;
- }
- drv->max_track = max_track;
- drv->last_sect = last_sect;
- drv->ro = ro;
- } else {
- FLOPPY_DPRINTF("No disk in drive\n");
- drv->last_sect = 0;
- drv->max_track = 0;
- drv->flags &= ~FDISK_DBL_SIDES;
- }
-}
-
-/* Motor control */
-static void fd_start (fdrive_t *drv)
-{
- drv->drflags |= FDRIVE_MOTOR_ON;
-}
-
-static void fd_stop (fdrive_t *drv)
-{
- drv->drflags &= ~FDRIVE_MOTOR_ON;
-}
-
-/* Re-initialise a drives (motor off, repositioned) */
-static void fd_reset (fdrive_t *drv)
-{
- fd_stop(drv);
- fd_recalibrate(drv);
-}
-
-/********************************************************/
-/* Intel 82078 floppy disk controller emulation */
-
-static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq);
-static void fdctrl_reset_fifo (fdctrl_t *fdctrl);
-static int fdctrl_transfer_handler (void *opaque, int nchan,
- int dma_pos, int dma_len);
-static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status);
-static void fdctrl_result_timer(void *opaque);
-
-static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl);
-static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl);
-static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl);
-static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl);
-static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_data (fdctrl_t *fdctrl);
-static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl);
-
-enum {
- FD_CTRL_ACTIVE = 0x01, /* XXX: suppress that */
- FD_CTRL_RESET = 0x02,
- FD_CTRL_SLEEP = 0x04, /* XXX: suppress that */
- FD_CTRL_BUSY = 0x08, /* dma transfer in progress */
- FD_CTRL_INTR = 0x10,
-};
-
-enum {
- FD_DIR_WRITE = 0,
- FD_DIR_READ = 1,
- FD_DIR_SCANE = 2,
- FD_DIR_SCANL = 3,
- FD_DIR_SCANH = 4,
-};
-
-enum {
- FD_STATE_CMD = 0x00,
- FD_STATE_STATUS = 0x01,
- FD_STATE_DATA = 0x02,
- FD_STATE_STATE = 0x03,
- FD_STATE_MULTI = 0x10,
- FD_STATE_SEEK = 0x20,
- FD_STATE_FORMAT = 0x40,
-};
-
-#define FD_STATE(state) ((state) & FD_STATE_STATE)
-#define FD_SET_STATE(state, new_state) \
-do { (state) = ((state) & ~FD_STATE_STATE) | (new_state); } while (0)
-#define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI)
-#define FD_DID_SEEK(state) ((state) & FD_STATE_SEEK)
-#define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
-
-struct fdctrl_t {
- fdctrl_t *fdctrl;
- /* Controller's identification */
- uint8_t version;
- /* HW */
- int irq_lvl;
- int dma_chann;
- uint32_t io_base;
- /* Controller state */
- QEMUTimer *result_timer;
- uint8_t state;
- uint8_t dma_en;
- uint8_t cur_drv;
- uint8_t bootsel;
- /* Command FIFO */
- uint8_t *fifo;
- uint32_t data_pos;
- uint32_t data_len;
- uint8_t data_state;
- uint8_t data_dir;
- uint8_t int_status;
- uint8_t eot; /* last wanted sector */
- /* States kept only to be returned back */
- /* Timers state */
- uint8_t timer0;
- uint8_t timer1;
- /* precompensation */
- uint8_t precomp_trk;
- uint8_t config;
- uint8_t lock;
- /* Power down config (also with status regB access mode */
- uint8_t pwrd;
- /* Floppy drives */
- fdrive_t drives[2];
-};
-
-static uint32_t fdctrl_read (void *opaque, uint32_t reg)
-{
- fdctrl_t *fdctrl = opaque;
- uint32_t retval;
-
- switch (reg & 0x07) {
-#ifdef TARGET_SPARC
- case 0x00:
- // Identify to Linux as S82078B
- retval = fdctrl_read_statusB(fdctrl);
- break;
-#endif
- case 0x01:
- retval = fdctrl_read_statusB(fdctrl);
- break;
- case 0x02:
- retval = fdctrl_read_dor(fdctrl);
- break;
- case 0x03:
- retval = fdctrl_read_tape(fdctrl);
- break;
- case 0x04:
- retval = fdctrl_read_main_status(fdctrl);
- break;
- case 0x05:
- retval = fdctrl_read_data(fdctrl);
- break;
- case 0x07:
- retval = fdctrl_read_dir(fdctrl);
- break;
- default:
- retval = (uint32_t)(-1);
- break;
- }
- FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval);
-
- return retval;
-}
-
-static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
-{
- fdctrl_t *fdctrl = opaque;
-
- FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
-
- switch (reg & 0x07) {
- case 0x02:
- fdctrl_write_dor(fdctrl, value);
- break;
- case 0x03:
- fdctrl_write_tape(fdctrl, value);
- break;
- case 0x04:
- fdctrl_write_rate(fdctrl, value);
- break;
- case 0x05:
- fdctrl_write_data(fdctrl, value);
- break;
- default:
- break;
- }
-}
-
-static uint32_t fdctrl_read_mem (void *opaque, target_phys_addr_t reg)
-{
- return fdctrl_read(opaque, reg);
-}
-
-static void fdctrl_write_mem (void *opaque,
- target_phys_addr_t reg, uint32_t value)
-{
- fdctrl_write(opaque, reg, value);
-}
-
-static CPUReadMemoryFunc *fdctrl_mem_read[3] = {
- fdctrl_read_mem,
- fdctrl_read_mem,
- fdctrl_read_mem,
-};
-
-static CPUWriteMemoryFunc *fdctrl_mem_write[3] = {
- fdctrl_write_mem,
- fdctrl_write_mem,
- fdctrl_write_mem,
-};
-
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
- uint32_t io_base,
- BlockDriverState **fds)
-{
- fdctrl_t *fdctrl;
- int io_mem;
- int i;
-
- FLOPPY_DPRINTF("init controller\n");
- fdctrl = qemu_mallocz(sizeof(fdctrl_t));
- if (!fdctrl)
- return NULL;
- fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
- if (fdctrl->fifo == NULL) {
- qemu_free(fdctrl);
- return NULL;
- }
- fdctrl->result_timer = qemu_new_timer(vm_clock,
- fdctrl_result_timer, fdctrl);
-
- fdctrl->version = 0x90; /* Intel 82078 controller */
- fdctrl->irq_lvl = irq_lvl;
- fdctrl->dma_chann = dma_chann;
- fdctrl->io_base = io_base;
- fdctrl->config = 0x60; /* Implicit seek, polling & FIFO enabled */
- if (fdctrl->dma_chann != -1) {
- fdctrl->dma_en = 1;
- DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
- } else {
- fdctrl->dma_en = 0;
- }
- for (i = 0; i < 2; i++) {
- fd_init(&fdctrl->drives[i], fds[i]);
- }
- fdctrl_reset(fdctrl, 0);
- fdctrl->state = FD_CTRL_ACTIVE;
- if (mem_mapped) {
- io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write, fdctrl);
- cpu_register_physical_memory(io_base, 0x08, io_mem);
- } else {
- register_ioport_read(io_base + 0x01, 5, 1, &fdctrl_read, fdctrl);
- register_ioport_read(io_base + 0x07, 1, 1, &fdctrl_read, fdctrl);
- register_ioport_write(io_base + 0x01, 5, 1, &fdctrl_write, fdctrl);
- register_ioport_write(io_base + 0x07, 1, 1, &fdctrl_write, fdctrl);
- }
- for (i = 0; i < 2; i++) {
- fd_revalidate(&fdctrl->drives[i]);
- }
-
- return fdctrl;
-}
-
-/* XXX: may change if moved to bdrv */
-int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num)
-{
- return fdctrl->drives[drive_num].drive;
-}
-
-/* Change IRQ state */
-static void fdctrl_reset_irq (fdctrl_t *fdctrl)
-{
- FLOPPY_DPRINTF("Reset interrupt\n");
- pic_set_irq(fdctrl->irq_lvl, 0);
- fdctrl->state &= ~FD_CTRL_INTR;
-}
-
-static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
-{
-#ifdef TARGET_SPARC
- // Sparc mutation
- if (!fdctrl->dma_en) {
- fdctrl->state &= ~FD_CTRL_BUSY;
- fdctrl->int_status = status;
- return;
- }
-#endif
- if (~(fdctrl->state & FD_CTRL_INTR)) {
- pic_set_irq(fdctrl->irq_lvl, 1);
- fdctrl->state |= FD_CTRL_INTR;
- }
- FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", status);
- fdctrl->int_status = status;
-}
-
-/* Reset controller */
-static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq)
-{
- int i;
-
- FLOPPY_DPRINTF("reset controller\n");
- fdctrl_reset_irq(fdctrl);
- /* Initialise controller */
- fdctrl->cur_drv = 0;
- /* FIFO state */
- fdctrl->data_pos = 0;
- fdctrl->data_len = 0;
- fdctrl->data_state = FD_STATE_CMD;
- fdctrl->data_dir = FD_DIR_WRITE;
- for (i = 0; i < MAX_FD; i++)
- fd_reset(&fdctrl->drives[i]);
- fdctrl_reset_fifo(fdctrl);
- if (do_irq)
- fdctrl_raise_irq(fdctrl, 0xc0);
-}
-
-static inline fdrive_t *drv0 (fdctrl_t *fdctrl)
-{
- return &fdctrl->drives[fdctrl->bootsel];
-}
-
-static inline fdrive_t *drv1 (fdctrl_t *fdctrl)
-{
- return &fdctrl->drives[1 - fdctrl->bootsel];
-}
-
-static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
-{
- return fdctrl->cur_drv == 0 ? drv0(fdctrl) : drv1(fdctrl);
-}
-
-/* Status B register : 0x01 (read-only) */
-static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl)
-{
- FLOPPY_DPRINTF("status register: 0x00\n");
- return 0;
-}
-
-/* Digital output register : 0x02 */
-static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- /* Drive motors state indicators */
- if (drv0(fdctrl)->drflags & FDRIVE_MOTOR_ON)
- retval |= 1 << 5;
- if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON)
- retval |= 1 << 4;
- /* DMA enable */
- retval |= fdctrl->dma_en << 3;
- /* Reset indicator */
- retval |= (fdctrl->state & FD_CTRL_RESET) == 0 ? 0x04 : 0;
- /* Selected drive */
- retval |= fdctrl->cur_drv;
- FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
-
- return retval;
-}
-
-static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value)
-{
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- if (!(value & 0x04)) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- }
- FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
- /* Drive motors state indicators */
- if (value & 0x20)
- fd_start(drv1(fdctrl));
- else
- fd_stop(drv1(fdctrl));
- if (value & 0x10)
- fd_start(drv0(fdctrl));
- else
- fd_stop(drv0(fdctrl));
- /* DMA enable */
-#if 0
- if (fdctrl->dma_chann != -1)
- fdctrl->dma_en = 1 - ((value >> 3) & 1);
-#endif
- /* Reset */
- if (!(value & 0x04)) {
- if (!(fdctrl->state & FD_CTRL_RESET)) {
- FLOPPY_DPRINTF("controller enter RESET state\n");
- fdctrl->state |= FD_CTRL_RESET;
- }
- } else {
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("controller out of RESET state\n");
- fdctrl_reset(fdctrl, 1);
- fdctrl->state &= ~(FD_CTRL_RESET | FD_CTRL_SLEEP);
- }
- }
- /* Selected drive */
- fdctrl->cur_drv = value & 1;
-}
-
-/* Tape drive register : 0x03 */
-static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- /* Disk boot selection indicator */
- retval |= fdctrl->bootsel << 2;
- /* Tape indicators: never allowed */
- FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
-
- return retval;
-}
-
-static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value)
-{
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
- /* Disk boot selection indicator */
- fdctrl->bootsel = (value >> 2) & 1;
- /* Tape indicators: never allow */
-}
-
-/* Main status register : 0x04 (read) */
-static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- fdctrl->state &= ~(FD_CTRL_SLEEP | FD_CTRL_RESET);
- if (!(fdctrl->state & FD_CTRL_BUSY)) {
- /* Data transfer allowed */
- retval |= 0x80;
- /* Data transfer direction indicator */
- if (fdctrl->data_dir == FD_DIR_READ)
- retval |= 0x40;
- }
- /* Should handle 0x20 for SPECIFY command */
- /* Command busy indicator */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA ||
- FD_STATE(fdctrl->data_state) == FD_STATE_STATUS)
- retval |= 0x10;
- FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
-
- return retval;
-}
-
-/* Data select rate register : 0x04 (write) */
-static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value)
-{
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
- /* Reset: autoclear */
- if (value & 0x80) {
- fdctrl->state |= FD_CTRL_RESET;
- fdctrl_reset(fdctrl, 1);
- fdctrl->state &= ~FD_CTRL_RESET;
- }
- if (value & 0x40) {
- fdctrl->state |= FD_CTRL_SLEEP;
- fdctrl_reset(fdctrl, 1);
- }
-// fdctrl.precomp = (value >> 2) & 0x07;
-}
-
-static int fdctrl_media_changed(fdrive_t *drv)
-{
- int ret;
- if (!drv->bs)
- return 0;
- ret = bdrv_media_changed(drv->bs);
- if (ret) {
- fd_revalidate(drv);
- }
- return ret;
-}
-
-/* Digital input register : 0x07 (read-only) */
-static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- if (fdctrl_media_changed(drv0(fdctrl)) ||
- fdctrl_media_changed(drv1(fdctrl)))
- retval |= 0x80;
- if (retval != 0)
- FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
-
- return retval;
-}
-
-/* FIFO state control */
-static void fdctrl_reset_fifo (fdctrl_t *fdctrl)
-{
- fdctrl->data_dir = FD_DIR_WRITE;
- fdctrl->data_pos = 0;
- FD_SET_STATE(fdctrl->data_state, FD_STATE_CMD);
-}
-
-/* Set FIFO status for the host to read */
-static void fdctrl_set_fifo (fdctrl_t *fdctrl, int fifo_len, int do_irq)
-{
- fdctrl->data_dir = FD_DIR_READ;
- fdctrl->data_len = fifo_len;
- fdctrl->data_pos = 0;
- FD_SET_STATE(fdctrl->data_state, FD_STATE_STATUS);
- if (do_irq)
- fdctrl_raise_irq(fdctrl, 0x00);
-}
-
-/* Set an error: unimplemented/unknown command */
-static void fdctrl_unimplemented (fdctrl_t *fdctrl)
-{
-#if 0
- fdrive_t *cur_drv;
-
- cur_drv = get_cur_drv(fdctrl);
- fdctrl->fifo[0] = 0x60 | (cur_drv->head << 2) | fdctrl->cur_drv;
- fdctrl->fifo[1] = 0x00;
- fdctrl->fifo[2] = 0x00;
- fdctrl_set_fifo(fdctrl, 3, 1);
-#else
- // fdctrl_reset_fifo(fdctrl);
- fdctrl->fifo[0] = 0x80;
- fdctrl_set_fifo(fdctrl, 1, 0);
-#endif
-}
-
-/* Callback for transfer end (stop or abort) */
-static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
- uint8_t status1, uint8_t status2)
-{
- fdrive_t *cur_drv;
-
- cur_drv = get_cur_drv(fdctrl);
- FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
- status0, status1, status2,
- status0 | (cur_drv->head << 2) | fdctrl->cur_drv);
- fdctrl->fifo[0] = status0 | (cur_drv->head << 2) | fdctrl->cur_drv;
- fdctrl->fifo[1] = status1;
- fdctrl->fifo[2] = status2;
- fdctrl->fifo[3] = cur_drv->track;
- fdctrl->fifo[4] = cur_drv->head;
- fdctrl->fifo[5] = cur_drv->sect;
- fdctrl->fifo[6] = FD_SECTOR_SC;
- fdctrl->data_dir = FD_DIR_READ;
- if (fdctrl->state & FD_CTRL_BUSY) {
- DMA_release_DREQ(fdctrl->dma_chann);
- fdctrl->state &= ~FD_CTRL_BUSY;
- }
- fdctrl_set_fifo(fdctrl, 7, 1);
-}
-
-/* Prepare a data transfer (either DMA or FIFO) */
-static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)
-{
- fdrive_t *cur_drv;
- uint8_t kh, kt, ks;
- int did_seek;
-
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- kt = fdctrl->fifo[2];
- kh = fdctrl->fifo[3];
- ks = fdctrl->fifo[4];
- FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
- fdctrl->cur_drv, kh, kt, ks,
- _fd_sector(kh, kt, ks, cur_drv->last_sect));
- did_seek = 0;
- switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {
- case 2:
- /* sect too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 3:
- /* track too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 4:
- /* No seek enabled */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 1:
- did_seek = 1;
- break;
- default:
- break;
- }
- /* Set the FIFO state */
- fdctrl->data_dir = direction;
- fdctrl->data_pos = 0;
- FD_SET_STATE(fdctrl->data_state, FD_STATE_DATA); /* FIFO ready for data */
- if (fdctrl->fifo[0] & 0x80)
- fdctrl->data_state |= FD_STATE_MULTI;
- else
- fdctrl->data_state &= ~FD_STATE_MULTI;
- if (did_seek)
- fdctrl->data_state |= FD_STATE_SEEK;
- else
- fdctrl->data_state &= ~FD_STATE_SEEK;
- if (fdctrl->fifo[5] == 00) {
- fdctrl->data_len = fdctrl->fifo[8];
- } else {
- int tmp;
- fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
- tmp = (cur_drv->last_sect - ks + 1);
- if (fdctrl->fifo[0] & 0x80)
- tmp += cur_drv->last_sect;
- fdctrl->data_len *= tmp;
- }
- fdctrl->eot = fdctrl->fifo[6];
- if (fdctrl->dma_en) {
- int dma_mode;
- /* DMA transfer are enabled. Check if DMA channel is well programmed */
- dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);
- dma_mode = (dma_mode >> 2) & 3;
- FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
- dma_mode, direction,
- (128 << fdctrl->fifo[5]) *
- (cur_drv->last_sect - ks + 1), fdctrl->data_len);
- if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||
- direction == FD_DIR_SCANH) && dma_mode == 0) ||
- (direction == FD_DIR_WRITE && dma_mode == 2) ||
- (direction == FD_DIR_READ && dma_mode == 1)) {
- /* No access is allowed until DMA transfer has completed */
- fdctrl->state |= FD_CTRL_BUSY;
- /* Now, we just have to wait for the DMA controller to
- * recall us...
- */
- DMA_hold_DREQ(fdctrl->dma_chann);
- DMA_schedule(fdctrl->dma_chann);
- return;
- } else {
- FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);
- }
- }
- FLOPPY_DPRINTF("start non-DMA transfer\n");
- /* IO based transfer: calculate len */
- fdctrl_raise_irq(fdctrl, 0x00);
-
- return;
-}
-
-/* Prepare a transfer of deleted data */
-static void fdctrl_start_transfer_del (fdctrl_t *fdctrl, int direction)
-{
- /* We don't handle deleted data,
- * so we don't return *ANYTHING*
- */
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
-}
-
-/* handlers for DMA transfers */
-static int fdctrl_transfer_handler (void *opaque, int nchan,
- int dma_pos, int dma_len)
-{
- fdctrl_t *fdctrl;
- fdrive_t *cur_drv;
- int len, start_pos, rel_pos;
- uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
-
- fdctrl = opaque;
- if (!(fdctrl->state & FD_CTRL_BUSY)) {
- FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
- return 0;
- }
- cur_drv = get_cur_drv(fdctrl);
- if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
- fdctrl->data_dir == FD_DIR_SCANH)
- status2 = 0x04;
- if (dma_len > fdctrl->data_len)
- dma_len = fdctrl->data_len;
- if (cur_drv->bs == NULL) {
- if (fdctrl->data_dir == FD_DIR_WRITE)
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
- else
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- len = 0;
- goto transfer_error;
- }
- rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
- for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
- len = dma_len - fdctrl->data_pos;
- if (len + rel_pos > FD_SECTOR_LEN)
- len = FD_SECTOR_LEN - rel_pos;
- FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x "
- "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos,
- fdctrl->data_len, fdctrl->cur_drv, cur_drv->head,
- cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
- fd_sector(cur_drv) * 512);
- if (fdctrl->data_dir != FD_DIR_WRITE ||
- len < FD_SECTOR_LEN || rel_pos != 0) {
- /* READ & SCAN commands and realign to a sector for WRITE */
- if (bdrv_read(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, 1) < 0) {
- FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
- fd_sector(cur_drv));
- /* Sure, image size is too small... */
- memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
- }
- }
- switch (fdctrl->data_dir) {
- case FD_DIR_READ:
- /* READ commands */
- DMA_write_memory (nchan, fdctrl->fifo + rel_pos,
- fdctrl->data_pos, len);
-/* cpu_physical_memory_write(addr + fdctrl->data_pos, */
-/* fdctrl->fifo + rel_pos, len); */
- break;
- case FD_DIR_WRITE:
- /* WRITE commands */
- DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
- fdctrl->data_pos, len);
-/* cpu_physical_memory_read(addr + fdctrl->data_pos, */
-/* fdctrl->fifo + rel_pos, len); */
- if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, 1) < 0) {
- FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv));
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
- goto transfer_error;
- }
- break;
- default:
- /* SCAN commands */
- {
- uint8_t tmpbuf[FD_SECTOR_LEN];
- int ret;
- DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
-/* cpu_physical_memory_read(addr + fdctrl->data_pos, */
-/* tmpbuf, len); */
- ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
- if (ret == 0) {
- status2 = 0x08;
- goto end_transfer;
- }
- if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
- (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
- status2 = 0x00;
- goto end_transfer;
- }
- }
- break;
- }
- fdctrl->data_pos += len;
- rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
- if (rel_pos == 0) {
- /* Seek to next sector */
- FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d) (%d)\n",
- cur_drv->head, cur_drv->track, cur_drv->sect,
- fd_sector(cur_drv),
- fdctrl->data_pos - len);
- /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
- error in fact */
- if (cur_drv->sect >= cur_drv->last_sect ||
- cur_drv->sect == fdctrl->eot) {
- cur_drv->sect = 1;
- if (FD_MULTI_TRACK(fdctrl->data_state)) {
- if (cur_drv->head == 0 &&
- (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
- cur_drv->head = 1;
- } else {
- cur_drv->head = 0;
- cur_drv->track++;
- if ((cur_drv->flags & FDISK_DBL_SIDES) == 0)
- break;
- }
- } else {
- cur_drv->track++;
- break;
- }
- FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
- cur_drv->head, cur_drv->track,
- cur_drv->sect, fd_sector(cur_drv));
- } else {
- cur_drv->sect++;
- }
- }
- }
-end_transfer:
- len = fdctrl->data_pos - start_pos;
- FLOPPY_DPRINTF("end transfer %d %d %d\n",
- fdctrl->data_pos, len, fdctrl->data_len);
- if (fdctrl->data_dir == FD_DIR_SCANE ||
- fdctrl->data_dir == FD_DIR_SCANL ||
- fdctrl->data_dir == FD_DIR_SCANH)
- status2 = 0x08;
- if (FD_DID_SEEK(fdctrl->data_state))
- status0 |= 0x20;
- fdctrl->data_len -= len;
- // if (fdctrl->data_len == 0)
- fdctrl_stop_transfer(fdctrl, status0, status1, status2);
-transfer_error:
-
- return len;
-}
-
-/* Data register : 0x05 */
-static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
-{
- fdrive_t *cur_drv;
- uint32_t retval = 0;
- int pos, len;
-
- cur_drv = get_cur_drv(fdctrl);
- fdctrl->state &= ~FD_CTRL_SLEEP;
- if (FD_STATE(fdctrl->data_state) == FD_STATE_CMD) {
- FLOPPY_ERROR("can't read data in CMD state\n");
- return 0;
- }
- pos = fdctrl->data_pos;
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
- pos %= FD_SECTOR_LEN;
- if (pos == 0) {
- len = fdctrl->data_len - fdctrl->data_pos;
- if (len > FD_SECTOR_LEN)
- len = FD_SECTOR_LEN;
- if (cur_drv->bs) {
- bdrv_read(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, len);
- } else {
- FLOPPY_ERROR("can't read data from drive\n");
- return 0;
- }
- }
- }
- retval = fdctrl->fifo[pos];
- if (++fdctrl->data_pos == fdctrl->data_len) {
- fdctrl->data_pos = 0;
- /* Switch from transfer mode to status mode
- * then from status mode to command mode
- */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- } else {
- fdctrl_reset_fifo(fdctrl);
- fdctrl_reset_irq(fdctrl);
- }
- }
- FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
-
- return retval;
-}
-
-static void fdctrl_format_sector (fdctrl_t *fdctrl)
-{
- fdrive_t *cur_drv;
- uint8_t kh, kt, ks;
- int did_seek;
-
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- kt = fdctrl->fifo[6];
- kh = fdctrl->fifo[7];
- ks = fdctrl->fifo[8];
- FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
- fdctrl->cur_drv, kh, kt, ks,
- _fd_sector(kh, kt, ks, cur_drv->last_sect));
- did_seek = 0;
- switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {
- case 2:
- /* sect too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 3:
- /* track too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 4:
- /* No seek enabled */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 1:
- did_seek = 1;
- fdctrl->data_state |= FD_STATE_SEEK;
- break;
- default:
- break;
- }
- memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
- if (cur_drv->bs == NULL ||
- bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
- FLOPPY_ERROR("formating sector %d\n", fd_sector(cur_drv));
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
- } else {
- if (cur_drv->sect == cur_drv->last_sect) {
- fdctrl->data_state &= ~FD_STATE_FORMAT;
- /* Last sector done */
- if (FD_DID_SEEK(fdctrl->data_state))
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- else
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
- } else {
- /* More to do */
- fdctrl->data_pos = 0;
- fdctrl->data_len = 4;
- }
- }
-}
-
-static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
-{
- fdrive_t *cur_drv;
-
- cur_drv = get_cur_drv(fdctrl);
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- fdctrl->state &= ~FD_CTRL_SLEEP;
- if (FD_STATE(fdctrl->data_state) == FD_STATE_STATUS) {
- FLOPPY_ERROR("can't write data in status mode\n");
- return;
- }
- /* Is it write command time ? */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
- /* FIFO data write */
- fdctrl->fifo[fdctrl->data_pos++] = value;
- if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) ||
- fdctrl->data_pos == fdctrl->data_len) {
- bdrv_write(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, FD_SECTOR_LEN);
- }
- /* Switch from transfer mode to status mode
- * then from status mode to command mode
- */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA)
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- return;
- }
- if (fdctrl->data_pos == 0) {
- /* Command */
- switch (value & 0x5F) {
- case 0x46:
- /* READ variants */
- FLOPPY_DPRINTF("READ command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x4C:
- /* READ_DELETED variants */
- FLOPPY_DPRINTF("READ_DELETED command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x50:
- /* SCAN_EQUAL variants */
- FLOPPY_DPRINTF("SCAN_EQUAL command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x56:
- /* VERIFY variants */
- FLOPPY_DPRINTF("VERIFY command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x59:
- /* SCAN_LOW_OR_EQUAL variants */
- FLOPPY_DPRINTF("SCAN_LOW_OR_EQUAL command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x5D:
- /* SCAN_HIGH_OR_EQUAL variants */
- FLOPPY_DPRINTF("SCAN_HIGH_OR_EQUAL command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- default:
- break;
- }
- switch (value & 0x7F) {
- case 0x45:
- /* WRITE variants */
- FLOPPY_DPRINTF("WRITE command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x49:
- /* WRITE_DELETED variants */
- FLOPPY_DPRINTF("WRITE_DELETED command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- default:
- break;
- }
- switch (value) {
- case 0x03:
- /* SPECIFY */
- FLOPPY_DPRINTF("SPECIFY command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x04:
- /* SENSE_DRIVE_STATUS */
- FLOPPY_DPRINTF("SENSE_DRIVE_STATUS command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x07:
- /* RECALIBRATE */
- FLOPPY_DPRINTF("RECALIBRATE command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x08:
- /* SENSE_INTERRUPT_STATUS */
- FLOPPY_DPRINTF("SENSE_INTERRUPT_STATUS command (%02x)\n",
- fdctrl->int_status);
- /* No parameters cmd: returns status if no interrupt */
-#if 0
- fdctrl->fifo[0] =
- fdctrl->int_status | (cur_drv->head << 2) | fdctrl->cur_drv;
-#else
- /* XXX: int_status handling is broken for read/write
- commands, so we do this hack. It should be suppressed
- ASAP */
- fdctrl->fifo[0] =
- 0x20 | (cur_drv->head << 2) | fdctrl->cur_drv;
-#endif
- fdctrl->fifo[1] = cur_drv->track;
- fdctrl_set_fifo(fdctrl, 2, 0);
- fdctrl_reset_irq(fdctrl);
- fdctrl->int_status = 0xC0;
- return;
- case 0x0E:
- /* DUMPREG */
- FLOPPY_DPRINTF("DUMPREG command\n");
- /* Drives position */
- fdctrl->fifo[0] = drv0(fdctrl)->track;
- fdctrl->fifo[1] = drv1(fdctrl)->track;
- fdctrl->fifo[2] = 0;
- fdctrl->fifo[3] = 0;
- /* timers */
- fdctrl->fifo[4] = fdctrl->timer0;
- fdctrl->fifo[5] = (fdctrl->timer1 << 1) | fdctrl->dma_en;
- fdctrl->fifo[6] = cur_drv->last_sect;
- fdctrl->fifo[7] = (fdctrl->lock << 7) |
- (cur_drv->perpendicular << 2);
- fdctrl->fifo[8] = fdctrl->config;
- fdctrl->fifo[9] = fdctrl->precomp_trk;
- fdctrl_set_fifo(fdctrl, 10, 0);
- return;
- case 0x0F:
- /* SEEK */
- FLOPPY_DPRINTF("SEEK command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x10:
- /* VERSION */
- FLOPPY_DPRINTF("VERSION command\n");
- /* No parameters cmd */
- /* Controller's version */
- fdctrl->fifo[0] = fdctrl->version;
- fdctrl_set_fifo(fdctrl, 1, 1);
- return;
- case 0x12:
- /* PERPENDICULAR_MODE */
- FLOPPY_DPRINTF("PERPENDICULAR_MODE command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x13:
- /* CONFIGURE */
- FLOPPY_DPRINTF("CONFIGURE command\n");
- /* 3 parameters cmd */
- fdctrl->data_len = 4;
- goto enqueue;
- case 0x14:
- /* UNLOCK */
- FLOPPY_DPRINTF("UNLOCK command\n");
- /* No parameters cmd */
- fdctrl->lock = 0;
- fdctrl->fifo[0] = 0;
- fdctrl_set_fifo(fdctrl, 1, 0);
- return;
- case 0x17:
- /* POWERDOWN_MODE */
- FLOPPY_DPRINTF("POWERDOWN_MODE command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x18:
- /* PART_ID */
- FLOPPY_DPRINTF("PART_ID command\n");
- /* No parameters cmd */
- fdctrl->fifo[0] = 0x41; /* Stepping 1 */
- fdctrl_set_fifo(fdctrl, 1, 0);
- return;
- case 0x2C:
- /* SAVE */
- FLOPPY_DPRINTF("SAVE command\n");
- /* No parameters cmd */
- fdctrl->fifo[0] = 0;
- fdctrl->fifo[1] = 0;
- /* Drives position */
- fdctrl->fifo[2] = drv0(fdctrl)->track;
- fdctrl->fifo[3] = drv1(fdctrl)->track;
- fdctrl->fifo[4] = 0;
- fdctrl->fifo[5] = 0;
- /* timers */
- fdctrl->fifo[6] = fdctrl->timer0;
- fdctrl->fifo[7] = fdctrl->timer1;
- fdctrl->fifo[8] = cur_drv->last_sect;
- fdctrl->fifo[9] = (fdctrl->lock << 7) |
- (cur_drv->perpendicular << 2);
- fdctrl->fifo[10] = fdctrl->config;
- fdctrl->fifo[11] = fdctrl->precomp_trk;
- fdctrl->fifo[12] = fdctrl->pwrd;
- fdctrl->fifo[13] = 0;
- fdctrl->fifo[14] = 0;
- fdctrl_set_fifo(fdctrl, 15, 1);
- return;
- case 0x33:
- /* OPTION */
- FLOPPY_DPRINTF("OPTION command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x42:
- /* READ_TRACK */
- FLOPPY_DPRINTF("READ_TRACK command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x4A:
- /* READ_ID */
- FLOPPY_DPRINTF("READ_ID command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x4C:
- /* RESTORE */
- FLOPPY_DPRINTF("RESTORE command\n");
- /* 17 parameters cmd */
- fdctrl->data_len = 18;
- goto enqueue;
- case 0x4D:
- /* FORMAT_TRACK */
- FLOPPY_DPRINTF("FORMAT_TRACK command\n");
- /* 5 parameters cmd */
- fdctrl->data_len = 6;
- goto enqueue;
- case 0x8E:
- /* DRIVE_SPECIFICATION_COMMAND */
- FLOPPY_DPRINTF("DRIVE_SPECIFICATION_COMMAND command\n");
- /* 5 parameters cmd */
- fdctrl->data_len = 6;
- goto enqueue;
- case 0x8F:
- /* RELATIVE_SEEK_OUT */
- FLOPPY_DPRINTF("RELATIVE_SEEK_OUT command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x94:
- /* LOCK */
- FLOPPY_DPRINTF("LOCK command\n");
- /* No parameters cmd */
- fdctrl->lock = 1;
- fdctrl->fifo[0] = 0x10;
- fdctrl_set_fifo(fdctrl, 1, 1);
- return;
- case 0xCD:
- /* FORMAT_AND_WRITE */
- FLOPPY_DPRINTF("FORMAT_AND_WRITE command\n");
- /* 10 parameters cmd */
- fdctrl->data_len = 11;
- goto enqueue;
- case 0xCF:
- /* RELATIVE_SEEK_IN */
- FLOPPY_DPRINTF("RELATIVE_SEEK_IN command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- default:
- /* Unknown command */
- FLOPPY_ERROR("unknown command: 0x%02x\n", value);
- fdctrl_unimplemented(fdctrl);
- return;
- }
- }
-enqueue:
- FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
- fdctrl->fifo[fdctrl->data_pos] = value;
- if (++fdctrl->data_pos == fdctrl->data_len) {
- /* We now have all parameters
- * and will be able to treat the command
- */
- if (fdctrl->data_state & FD_STATE_FORMAT) {
- fdctrl_format_sector(fdctrl);
- return;
- }
- switch (fdctrl->fifo[0] & 0x1F) {
- case 0x06:
- {
- /* READ variants */
- FLOPPY_DPRINTF("treat READ command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_READ);
- return;
- }
- case 0x0C:
- /* READ_DELETED variants */
-// FLOPPY_DPRINTF("treat READ_DELETED command\n");
- FLOPPY_ERROR("treat READ_DELETED command\n");
- fdctrl_start_transfer_del(fdctrl, FD_DIR_READ);
- return;
- case 0x16:
- /* VERIFY variants */
-// FLOPPY_DPRINTF("treat VERIFY command\n");
- FLOPPY_ERROR("treat VERIFY command\n");
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- return;
- case 0x10:
- /* SCAN_EQUAL variants */
-// FLOPPY_DPRINTF("treat SCAN_EQUAL command\n");
- FLOPPY_ERROR("treat SCAN_EQUAL command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_SCANE);
- return;
- case 0x19:
- /* SCAN_LOW_OR_EQUAL variants */
-// FLOPPY_DPRINTF("treat SCAN_LOW_OR_EQUAL command\n");
- FLOPPY_ERROR("treat SCAN_LOW_OR_EQUAL command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_SCANL);
- return;
- case 0x1D:
- /* SCAN_HIGH_OR_EQUAL variants */
-// FLOPPY_DPRINTF("treat SCAN_HIGH_OR_EQUAL command\n");
- FLOPPY_ERROR("treat SCAN_HIGH_OR_EQUAL command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_SCANH);
- return;
- default:
- break;
- }
- switch (fdctrl->fifo[0] & 0x3F) {
- case 0x05:
- /* WRITE variants */
- FLOPPY_DPRINTF("treat WRITE command (%02x)\n", fdctrl->fifo[0]);
- fdctrl_start_transfer(fdctrl, FD_DIR_WRITE);
- return;
- case 0x09:
- /* WRITE_DELETED variants */
-// FLOPPY_DPRINTF("treat WRITE_DELETED command\n");
- FLOPPY_ERROR("treat WRITE_DELETED command\n");
- fdctrl_start_transfer_del(fdctrl, FD_DIR_WRITE);
- return;
- default:
- break;
- }
- switch (fdctrl->fifo[0]) {
- case 0x03:
- /* SPECIFY */
- FLOPPY_DPRINTF("treat SPECIFY command\n");
- fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
- fdctrl->timer1 = fdctrl->fifo[2] >> 1;
- fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ;
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x04:
- /* SENSE_DRIVE_STATUS */
- FLOPPY_DPRINTF("treat SENSE_DRIVE_STATUS command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
- /* 1 Byte status back */
- fdctrl->fifo[0] = (cur_drv->ro << 6) |
- (cur_drv->track == 0 ? 0x10 : 0x00) |
- (cur_drv->head << 2) |
- fdctrl->cur_drv |
- 0x28;
- fdctrl_set_fifo(fdctrl, 1, 0);
- break;
- case 0x07:
- /* RECALIBRATE */
- FLOPPY_DPRINTF("treat RECALIBRATE command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_recalibrate(cur_drv);
- fdctrl_reset_fifo(fdctrl);
- /* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, 0x20);
- break;
- case 0x0F:
- /* SEEK */
- FLOPPY_DPRINTF("treat SEEK command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_start(cur_drv);
- if (fdctrl->fifo[2] <= cur_drv->track)
- cur_drv->dir = 1;
- else
- cur_drv->dir = 0;
- fdctrl_reset_fifo(fdctrl);
- if (fdctrl->fifo[2] > cur_drv->max_track) {
- fdctrl_raise_irq(fdctrl, 0x60);
- } else {
- cur_drv->track = fdctrl->fifo[2];
- /* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, 0x20);
- }
- break;
- case 0x12:
- /* PERPENDICULAR_MODE */
- FLOPPY_DPRINTF("treat PERPENDICULAR_MODE command\n");
- if (fdctrl->fifo[1] & 0x80)
- cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x13:
- /* CONFIGURE */
- FLOPPY_DPRINTF("treat CONFIGURE command\n");
- fdctrl->config = fdctrl->fifo[2];
- fdctrl->precomp_trk = fdctrl->fifo[3];
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x17:
- /* POWERDOWN_MODE */
- FLOPPY_DPRINTF("treat POWERDOWN_MODE command\n");
- fdctrl->pwrd = fdctrl->fifo[1];
- fdctrl->fifo[0] = fdctrl->fifo[1];
- fdctrl_set_fifo(fdctrl, 1, 1);
- break;
- case 0x33:
- /* OPTION */
- FLOPPY_DPRINTF("treat OPTION command\n");
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x42:
- /* READ_TRACK */
-// FLOPPY_DPRINTF("treat READ_TRACK command\n");
- FLOPPY_ERROR("treat READ_TRACK command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_READ);
- break;
- case 0x4A:
- /* READ_ID */
- FLOPPY_DPRINTF("treat READ_ID command\n");
- /* XXX: should set main status register to busy */
- cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
- qemu_mod_timer(fdctrl->result_timer,
- qemu_get_clock(vm_clock) + (ticks_per_sec / 50));
- break;
- case 0x4C:
- /* RESTORE */
- FLOPPY_DPRINTF("treat RESTORE command\n");
- /* Drives position */
- drv0(fdctrl)->track = fdctrl->fifo[3];
- drv1(fdctrl)->track = fdctrl->fifo[4];
- /* timers */
- fdctrl->timer0 = fdctrl->fifo[7];
- fdctrl->timer1 = fdctrl->fifo[8];
- cur_drv->last_sect = fdctrl->fifo[9];
- fdctrl->lock = fdctrl->fifo[10] >> 7;
- cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
- fdctrl->config = fdctrl->fifo[11];
- fdctrl->precomp_trk = fdctrl->fifo[12];
- fdctrl->pwrd = fdctrl->fifo[13];
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x4D:
- /* FORMAT_TRACK */
- FLOPPY_DPRINTF("treat FORMAT_TRACK command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fdctrl->data_state |= FD_STATE_FORMAT;
- if (fdctrl->fifo[0] & 0x80)
- fdctrl->data_state |= FD_STATE_MULTI;
- else
- fdctrl->data_state &= ~FD_STATE_MULTI;
- fdctrl->data_state &= ~FD_STATE_SEEK;
- cur_drv->bps =
- fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
-#if 0
- cur_drv->last_sect =
- cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
- fdctrl->fifo[3] / 2;
-#else
- cur_drv->last_sect = fdctrl->fifo[3];
-#endif
- /* TODO: implement format using DMA expected by the Bochs BIOS
- * and Linux fdformat (read 3 bytes per sector via DMA and fill
- * the sector with the specified fill byte
- */
- fdctrl->data_state &= ~FD_STATE_FORMAT;
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
- break;
- case 0x8E:
- /* DRIVE_SPECIFICATION_COMMAND */
- FLOPPY_DPRINTF("treat DRIVE_SPECIFICATION_COMMAND command\n");
- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
- /* Command parameters done */
- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
- fdctrl->fifo[0] = fdctrl->fifo[1];
- fdctrl->fifo[2] = 0;
- fdctrl->fifo[3] = 0;
- fdctrl_set_fifo(fdctrl, 4, 1);
- } else {
- fdctrl_reset_fifo(fdctrl);
- }
- } else if (fdctrl->data_len > 7) {
- /* ERROR */
- fdctrl->fifo[0] = 0x80 |
- (cur_drv->head << 2) | fdctrl->cur_drv;
- fdctrl_set_fifo(fdctrl, 1, 1);
- }
- break;
- case 0x8F:
- /* RELATIVE_SEEK_OUT */
- FLOPPY_DPRINTF("treat RELATIVE_SEEK_OUT command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_start(cur_drv);
- cur_drv->dir = 0;
- if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
- cur_drv->track = cur_drv->max_track - 1;
- } else {
- cur_drv->track += fdctrl->fifo[2];
- }
- fdctrl_reset_fifo(fdctrl);
- fdctrl_raise_irq(fdctrl, 0x20);
- break;
- case 0xCD:
- /* FORMAT_AND_WRITE */
-// FLOPPY_DPRINTF("treat FORMAT_AND_WRITE command\n");
- FLOPPY_ERROR("treat FORMAT_AND_WRITE command\n");
- fdctrl_unimplemented(fdctrl);
- break;
- case 0xCF:
- /* RELATIVE_SEEK_IN */
- FLOPPY_DPRINTF("treat RELATIVE_SEEK_IN command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_start(cur_drv);
- cur_drv->dir = 1;
- if (fdctrl->fifo[2] > cur_drv->track) {
- cur_drv->track = 0;
- } else {
- cur_drv->track -= fdctrl->fifo[2];
- }
- fdctrl_reset_fifo(fdctrl);
- /* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, 0x20);
- break;
- }
- }
-}
-
-static void fdctrl_result_timer(void *opaque)
-{
- fdctrl_t *fdctrl = opaque;
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
-}
diff --git a/tools/ioemu/hw/fmopl.c b/tools/ioemu/hw/fmopl.c
deleted file mode 100644
index 2b0e82b0cc..0000000000
--- a/tools/ioemu/hw/fmopl.c
+++ /dev/null
@@ -1,1390 +0,0 @@
-/*
-**
-** File: fmopl.c -- software implementation of FM sound generator
-**
-** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
-**
-** Version 0.37a
-**
-*/
-
-/*
- preliminary :
- Problem :
- note:
-*/
-
-/* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define INLINE __inline
-#define HAS_YM3812 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <math.h>
-//#include "driver.h" /* use M.A.M.E. */
-#include "fmopl.h"
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-/* -------------------- for debug --------------------- */
-/* #define OPL_OUTPUT_LOG */
-#ifdef OPL_OUTPUT_LOG
-static FILE *opl_dbg_fp = NULL;
-static FM_OPL *opl_dbg_opl[16];
-static int opl_dbg_maxchip,opl_dbg_chip;
-#endif
-
-/* -------------------- preliminary define section --------------------- */
-/* attack/decay rate time rate */
-#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
-#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
-
-#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
-
-#define FREQ_BITS 24 /* frequency turn */
-
-/* counter bits = 20 , octerve 7 */
-#define FREQ_RATE (1<<(FREQ_BITS-20))
-#define TL_BITS (FREQ_BITS+2)
-
-/* final output shift , limit minimum and maximum */
-#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
-#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
-#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
-
-/* -------------------- quality selection --------------------- */
-
-/* sinwave entries */
-/* used static memory = SIN_ENT * 4 (byte) */
-#define SIN_ENT 2048
-
-/* output level entries (envelope,sinwave) */
-/* envelope counter lower bits */
-#define ENV_BITS 16
-/* envelope output entries */
-#define EG_ENT 4096
-/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
-/* used static memory = EG_ENT*4 (byte) */
-
-#define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */
-#define EG_DED EG_OFF
-#define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */
-#define EG_AED EG_DST
-#define EG_AST 0 /* ATTACK START */
-
-#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
-
-/* LFO table entries */
-#define VIB_ENT 512
-#define VIB_SHIFT (32-9)
-#define AMS_ENT 512
-#define AMS_SHIFT (32-9)
-
-#define VIB_RATE 256
-
-/* -------------------- local defines , macros --------------------- */
-
-/* register number to channel number , slot offset */
-#define SLOT1 0
-#define SLOT2 1
-
-/* envelope phase */
-#define ENV_MOD_RR 0x00
-#define ENV_MOD_DR 0x01
-#define ENV_MOD_AR 0x02
-
-/* -------------------- tables --------------------- */
-static const int slot_array[32]=
-{
- 0, 2, 4, 1, 3, 5,-1,-1,
- 6, 8,10, 7, 9,11,-1,-1,
- 12,14,16,13,15,17,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1
-};
-
-/* key scale level */
-/* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
-#define DV (EG_STEP/2)
-static const UINT32 KSL_TABLE[8*16]=
-{
- /* OCT 0 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- /* OCT 1 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
- 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
- /* OCT 2 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
- 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
- 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
- /* OCT 3 */
- 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
- 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
- 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
- 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
- /* OCT 4 */
- 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
- 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
- 9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
- 10.875/DV,11.250/DV,11.625/DV,12.000/DV,
- /* OCT 5 */
- 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
- 9.000/DV,10.125/DV,10.875/DV,11.625/DV,
- 12.000/DV,12.750/DV,13.125/DV,13.500/DV,
- 13.875/DV,14.250/DV,14.625/DV,15.000/DV,
- /* OCT 6 */
- 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
- 12.000/DV,13.125/DV,13.875/DV,14.625/DV,
- 15.000/DV,15.750/DV,16.125/DV,16.500/DV,
- 16.875/DV,17.250/DV,17.625/DV,18.000/DV,
- /* OCT 7 */
- 0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
- 15.000/DV,16.125/DV,16.875/DV,17.625/DV,
- 18.000/DV,18.750/DV,19.125/DV,19.500/DV,
- 19.875/DV,20.250/DV,20.625/DV,21.000/DV
-};
-#undef DV
-
-/* sustain lebel table (3db per step) */
-/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
-#define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
-static const INT32 SL_TABLE[16]={
- SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
- SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
-};
-#undef SC
-
-#define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
-/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
-/* TL_TABLE[ 0 to TL_MAX ] : plus section */
-/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
-static INT32 *TL_TABLE;
-
-/* pointers to TL_TABLE with sinwave output offset */
-static INT32 **SIN_TABLE;
-
-/* LFO table */
-static INT32 *AMS_TABLE;
-static INT32 *VIB_TABLE;
-
-/* envelope output curve table */
-/* attack + decay + OFF */
-static INT32 ENV_CURVE[2*EG_ENT+1];
-
-/* multiple table */
-#define ML 2
-static const UINT32 MUL_TABLE[16]= {
-/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
- 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
- 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
-};
-#undef ML
-
-/* dummy attack / decay rate ( when rate == 0 ) */
-static INT32 RATE_0[16]=
-{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-/* -------------------- static state --------------------- */
-
-/* lock level of common table */
-static int num_lock = 0;
-
-/* work table */
-static void *cur_chip = NULL; /* current chip point */
-/* currenct chip state */
-/* static OPLSAMPLE *bufL,*bufR; */
-static OPL_CH *S_CH;
-static OPL_CH *E_CH;
-OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
-
-static INT32 outd[1];
-static INT32 ams;
-static INT32 vib;
-INT32 *ams_table;
-INT32 *vib_table;
-static INT32 amsIncr;
-static INT32 vibIncr;
-static INT32 feedback2; /* connect for SLOT 2 */
-
-/* log output level */
-#define LOG_ERR 3 /* ERROR */
-#define LOG_WAR 2 /* WARNING */
-#define LOG_INF 1 /* INFORMATION */
-
-//#define LOG_LEVEL LOG_INF
-#define LOG_LEVEL LOG_ERR
-
-//#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
-#define LOG(n,x)
-
-/* --------------------- subroutines --------------------- */
-
-INLINE int Limit( int val, int max, int min ) {
- if ( val > max )
- val = max;
- else if ( val < min )
- val = min;
-
- return val;
-}
-
-/* status set and IRQ handling */
-INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
-{
- /* set status flag */
- OPL->status |= flag;
- if(!(OPL->status & 0x80))
- {
- if(OPL->status & OPL->statusmask)
- { /* IRQ on */
- OPL->status |= 0x80;
- /* callback user interrupt handler (IRQ is OFF to ON) */
- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
- }
- }
-}
-
-/* status reset and IRQ handling */
-INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
-{
- /* reset status flag */
- OPL->status &=~flag;
- if((OPL->status & 0x80))
- {
- if (!(OPL->status & OPL->statusmask) )
- {
- OPL->status &= 0x7f;
- /* callback user interrupt handler (IRQ is ON to OFF) */
- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
- }
- }
-}
-
-/* IRQ mask set */
-INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
-{
- OPL->statusmask = flag;
- /* IRQ handling check */
- OPL_STATUS_SET(OPL,0);
- OPL_STATUS_RESET(OPL,0);
-}
-
-/* ----- key on ----- */
-INLINE void OPL_KEYON(OPL_SLOT *SLOT)
-{
- /* sin wave restart */
- SLOT->Cnt = 0;
- /* set attack */
- SLOT->evm = ENV_MOD_AR;
- SLOT->evs = SLOT->evsa;
- SLOT->evc = EG_AST;
- SLOT->eve = EG_AED;
-}
-/* ----- key off ----- */
-INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
-{
- if( SLOT->evm > ENV_MOD_RR)
- {
- /* set envelope counter from envleope output */
- SLOT->evm = ENV_MOD_RR;
- if( !(SLOT->evc&EG_DST) )
- //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
- SLOT->evc = EG_DST;
- SLOT->eve = EG_DED;
- SLOT->evs = SLOT->evsr;
- }
-}
-
-/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
-/* return : envelope output */
-INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
-{
- /* calcrate envelope generator */
- if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
- {
- switch( SLOT->evm ){
- case ENV_MOD_AR: /* ATTACK -> DECAY1 */
- /* next DR */
- SLOT->evm = ENV_MOD_DR;
- SLOT->evc = EG_DST;
- SLOT->eve = SLOT->SL;
- SLOT->evs = SLOT->evsd;
- break;
- case ENV_MOD_DR: /* DECAY -> SL or RR */
- SLOT->evc = SLOT->SL;
- SLOT->eve = EG_DED;
- if(SLOT->eg_typ)
- {
- SLOT->evs = 0;
- }
- else
- {
- SLOT->evm = ENV_MOD_RR;
- SLOT->evs = SLOT->evsr;
- }
- break;
- case ENV_MOD_RR: /* RR -> OFF */
- SLOT->evc = EG_OFF;
- SLOT->eve = EG_OFF+1;
- SLOT->evs = 0;
- break;
- }
- }
- /* calcrate envelope */
- return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
-}
-
-/* set algorythm connection */
-static void set_algorythm( OPL_CH *CH)
-{
- INT32 *carrier = &outd[0];
- CH->connect1 = CH->CON ? carrier : &feedback2;
- CH->connect2 = carrier;
-}
-
-/* ---------- frequency counter for operater update ---------- */
-INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
-{
- int ksr;
-
- /* frequency step counter */
- SLOT->Incr = CH->fc * SLOT->mul;
- ksr = CH->kcode >> SLOT->KSR;
-
- if( SLOT->ksr != ksr )
- {
- SLOT->ksr = ksr;
- /* attack , decay rate recalcration */
- SLOT->evsa = SLOT->AR[ksr];
- SLOT->evsd = SLOT->DR[ksr];
- SLOT->evsr = SLOT->RR[ksr];
- }
- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
-}
-
-/* set multi,am,vib,EG-TYP,KSR,mul */
-INLINE void set_mul(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
-
- SLOT->mul = MUL_TABLE[v&0x0f];
- SLOT->KSR = (v&0x10) ? 0 : 2;
- SLOT->eg_typ = (v&0x20)>>5;
- SLOT->vib = (v&0x40);
- SLOT->ams = (v&0x80);
- CALC_FCSLOT(CH,SLOT);
-}
-
-/* set ksl & tl */
-INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
-
- SLOT->ksl = ksl ? 3-ksl : 31;
- SLOT->TL = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
-
- if( !(OPL->mode&0x80) )
- { /* not CSM latch total level */
- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
- }
-}
-
-/* set attack rate & decay rate */
-INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int ar = v>>4;
- int dr = v&0x0f;
-
- SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
- SLOT->evsa = SLOT->AR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
-
- SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
- SLOT->evsd = SLOT->DR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
-}
-
-/* set sustain level & release rate */
-INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int sl = v>>4;
- int rr = v & 0x0f;
-
- SLOT->SL = SL_TABLE[sl];
- if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
- SLOT->RR = &OPL->DR_TABLE[rr<<2];
- SLOT->evsr = SLOT->RR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
-}
-
-/* operator output calcrator */
-#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
-/* ---------- calcrate one of channel ---------- */
-INLINE void OPL_CALC_CH( OPL_CH *CH )
-{
- UINT32 env_out;
- OPL_SLOT *SLOT;
-
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH->SLOT[SLOT1];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH->FB)
- {
- int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
- CH->op1_out[1] = CH->op1_out[0];
- *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
- }
- else
- {
- *CH->connect1 += OP_OUT(SLOT,env_out,0);
- }
- }else
- {
- CH->op1_out[1] = CH->op1_out[0];
- CH->op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH->SLOT[SLOT2];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT,env_out, feedback2);
- }
-}
-
-/* ---------- calcrate rythm block ---------- */
-#define WHITE_NOISE_db 6.0
-INLINE void OPL_CALC_RH( OPL_CH *CH )
-{
- UINT32 env_tam,env_sd,env_top,env_hh;
- int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
- INT32 tone8;
-
- OPL_SLOT *SLOT;
- int env_out;
-
- /* BD : same as FM serial mode and output level is large */
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH[6].SLOT[SLOT1];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH[6].FB)
- {
- int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
- }
- else
- {
- feedback2 = OP_OUT(SLOT,env_out,0);
- }
- }else
- {
- feedback2 = 0;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- CH[6].op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH[6].SLOT[SLOT2];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
- }
-
- // SD (17) = mul14[fnum7] + white noise
- // TAM (15) = mul15[fnum8]
- // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
- // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
- env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
- env_tam=OPL_CALC_SLOT(SLOT8_1);
- env_top=OPL_CALC_SLOT(SLOT8_2);
- env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
-
- /* PG */
- if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
- else SLOT7_1->Cnt += 2*SLOT7_1->Incr;
- if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
- else SLOT7_2->Cnt += (CH[7].fc*8);
- if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
- else SLOT8_1->Cnt += SLOT8_1->Incr;
- if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
- else SLOT8_2->Cnt += (CH[8].fc*48);
-
- tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
-
- /* SD */
- if( env_sd < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
- /* TAM */
- if( env_tam < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
- /* TOP-CY */
- if( env_top < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
- /* HH */
- if( env_hh < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
-}
-
-/* ----------- initialize time tabls ----------- */
-static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
-{
- int i;
- double rate;
-
- /* make attack rate & decay rate tables */
- for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
- for (i = 4;i <= 60;i++){
- rate = OPL->freqbase; /* frequency rate */
- if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
- rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */
- rate *= (double)(EG_ENT<<ENV_BITS);
- OPL->AR_TABLE[i] = rate / ARRATE;
- OPL->DR_TABLE[i] = rate / DRRATE;
- }
- for (i = 60;i < 76;i++)
- {
- OPL->AR_TABLE[i] = EG_AED-1;
- OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
- }
-#if 0
- for (i = 0;i < 64 ;i++){ /* make for overflow area */
- LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
- ((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
- ((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
- }
-#endif
-}
-
-/* ---------- generic table initialize ---------- */
-static int OPLOpenTable( void )
-{
- int s,t;
- double rate;
- int i,j;
- double pom;
-
- /* allocate dynamic tables */
- if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
- return 0;
- if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
- {
- free(TL_TABLE);
- return 0;
- }
- if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
- {
- free(TL_TABLE);
- free(SIN_TABLE);
- return 0;
- }
- if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
- {
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- return 0;
- }
- /* make total level table */
- for (t = 0;t < EG_ENT-1 ;t++){
- rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */
- TL_TABLE[ t] = (int)rate;
- TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
-/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
- }
- /* fill volume off area */
- for ( t = EG_ENT-1; t < TL_MAX ;t++){
- TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
- }
-
- /* make sinwave table (total level offet) */
- /* degree 0 = degree 180 = off */
- SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
- for (s = 1;s <= SIN_ENT/4;s++){
- pom = sin(2*PI*s/SIN_ENT); /* sin */
- pom = 20*log10(1/pom); /* decibel */
- j = pom / EG_STEP; /* TL_TABLE steps */
-
- /* degree 0 - 90 , degree 180 - 90 : plus section */
- SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
- /* degree 180 - 270 , degree 360 - 270 : minus section */
- SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
-/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
- }
- for (s = 0;s < SIN_ENT;s++)
- {
- SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
- SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
- SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
- }
-
- /* envelope counter -> envelope output table */
- for (i=0; i<EG_ENT; i++)
- {
- /* ATTACK curve */
- pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
- /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
- ENV_CURVE[i] = (int)pom;
- /* DECAY ,RELEASE curve */
- ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
- }
- /* off */
- ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
- /* make LFO ams table */
- for (i=0; i<AMS_ENT; i++)
- {
- pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
- AMS_TABLE[i] = (1.0/EG_STEP)*pom; /* 1dB */
- AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
- }
- /* make LFO vibrate table */
- for (i=0; i<VIB_ENT; i++)
- {
- /* 100cent = 1seminote = 6% ?? */
- pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
- VIB_TABLE[i] = VIB_RATE + (pom*0.07); /* +- 7cent */
- VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
- /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
- }
- return 1;
-}
-
-
-static void OPLCloseTable( void )
-{
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- free(VIB_TABLE);
-}
-
-/* CSM Key Controll */
-INLINE void CSMKeyControll(OPL_CH *CH)
-{
- OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
- OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
- /* all key off */
- OPL_KEYOFF(slot1);
- OPL_KEYOFF(slot2);
- /* total level latch */
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- /* key on */
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(slot1);
- OPL_KEYON(slot2);
-}
-
-/* ---------- opl initialize ---------- */
-static void OPL_initalize(FM_OPL *OPL)
-{
- int fn;
-
- /* frequency base */
- OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
- /* Timer base time */
- OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
- /* make time tables */
- init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
- /* make fnumber -> increment counter table */
- for( fn=0 ; fn < 1024 ; fn++ )
- {
- OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
- }
- /* LFO freq.table */
- OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
- OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
-}
-
-/* ---------- write a OPL registers ---------- */
-static void OPLWriteReg(FM_OPL *OPL, int r, int v)
-{
- OPL_CH *CH;
- int slot;
- int block_fnum;
-
- switch(r&0xe0)
- {
- case 0x00: /* 00-1f:controll */
- switch(r&0x1f)
- {
- case 0x01:
- /* wave selector enable */
- if(OPL->type&OPL_TYPE_WAVESEL)
- {
- OPL->wavesel = v&0x20;
- if(!OPL->wavesel)
- {
- /* preset compatible mode */
- int c;
- for(c=0;c<OPL->max_ch;c++)
- {
- OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
- OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
- }
- }
- }
- return;
- case 0x02: /* Timer 1 */
- OPL->T[0] = (256-v)*4;
- break;
- case 0x03: /* Timer 2 */
- OPL->T[1] = (256-v)*16;
- return;
- case 0x04: /* IRQ clear / mask and Timer enable */
- if(v&0x80)
- { /* IRQ flag clear */
- OPL_STATUS_RESET(OPL,0x7f);
- }
- else
- { /* set IRQ mask ,timer enable*/
- UINT8 st1 = v&1;
- UINT8 st2 = (v>>1)&1;
- /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
- OPL_STATUS_RESET(OPL,v&0x78);
- OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
- /* timer 2 */
- if(OPL->st[1] != st2)
- {
- double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
- OPL->st[1] = st2;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
- }
- /* timer 1 */
- if(OPL->st[0] != st1)
- {
- double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
- OPL->st[0] = st1;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
- }
- }
- return;
-#if BUILD_Y8950
- case 0x06: /* Key Board OUT */
- if(OPL->type&OPL_TYPE_KEYBOARD)
- {
- if(OPL->keyboardhandler_w)
- OPL->keyboardhandler_w(OPL->keyboard_param,v);
- else
- LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
- }
- return;
- case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
- if(OPL->type&OPL_TYPE_ADPCM)
- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
- return;
- case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
- OPL->mode = v;
- v&=0x1f; /* for DELTA-T unit */
- case 0x09: /* START ADD */
- case 0x0a:
- case 0x0b: /* STOP ADD */
- case 0x0c:
- case 0x0d: /* PRESCALE */
- case 0x0e:
- case 0x0f: /* ADPCM data */
- case 0x10: /* DELTA-N */
- case 0x11: /* DELTA-N */
- case 0x12: /* EG-CTRL */
- if(OPL->type&OPL_TYPE_ADPCM)
- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
- return;
-#if 0
- case 0x15: /* DAC data */
- case 0x16:
- case 0x17: /* SHIFT */
- return;
- case 0x18: /* I/O CTRL (Direction) */
- if(OPL->type&OPL_TYPE_IO)
- OPL->portDirection = v&0x0f;
- return;
- case 0x19: /* I/O DATA */
- if(OPL->type&OPL_TYPE_IO)
- {
- OPL->portLatch = v;
- if(OPL->porthandler_w)
- OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
- }
- return;
- case 0x1a: /* PCM data */
- return;
-#endif
-#endif
- }
- break;
- case 0x20: /* am,vib,ksr,eg type,mul */
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_mul(OPL,slot,v);
- return;
- case 0x40:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_ksl_tl(OPL,slot,v);
- return;
- case 0x60:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_ar_dr(OPL,slot,v);
- return;
- case 0x80:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_sl_rr(OPL,slot,v);
- return;
- case 0xa0:
- switch(r)
- {
- case 0xbd:
- /* amsep,vibdep,r,bd,sd,tom,tc,hh */
- {
- UINT8 rkey = OPL->rythm^v;
- OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
- OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
- OPL->rythm = v&0x3f;
- if(OPL->rythm&0x20)
- {
-#if 0
- usrintf_showmessage("OPL Rythm mode select");
-#endif
- /* BD key on/off */
- if(rkey&0x10)
- {
- if(v&0x10)
- {
- OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- else
- {
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- }
- /* SD key on/off */
- if(rkey&0x08)
- {
- if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
- }/* TAM key on/off */
- if(rkey&0x04)
- {
- if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
- }
- /* TOP-CY key on/off */
- if(rkey&0x02)
- {
- if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
- }
- /* HH key on/off */
- if(rkey&0x01)
- {
- if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
- }
- }
- }
- return;
- }
- /* keyon,block,fnum */
- if( (r&0x0f) > 8) return;
- CH = &OPL->P_CH[r&0x0f];
- if(!(r&0x10))
- { /* a0-a8 */
- block_fnum = (CH->block_fnum&0x1f00) | v;
- }
- else
- { /* b0-b8 */
- int keyon = (v>>5)&1;
- block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
- if(CH->keyon != keyon)
- {
- if( (CH->keyon=keyon) )
- {
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(&CH->SLOT[SLOT1]);
- OPL_KEYON(&CH->SLOT[SLOT2]);
- }
- else
- {
- OPL_KEYOFF(&CH->SLOT[SLOT1]);
- OPL_KEYOFF(&CH->SLOT[SLOT2]);
- }
- }
- }
- /* update */
- if(CH->block_fnum != block_fnum)
- {
- int blockRv = 7-(block_fnum>>10);
- int fnum = block_fnum&0x3ff;
- CH->block_fnum = block_fnum;
-
- CH->ksl_base = KSL_TABLE[block_fnum>>6];
- CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
- CH->kcode = CH->block_fnum>>9;
- if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
- CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
- CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
- }
- return;
- case 0xc0:
- /* FB,C */
- if( (r&0x0f) > 8) return;
- CH = &OPL->P_CH[r&0x0f];
- {
- int feedback = (v>>1)&7;
- CH->FB = feedback ? (8+1) - feedback : 0;
- CH->CON = v&1;
- set_algorythm(CH);
- }
- return;
- case 0xe0: /* wave type */
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- CH = &OPL->P_CH[slot/2];
- if(OPL->wavesel)
- {
- /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
- CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
- }
- return;
- }
-}
-
-/* lock/unlock for common table */
-static int OPL_LockTable(void)
-{
- num_lock++;
- if(num_lock>1) return 0;
- /* first time */
- cur_chip = NULL;
- /* allocate total level table (128kb space) */
- if( !OPLOpenTable() )
- {
- num_lock--;
- return -1;
- }
- return 0;
-}
-
-static void OPL_UnLockTable(void)
-{
- if(num_lock) num_lock--;
- if(num_lock) return;
- /* last time */
- cur_chip = NULL;
- OPLCloseTable();
-}
-
-#if (BUILD_YM3812 || BUILD_YM3526)
-/*******************************************************************************/
-/* YM3812 local section */
-/*******************************************************************************/
-
-/* ---------- update one of chip ----------- */
-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
-{
- int i;
- int data;
- OPLSAMPLE *buf = buffer;
- UINT32 amsCnt = OPL->amsCnt;
- UINT32 vibCnt = OPL->vibCnt;
- UINT8 rythm = OPL->rythm&0x20;
- OPL_CH *CH,*R_CH;
-
- if( (void *)OPL != cur_chip ){
- cur_chip = (void *)OPL;
- /* channel pointers */
- S_CH = OPL->P_CH;
- E_CH = &S_CH[9];
- /* rythm slot */
- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
- /* LFO state */
- amsIncr = OPL->amsIncr;
- vibIncr = OPL->vibIncr;
- ams_table = OPL->ams_table;
- vib_table = OPL->vib_table;
- }
- R_CH = rythm ? &S_CH[6] : E_CH;
- for( i=0; i < length ; i++ )
- {
- /* channel A channel B channel C */
- /* LFO */
- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
- outd[0] = 0;
- /* FM part */
- for(CH=S_CH ; CH < R_CH ; CH++)
- OPL_CALC_CH(CH);
- /* Rythn part */
- if(rythm)
- OPL_CALC_RH(S_CH);
- /* limit check */
- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
- /* store to sound buffer */
- buf[i] = data >> OPL_OUTSB;
- }
-
- OPL->amsCnt = amsCnt;
- OPL->vibCnt = vibCnt;
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
- if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
- fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);
- }
-#endif
-}
-#endif /* (BUILD_YM3812 || BUILD_YM3526) */
-
-#if BUILD_Y8950
-
-void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
-{
- int i;
- int data;
- OPLSAMPLE *buf = buffer;
- UINT32 amsCnt = OPL->amsCnt;
- UINT32 vibCnt = OPL->vibCnt;
- UINT8 rythm = OPL->rythm&0x20;
- OPL_CH *CH,*R_CH;
- YM_DELTAT *DELTAT = OPL->deltat;
-
- /* setup DELTA-T unit */
- YM_DELTAT_DECODE_PRESET(DELTAT);
-
- if( (void *)OPL != cur_chip ){
- cur_chip = (void *)OPL;
- /* channel pointers */
- S_CH = OPL->P_CH;
- E_CH = &S_CH[9];
- /* rythm slot */
- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
- /* LFO state */
- amsIncr = OPL->amsIncr;
- vibIncr = OPL->vibIncr;
- ams_table = OPL->ams_table;
- vib_table = OPL->vib_table;
- }
- R_CH = rythm ? &S_CH[6] : E_CH;
- for( i=0; i < length ; i++ )
- {
- /* channel A channel B channel C */
- /* LFO */
- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
- outd[0] = 0;
- /* deltaT ADPCM */
- if( DELTAT->portstate )
- YM_DELTAT_ADPCM_CALC(DELTAT);
- /* FM part */
- for(CH=S_CH ; CH < R_CH ; CH++)
- OPL_CALC_CH(CH);
- /* Rythn part */
- if(rythm)
- OPL_CALC_RH(S_CH);
- /* limit check */
- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
- /* store to sound buffer */
- buf[i] = data >> OPL_OUTSB;
- }
- OPL->amsCnt = amsCnt;
- OPL->vibCnt = vibCnt;
- /* deltaT START flag */
- if( !DELTAT->portstate )
- OPL->status &= 0xfe;
-}
-#endif
-
-/* ---------- reset one of chip ---------- */
-void OPLResetChip(FM_OPL *OPL)
-{
- int c,s;
- int i;
-
- /* reset chip */
- OPL->mode = 0; /* normal mode */
- OPL_STATUS_RESET(OPL,0x7f);
- /* reset with register write */
- OPLWriteReg(OPL,0x01,0); /* wabesel disable */
- OPLWriteReg(OPL,0x02,0); /* Timer1 */
- OPLWriteReg(OPL,0x03,0); /* Timer2 */
- OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
- for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
- /* reset OPerator paramater */
- for( c = 0 ; c < OPL->max_ch ; c++ )
- {
- OPL_CH *CH = &OPL->P_CH[c];
- /* OPL->P_CH[c].PAN = OPN_CENTER; */
- for(s = 0 ; s < 2 ; s++ )
- {
- /* wave table */
- CH->SLOT[s].wavetable = &SIN_TABLE[0];
- /* CH->SLOT[s].evm = ENV_MOD_RR; */
- CH->SLOT[s].evc = EG_OFF;
- CH->SLOT[s].eve = EG_OFF+1;
- CH->SLOT[s].evs = 0;
- }
- }
-#if BUILD_Y8950
- if(OPL->type&OPL_TYPE_ADPCM)
- {
- YM_DELTAT *DELTAT = OPL->deltat;
-
- DELTAT->freqbase = OPL->freqbase;
- DELTAT->output_pointer = outd;
- DELTAT->portshift = 5;
- DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
- YM_DELTAT_ADPCM_Reset(DELTAT,0);
- }
-#endif
-}
-
-/* ---------- Create one of vietual YM3812 ---------- */
-/* 'rate' is sampling rate and 'bufsiz' is the size of the */
-FM_OPL *OPLCreate(int type, int clock, int rate)
-{
- char *ptr;
- FM_OPL *OPL;
- int state_size;
- int max_ch = 9; /* normaly 9 channels */
-
- if( OPL_LockTable() ==-1) return NULL;
- /* allocate OPL state space */
- state_size = sizeof(FM_OPL);
- state_size += sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
- if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
-#endif
- /* allocate memory block */
- ptr = malloc(state_size);
- if(ptr==NULL) return NULL;
- /* clear */
- memset(ptr,0,state_size);
- OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
- OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
- if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
-#endif
- /* set channel state pointer */
- OPL->type = type;
- OPL->clock = clock;
- OPL->rate = rate;
- OPL->max_ch = max_ch;
- /* init grobal tables */
- OPL_initalize(OPL);
- /* reset chip */
- OPLResetChip(OPL);
-#ifdef OPL_OUTPUT_LOG
- if(!opl_dbg_fp)
- {
- opl_dbg_fp = fopen("opllog.opl","wb");
- opl_dbg_maxchip = 0;
- }
- if(opl_dbg_fp)
- {
- opl_dbg_opl[opl_dbg_maxchip] = OPL;
- fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
- type,
- clock&0xff,
- (clock/0x100)&0xff,
- (clock/0x10000)&0xff,
- (clock/0x1000000)&0xff);
- opl_dbg_maxchip++;
- }
-#endif
- return OPL;
-}
-
-/* ---------- Destroy one of vietual YM3812 ---------- */
-void OPLDestroy(FM_OPL *OPL)
-{
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- fclose(opl_dbg_fp);
- opl_dbg_fp = NULL;
- }
-#endif
- OPL_UnLockTable();
- free(OPL);
-}
-
-/* ---------- Option handlers ---------- */
-
-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
-{
- OPL->TimerHandler = TimerHandler;
- OPL->TimerParam = channelOffset;
-}
-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
-{
- OPL->IRQHandler = IRQHandler;
- OPL->IRQParam = param;
-}
-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
- OPL->UpdateHandler = UpdateHandler;
- OPL->UpdateParam = param;
-}
-#if BUILD_Y8950
-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
-{
- OPL->porthandler_w = PortHandler_w;
- OPL->porthandler_r = PortHandler_r;
- OPL->port_param = param;
-}
-
-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
-{
- OPL->keyboardhandler_w = KeyboardHandler_w;
- OPL->keyboardhandler_r = KeyboardHandler_r;
- OPL->keyboard_param = param;
-}
-#endif
-/* ---------- YM3812 I/O interface ---------- */
-int OPLWrite(FM_OPL *OPL,int a,int v)
-{
- if( !(a&1) )
- { /* address port */
- OPL->address = v & 0xff;
- }
- else
- { /* data port */
- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
- if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
- fprintf(opl_dbg_fp,"%c%c%c",0x10+opl_dbg_chip,OPL->address,v);
- }
-#endif
- OPLWriteReg(OPL,OPL->address,v);
- }
- return OPL->status>>7;
-}
-
-unsigned char OPLRead(FM_OPL *OPL,int a)
-{
- if( !(a&1) )
- { /* status port */
- return OPL->status & (OPL->statusmask|0x80);
- }
- /* data port */
- switch(OPL->address)
- {
- case 0x05: /* KeyBoard IN */
- if(OPL->type&OPL_TYPE_KEYBOARD)
- {
- if(OPL->keyboardhandler_r)
- return OPL->keyboardhandler_r(OPL->keyboard_param);
- else
- LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
- }
- return 0;
-#if 0
- case 0x0f: /* ADPCM-DATA */
- return 0;
-#endif
- case 0x19: /* I/O DATA */
- if(OPL->type&OPL_TYPE_IO)
- {
- if(OPL->porthandler_r)
- return OPL->porthandler_r(OPL->port_param);
- else
- LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
- }
- return 0;
- case 0x1a: /* PCM-DATA */
- return 0;
- }
- return 0;
-}
-
-int OPLTimerOver(FM_OPL *OPL,int c)
-{
- if( c )
- { /* Timer B */
- OPL_STATUS_SET(OPL,0x20);
- }
- else
- { /* Timer A */
- OPL_STATUS_SET(OPL,0x40);
- /* CSM mode key,TL controll */
- if( OPL->mode & 0x80 )
- { /* CSM mode total level latch and auto key on */
- int ch;
- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
- for(ch=0;ch<9;ch++)
- CSMKeyControll( &OPL->P_CH[ch] );
- }
- }
- /* reload timer */
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
- return OPL->status>>7;
-}
diff --git a/tools/ioemu/hw/fmopl.h b/tools/ioemu/hw/fmopl.h
deleted file mode 100644
index a01ff902c7..0000000000
--- a/tools/ioemu/hw/fmopl.h
+++ /dev/null
@@ -1,174 +0,0 @@
-#ifndef __FMOPL_H_
-#define __FMOPL_H_
-
-/* --- select emulation chips --- */
-#define BUILD_YM3812 (HAS_YM3812)
-//#define BUILD_YM3526 (HAS_YM3526)
-//#define BUILD_Y8950 (HAS_Y8950)
-
-/* --- system optimize --- */
-/* select bit size of output : 8 or 16 */
-#define OPL_OUTPUT_BIT 16
-
-/* compiler dependence */
-#ifndef OSD_CPU_H
-#define OSD_CPU_H
-typedef unsigned char UINT8; /* unsigned 8bit */
-typedef unsigned short UINT16; /* unsigned 16bit */
-typedef unsigned int UINT32; /* unsigned 32bit */
-typedef signed char INT8; /* signed 8bit */
-typedef signed short INT16; /* signed 16bit */
-typedef signed int INT32; /* signed 32bit */
-#endif
-
-#if (OPL_OUTPUT_BIT==16)
-typedef INT16 OPLSAMPLE;
-#endif
-#if (OPL_OUTPUT_BIT==8)
-typedef unsigned char OPLSAMPLE;
-#endif
-
-
-#if BUILD_Y8950
-#include "ymdeltat.h"
-#endif
-
-typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec);
-typedef void (*OPL_IRQHANDLER)(int param,int irq);
-typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us);
-typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data);
-typedef unsigned char (*OPL_PORTHANDLER_R)(int param);
-
-/* !!!!! here is private section , do not access there member direct !!!!! */
-
-#define OPL_TYPE_WAVESEL 0x01 /* waveform select */
-#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */
-#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */
-#define OPL_TYPE_IO 0x08 /* I/O port */
-
-/* Saving is necessary for member of the 'R' mark for suspend/resume */
-/* ---------- OPL one of slot ---------- */
-typedef struct fm_opl_slot {
- INT32 TL; /* total level :TL << 8 */
- INT32 TLL; /* adjusted now TL */
- UINT8 KSR; /* key scale rate :(shift down bit) */
- INT32 *AR; /* attack rate :&AR_TABLE[AR<<2] */
- INT32 *DR; /* decay rate :&DR_TALBE[DR<<2] */
- INT32 SL; /* sustin level :SL_TALBE[SL] */
- INT32 *RR; /* release rate :&DR_TABLE[RR<<2] */
- UINT8 ksl; /* keyscale level :(shift down bits) */
- UINT8 ksr; /* key scale rate :kcode>>KSR */
- UINT32 mul; /* multiple :ML_TABLE[ML] */
- UINT32 Cnt; /* frequency count : */
- UINT32 Incr; /* frequency step : */
- /* envelope generator state */
- UINT8 eg_typ; /* envelope type flag */
- UINT8 evm; /* envelope phase */
- INT32 evc; /* envelope counter */
- INT32 eve; /* envelope counter end point */
- INT32 evs; /* envelope counter step */
- INT32 evsa; /* envelope step for AR :AR[ksr] */
- INT32 evsd; /* envelope step for DR :DR[ksr] */
- INT32 evsr; /* envelope step for RR :RR[ksr] */
- /* LFO */
- UINT8 ams; /* ams flag */
- UINT8 vib; /* vibrate flag */
- /* wave selector */
- INT32 **wavetable;
-}OPL_SLOT;
-
-/* ---------- OPL one of channel ---------- */
-typedef struct fm_opl_channel {
- OPL_SLOT SLOT[2];
- UINT8 CON; /* connection type */
- UINT8 FB; /* feed back :(shift down bit) */
- INT32 *connect1; /* slot1 output pointer */
- INT32 *connect2; /* slot2 output pointer */
- INT32 op1_out[2]; /* slot1 output for selfeedback */
- /* phase generator state */
- UINT32 block_fnum; /* block+fnum : */
- UINT8 kcode; /* key code : KeyScaleCode */
- UINT32 fc; /* Freq. Increment base */
- UINT32 ksl_base; /* KeyScaleLevel Base step */
- UINT8 keyon; /* key on/off flag */
-} OPL_CH;
-
-/* OPL state */
-typedef struct fm_opl_f {
- UINT8 type; /* chip type */
- int clock; /* master clock (Hz) */
- int rate; /* sampling rate (Hz) */
- double freqbase; /* frequency base */
- double TimerBase; /* Timer base time (==sampling time) */
- UINT8 address; /* address register */
- UINT8 status; /* status flag */
- UINT8 statusmask; /* status mask */
- UINT32 mode; /* Reg.08 : CSM , notesel,etc. */
- /* Timer */
- int T[2]; /* timer counter */
- UINT8 st[2]; /* timer enable */
- /* FM channel slots */
- OPL_CH *P_CH; /* pointer of CH */
- int max_ch; /* maximum channel */
- /* Rythm sention */
- UINT8 rythm; /* Rythm mode , key flag */
-#if BUILD_Y8950
- /* Delta-T ADPCM unit (Y8950) */
- YM_DELTAT *deltat; /* DELTA-T ADPCM */
-#endif
- /* Keyboard / I/O interface unit (Y8950) */
- UINT8 portDirection;
- UINT8 portLatch;
- OPL_PORTHANDLER_R porthandler_r;
- OPL_PORTHANDLER_W porthandler_w;
- int port_param;
- OPL_PORTHANDLER_R keyboardhandler_r;
- OPL_PORTHANDLER_W keyboardhandler_w;
- int keyboard_param;
- /* time tables */
- INT32 AR_TABLE[75]; /* atttack rate tables */
- INT32 DR_TABLE[75]; /* decay rate tables */
- UINT32 FN_TABLE[1024]; /* fnumber -> increment counter */
- /* LFO */
- INT32 *ams_table;
- INT32 *vib_table;
- INT32 amsCnt;
- INT32 amsIncr;
- INT32 vibCnt;
- INT32 vibIncr;
- /* wave selector enable flag */
- UINT8 wavesel;
- /* external event callback handler */
- OPL_TIMERHANDLER TimerHandler; /* TIMER handler */
- int TimerParam; /* TIMER parameter */
- OPL_IRQHANDLER IRQHandler; /* IRQ handler */
- int IRQParam; /* IRQ parameter */
- OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */
- int UpdateParam; /* stream update parameter */
-} FM_OPL;
-
-/* ---------- Generic interface section ---------- */
-#define OPL_TYPE_YM3526 (0)
-#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
-#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
-
-FM_OPL *OPLCreate(int type, int clock, int rate);
-void OPLDestroy(FM_OPL *OPL);
-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset);
-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param);
-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param);
-/* Y8950 port handlers */
-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param);
-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param);
-
-void OPLResetChip(FM_OPL *OPL);
-int OPLWrite(FM_OPL *OPL,int a,int v);
-unsigned char OPLRead(FM_OPL *OPL,int a);
-int OPLTimerOver(FM_OPL *OPL,int c);
-
-/* YM3626/YM3812 local section */
-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
-
-void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
-
-#endif
diff --git a/tools/ioemu/hw/grackle_pci.c b/tools/ioemu/hw/grackle_pci.c
deleted file mode 100644
index 4004f9942f..0000000000
--- a/tools/ioemu/hw/grackle_pci.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * QEMU Grackle (heathrow PPC) PCI host
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-typedef target_phys_addr_t pci_addr_t;
-#include "pci_host.h"
-
-typedef PCIHostState GrackleState;
-
-static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- GrackleState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- s->config_reg = val;
-}
-
-static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
-{
- GrackleState *s = opaque;
- uint32_t val;
-
- val = s->config_reg;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
- &pci_grackle_config_writel,
- &pci_grackle_config_writel,
- &pci_grackle_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_grackle_config_read[] = {
- &pci_grackle_config_readl,
- &pci_grackle_config_readl,
- &pci_grackle_config_readl,
-};
-
-static CPUWriteMemoryFunc *pci_grackle_write[] = {
- &pci_host_data_writeb,
- &pci_host_data_writew,
- &pci_host_data_writel,
-};
-
-static CPUReadMemoryFunc *pci_grackle_read[] = {
- &pci_host_data_readb,
- &pci_host_data_readw,
- &pci_host_data_readl,
-};
-
-/* Don't know if this matches real hardware, but it agrees with OHW. */
-static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num)
-{
- return (irq_num + (pci_dev->devfn >> 3)) & 3;
-}
-
-static void pci_grackle_set_irq(void *pic, int irq_num, int level)
-{
- heathrow_pic_set_irq(pic, irq_num + 8, level);
-}
-
-PCIBus *pci_grackle_init(uint32_t base, void *pic)
-{
- GrackleState *s;
- PCIDevice *d;
- int pci_mem_config, pci_mem_data;
-
- s = qemu_mallocz(sizeof(GrackleState));
- s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq,
- pic, 0, 0);
-
- pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
- pci_grackle_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_grackle_read,
- pci_grackle_write, s);
- cpu_register_physical_memory(base, 0x1000, pci_mem_config);
- cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);
- d = pci_register_device(s->bus, "Grackle host bridge", sizeof(PCIDevice),
- 0, NULL, NULL);
- d->config[0x00] = 0x57; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x02; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x00; // revision
- d->config[0x09] = 0x01;
- d->config[0x0a] = 0x00; // class_sub = host
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x00; // header_type
-
- d->config[0x18] = 0x00; // primary_bus
- d->config[0x19] = 0x01; // secondary_bus
- d->config[0x1a] = 0x00; // subordinate_bus
- d->config[0x1c] = 0x00;
- d->config[0x1d] = 0x00;
-
- d->config[0x20] = 0x00; // memory_base
- d->config[0x21] = 0x00;
- d->config[0x22] = 0x01; // memory_limit
- d->config[0x23] = 0x00;
-
- d->config[0x24] = 0x00; // prefetchable_memory_base
- d->config[0x25] = 0x00;
- d->config[0x26] = 0x00; // prefetchable_memory_limit
- d->config[0x27] = 0x00;
-
-#if 0
- /* PCI2PCI bridge same values as PearPC - check this */
- d->config[0x00] = 0x11; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x26; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x02; // revision
- d->config[0x0a] = 0x04; // class_sub = pci2pci
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x01; // header_type
-
- d->config[0x18] = 0x0; // primary_bus
- d->config[0x19] = 0x1; // secondary_bus
- d->config[0x1a] = 0x1; // subordinate_bus
- d->config[0x1c] = 0x10; // io_base
- d->config[0x1d] = 0x20; // io_limit
-
- d->config[0x20] = 0x80; // memory_base
- d->config[0x21] = 0x80;
- d->config[0x22] = 0x90; // memory_limit
- d->config[0x23] = 0x80;
-
- d->config[0x24] = 0x00; // prefetchable_memory_base
- d->config[0x25] = 0x84;
- d->config[0x26] = 0x00; // prefetchable_memory_limit
- d->config[0x27] = 0x85;
-#endif
- return s->bus;
-}
-
diff --git a/tools/ioemu/hw/gt64xxx.c b/tools/ioemu/hw/gt64xxx.c
deleted file mode 100644
index ccb6a7c1a2..0000000000
--- a/tools/ioemu/hw/gt64xxx.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * QEMU GT64120 PCI host
- *
- * Copyright (c) 2006,2007 Aurelien Jarno
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-typedef target_phys_addr_t pci_addr_t;
-#include "pci_host.h"
-
-#define GT_REGS (0x1000 >> 2)
-
-/* CPU Configuration */
-#define GT_CPU (0x000 >> 2)
-#define GT_MULTI (0x120 >> 2)
-
-/* CPU Address Decode */
-#define GT_SCS10LD (0x008 >> 2)
-#define GT_SCS10HD (0x010 >> 2)
-#define GT_SCS32LD (0x018 >> 2)
-#define GT_SCS32HD (0x020 >> 2)
-#define GT_CS20LD (0x028 >> 2)
-#define GT_CS20HD (0x030 >> 2)
-#define GT_CS3BOOTLD (0x038 >> 2)
-#define GT_CS3BOOTHD (0x040 >> 2)
-#define GT_PCI0IOLD (0x048 >> 2)
-#define GT_PCI0IOHD (0x050 >> 2)
-#define GT_PCI0M0LD (0x058 >> 2)
-#define GT_PCI0M0HD (0x060 >> 2)
-#define GT_ISD (0x068 >> 2)
-
-#define GT_PCI0M1LD (0x080 >> 2)
-#define GT_PCI0M1HD (0x088 >> 2)
-#define GT_PCI1IOLD (0x090 >> 2)
-#define GT_PCI1IOHD (0x098 >> 2)
-#define GT_PCI1M0LD (0x0a0 >> 2)
-#define GT_PCI1M0HD (0x0a8 >> 2)
-#define GT_PCI1M1LD (0x0b0 >> 2)
-#define GT_PCI1M1HD (0x0b8 >> 2)
-#define GT_PCI1M1LD (0x0b0 >> 2)
-#define GT_PCI1M1HD (0x0b8 >> 2)
-
-#define GT_SCS10AR (0x0d0 >> 2)
-#define GT_SCS32AR (0x0d8 >> 2)
-#define GT_CS20R (0x0e0 >> 2)
-#define GT_CS3BOOTR (0x0e8 >> 2)
-
-#define GT_PCI0IOREMAP (0x0f0 >> 2)
-#define GT_PCI0M0REMAP (0x0f8 >> 2)
-#define GT_PCI0M1REMAP (0x100 >> 2)
-#define GT_PCI1IOREMAP (0x108 >> 2)
-#define GT_PCI1M0REMAP (0x110 >> 2)
-#define GT_PCI1M1REMAP (0x118 >> 2)
-
-/* CPU Error Report */
-#define GT_CPUERR_ADDRLO (0x070 >> 2)
-#define GT_CPUERR_ADDRHI (0x078 >> 2)
-#define GT_CPUERR_DATALO (0x128 >> 2) /* GT-64120A only */
-#define GT_CPUERR_DATAHI (0x130 >> 2) /* GT-64120A only */
-#define GT_CPUERR_PARITY (0x138 >> 2) /* GT-64120A only */
-
-/* CPU Sync Barrier */
-#define GT_PCI0SYNC (0x0c0 >> 2)
-#define GT_PCI1SYNC (0x0c8 >> 2)
-
-/* SDRAM and Device Address Decode */
-#define GT_SCS0LD (0x400 >> 2)
-#define GT_SCS0HD (0x404 >> 2)
-#define GT_SCS1LD (0x408 >> 2)
-#define GT_SCS1HD (0x40c >> 2)
-#define GT_SCS2LD (0x410 >> 2)
-#define GT_SCS2HD (0x414 >> 2)
-#define GT_SCS3LD (0x418 >> 2)
-#define GT_SCS3HD (0x41c >> 2)
-#define GT_CS0LD (0x420 >> 2)
-#define GT_CS0HD (0x424 >> 2)
-#define GT_CS1LD (0x428 >> 2)
-#define GT_CS1HD (0x42c >> 2)
-#define GT_CS2LD (0x430 >> 2)
-#define GT_CS2HD (0x434 >> 2)
-#define GT_CS3LD (0x438 >> 2)
-#define GT_CS3HD (0x43c >> 2)
-#define GT_BOOTLD (0x440 >> 2)
-#define GT_BOOTHD (0x444 >> 2)
-#define GT_ADERR (0x470 >> 2)
-
-/* SDRAM Configuration */
-#define GT_SDRAM_CFG (0x448 >> 2)
-#define GT_SDRAM_OPMODE (0x474 >> 2)
-#define GT_SDRAM_BM (0x478 >> 2)
-#define GT_SDRAM_ADDRDECODE (0x47c >> 2)
-
-/* SDRAM Parameters */
-#define GT_SDRAM_B0 (0x44c >> 2)
-#define GT_SDRAM_B1 (0x450 >> 2)
-#define GT_SDRAM_B2 (0x454 >> 2)
-#define GT_SDRAM_B3 (0x458 >> 2)
-
-/* Device Parameters */
-#define GT_DEV_B0 (0x45c >> 2)
-#define GT_DEV_B1 (0x460 >> 2)
-#define GT_DEV_B2 (0x464 >> 2)
-#define GT_DEV_B3 (0x468 >> 2)
-#define GT_DEV_BOOT (0x46c >> 2)
-
-/* ECC */
-#define GT_ECC_ERRDATALO (0x480 >> 2) /* GT-64120A only */
-#define GT_ECC_ERRDATAHI (0x484 >> 2) /* GT-64120A only */
-#define GT_ECC_MEM (0x488 >> 2) /* GT-64120A only */
-#define GT_ECC_CALC (0x48c >> 2) /* GT-64120A only */
-#define GT_ECC_ERRADDR (0x490 >> 2) /* GT-64120A only */
-
-/* DMA Record */
-#define GT_DMA0_CNT (0x800 >> 2)
-#define GT_DMA1_CNT (0x804 >> 2)
-#define GT_DMA2_CNT (0x808 >> 2)
-#define GT_DMA3_CNT (0x80c >> 2)
-#define GT_DMA0_SA (0x810 >> 2)
-#define GT_DMA1_SA (0x814 >> 2)
-#define GT_DMA2_SA (0x818 >> 2)
-#define GT_DMA3_SA (0x81c >> 2)
-#define GT_DMA0_DA (0x820 >> 2)
-#define GT_DMA1_DA (0x824 >> 2)
-#define GT_DMA2_DA (0x828 >> 2)
-#define GT_DMA3_DA (0x82c >> 2)
-#define GT_DMA0_NEXT (0x830 >> 2)
-#define GT_DMA1_NEXT (0x834 >> 2)
-#define GT_DMA2_NEXT (0x838 >> 2)
-#define GT_DMA3_NEXT (0x83c >> 2)
-#define GT_DMA0_CUR (0x870 >> 2)
-#define GT_DMA1_CUR (0x874 >> 2)
-#define GT_DMA2_CUR (0x878 >> 2)
-#define GT_DMA3_CUR (0x87c >> 2)
-
-/* DMA Channel Control */
-#define GT_DMA0_CTRL (0x840 >> 2)
-#define GT_DMA1_CTRL (0x844 >> 2)
-#define GT_DMA2_CTRL (0x848 >> 2)
-#define GT_DMA3_CTRL (0x84c >> 2)
-
-/* DMA Arbiter */
-#define GT_DMA_ARB (0x860 >> 2)
-
-/* Timer/Counter */
-#define GT_TC0 (0x850 >> 2)
-#define GT_TC1 (0x854 >> 2)
-#define GT_TC2 (0x858 >> 2)
-#define GT_TC3 (0x85c >> 2)
-#define GT_TC_CONTROL (0x864 >> 2)
-
-/* PCI Internal */
-#define GT_PCI0_CMD (0xc00 >> 2)
-#define GT_PCI0_TOR (0xc04 >> 2)
-#define GT_PCI0_BS_SCS10 (0xc08 >> 2)
-#define GT_PCI0_BS_SCS32 (0xc0c >> 2)
-#define GT_PCI0_BS_CS20 (0xc10 >> 2)
-#define GT_PCI0_BS_CS3BT (0xc14 >> 2)
-#define GT_PCI1_IACK (0xc30 >> 2)
-#define GT_PCI0_IACK (0xc34 >> 2)
-#define GT_PCI0_BARE (0xc3c >> 2)
-#define GT_PCI0_PREFMBR (0xc40 >> 2)
-#define GT_PCI0_SCS10_BAR (0xc48 >> 2)
-#define GT_PCI0_SCS32_BAR (0xc4c >> 2)
-#define GT_PCI0_CS20_BAR (0xc50 >> 2)
-#define GT_PCI0_CS3BT_BAR (0xc54 >> 2)
-#define GT_PCI0_SSCS10_BAR (0xc58 >> 2)
-#define GT_PCI0_SSCS32_BAR (0xc5c >> 2)
-#define GT_PCI0_SCS3BT_BAR (0xc64 >> 2)
-#define GT_PCI1_CMD (0xc80 >> 2)
-#define GT_PCI1_TOR (0xc84 >> 2)
-#define GT_PCI1_BS_SCS10 (0xc88 >> 2)
-#define GT_PCI1_BS_SCS32 (0xc8c >> 2)
-#define GT_PCI1_BS_CS20 (0xc90 >> 2)
-#define GT_PCI1_BS_CS3BT (0xc94 >> 2)
-#define GT_PCI1_BARE (0xcbc >> 2)
-#define GT_PCI1_PREFMBR (0xcc0 >> 2)
-#define GT_PCI1_SCS10_BAR (0xcc8 >> 2)
-#define GT_PCI1_SCS32_BAR (0xccc >> 2)
-#define GT_PCI1_CS20_BAR (0xcd0 >> 2)
-#define GT_PCI1_CS3BT_BAR (0xcd4 >> 2)
-#define GT_PCI1_SSCS10_BAR (0xcd8 >> 2)
-#define GT_PCI1_SSCS32_BAR (0xcdc >> 2)
-#define GT_PCI1_SCS3BT_BAR (0xce4 >> 2)
-#define GT_PCI1_CFGADDR (0xcf0 >> 2)
-#define GT_PCI1_CFGDATA (0xcf4 >> 2)
-#define GT_PCI0_CFGADDR (0xcf8 >> 2)
-#define GT_PCI0_CFGDATA (0xcfc >> 2)
-
-/* Interrupts */
-#define GT_INTRCAUSE (0xc18 >> 2)
-#define GT_INTRMASK (0xc1c >> 2)
-#define GT_PCI0_ICMASK (0xc24 >> 2)
-#define GT_PCI0_SERR0MASK (0xc28 >> 2)
-#define GT_CPU_INTSEL (0xc70 >> 2)
-#define GT_PCI0_INTSEL (0xc74 >> 2)
-#define GT_HINTRCAUSE (0xc98 >> 2)
-#define GT_HINTRMASK (0xc9c >> 2)
-#define GT_PCI0_HICMASK (0xca4 >> 2)
-#define GT_PCI1_SERR1MASK (0xca8 >> 2)
-
-
-typedef PCIHostState GT64120PCIState;
-
-typedef struct GT64120State {
- GT64120PCIState *pci;
- uint32_t regs[GT_REGS];
-} GT64120State;
-
-static void gt64120_pci_mapping(GT64120State *s)
-{
- target_phys_addr_t start, length;
-
- /* Update IO mapping */
- if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD])
- {
- start = s->regs[GT_PCI0IOLD] << 21;
- length = ((s->regs[GT_PCI0IOHD] + 1) - (s->regs[GT_PCI0IOLD] & 0x7f)) << 21;
- isa_mmio_init(start, length);
- }
-}
-
-static void gt64120_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- GT64120State *s = opaque;
- uint32_t saddr;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- saddr = (addr & 0xfff) >> 2;
- switch (saddr) {
-
- /* CPU Configuration */
- case GT_CPU:
- s->regs[GT_CPU] = val;
- break;
- case GT_MULTI:
- /* Read-only register as only one GT64xxx is present on the CPU bus */
- break;
-
- /* CPU Address Decode */
- case GT_PCI0IOLD:
- s->regs[GT_PCI0IOLD] = val & 0x00007fff;
- s->regs[GT_PCI0IOREMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI0M0LD:
- s->regs[GT_PCI0M0LD] = val & 0x00007fff;
- s->regs[GT_PCI0M0REMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI0M1LD:
- s->regs[GT_PCI0M1LD] = val & 0x00007fff;
- s->regs[GT_PCI0M1REMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI1IOLD:
- s->regs[GT_PCI1IOLD] = val & 0x00007fff;
- s->regs[GT_PCI1IOREMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI1M0LD:
- s->regs[GT_PCI1M0LD] = val & 0x00007fff;
- s->regs[GT_PCI1M0REMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI1M1LD:
- s->regs[GT_PCI1M1LD] = val & 0x00007fff;
- s->regs[GT_PCI1M1REMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI0IOHD:
- case GT_PCI0M0HD:
- case GT_PCI0M1HD:
- case GT_PCI1IOHD:
- case GT_PCI1M0HD:
- case GT_PCI1M1HD:
- s->regs[saddr] = val & 0x0000007f;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI0IOREMAP:
- case GT_PCI0M0REMAP:
- case GT_PCI0M1REMAP:
- case GT_PCI1IOREMAP:
- case GT_PCI1M0REMAP:
- case GT_PCI1M1REMAP:
- s->regs[saddr] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
-
- /* CPU Error Report */
- case GT_CPUERR_ADDRLO:
- case GT_CPUERR_ADDRHI:
- case GT_CPUERR_DATALO:
- case GT_CPUERR_DATAHI:
- case GT_CPUERR_PARITY:
- /* Read-only registers, do nothing */
- break;
-
- /* CPU Sync Barrier */
- case GT_PCI0SYNC:
- case GT_PCI1SYNC:
- /* Read-only registers, do nothing */
- break;
-
- /* ECC */
- case GT_ECC_ERRDATALO:
- case GT_ECC_ERRDATAHI:
- case GT_ECC_MEM:
- case GT_ECC_CALC:
- case GT_ECC_ERRADDR:
- /* Read-only registers, do nothing */
- break;
-
- /* PCI Internal */
- case GT_PCI0_CMD:
- case GT_PCI1_CMD:
- s->regs[saddr] = val & 0x0401fc0f;
- break;
- case GT_PCI0_CFGADDR:
- s->pci->config_reg = val & 0x80fffffc;
- break;
- case GT_PCI0_CFGDATA:
- pci_host_data_writel(s->pci, 0, val);
- break;
-
- /* SDRAM Parameters */
- case GT_SDRAM_B0:
- case GT_SDRAM_B1:
- case GT_SDRAM_B2:
- case GT_SDRAM_B3:
- /* We don't simulate electrical parameters of the SDRAM.
- Accept, but ignore the values. */
- s->regs[saddr] = val;
- break;
-
- default:
-#if 0
- printf ("gt64120_writel: Bad register offset 0x%x\n", (int)addr);
-#endif
- break;
- }
-}
-
-static uint32_t gt64120_readl (void *opaque,
- target_phys_addr_t addr)
-{
- GT64120State *s = opaque;
- uint32_t val;
- uint32_t saddr;
-
- val = 0;
- saddr = (addr & 0xfff) >> 2;
-
- switch (saddr) {
-
- /* CPU Configuration */
- case GT_MULTI:
- /* Only one GT64xxx is present on the CPU bus, return
- the initial value */
- val = s->regs[saddr];
- break;
-
- /* CPU Error Report */
- case GT_CPUERR_ADDRLO:
- case GT_CPUERR_ADDRHI:
- case GT_CPUERR_DATALO:
- case GT_CPUERR_DATAHI:
- case GT_CPUERR_PARITY:
- /* Emulated memory has no error, always return the initial
- values */
- val = s->regs[saddr];
- break;
-
- /* CPU Sync Barrier */
- case GT_PCI0SYNC:
- case GT_PCI1SYNC:
- /* Reading those register should empty all FIFO on the PCI
- bus, which are not emulated. The return value should be
- a random value that should be ignored. */
- val = 0xc000ffee;
- break;
-
- /* ECC */
- case GT_ECC_ERRDATALO:
- case GT_ECC_ERRDATAHI:
- case GT_ECC_MEM:
- case GT_ECC_CALC:
- case GT_ECC_ERRADDR:
- /* Emulated memory has no error, always return the initial
- values */
- val = s->regs[saddr];
- break;
-
- case GT_CPU:
- case GT_PCI0IOLD:
- case GT_PCI0M0LD:
- case GT_PCI0M1LD:
- case GT_PCI1IOLD:
- case GT_PCI1M0LD:
- case GT_PCI1M1LD:
- case GT_PCI0IOHD:
- case GT_PCI0M0HD:
- case GT_PCI0M1HD:
- case GT_PCI1IOHD:
- case GT_PCI1M0HD:
- case GT_PCI1M1HD:
- case GT_PCI0_CMD:
- case GT_PCI1_CMD:
- case GT_PCI0IOREMAP:
- case GT_PCI0M0REMAP:
- case GT_PCI0M1REMAP:
- case GT_PCI1IOREMAP:
- case GT_PCI1M0REMAP:
- case GT_PCI1M1REMAP:
- val = s->regs[saddr];
- break;
- case GT_PCI0_IACK:
- /* Read the IRQ number */
- val = pic_read_irq(isa_pic);
- break;
-
- /* SDRAM Parameters */
- case GT_SDRAM_B0:
- case GT_SDRAM_B1:
- case GT_SDRAM_B2:
- case GT_SDRAM_B3:
- /* We don't simulate electrical parameters of the SDRAM.
- Just return the last written value. */
- val = s->regs[saddr];
- break;
-
- /* PCI Internal */
- case GT_PCI0_CFGADDR:
- val = s->pci->config_reg;
- break;
- case GT_PCI0_CFGDATA:
- val = pci_host_data_readl(s->pci, 0);
- break;
-
- default:
- val = s->regs[saddr];
-#if 0
- printf ("gt64120_readl: Bad register offset 0x%x\n", (int)addr);
-#endif
- break;
- }
-
-#ifdef TARGET_WORDS_BIGENDIAN
- return bswap32(val);
-#else
- return val;
-#endif
-}
-
-static CPUWriteMemoryFunc *gt64120_write[] = {
- &gt64120_writel,
- &gt64120_writel,
- &gt64120_writel,
-};
-
-static CPUReadMemoryFunc *gt64120_read[] = {
- &gt64120_readl,
- &gt64120_readl,
- &gt64120_readl,
-};
-
-static int pci_gt64120_map_irq(PCIDevice *pci_dev, int irq_num)
-{
- int slot;
-
- slot = (pci_dev->devfn >> 3);
-
- switch (slot) {
- /* PIIX4 USB */
- case 10:
- return 3;
- /* AMD 79C973 Ethernet */
- case 11:
- return 0;
- /* Crystal 4281 Sound */
- case 12:
- return 0;
- /* PCI slot 1 to 4 */
- case 18 ... 21:
- return ((slot - 18) + irq_num) & 0x03;
- /* Unknown device, don't do any translation */
- default:
- return irq_num;
- }
-}
-
-extern PCIDevice *piix4_dev;
-static int pci_irq_levels[4];
-
-static void pci_gt64120_set_irq(void *pic, int irq_num, int level)
-{
- int i, pic_irq, pic_level;
-
- pci_irq_levels[irq_num] = level;
-
- /* now we change the pic irq level according to the piix irq mappings */
- /* XXX: optimize */
- pic_irq = piix4_dev->config[0x60 + irq_num];
- if (pic_irq < 16) {
- /* The pic level is the logical OR of all the PCI irqs mapped
- to it */
- pic_level = 0;
- for (i = 0; i < 4; i++) {
- if (pic_irq == piix4_dev->config[0x60 + i])
- pic_level |= pci_irq_levels[i];
- }
- pic_set_irq(pic_irq, pic_level);
- }
-}
-
-
-void gt64120_reset(void *opaque)
-{
- GT64120State *s = opaque;
-
- /* CPU Configuration */
-#ifdef TARGET_WORDS_BIGENDIAN
- s->regs[GT_CPU] = 0x00000000;
-#else
- s->regs[GT_CPU] = 0x00000800;
-#endif
- s->regs[GT_MULTI] = 0x00000000;
-
- /* CPU Address decode FIXME: not complete*/
- s->regs[GT_PCI0IOLD] = 0x00000080;
- s->regs[GT_PCI0IOHD] = 0x0000000f;
- s->regs[GT_PCI0M0LD] = 0x00000090;
- s->regs[GT_PCI0M0HD] = 0x0000001f;
- s->regs[GT_PCI0M1LD] = 0x00000790;
- s->regs[GT_PCI0M1HD] = 0x0000001f;
- s->regs[GT_PCI1IOLD] = 0x00000100;
- s->regs[GT_PCI1IOHD] = 0x0000000f;
- s->regs[GT_PCI1M0LD] = 0x00000110;
- s->regs[GT_PCI1M0HD] = 0x0000001f;
- s->regs[GT_PCI1M1LD] = 0x00000120;
- s->regs[GT_PCI1M1HD] = 0x0000002f;
- s->regs[GT_PCI0IOREMAP] = 0x00000080;
- s->regs[GT_PCI0M0REMAP] = 0x00000090;
- s->regs[GT_PCI0M1REMAP] = 0x00000790;
- s->regs[GT_PCI1IOREMAP] = 0x00000100;
- s->regs[GT_PCI1M0REMAP] = 0x00000110;
- s->regs[GT_PCI1M1REMAP] = 0x00000120;
-
- /* CPU Error Report */
- s->regs[GT_CPUERR_ADDRLO] = 0x00000000;
- s->regs[GT_CPUERR_ADDRHI] = 0x00000000;
- s->regs[GT_CPUERR_DATALO] = 0xffffffff;
- s->regs[GT_CPUERR_DATAHI] = 0xffffffff;
- s->regs[GT_CPUERR_PARITY] = 0x000000ff;
-
- /* ECC */
- s->regs[GT_ECC_ERRDATALO] = 0x00000000;
- s->regs[GT_ECC_ERRDATAHI] = 0x00000000;
- s->regs[GT_ECC_MEM] = 0x00000000;
- s->regs[GT_ECC_CALC] = 0x00000000;
- s->regs[GT_ECC_ERRADDR] = 0x00000000;
-
- /* SDRAM Parameters */
- s->regs[GT_SDRAM_B0] = 0x00000005;
- s->regs[GT_SDRAM_B1] = 0x00000005;
- s->regs[GT_SDRAM_B2] = 0x00000005;
- s->regs[GT_SDRAM_B3] = 0x00000005;
-
- /* PCI Internal FIXME: not complete*/
-#ifdef TARGET_WORDS_BIGENDIAN
- s->regs[GT_PCI0_CMD] = 0x00000000;
- s->regs[GT_PCI1_CMD] = 0x00000000;
-#else
- s->regs[GT_PCI0_CMD] = 0x00010001;
- s->regs[GT_PCI1_CMD] = 0x00010001;
-#endif
- s->regs[GT_PCI0_IACK] = 0x00000000;
- s->regs[GT_PCI1_IACK] = 0x00000000;
-
- gt64120_pci_mapping(s);
-}
-
-PCIBus *pci_gt64120_init(void *pic)
-{
- GT64120State *s;
- PCIDevice *d;
- int gt64120;
-
- s = qemu_mallocz(sizeof(GT64120State));
- s->pci = qemu_mallocz(sizeof(GT64120PCIState));
- gt64120_reset(s);
-
- s->pci->bus = pci_register_bus(pci_gt64120_set_irq, pci_gt64120_map_irq,
- pic, 144, 4);
-
- gt64120 = cpu_register_io_memory(0, gt64120_read,
- gt64120_write, s);
- cpu_register_physical_memory(0x1be00000LL, 0x1000, gt64120);
-
- d = pci_register_device(s->pci->bus, "GT64120 PCI Bus", sizeof(PCIDevice),
- 0, NULL, NULL);
-
- d->config[0x00] = 0xab; // vendor_id
- d->config[0x01] = 0x11;
- d->config[0x02] = 0x46; // device_id
- d->config[0x03] = 0x20;
- d->config[0x04] = 0x06;
- d->config[0x05] = 0x00;
- d->config[0x06] = 0x80;
- d->config[0x07] = 0xa2;
- d->config[0x08] = 0x10;
- d->config[0x09] = 0x00;
- d->config[0x0A] = 0x80;
- d->config[0x0B] = 0x05;
- d->config[0x0C] = 0x08;
- d->config[0x0D] = 0x40;
- d->config[0x0E] = 0x00;
- d->config[0x0F] = 0x00;
- d->config[0x17] = 0x08;
- d->config[0x1B] = 0x1c;
- d->config[0x1F] = 0x1f;
- d->config[0x23] = 0x14;
- d->config[0x27] = 0x14;
- d->config[0x3D] = 0x01;
-
- return s->pci->bus;
-}
diff --git a/tools/ioemu/hw/heathrow_pic.c b/tools/ioemu/hw/heathrow_pic.c
deleted file mode 100644
index 4980cef467..0000000000
--- a/tools/ioemu/hw/heathrow_pic.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Heathrow PIC support (standard PowerMac PIC)
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG
-
-typedef struct HeathrowPIC {
- uint32_t events;
- uint32_t mask;
- uint32_t levels;
- uint32_t level_triggered;
-} HeathrowPIC;
-
-struct HeathrowPICS {
- HeathrowPIC pics[2];
-};
-
-static inline int check_irq(HeathrowPIC *pic)
-{
- return (pic->events | (pic->levels & pic->level_triggered)) & pic->mask;
-}
-
-/* update the CPU irq state */
-static void heathrow_pic_update(HeathrowPICS *s)
-{
- if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) {
- cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
- }
-}
-
-static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- HeathrowPICS *s = opaque;
- HeathrowPIC *pic;
- unsigned int n;
-
- value = bswap32(value);
-#ifdef DEBUG
- printf("pic_writel: %08x: %08x\n",
- addr, value);
-#endif
- n = ((addr & 0xfff) - 0x10) >> 4;
- if (n >= 2)
- return;
- pic = &s->pics[n];
- switch(addr & 0xf) {
- case 0x04:
- pic->mask = value;
- heathrow_pic_update(s);
- break;
- case 0x08:
- /* do not reset level triggered IRQs */
- value &= ~pic->level_triggered;
- pic->events &= ~value;
- heathrow_pic_update(s);
- break;
- default:
- break;
- }
-}
-
-static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
-{
- HeathrowPICS *s = opaque;
- HeathrowPIC *pic;
- unsigned int n;
- uint32_t value;
-
- n = ((addr & 0xfff) - 0x10) >> 4;
- if (n >= 2) {
- value = 0;
- } else {
- pic = &s->pics[n];
- switch(addr & 0xf) {
- case 0x0:
- value = pic->events;
- break;
- case 0x4:
- value = pic->mask;
- break;
- case 0xc:
- value = pic->levels;
- break;
- default:
- value = 0;
- break;
- }
- }
-#ifdef DEBUG
- printf("pic_readl: %08x: %08x\n",
- addr, value);
-#endif
- value = bswap32(value);
- return value;
-}
-
-static CPUWriteMemoryFunc *pic_write[] = {
- &pic_writel,
- &pic_writel,
- &pic_writel,
-};
-
-static CPUReadMemoryFunc *pic_read[] = {
- &pic_readl,
- &pic_readl,
- &pic_readl,
-};
-
-
-void heathrow_pic_set_irq(void *opaque, int num, int level)
-{
- HeathrowPICS *s = opaque;
- HeathrowPIC *pic;
- unsigned int irq_bit;
-
-#if defined(DEBUG)
- {
- static int last_level[64];
- if (last_level[num] != level) {
- printf("set_irq: num=0x%02x level=%d\n", num, level);
- last_level[num] = level;
- }
- }
-#endif
- pic = &s->pics[1 - (num >> 5)];
- irq_bit = 1 << (num & 0x1f);
- if (level) {
- pic->events |= irq_bit & ~pic->level_triggered;
- pic->levels |= irq_bit;
- } else {
- pic->levels &= ~irq_bit;
- }
- heathrow_pic_update(s);
-}
-
-HeathrowPICS *heathrow_pic_init(int *pmem_index)
-{
- HeathrowPICS *s;
-
- s = qemu_mallocz(sizeof(HeathrowPICS));
- s->pics[0].level_triggered = 0;
- s->pics[1].level_triggered = 0x1ff00000;
- *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s);
- return s;
-}
diff --git a/tools/ioemu/hw/i8254.c b/tools/ioemu/hw/i8254.c
deleted file mode 100644
index a4097632eb..0000000000
--- a/tools/ioemu/hw/i8254.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * QEMU 8253/8254 interval timer emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_PIT
-
-#define RW_STATE_LSB 1
-#define RW_STATE_MSB 2
-#define RW_STATE_WORD0 3
-#define RW_STATE_WORD1 4
-
-typedef struct PITChannelState {
- int count; /* can be 65536 */
- uint16_t latched_count;
- uint8_t count_latched;
- uint8_t status_latched;
- uint8_t status;
- uint8_t read_state;
- uint8_t write_state;
- uint8_t write_latch;
- uint8_t rw_mode;
- uint8_t mode;
- uint8_t bcd; /* not supported */
- uint8_t gate; /* timer start */
- int64_t count_load_time;
- /* irq handling */
- int64_t next_transition_time;
- QEMUTimer *irq_timer;
- int irq;
-} PITChannelState;
-
-struct PITState {
- PITChannelState channels[3];
-};
-
-static PITState pit_state;
-
-static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
-
-static int pit_get_count(PITChannelState *s)
-{
- uint64_t d;
- int counter;
-
- d = muldiv64(qemu_get_clock(vm_clock) - s->count_load_time, PIT_FREQ, ticks_per_sec);
- switch(s->mode) {
- case 0:
- case 1:
- case 4:
- case 5:
- counter = (s->count - d) & 0xffff;
- break;
- case 3:
- /* XXX: may be incorrect for odd counts */
- counter = s->count - ((2 * d) % s->count);
- break;
- default:
- counter = s->count - (d % s->count);
- break;
- }
- return counter;
-}
-
-/* get pit output bit */
-static int pit_get_out1(PITChannelState *s, int64_t current_time)
-{
- uint64_t d;
- int out;
-
- d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
- switch(s->mode) {
- default:
- case 0:
- out = (d >= s->count);
- break;
- case 1:
- out = (d < s->count);
- break;
- case 2:
- if ((d % s->count) == 0 && d != 0)
- out = 1;
- else
- out = 0;
- break;
- case 3:
- out = (d % s->count) < ((s->count + 1) >> 1);
- break;
- case 4:
- case 5:
- out = (d == s->count);
- break;
- }
- return out;
-}
-
-int pit_get_out(PITState *pit, int channel, int64_t current_time)
-{
- PITChannelState *s = &pit->channels[channel];
- return pit_get_out1(s, current_time);
-}
-
-/* return -1 if no transition will occur. */
-static int64_t pit_get_next_transition_time(PITChannelState *s,
- int64_t current_time)
-{
- uint64_t d, next_time, base;
- int period2;
-
- d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
- switch(s->mode) {
- default:
- case 0:
- case 1:
- if (d < s->count)
- next_time = s->count;
- else
- return -1;
- break;
- case 2:
- base = (d / s->count) * s->count;
- if ((d - base) == 0 && d != 0)
- next_time = base + s->count;
- else
- next_time = base + s->count + 1;
- break;
- case 3:
- base = (d / s->count) * s->count;
- period2 = ((s->count + 1) >> 1);
- if ((d - base) < period2)
- next_time = base + period2;
- else
- next_time = base + s->count;
- break;
- case 4:
- case 5:
- if (d < s->count)
- next_time = s->count;
- else if (d == s->count)
- next_time = s->count + 1;
- else
- return -1;
- break;
- }
- /* convert to timer units */
- next_time = s->count_load_time + muldiv64(next_time, ticks_per_sec, PIT_FREQ);
- /* fix potential rounding problems */
- /* XXX: better solution: use a clock at PIT_FREQ Hz */
- if (next_time <= current_time)
- next_time = current_time + 1;
- return next_time;
-}
-
-/* val must be 0 or 1 */
-void pit_set_gate(PITState *pit, int channel, int val)
-{
- PITChannelState *s = &pit->channels[channel];
-
- switch(s->mode) {
- default:
- case 0:
- case 4:
- /* XXX: just disable/enable counting */
- break;
- case 1:
- case 5:
- if (s->gate < val) {
- /* restart counting on rising edge */
- s->count_load_time = qemu_get_clock(vm_clock);
- pit_irq_timer_update(s, s->count_load_time);
- }
- break;
- case 2:
- case 3:
- if (s->gate < val) {
- /* restart counting on rising edge */
- s->count_load_time = qemu_get_clock(vm_clock);
- pit_irq_timer_update(s, s->count_load_time);
- }
- /* XXX: disable/enable counting */
- break;
- }
- s->gate = val;
-}
-
-int pit_get_gate(PITState *pit, int channel)
-{
- PITChannelState *s = &pit->channels[channel];
- return s->gate;
-}
-
-int pit_get_initial_count(PITState *pit, int channel)
-{
- PITChannelState *s = &pit->channels[channel];
- return s->count;
-}
-
-int pit_get_mode(PITState *pit, int channel)
-{
- PITChannelState *s = &pit->channels[channel];
- return s->mode;
-}
-
-static inline void pit_load_count(PITChannelState *s, int val)
-{
- if (val == 0)
- val = 0x10000;
- s->count_load_time = qemu_get_clock(vm_clock);
- s->count = val;
- pit_irq_timer_update(s, s->count_load_time);
-}
-
-/* if already latched, do not latch again */
-static void pit_latch_count(PITChannelState *s)
-{
- if (!s->count_latched) {
- s->latched_count = pit_get_count(s);
- s->count_latched = s->rw_mode;
- }
-}
-
-static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- PITState *pit = opaque;
- int channel, access;
- PITChannelState *s;
-
- addr &= 3;
- if (addr == 3) {
- channel = val >> 6;
- if (channel == 3) {
- /* read back command */
- for(channel = 0; channel < 3; channel++) {
- s = &pit->channels[channel];
- if (val & (2 << channel)) {
- if (!(val & 0x20)) {
- pit_latch_count(s);
- }
- if (!(val & 0x10) && !s->status_latched) {
- /* status latch */
- /* XXX: add BCD and null count */
- s->status = (pit_get_out1(s, qemu_get_clock(vm_clock)) << 7) |
- (s->rw_mode << 4) |
- (s->mode << 1) |
- s->bcd;
- s->status_latched = 1;
- }
- }
- }
- } else {
- s = &pit->channels[channel];
- access = (val >> 4) & 3;
- if (access == 0) {
- pit_latch_count(s);
- } else {
- s->rw_mode = access;
- s->read_state = access;
- s->write_state = access;
-
- s->mode = (val >> 1) & 7;
- s->bcd = val & 1;
- /* XXX: update irq timer ? */
- }
- }
- } else {
- s = &pit->channels[addr];
- switch(s->write_state) {
- default:
- case RW_STATE_LSB:
- pit_load_count(s, val);
- break;
- case RW_STATE_MSB:
- pit_load_count(s, val << 8);
- break;
- case RW_STATE_WORD0:
- s->write_latch = val;
- s->write_state = RW_STATE_WORD1;
- break;
- case RW_STATE_WORD1:
- pit_load_count(s, s->write_latch | (val << 8));
- s->write_state = RW_STATE_WORD0;
- break;
- }
- }
-}
-
-static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
-{
- PITState *pit = opaque;
- int ret, count;
- PITChannelState *s;
-
- addr &= 3;
- s = &pit->channels[addr];
- if (s->status_latched) {
- s->status_latched = 0;
- ret = s->status;
- } else if (s->count_latched) {
- switch(s->count_latched) {
- default:
- case RW_STATE_LSB:
- ret = s->latched_count & 0xff;
- s->count_latched = 0;
- break;
- case RW_STATE_MSB:
- ret = s->latched_count >> 8;
- s->count_latched = 0;
- break;
- case RW_STATE_WORD0:
- ret = s->latched_count & 0xff;
- s->count_latched = RW_STATE_MSB;
- break;
- }
- } else {
- switch(s->read_state) {
- default:
- case RW_STATE_LSB:
- count = pit_get_count(s);
- ret = count & 0xff;
- break;
- case RW_STATE_MSB:
- count = pit_get_count(s);
- ret = (count >> 8) & 0xff;
- break;
- case RW_STATE_WORD0:
- count = pit_get_count(s);
- ret = count & 0xff;
- s->read_state = RW_STATE_WORD1;
- break;
- case RW_STATE_WORD1:
- count = pit_get_count(s);
- ret = (count >> 8) & 0xff;
- s->read_state = RW_STATE_WORD0;
- break;
- }
- }
- return ret;
-}
-
-static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
-{
- int64_t expire_time;
- int irq_level;
-
- if (!s->irq_timer)
- return;
- expire_time = pit_get_next_transition_time(s, current_time);
- irq_level = pit_get_out1(s, current_time);
- pic_set_irq(s->irq, irq_level);
-#ifdef DEBUG_PIT
- printf("irq_level=%d next_delay=%f\n",
- irq_level,
- (double)(expire_time - current_time) / ticks_per_sec);
-#endif
- s->next_transition_time = expire_time;
- if (expire_time != -1)
- qemu_mod_timer(s->irq_timer, expire_time);
- else
- qemu_del_timer(s->irq_timer);
-}
-
-static void pit_irq_timer(void *opaque)
-{
- PITChannelState *s = opaque;
-
- pit_irq_timer_update(s, s->next_transition_time);
-}
-
-static void pit_save(QEMUFile *f, void *opaque)
-{
- PITState *pit = opaque;
- PITChannelState *s;
- int i;
-
- for(i = 0; i < 3; i++) {
- s = &pit->channels[i];
- qemu_put_be32s(f, &s->count);
- qemu_put_be16s(f, &s->latched_count);
- qemu_put_8s(f, &s->count_latched);
- qemu_put_8s(f, &s->status_latched);
- qemu_put_8s(f, &s->status);
- qemu_put_8s(f, &s->read_state);
- qemu_put_8s(f, &s->write_state);
- qemu_put_8s(f, &s->write_latch);
- qemu_put_8s(f, &s->rw_mode);
- qemu_put_8s(f, &s->mode);
- qemu_put_8s(f, &s->bcd);
- qemu_put_8s(f, &s->gate);
- qemu_put_be64s(f, &s->count_load_time);
- if (s->irq_timer) {
- qemu_put_be64s(f, &s->next_transition_time);
- qemu_put_timer(f, s->irq_timer);
- }
- }
-}
-
-static int pit_load(QEMUFile *f, void *opaque, int version_id)
-{
- PITState *pit = opaque;
- PITChannelState *s;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- for(i = 0; i < 3; i++) {
- s = &pit->channels[i];
- qemu_get_be32s(f, &s->count);
- qemu_get_be16s(f, &s->latched_count);
- qemu_get_8s(f, &s->count_latched);
- qemu_get_8s(f, &s->status_latched);
- qemu_get_8s(f, &s->status);
- qemu_get_8s(f, &s->read_state);
- qemu_get_8s(f, &s->write_state);
- qemu_get_8s(f, &s->write_latch);
- qemu_get_8s(f, &s->rw_mode);
- qemu_get_8s(f, &s->mode);
- qemu_get_8s(f, &s->bcd);
- qemu_get_8s(f, &s->gate);
- qemu_get_be64s(f, &s->count_load_time);
- if (s->irq_timer) {
- qemu_get_be64s(f, &s->next_transition_time);
- qemu_get_timer(f, s->irq_timer);
- }
- }
- return 0;
-}
-
-static void pit_reset(void *opaque)
-{
- PITState *pit = opaque;
- PITChannelState *s;
- int i;
-
- for(i = 0;i < 3; i++) {
- s = &pit->channels[i];
- s->mode = 3;
- s->gate = (i != 2);
- pit_load_count(s, 0);
- }
-}
-
-PITState *pit_init(int base, int irq)
-{
- PITState *pit = &pit_state;
- PITChannelState *s;
-
- s = &pit->channels[0];
- /* the timer 0 is connected to an IRQ */
- s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
- s->irq = irq;
-
- register_savevm("i8254", base, 1, pit_save, pit_load, pit);
-
- qemu_register_reset(pit_reset, pit);
- register_ioport_write(base, 4, 1, pit_ioport_write, pit);
- register_ioport_read(base, 3, 1, pit_ioport_read, pit);
-
- pit_reset(pit);
-
- return pit;
-}
diff --git a/tools/ioemu/hw/i8259.c b/tools/ioemu/hw/i8259.c
deleted file mode 100644
index f8b5a984b5..0000000000
--- a/tools/ioemu/hw/i8259.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * QEMU 8259 interrupt controller emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug PIC */
-//#define DEBUG_PIC
-
-//#define DEBUG_IRQ_LATENCY
-//#define DEBUG_IRQ_COUNT
-
-typedef struct PicState {
- uint8_t last_irr; /* edge detection */
- uint8_t irr; /* interrupt request register */
- uint8_t imr; /* interrupt mask register */
- uint8_t isr; /* interrupt service register */
- uint8_t priority_add; /* highest irq priority */
- uint8_t irq_base;
- uint8_t read_reg_select;
- uint8_t poll;
- uint8_t special_mask;
- uint8_t init_state;
- uint8_t auto_eoi;
- uint8_t rotate_on_auto_eoi;
- uint8_t special_fully_nested_mode;
- uint8_t init4; /* true if 4 byte init */
- uint8_t elcr; /* PIIX edge/trigger selection*/
- uint8_t elcr_mask;
- PicState2 *pics_state;
-} PicState;
-
-struct PicState2 {
- /* 0 is master pic, 1 is slave pic */
- /* XXX: better separation between the two pics */
- PicState pics[2];
- IRQRequestFunc *irq_request;
- void *irq_request_opaque;
- /* IOAPIC callback support */
- SetIRQFunc *alt_irq_func;
- void *alt_irq_opaque;
-};
-
-#if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT)
-static int irq_level[16];
-#endif
-#ifdef DEBUG_IRQ_COUNT
-static uint64_t irq_count[16];
-#endif
-
-/* set irq level. If an edge is detected, then the IRR is set to 1 */
-static inline void pic_set_irq1(PicState *s, int irq, int level)
-{
- int mask;
- mask = 1 << irq;
- if (s->elcr & mask) {
- /* level triggered */
- if (level) {
- s->irr |= mask;
- s->last_irr |= mask;
- } else {
- s->irr &= ~mask;
- s->last_irr &= ~mask;
- }
- } else {
- /* edge triggered */
- if (level) {
- if ((s->last_irr & mask) == 0)
- s->irr |= mask;
- s->last_irr |= mask;
- } else {
- s->last_irr &= ~mask;
- }
- }
-}
-
-/* return the highest priority found in mask (highest = smallest
- number). Return 8 if no irq */
-static inline int get_priority(PicState *s, int mask)
-{
- int priority;
- if (mask == 0)
- return 8;
- priority = 0;
- while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
- priority++;
- return priority;
-}
-
-/* return the pic wanted interrupt. return -1 if none */
-static int pic_get_irq(PicState *s)
-{
- int mask, cur_priority, priority;
-
- mask = s->irr & ~s->imr;
- priority = get_priority(s, mask);
- if (priority == 8)
- return -1;
- /* compute current priority. If special fully nested mode on the
- master, the IRQ coming from the slave is not taken into account
- for the priority computation. */
- mask = s->isr;
- if (s->special_fully_nested_mode && s == &s->pics_state->pics[0])
- mask &= ~(1 << 2);
- cur_priority = get_priority(s, mask);
- if (priority < cur_priority) {
- /* higher priority found: an irq should be generated */
- return (priority + s->priority_add) & 7;
- } else {
- return -1;
- }
-}
-
-/* raise irq to CPU if necessary. must be called every time the active
- irq may change */
-/* XXX: should not export it, but it is needed for an APIC kludge */
-void pic_update_irq(PicState2 *s)
-{
- int irq2, irq;
-
- /* first look at slave pic */
- irq2 = pic_get_irq(&s->pics[1]);
- if (irq2 >= 0) {
- /* if irq request by slave pic, signal master PIC */
- pic_set_irq1(&s->pics[0], 2, 1);
- pic_set_irq1(&s->pics[0], 2, 0);
- }
- /* look at requested irq */
- irq = pic_get_irq(&s->pics[0]);
- if (irq >= 0) {
-#if defined(DEBUG_PIC)
- {
- int i;
- for(i = 0; i < 2; i++) {
- printf("pic%d: imr=%x irr=%x padd=%d\n",
- i, s->pics[i].imr, s->pics[i].irr,
- s->pics[i].priority_add);
-
- }
- }
- printf("pic: cpu_interrupt\n");
-#endif
- s->irq_request(s->irq_request_opaque, 1);
- }
-
-/* all targets should do this rather than acking the IRQ in the cpu */
-#if defined(TARGET_MIPS)
- else {
- s->irq_request(s->irq_request_opaque, 0);
- }
-#endif
-}
-
-#ifdef DEBUG_IRQ_LATENCY
-int64_t irq_time[16];
-#endif
-
-void pic_set_irq_new(void *opaque, int irq, int level)
-{
- PicState2 *s = opaque;
-
-#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
- if (level != irq_level[irq]) {
-#if defined(DEBUG_PIC)
- printf("pic_set_irq: irq=%d level=%d\n", irq, level);
-#endif
- irq_level[irq] = level;
-#ifdef DEBUG_IRQ_COUNT
- if (level == 1)
- irq_count[irq]++;
-#endif
- }
-#endif
-#ifdef DEBUG_IRQ_LATENCY
- if (level) {
- irq_time[irq] = qemu_get_clock(vm_clock);
- }
-#endif
- pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
- /* used for IOAPIC irqs */
- if (s->alt_irq_func)
- s->alt_irq_func(s->alt_irq_opaque, irq, level);
- pic_update_irq(s);
-}
-
-/* obsolete function */
-void pic_set_irq(int irq, int level)
-{
- pic_set_irq_new(isa_pic, irq, level);
-}
-
-/* acknowledge interrupt 'irq' */
-static inline void pic_intack(PicState *s, int irq)
-{
- if (s->auto_eoi) {
- if (s->rotate_on_auto_eoi)
- s->priority_add = (irq + 1) & 7;
- } else {
- s->isr |= (1 << irq);
- }
- /* We don't clear a level sensitive interrupt here */
- if (!(s->elcr & (1 << irq)))
- s->irr &= ~(1 << irq);
-}
-
-int pic_read_irq(PicState2 *s)
-{
- int irq, irq2, intno;
-
- irq = pic_get_irq(&s->pics[0]);
- if (irq >= 0) {
- pic_intack(&s->pics[0], irq);
- if (irq == 2) {
- irq2 = pic_get_irq(&s->pics[1]);
- if (irq2 >= 0) {
- pic_intack(&s->pics[1], irq2);
- } else {
- /* spurious IRQ on slave controller */
- irq2 = 7;
- }
- intno = s->pics[1].irq_base + irq2;
- irq = irq2 + 8;
- } else {
- intno = s->pics[0].irq_base + irq;
- }
- } else {
- /* spurious IRQ on host controller */
- irq = 7;
- intno = s->pics[0].irq_base + irq;
- }
- pic_update_irq(s);
-
-#ifdef DEBUG_IRQ_LATENCY
- printf("IRQ%d latency=%0.3fus\n",
- irq,
- (double)(qemu_get_clock(vm_clock) - irq_time[irq]) * 1000000.0 / ticks_per_sec);
-#endif
-#if defined(DEBUG_PIC)
- printf("pic_interrupt: irq=%d\n", irq);
-#endif
- return intno;
-}
-
-static void pic_reset(void *opaque)
-{
- PicState *s = opaque;
-
- s->last_irr = 0;
- s->irr = 0;
- s->imr = 0;
- s->isr = 0;
- s->priority_add = 0;
- s->irq_base = 0;
- s->read_reg_select = 0;
- s->poll = 0;
- s->special_mask = 0;
- s->init_state = 0;
- s->auto_eoi = 0;
- s->rotate_on_auto_eoi = 0;
- s->special_fully_nested_mode = 0;
- s->init4 = 0;
- /* Note: ELCR is not reset */
-}
-
-static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- PicState *s = opaque;
- int priority, cmd, irq;
-
-#ifdef DEBUG_PIC
- printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
-#endif
- addr &= 1;
- if (addr == 0) {
- if (val & 0x10) {
- /* init */
- pic_reset(s);
- /* deassert a pending interrupt */
- s->pics_state->irq_request(s->pics_state->irq_request_opaque, 0);
- s->init_state = 1;
- s->init4 = val & 1;
- if (val & 0x02)
- hw_error("single mode not supported");
- if (val & 0x08)
- hw_error("level sensitive irq not supported");
- } else if (val & 0x08) {
- if (val & 0x04)
- s->poll = 1;
- if (val & 0x02)
- s->read_reg_select = val & 1;
- if (val & 0x40)
- s->special_mask = (val >> 5) & 1;
- } else {
- cmd = val >> 5;
- switch(cmd) {
- case 0:
- case 4:
- s->rotate_on_auto_eoi = cmd >> 2;
- break;
- case 1: /* end of interrupt */
- case 5:
- priority = get_priority(s, s->isr);
- if (priority != 8) {
- irq = (priority + s->priority_add) & 7;
- s->isr &= ~(1 << irq);
- if (cmd == 5)
- s->priority_add = (irq + 1) & 7;
- pic_update_irq(s->pics_state);
- }
- break;
- case 3:
- irq = val & 7;
- s->isr &= ~(1 << irq);
- pic_update_irq(s->pics_state);
- break;
- case 6:
- s->priority_add = (val + 1) & 7;
- pic_update_irq(s->pics_state);
- break;
- case 7:
- irq = val & 7;
- s->isr &= ~(1 << irq);
- s->priority_add = (irq + 1) & 7;
- pic_update_irq(s->pics_state);
- break;
- default:
- /* no operation */
- break;
- }
- }
- } else {
- switch(s->init_state) {
- case 0:
- /* normal mode */
- s->imr = val;
- pic_update_irq(s->pics_state);
- break;
- case 1:
- s->irq_base = val & 0xf8;
- s->init_state = 2;
- break;
- case 2:
- if (s->init4) {
- s->init_state = 3;
- } else {
- s->init_state = 0;
- }
- break;
- case 3:
- s->special_fully_nested_mode = (val >> 4) & 1;
- s->auto_eoi = (val >> 1) & 1;
- s->init_state = 0;
- break;
- }
- }
-}
-
-static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
-{
- int ret;
-
- ret = pic_get_irq(s);
- if (ret >= 0) {
- if (addr1 >> 7) {
- s->pics_state->pics[0].isr &= ~(1 << 2);
- s->pics_state->pics[0].irr &= ~(1 << 2);
- }
- s->irr &= ~(1 << ret);
- s->isr &= ~(1 << ret);
- if (addr1 >> 7 || ret != 2)
- pic_update_irq(s->pics_state);
- } else {
- ret = 0x07;
- pic_update_irq(s->pics_state);
- }
-
- return ret;
-}
-
-static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
-{
- PicState *s = opaque;
- unsigned int addr;
- int ret;
-
- addr = addr1;
- addr &= 1;
- if (s->poll) {
- ret = pic_poll_read(s, addr1);
- s->poll = 0;
- } else {
- if (addr == 0) {
- if (s->read_reg_select)
- ret = s->isr;
- else
- ret = s->irr;
- } else {
- ret = s->imr;
- }
- }
-#ifdef DEBUG_PIC
- printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
-#endif
- return ret;
-}
-
-/* memory mapped interrupt status */
-/* XXX: may be the same than pic_read_irq() */
-uint32_t pic_intack_read(PicState2 *s)
-{
- int ret;
-
- ret = pic_poll_read(&s->pics[0], 0x00);
- if (ret == 2)
- ret = pic_poll_read(&s->pics[1], 0x80) + 8;
- /* Prepare for ISR read */
- s->pics[0].read_reg_select = 1;
-
- return ret;
-}
-
-static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- PicState *s = opaque;
- s->elcr = val & s->elcr_mask;
-}
-
-static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1)
-{
- PicState *s = opaque;
- return s->elcr;
-}
-
-static void pic_save(QEMUFile *f, void *opaque)
-{
- PicState *s = opaque;
-
- qemu_put_8s(f, &s->last_irr);
- qemu_put_8s(f, &s->irr);
- qemu_put_8s(f, &s->imr);
- qemu_put_8s(f, &s->isr);
- qemu_put_8s(f, &s->priority_add);
- qemu_put_8s(f, &s->irq_base);
- qemu_put_8s(f, &s->read_reg_select);
- qemu_put_8s(f, &s->poll);
- qemu_put_8s(f, &s->special_mask);
- qemu_put_8s(f, &s->init_state);
- qemu_put_8s(f, &s->auto_eoi);
- qemu_put_8s(f, &s->rotate_on_auto_eoi);
- qemu_put_8s(f, &s->special_fully_nested_mode);
- qemu_put_8s(f, &s->init4);
- qemu_put_8s(f, &s->elcr);
-}
-
-static int pic_load(QEMUFile *f, void *opaque, int version_id)
-{
- PicState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_8s(f, &s->last_irr);
- qemu_get_8s(f, &s->irr);
- qemu_get_8s(f, &s->imr);
- qemu_get_8s(f, &s->isr);
- qemu_get_8s(f, &s->priority_add);
- qemu_get_8s(f, &s->irq_base);
- qemu_get_8s(f, &s->read_reg_select);
- qemu_get_8s(f, &s->poll);
- qemu_get_8s(f, &s->special_mask);
- qemu_get_8s(f, &s->init_state);
- qemu_get_8s(f, &s->auto_eoi);
- qemu_get_8s(f, &s->rotate_on_auto_eoi);
- qemu_get_8s(f, &s->special_fully_nested_mode);
- qemu_get_8s(f, &s->init4);
- qemu_get_8s(f, &s->elcr);
- return 0;
-}
-
-/* XXX: add generic master/slave system */
-static void pic_init1(int io_addr, int elcr_addr, PicState *s)
-{
- register_ioport_write(io_addr, 2, 1, pic_ioport_write, s);
- register_ioport_read(io_addr, 2, 1, pic_ioport_read, s);
- if (elcr_addr >= 0) {
- register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s);
- register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
- }
- register_savevm("i8259", io_addr, 1, pic_save, pic_load, s);
- qemu_register_reset(pic_reset, s);
-}
-
-void pic_info(void)
-{
- int i;
- PicState *s;
-
- if (!isa_pic)
- return;
-
- for(i=0;i<2;i++) {
- s = &isa_pic->pics[i];
- term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
- i, s->irr, s->imr, s->isr, s->priority_add,
- s->irq_base, s->read_reg_select, s->elcr,
- s->special_fully_nested_mode);
- }
-}
-
-void irq_info(void)
-{
-#ifndef DEBUG_IRQ_COUNT
- term_printf("irq statistic code not compiled.\n");
-#else
- int i;
- int64_t count;
-
- term_printf("IRQ statistics:\n");
- for (i = 0; i < 16; i++) {
- count = irq_count[i];
- if (count > 0)
- term_printf("%2d: %" PRId64 "\n", i, count);
- }
-#endif
-}
-
-PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque)
-{
- PicState2 *s;
- s = qemu_mallocz(sizeof(PicState2));
- if (!s)
- return NULL;
- pic_init1(0x20, 0x4d0, &s->pics[0]);
- pic_init1(0xa0, 0x4d1, &s->pics[1]);
- s->pics[0].elcr_mask = 0xf8;
- s->pics[1].elcr_mask = 0xde;
- s->irq_request = irq_request;
- s->irq_request_opaque = irq_request_opaque;
- s->pics[0].pics_state = s;
- s->pics[1].pics_state = s;
- return s;
-}
-
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
- void *alt_irq_opaque)
-{
- s->alt_irq_func = alt_irq_func;
- s->alt_irq_opaque = alt_irq_opaque;
-}
diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c
deleted file mode 100644
index 63704ef04c..0000000000
--- a/tools/ioemu/hw/ide.c
+++ /dev/null
@@ -1,3077 +0,0 @@
-/*
- * QEMU IDE disk and CD-ROM Emulator
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include <malloc.h>
-
-/* debug IDE devices */
-//#define DEBUG_IDE
-//#define DEBUG_IDE_ATAPI
-//#define DEBUG_AIO
-#define USE_DMA_CDROM
-
-/* Bits of HD_STATUS */
-#define ERR_STAT 0x01
-#define INDEX_STAT 0x02
-#define ECC_STAT 0x04 /* Corrected error */
-#define DRQ_STAT 0x08
-#define SEEK_STAT 0x10
-#define SRV_STAT 0x10
-#define WRERR_STAT 0x20
-#define READY_STAT 0x40
-#define BUSY_STAT 0x80
-
-/* Bits for HD_ERROR */
-#define MARK_ERR 0x01 /* Bad address mark */
-#define TRK0_ERR 0x02 /* couldn't find track 0 */
-#define ABRT_ERR 0x04 /* Command aborted */
-#define MCR_ERR 0x08 /* media change request */
-#define ID_ERR 0x10 /* ID field not found */
-#define MC_ERR 0x20 /* media changed */
-#define ECC_ERR 0x40 /* Uncorrectable ECC error */
-#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
-#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
-
-/* Bits of HD_NSECTOR */
-#define CD 0x01
-#define IO 0x02
-#define REL 0x04
-#define TAG_MASK 0xf8
-
-#define IDE_CMD_RESET 0x04
-#define IDE_CMD_DISABLE_IRQ 0x02
-
-/* ATA/ATAPI Commands pre T13 Spec */
-#define WIN_NOP 0x00
-/*
- * 0x01->0x02 Reserved
- */
-#define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */
-/*
- * 0x04->0x07 Reserved
- */
-#define WIN_SRST 0x08 /* ATAPI soft reset command */
-#define WIN_DEVICE_RESET 0x08
-/*
- * 0x09->0x0F Reserved
- */
-#define WIN_RECAL 0x10
-#define WIN_RESTORE WIN_RECAL
-/*
- * 0x10->0x1F Reserved
- */
-#define WIN_READ 0x20 /* 28-Bit */
-#define WIN_READ_ONCE 0x21 /* 28-Bit without retries */
-#define WIN_READ_LONG 0x22 /* 28-Bit */
-#define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */
-#define WIN_READ_EXT 0x24 /* 48-Bit */
-#define WIN_READDMA_EXT 0x25 /* 48-Bit */
-#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */
-#define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */
-/*
- * 0x28
- */
-#define WIN_MULTREAD_EXT 0x29 /* 48-Bit */
-/*
- * 0x2A->0x2F Reserved
- */
-#define WIN_WRITE 0x30 /* 28-Bit */
-#define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */
-#define WIN_WRITE_LONG 0x32 /* 28-Bit */
-#define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */
-#define WIN_WRITE_EXT 0x34 /* 48-Bit */
-#define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */
-#define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */
-#define WIN_SET_MAX_EXT 0x37 /* 48-Bit */
-#define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */
-#define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */
-/*
- * 0x3A->0x3B Reserved
- */
-#define WIN_WRITE_VERIFY 0x3C /* 28-Bit */
-/*
- * 0x3D->0x3F Reserved
- */
-#define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */
-#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */
-#define WIN_VERIFY_EXT 0x42 /* 48-Bit */
-/*
- * 0x43->0x4F Reserved
- */
-#define WIN_FORMAT 0x50
-/*
- * 0x51->0x5F Reserved
- */
-#define WIN_INIT 0x60
-/*
- * 0x61->0x5F Reserved
- */
-#define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */
-#define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */
-#define WIN_DIAGNOSE 0x90
-#define WIN_SPECIFY 0x91 /* set drive geometry translation */
-#define WIN_DOWNLOAD_MICROCODE 0x92
-#define WIN_STANDBYNOW2 0x94
-#define WIN_STANDBY2 0x96
-#define WIN_SETIDLE2 0x97
-#define WIN_CHECKPOWERMODE2 0x98
-#define WIN_SLEEPNOW2 0x99
-/*
- * 0x9A VENDOR
- */
-#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
-#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
-#define WIN_QUEUED_SERVICE 0xA2
-#define WIN_SMART 0xB0 /* self-monitoring and reporting */
-#define CFA_ERASE_SECTORS 0xC0
-#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/
-#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */
-#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
-#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */
-#define WIN_READDMA 0xC8 /* read sectors using DMA transfers */
-#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */
-#define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */
-#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */
-#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */
-#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */
-#define WIN_GETMEDIASTATUS 0xDA
-#define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */
-#define WIN_POSTBOOT 0xDC
-#define WIN_PREBOOT 0xDD
-#define WIN_DOORLOCK 0xDE /* lock door on removable drives */
-#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */
-#define WIN_STANDBYNOW1 0xE0
-#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
-#define WIN_STANDBY 0xE2 /* Set device in Standby Mode */
-#define WIN_SETIDLE1 0xE3
-#define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */
-#define WIN_CHECKPOWERMODE1 0xE5
-#define WIN_SLEEPNOW1 0xE6
-#define WIN_FLUSH_CACHE 0xE7
-#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
-#define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */
- /* SET_FEATURES 0x22 or 0xDD */
-#define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */
-#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */
-#define WIN_MEDIAEJECT 0xED
-#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */
-#define WIN_SETFEATURES 0xEF /* set special drive features */
-#define EXABYTE_ENABLE_NEST 0xF0
-#define WIN_SECURITY_SET_PASS 0xF1
-#define WIN_SECURITY_UNLOCK 0xF2
-#define WIN_SECURITY_ERASE_PREPARE 0xF3
-#define WIN_SECURITY_ERASE_UNIT 0xF4
-#define WIN_SECURITY_FREEZE_LOCK 0xF5
-#define WIN_SECURITY_DISABLE 0xF6
-#define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */
-#define WIN_SET_MAX 0xF9
-#define DISABLE_SEAGATE 0xFB
-
-/* set to 1 set disable mult support */
-#define MAX_MULT_SECTORS 16
-#ifdef CONFIG_STUBDOM
-#include <xen/io/blkif.h>
-#define IDE_DMA_BUF_SIZE (BLKIF_MAX_SEGMENTS_PER_REQUEST * TARGET_PAGE_SIZE)
-#else
-#define IDE_DMA_BUF_SIZE 131072
-#endif
-#if (IDE_DMA_BUF_SIZE < MAX_MULT_SECTORS * 512)
-#error "IDE_DMA_BUF_SIZE must be bigger or equal to MAX_MULT_SECTORS * 512"
-#endif
-
-/* ATAPI defines */
-
-#define ATAPI_PACKET_SIZE 12
-
-/* The generic packet command opcodes for CD/DVD Logical Units,
- * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
-#define GPCMD_BLANK 0xa1
-#define GPCMD_CLOSE_TRACK 0x5b
-#define GPCMD_FLUSH_CACHE 0x35
-#define GPCMD_FORMAT_UNIT 0x04
-#define GPCMD_GET_CONFIGURATION 0x46
-#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
-#define GPCMD_GET_PERFORMANCE 0xac
-#define GPCMD_INQUIRY 0x12
-#define GPCMD_LOAD_UNLOAD 0xa6
-#define GPCMD_MECHANISM_STATUS 0xbd
-#define GPCMD_MODE_SELECT_10 0x55
-#define GPCMD_MODE_SENSE_10 0x5a
-#define GPCMD_PAUSE_RESUME 0x4b
-#define GPCMD_PLAY_AUDIO_10 0x45
-#define GPCMD_PLAY_AUDIO_MSF 0x47
-#define GPCMD_PLAY_AUDIO_TI 0x48
-#define GPCMD_PLAY_CD 0xbc
-#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
-#define GPCMD_READ_10 0x28
-#define GPCMD_READ_12 0xa8
-#define GPCMD_READ_CDVD_CAPACITY 0x25
-#define GPCMD_READ_CD 0xbe
-#define GPCMD_READ_CD_MSF 0xb9
-#define GPCMD_READ_DISC_INFO 0x51
-#define GPCMD_READ_DVD_STRUCTURE 0xad
-#define GPCMD_READ_FORMAT_CAPACITIES 0x23
-#define GPCMD_READ_HEADER 0x44
-#define GPCMD_READ_TRACK_RZONE_INFO 0x52
-#define GPCMD_READ_SUBCHANNEL 0x42
-#define GPCMD_READ_TOC_PMA_ATIP 0x43
-#define GPCMD_REPAIR_RZONE_TRACK 0x58
-#define GPCMD_REPORT_KEY 0xa4
-#define GPCMD_REQUEST_SENSE 0x03
-#define GPCMD_RESERVE_RZONE_TRACK 0x53
-#define GPCMD_SCAN 0xba
-#define GPCMD_SEEK 0x2b
-#define GPCMD_SEND_DVD_STRUCTURE 0xad
-#define GPCMD_SEND_EVENT 0xa2
-#define GPCMD_SEND_KEY 0xa3
-#define GPCMD_SEND_OPC 0x54
-#define GPCMD_SET_READ_AHEAD 0xa7
-#define GPCMD_SET_STREAMING 0xb6
-#define GPCMD_START_STOP_UNIT 0x1b
-#define GPCMD_STOP_PLAY_SCAN 0x4e
-#define GPCMD_TEST_UNIT_READY 0x00
-#define GPCMD_VERIFY_10 0x2f
-#define GPCMD_WRITE_10 0x2a
-#define GPCMD_WRITE_AND_VERIFY_10 0x2e
-/* This is listed as optional in ATAPI 2.6, but is (curiously)
- * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
- * Table 377 as an MMC command for SCSi devices though... Most ATAPI
- * drives support it. */
-#define GPCMD_SET_SPEED 0xbb
-/* This seems to be a SCSI specific CD-ROM opcode
- * to play data at track/index */
-#define GPCMD_PLAYAUDIO_TI 0x48
-/*
- * From MS Media Status Notification Support Specification. For
- * older drives only.
- */
-#define GPCMD_GET_MEDIA_STATUS 0xda
-
-/* Mode page codes for mode sense/set */
-#define GPMODE_R_W_ERROR_PAGE 0x01
-#define GPMODE_WRITE_PARMS_PAGE 0x05
-#define GPMODE_AUDIO_CTL_PAGE 0x0e
-#define GPMODE_POWER_PAGE 0x1a
-#define GPMODE_FAULT_FAIL_PAGE 0x1c
-#define GPMODE_TO_PROTECT_PAGE 0x1d
-#define GPMODE_CAPABILITIES_PAGE 0x2a
-#define GPMODE_ALL_PAGES 0x3f
-/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
- * of MODE_SENSE_POWER_PAGE */
-#define GPMODE_CDROM_PAGE 0x0d
-
-#define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */
-#define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */
-#define ATAPI_INT_REASON_REL 0x04
-#define ATAPI_INT_REASON_TAG 0xf8
-
-/* same constants as bochs */
-#define ASC_ILLEGAL_OPCODE 0x20
-#define ASC_LOGICAL_BLOCK_OOR 0x21
-#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
-#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28
-#define ASC_MEDIUM_NOT_PRESENT 0x3a
-#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
-
-#define SENSE_NONE 0
-#define SENSE_NOT_READY 2
-#define SENSE_ILLEGAL_REQUEST 5
-#define SENSE_UNIT_ATTENTION 6
-
-struct IDEState;
-
-typedef void EndTransferFunc(struct IDEState *);
-
-/* NOTE: IDEState represents in fact one drive */
-typedef struct IDEState {
- /* ide config */
- int is_cdrom;
- int cylinders, heads, sectors;
- int64_t nb_sectors;
- int mult_sectors;
- int identify_set;
- uint16_t identify_data[256];
- SetIRQFunc *set_irq;
- void *irq_opaque;
- int irq;
- PCIDevice *pci_dev;
- struct BMDMAState *bmdma;
- int drive_serial;
- int write_cache;
- /* ide regs */
- uint8_t feature;
- uint8_t error;
- uint32_t nsector;
- uint8_t sector;
- uint8_t lcyl;
- uint8_t hcyl;
- /* other part of tf for lba48 support */
- uint8_t hob_feature;
- uint8_t hob_nsector;
- uint8_t hob_sector;
- uint8_t hob_lcyl;
- uint8_t hob_hcyl;
-
- uint8_t select;
- uint8_t status;
-
- /* 0x3f6 command, only meaningful for drive 0 */
- uint8_t cmd;
- /* set for lba48 access */
- uint8_t lba48;
- /* depends on bit 4 in select, only meaningful for drive 0 */
- struct IDEState *cur_drive;
- BlockDriverState *bs;
- /* ATAPI specific */
- uint8_t sense_key;
- uint8_t asc;
- int packet_transfer_size;
- int elementary_transfer_size;
- int io_buffer_index;
- int lba;
- int cd_sector_size;
- int atapi_dma; /* true if dma is requested for the packet cmd */
- /* ATA DMA state */
- int io_buffer_size;
- /* PIO transfer handling */
- int req_nb_sectors; /* number of sectors per interrupt */
- EndTransferFunc *end_transfer_func;
- uint8_t *data_ptr;
- uint8_t *data_end;
- uint8_t *io_buffer;
- QEMUTimer *sector_write_timer; /* only used for win2k instal hack */
- uint32_t irq_count; /* counts IRQs when using win2k install hack */
-} IDEState;
-
-#define BM_STATUS_DMAING 0x01
-#define BM_STATUS_ERROR 0x02
-#define BM_STATUS_INT 0x04
-
-#define BM_CMD_START 0x01
-#define BM_CMD_READ 0x08
-
-#define IDE_TYPE_PIIX3 0
-#define IDE_TYPE_CMD646 1
-
-/* CMD646 specific */
-#define MRDMODE 0x71
-#define MRDMODE_INTR_CH0 0x04
-#define MRDMODE_INTR_CH1 0x08
-#define MRDMODE_BLK_CH0 0x10
-#define MRDMODE_BLK_CH1 0x20
-#define UDIDETCR0 0x73
-#define UDIDETCR1 0x7B
-
-typedef struct BMDMAState {
- uint8_t cmd;
- uint8_t status;
- uint32_t addr;
-
- struct PCIIDEState *pci_dev;
- /* current transfer state */
- uint32_t cur_addr;
- uint32_t cur_prd_last;
- uint32_t cur_prd_addr;
- uint32_t cur_prd_len;
- IDEState *ide_if;
- BlockDriverCompletionFunc *dma_cb;
- BlockDriverAIOCB *aiocb;
-} BMDMAState;
-
-typedef struct PCIIDEState {
- PCIDevice dev;
- IDEState ide_if[4];
- BMDMAState bmdma[2];
- int type; /* see IDE_TYPE_xxx */
-} PCIIDEState;
-
-#if defined(__ia64__)
-#include <xen/hvm/ioreq.h>
-
-struct buffered_piopage *buffered_pio_page;
-
-static inline struct pio_buffer *
-piobuf_by_addr(uint32_t addr)
-{
- if (addr == 0x1F0)
- return &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
- if (addr == 0x170)
- return &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
- return NULL;
-}
-
-static void
-buffered_pio_init(void)
-{
- struct pio_buffer *p1, *p2;
- uint32_t off1, off2;
-
- if (!buffered_pio_page)
- return;
-
- p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
- p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
- off1 = offsetof(struct buffered_piopage, buffer);
- off2 = (off1 + TARGET_PAGE_SIZE)/2;
-
- p1->buf_size = off2 - off1;
- p1->page_offset = off1;
-
- p2->buf_size = TARGET_PAGE_SIZE - off2;
- p2->page_offset = off2;
-}
-
-static inline void
-__buffered_pio_flush(struct pio_buffer *piobuf, IDEState *s, uint32_t pointer)
-{
- uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
- memcpy(s->data_ptr, buf, pointer);
- s->data_ptr += pointer;
-}
-
-static inline void
-buffered_pio_flush(struct pio_buffer *piobuf)
-{
- IDEState *s = piobuf->opaque;
- uint32_t pointer = piobuf->pointer;
-
- if (s != NULL && pointer > 0)
- __buffered_pio_flush(piobuf, s, pointer);
-}
-
-static inline void
-buffered_pio_reset(IDEState *s)
-{
- struct pio_buffer *piobuf;
-
- if ((unsigned)s->drive_serial - 1 < 2) /* 1,2 */
- piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
- else if ((unsigned)s->drive_serial - 3 < 2) /* 3,4 */
- piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
- else
- return;
- buffered_pio_flush(piobuf);
- piobuf->pointer = 0;
- piobuf->data_end = 0;
- piobuf->opaque = NULL;
-}
-
-static inline void
-buffered_pio_write(IDEState *s, uint32_t addr, int size)
-{
- struct pio_buffer *piobuf = piobuf_by_addr(addr);
- int data_end;
-
- if (!piobuf)
- return;
- buffered_pio_flush(piobuf);
- data_end = s->data_end - s->data_ptr - size;
- if (data_end <= 0)
- data_end = 0;
- else if (data_end > piobuf->buf_size)
- data_end = piobuf->buf_size;
- piobuf->pointer = 0;
- piobuf->data_end = data_end;
- piobuf->opaque = s;
-}
-
-static inline void
-buffered_pio_read(IDEState *s, uint32_t addr, int size)
-{
- struct pio_buffer *piobuf = piobuf_by_addr(addr);
- int data_end;
-
- if (!piobuf)
- return;
- s->data_ptr += piobuf->pointer;
- data_end = s->data_end - s->data_ptr - size;
- if (data_end <= 0) {
- data_end = 0;
- } else {
- uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
- if (data_end > piobuf->buf_size)
- data_end = piobuf->buf_size;
- memcpy(buf, s->data_ptr + size, data_end);
- }
- piobuf->pointer = 0;
- piobuf->data_end = data_end;
- piobuf->opaque = NULL;
-}
-
-/*
- * buffered pio reads are undone. It results in normal pio when the domain
- * is restored.
- * buffered pio writes are handled before saving domain.
- * However currently pci_ide_save/load() just discards a pending transfer. XXX
- */
-static void
-__handle_buffered_pio(struct pio_buffer *piobuf)
-{
- IDEState *s = piobuf->opaque;
- uint32_t pointer = piobuf->pointer;
-
-
- if (pointer == 0)
- return;/* no buffered pio */
-
- if (s != NULL) {
- /* written data are pending in pio_buffer. process it */
- __buffered_pio_flush(piobuf, s, pointer);
- } else {
- /* data are buffered for pio read in pio_buffer.
- * undone buffering by buffered_pio_read()
- */
- if (pointer > s->data_ptr - s->io_buffer)
- pointer = s->data_ptr - s->io_buffer;
- s->data_ptr -= pointer;
- }
-
- piobuf->pointer = 0;
- piobuf->data_end = 0;
- piobuf->opaque = NULL;
-}
-
-void
-handle_buffered_pio(void)
-{
- struct pio_buffer *p1, *p2;
-
- if (!buffered_pio_page)
- return;
-
- p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
- p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
-
- __handle_buffered_pio(p1);
- __handle_buffered_pio(p2);
-}
-
-#else /* !__ia64__ */
-#define buffered_pio_init() do {} while (0)
-#define buffered_pio_reset(I) do {} while (0)
-#define buffered_pio_write(I,A,S) do {} while (0)
-#define buffered_pio_read(I,A,S) do {} while (0)
-#endif
-
-static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
-static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
-
-static void padstr(char *str, const char *src, int len)
-{
- int i, v;
- for(i = 0; i < len; i++) {
- if (*src)
- v = *src++;
- else
- v = ' ';
- *(char *)((long)str ^ 1) = v;
- str++;
- }
-}
-
-static void padstr8(uint8_t *buf, int buf_size, const char *src)
-{
- int i;
- for(i = 0; i < buf_size; i++) {
- if (*src)
- buf[i] = *src++;
- else
- buf[i] = ' ';
- }
-}
-
-static void put_le16(uint16_t *p, unsigned int v)
-{
- *p = cpu_to_le16(v);
-}
-
-static void ide_identify(IDEState *s)
-{
- uint16_t *p;
- unsigned int oldsize;
- char buf[20];
-
- if (s->identify_set) {
- memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
- return;
- }
-
- memset(s->io_buffer, 0, 512);
- p = (uint16_t *)s->io_buffer;
- put_le16(p + 0, 0x0040);
- put_le16(p + 1, s->cylinders);
- put_le16(p + 3, s->heads);
- put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
- put_le16(p + 5, 512); /* XXX: retired, remove ? */
- put_le16(p + 6, s->sectors);
- snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
- padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
- put_le16(p + 20, 3); /* XXX: retired, remove ? */
- put_le16(p + 21, 512); /* cache size in sectors */
- put_le16(p + 22, 4); /* ecc bytes */
- padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
- padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
-#if MAX_MULT_SECTORS > 1
- put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
-#endif
- put_le16(p + 48, 1); /* dword I/O */
- put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
- put_le16(p + 51, 0x200); /* PIO transfer cycle */
- put_le16(p + 52, 0x200); /* DMA transfer cycle */
- put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
- put_le16(p + 54, s->cylinders);
- put_le16(p + 55, s->heads);
- put_le16(p + 56, s->sectors);
- oldsize = s->cylinders * s->heads * s->sectors;
- put_le16(p + 57, oldsize);
- put_le16(p + 58, oldsize >> 16);
- if (s->mult_sectors)
- put_le16(p + 59, 0x100 | s->mult_sectors);
- put_le16(p + 60, s->nb_sectors);
- put_le16(p + 61, s->nb_sectors >> 16);
- put_le16(p + 63, 0x07); /* mdma0-2 supported */
- put_le16(p + 65, 120);
- put_le16(p + 66, 120);
- put_le16(p + 67, 120);
- put_le16(p + 68, 120);
- put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
- put_le16(p + 81, 0x16); /* conforms to ata5 */
- /* 14=nop 5=write_cache */
- put_le16(p + 82, (1 << 14) | (1 << 5));
- /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
- put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
- put_le16(p + 84, (1 << 14));
- /* 14=nop 5=write_cache */
- put_le16(p + 85, (1 << 14) | (s->write_cache << 5));
- /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
- put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
- put_le16(p + 87, (1 << 14));
- put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
- put_le16(p + 93, 1 | (1 << 14) | 0x2000);
- put_le16(p + 100, s->nb_sectors);
- put_le16(p + 101, s->nb_sectors >> 16);
- put_le16(p + 102, s->nb_sectors >> 32);
- put_le16(p + 103, s->nb_sectors >> 48);
-
- memcpy(s->identify_data, p, sizeof(s->identify_data));
- s->identify_set = 1;
-}
-
-static void ide_atapi_identify(IDEState *s)
-{
- uint16_t *p;
- char buf[20];
-
- if (s->identify_set) {
- memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
- return;
- }
-
- memset(s->io_buffer, 0, 512);
- p = (uint16_t *)s->io_buffer;
- /* Removable CDROM, 50us response, 12 byte packets */
- put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
- snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
- padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
- put_le16(p + 20, 3); /* buffer type */
- put_le16(p + 21, 512); /* cache size in sectors */
- put_le16(p + 22, 4); /* ecc bytes */
- padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
- padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
- put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
-#ifdef USE_DMA_CDROM
- put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
- put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
- put_le16(p + 63, 7); /* mdma0-2 supported */
- put_le16(p + 64, 0x3f); /* PIO modes supported */
-#else
- put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
- put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
- put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
- put_le16(p + 64, 1); /* PIO modes */
-#endif
- put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
- put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
- put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
- put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
-
- put_le16(p + 71, 30); /* in ns */
- put_le16(p + 72, 30); /* in ns */
-
- put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
-#ifdef USE_DMA_CDROM
- put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
-#endif
- memcpy(s->identify_data, p, sizeof(s->identify_data));
- s->identify_set = 1;
-}
-
-static void ide_set_signature(IDEState *s)
-{
- s->select &= 0xf0; /* clear head */
- /* put signature */
- s->nsector = 1;
- s->sector = 1;
- if (s->is_cdrom) {
- s->lcyl = 0x14;
- s->hcyl = 0xeb;
- } else if (s->bs) {
- s->lcyl = 0;
- s->hcyl = 0;
- } else {
- s->lcyl = 0xff;
- s->hcyl = 0xff;
- }
-}
-
-static inline void ide_abort_command(IDEState *s)
-{
- s->status = READY_STAT | ERR_STAT;
- s->error = ABRT_ERR;
-}
-
-static inline void ide_set_irq(IDEState *s)
-{
- BMDMAState *bm = s->bmdma;
- if (!s->bs) return; /* yikes */
- if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
- if (bm) {
- bm->status |= BM_STATUS_INT;
- }
- s->set_irq(s->irq_opaque, s->irq, 1);
- }
-}
-
-/* prepare data transfer and tell what to do after */
-static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
- EndTransferFunc *end_transfer_func)
-{
- s->end_transfer_func = end_transfer_func;
- s->data_ptr = buf;
- s->data_end = buf + size;
- /* don't violate the HSM */
- if (!(s->status & ERR_STAT))
- s->status |= DRQ_STAT;
- buffered_pio_reset(s);
-}
-
-static void ide_transfer_stop(IDEState *s)
-{
- s->end_transfer_func = ide_transfer_stop;
- s->data_ptr = s->io_buffer;
- s->data_end = s->io_buffer;
- s->status &= ~DRQ_STAT;
- buffered_pio_reset(s);
-}
-
-static int64_t ide_get_sector(IDEState *s)
-{
- int64_t sector_num;
- if (s->select & 0x40) {
- /* lba */
- if (!s->lba48) {
- sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
- (s->lcyl << 8) | s->sector;
- } else {
- sector_num = ((int64_t)s->hob_hcyl << 40) |
- ((int64_t) s->hob_lcyl << 32) |
- ((int64_t) s->hob_sector << 24) |
- ((int64_t) s->hcyl << 16) |
- ((int64_t) s->lcyl << 8) | s->sector;
- }
- } else {
- sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
- (s->select & 0x0f) * s->sectors + (s->sector - 1);
- }
- return sector_num;
-}
-
-static void ide_set_sector(IDEState *s, int64_t sector_num)
-{
- unsigned int cyl, r;
- if (s->select & 0x40) {
- if (!s->lba48) {
- s->select = (s->select & 0xf0) | (sector_num >> 24);
- s->hcyl = (sector_num >> 16);
- s->lcyl = (sector_num >> 8);
- s->sector = (sector_num);
- } else {
- s->sector = sector_num;
- s->lcyl = sector_num >> 8;
- s->hcyl = sector_num >> 16;
- s->hob_sector = sector_num >> 24;
- s->hob_lcyl = sector_num >> 32;
- s->hob_hcyl = sector_num >> 40;
- }
- } else {
- cyl = sector_num / (s->heads * s->sectors);
- r = sector_num % (s->heads * s->sectors);
- s->hcyl = cyl >> 8;
- s->lcyl = cyl;
- s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
- s->sector = (r % s->sectors) + 1;
- }
-}
-
-static void ide_sector_read(IDEState *s)
-{
- int64_t sector_num;
- int n;
-
- s->status = READY_STAT | SEEK_STAT;
- s->error = 0; /* not needed by IDE spec, but needed by Windows */
- sector_num = ide_get_sector(s);
- n = s->nsector;
- if (n == 0) {
- /* no more sector to read from disk */
- ide_transfer_stop(s);
- } else {
-#if defined(DEBUG_IDE)
- printf("read sector=%Ld\n", sector_num);
-#endif
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
- if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) {
- ide_abort_command(s);
- ide_set_irq(s);
- return;
- }
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
- ide_set_irq(s);
- ide_set_sector(s, sector_num + n);
- s->nsector -= n;
- }
-}
-
-/* return 0 if buffer completed */
-static int dma_buf_rw(BMDMAState *bm, int is_write)
-{
- IDEState *s = bm->ide_if;
- struct {
- uint32_t addr;
- uint32_t size;
- } prd;
- int l, len;
-
- for(;;) {
- l = s->io_buffer_size - s->io_buffer_index;
- if (l <= 0)
- break;
- if (bm->cur_prd_len == 0) {
- /* end of table (with a fail safe of one page) */
- if (bm->cur_prd_last ||
- (bm->cur_addr - bm->addr) >= 4096)
- return 0;
- cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);
- bm->cur_addr += 8;
- prd.addr = le32_to_cpu(prd.addr);
- prd.size = le32_to_cpu(prd.size);
- len = prd.size & 0xfffe;
- if (len == 0)
- len = 0x10000;
- bm->cur_prd_len = len;
- bm->cur_prd_addr = prd.addr;
- bm->cur_prd_last = (prd.size & 0x80000000);
- }
- if (l > bm->cur_prd_len)
- l = bm->cur_prd_len;
- if (l > 0) {
- if (is_write) {
- cpu_physical_memory_write(bm->cur_prd_addr,
- s->io_buffer + s->io_buffer_index, l);
- } else {
- cpu_physical_memory_read(bm->cur_prd_addr,
- s->io_buffer + s->io_buffer_index, l);
- }
- bm->cur_prd_addr += l;
- bm->cur_prd_len -= l;
- s->io_buffer_index += l;
- }
- }
- return 1;
-}
-
-/* XXX: handle errors */
-static void ide_read_dma_cb(void *opaque, int ret)
-{
- BMDMAState *bm = opaque;
- IDEState *s = bm->ide_if;
- int n;
- int64_t sector_num;
-
- if (!s->bs) return; /* yikes */
-
- n = s->io_buffer_size >> 9;
- sector_num = ide_get_sector(s);
- if (n > 0) {
- sector_num += n;
- ide_set_sector(s, sector_num);
- s->nsector -= n;
- if (dma_buf_rw(bm, 1) == 0)
- goto eot;
- }
-
- /* end of transfer ? */
- if (s->nsector == 0) {
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- eot:
- bm->status &= ~BM_STATUS_DMAING;
- bm->status |= BM_STATUS_INT;
- bm->dma_cb = NULL;
- bm->ide_if = NULL;
- bm->aiocb = NULL;
- return;
- }
-
- /* launch next transfer */
- n = s->nsector;
- if (n > IDE_DMA_BUF_SIZE / 512)
- n = IDE_DMA_BUF_SIZE / 512;
- s->io_buffer_index = 0;
- s->io_buffer_size = n * 512;
-#ifdef DEBUG_AIO
- printf("aio_read: sector_num=%lld n=%d\n", sector_num, n);
-#endif
- bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n,
- ide_read_dma_cb, bm);
-}
-
-static void ide_sector_read_dma(IDEState *s)
-{
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
- s->io_buffer_index = 0;
- s->io_buffer_size = 0;
- ide_dma_start(s, ide_read_dma_cb);
-}
-
-static void ide_sector_write_timer_cb(void *opaque)
-{
- IDEState *s = opaque;
- ide_set_irq(s);
-}
-
-static void ide_sector_write(IDEState *s)
-{
- int64_t sector_num;
- int n, n1;
-
- s->status = READY_STAT | SEEK_STAT;
- sector_num = ide_get_sector(s);
-#if defined(DEBUG_IDE)
- printf("write sector=%Ld\n", sector_num);
-#endif
- n = s->nsector;
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
- if (bdrv_write(s->bs, sector_num, s->io_buffer, n) != 0) {
- ide_abort_command(s);
- ide_set_irq(s);
- return;
- }
- s->nsector -= n;
- if (s->nsector == 0) {
- /* no more sector to write */
- ide_transfer_stop(s);
- } else {
- n1 = s->nsector;
- if (n1 > s->req_nb_sectors)
- n1 = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
- }
- ide_set_sector(s, sector_num + n);
-
- if (!s->write_cache)
- bdrv_flush(s->bs);
-
-#ifdef TARGET_I386
- if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
- /* It seems there is a bug in the Windows 2000 installer HDD
- IDE driver which fills the disk with empty logs when the
- IDE write IRQ comes too early. This hack tries to correct
- that at the expense of slower write performances. Use this
- option _only_ to install Windows 2000. You must disable it
- for normal use. */
- qemu_mod_timer(s->sector_write_timer,
- qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
- } else
-#endif
- {
- ide_set_irq(s);
- }
-}
-
-/* XXX: handle errors */
-static void ide_write_dma_cb(void *opaque, int ret)
-{
- BMDMAState *bm = opaque;
- IDEState *s = bm->ide_if;
- int n;
- int64_t sector_num;
-
- if (!s->bs) return; /* yikes */
-
- n = s->io_buffer_size >> 9;
- sector_num = ide_get_sector(s);
- if (n > 0) {
- sector_num += n;
- ide_set_sector(s, sector_num);
- s->nsector -= n;
- }
-
- /* end of transfer ? */
- if (s->nsector == 0) {
- /* Ensure the data hit disk before telling the guest OS so. */
- if (!s->write_cache)
- bdrv_flush(s->bs);
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- eot:
- bm->status &= ~BM_STATUS_DMAING;
- bm->status |= BM_STATUS_INT;
- bm->dma_cb = NULL;
- bm->ide_if = NULL;
- bm->aiocb = NULL;
- return;
- }
-
- /* launch next transfer */
- n = s->nsector;
- if (n > IDE_DMA_BUF_SIZE / 512)
- n = IDE_DMA_BUF_SIZE / 512;
- s->io_buffer_index = 0;
- s->io_buffer_size = n * 512;
-
- if (dma_buf_rw(bm, 0) == 0)
- goto eot;
-#ifdef DEBUG_AIO
- printf("aio_write: sector_num=%lld n=%d\n", sector_num, n);
-#endif
- bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
- ide_write_dma_cb, bm);
-}
-
-static void ide_sector_write_dma(IDEState *s)
-{
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
- s->io_buffer_index = 0;
- s->io_buffer_size = 0;
- ide_dma_start(s, ide_write_dma_cb);
-}
-
-static void ide_device_utterly_broken(IDEState *s) {
- s->status |= BUSY_STAT;
- s->bs = NULL;
- /* This prevents all future commands from working. All of the
- * asynchronous callbacks (and ide_set_irq, as a safety measure)
- * check to see whether this has happened and bail if so.
- */
-}
-
-static void ide_flush_cb(void *opaque, int ret)
-{
- IDEState *s = opaque;
-
- if (!s->bs) return; /* yikes */
-
- if (ret) {
- /* We are completely doomed. The IDE spec does not permit us
- * to return an error from a flush except via a protocol which
- * requires us to say where the error is and which
- * contemplates the guest repeating the flush attempt to
- * attempt flush the remaining data. We can't support that
- * because f(data)sync (which is what the block drivers use
- * eventually) doesn't report the necessary information or
- * give us the necessary control. So we make the disk vanish.
- */
- ide_device_utterly_broken(s);
- return;
- }
- else
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
-}
-
-static void ide_atapi_cmd_ok(IDEState *s)
-{
- s->error = 0;
- s->status = READY_STAT | SEEK_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s);
-}
-
-static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
-{
-#ifdef DEBUG_IDE_ATAPI
- printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
-#endif
- s->error = sense_key << 4;
- s->status = READY_STAT | ERR_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- s->sense_key = sense_key;
- s->asc = asc;
- ide_set_irq(s);
-}
-
-static inline void cpu_to_ube16(uint8_t *buf, int val)
-{
- buf[0] = val >> 8;
- buf[1] = val;
-}
-
-static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
-{
- buf[0] = val >> 24;
- buf[1] = val >> 16;
- buf[2] = val >> 8;
- buf[3] = val;
-}
-
-static inline int ube16_to_cpu(const uint8_t *buf)
-{
- return (buf[0] << 8) | buf[1];
-}
-
-static inline int ube32_to_cpu(const uint8_t *buf)
-{
- return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-}
-
-static void lba_to_msf(uint8_t *buf, int lba)
-{
- lba += 150;
- buf[0] = (lba / 75) / 60;
- buf[1] = (lba / 75) % 60;
- buf[2] = lba % 75;
-}
-
-static void cd_data_to_raw(uint8_t *buf, int lba)
-{
- /* sync bytes */
- buf[0] = 0x00;
- memset(buf + 1, 0xff, 10);
- buf[11] = 0x00;
- buf += 12;
- /* MSF */
- lba_to_msf(buf, lba);
- buf[3] = 0x01; /* mode 1 data */
- buf += 4;
- /* data */
- buf += 2048;
- /* XXX: ECC not computed */
- memset(buf, 0, 288);
-}
-
-static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
- int sector_size)
-{
- int ret;
-
- switch(sector_size) {
- case 2048:
- ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
- break;
- case 2352:
- ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
- if (ret < 0)
- return ret;
- cd_data_to_raw(buf, lba);
- break;
- default:
- ret = -EIO;
- break;
- }
- return ret;
-}
-
-static void ide_atapi_io_error(IDEState *s, int ret)
-{
- /* XXX: handle more errors */
- if (ret == -ENOMEDIUM) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- } else {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_LOGICAL_BLOCK_OOR);
- }
-}
-
-/* The whole ATAPI transfer logic is handled in this function */
-static void ide_atapi_cmd_reply_end(IDEState *s)
-{
- int byte_count_limit, size, ret;
-#ifdef DEBUG_IDE_ATAPI
- printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
- s->packet_transfer_size,
- s->elementary_transfer_size,
- s->io_buffer_index);
-#endif
- if (s->packet_transfer_size <= 0) {
- /* end of transfer */
- ide_transfer_stop(s);
- s->status = READY_STAT | SEEK_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s);
-#ifdef DEBUG_IDE_ATAPI
- printf("status=0x%x\n", s->status);
-#endif
- } else {
- /* see if a new sector must be read */
- if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
- ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
- if (ret < 0) {
- ide_transfer_stop(s);
- ide_atapi_io_error(s, ret);
- return;
- }
- s->lba++;
- s->io_buffer_index = 0;
- }
- if (s->elementary_transfer_size > 0) {
- /* there are some data left to transmit in this elementary
- transfer */
- size = s->cd_sector_size - s->io_buffer_index;
- if (size > s->elementary_transfer_size)
- size = s->elementary_transfer_size;
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
- size, ide_atapi_cmd_reply_end);
- s->packet_transfer_size -= size;
- s->elementary_transfer_size -= size;
- s->io_buffer_index += size;
- } else {
- /* a new transfer is needed */
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
- byte_count_limit = s->lcyl | (s->hcyl << 8);
-#ifdef DEBUG_IDE_ATAPI
- printf("byte_count_limit=%d\n", byte_count_limit);
-#endif
- if (byte_count_limit == 0xffff)
- byte_count_limit--;
- size = s->packet_transfer_size;
- if (size > byte_count_limit) {
- /* byte count limit must be even if this case */
- if (byte_count_limit & 1)
- byte_count_limit--;
- size = byte_count_limit;
- }
- s->lcyl = size;
- s->hcyl = size >> 8;
- s->elementary_transfer_size = size;
- /* we cannot transmit more than one sector at a time */
- if (s->lba != -1) {
- if (size > (s->cd_sector_size - s->io_buffer_index))
- size = (s->cd_sector_size - s->io_buffer_index);
- }
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
- size, ide_atapi_cmd_reply_end);
- s->packet_transfer_size -= size;
- s->elementary_transfer_size -= size;
- s->io_buffer_index += size;
- ide_set_irq(s);
-#ifdef DEBUG_IDE_ATAPI
- printf("status=0x%x\n", s->status);
-#endif
- }
- }
-}
-
-/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
-static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
-{
- if (size > max_size)
- size = max_size;
- s->lba = -1; /* no sector read */
- s->packet_transfer_size = size;
- s->io_buffer_size = size; /* dma: send the reply data as one chunk */
- s->elementary_transfer_size = 0;
- s->io_buffer_index = 0;
-
- if (s->atapi_dma) {
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
- ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
- } else {
- s->status = READY_STAT | SEEK_STAT;
- ide_atapi_cmd_reply_end(s);
- }
-}
-
-/* start a CD-CDROM read command */
-static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
- s->lba = lba;
- s->packet_transfer_size = nb_sectors * sector_size;
- s->elementary_transfer_size = 0;
- s->io_buffer_index = sector_size;
- s->cd_sector_size = sector_size;
-
- s->status = READY_STAT | SEEK_STAT;
- ide_atapi_cmd_reply_end(s);
-}
-
-/* ATAPI DMA support */
-
-/* XXX: handle read errors */
-static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
-{
- BMDMAState *bm = opaque;
- IDEState *s = bm->ide_if;
- int data_offset, n;
-
- if (!s->bs) return; /* yikes */
-
- if (ret < 0) {
- ide_atapi_io_error(s, ret);
- goto eot;
- }
-
- if (s->io_buffer_size > 0) {
- /*
- * For a cdrom read sector command (s->lba != -1),
- * adjust the lba for the next s->io_buffer_size chunk
- * and dma the current chunk.
- * For a command != read (s->lba == -1), just transfer
- * the reply data.
- */
- if (s->lba != -1) {
- if (s->cd_sector_size == 2352) {
- n = 1;
- cd_data_to_raw(s->io_buffer, s->lba);
- } else {
- n = s->io_buffer_size >> 11;
- }
- s->lba += n;
- }
- s->packet_transfer_size -= s->io_buffer_size;
- if (dma_buf_rw(bm, 1) == 0)
- goto eot;
- }
-
- if (s->packet_transfer_size <= 0) {
- s->status = READY_STAT | SEEK_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s);
- eot:
- bm->status &= ~BM_STATUS_DMAING;
- bm->status |= BM_STATUS_INT;
- bm->dma_cb = NULL;
- bm->ide_if = NULL;
- bm->aiocb = NULL;
- return;
- }
-
- s->io_buffer_index = 0;
- if (s->cd_sector_size == 2352) {
- n = 1;
- s->io_buffer_size = s->cd_sector_size;
- data_offset = 16;
- } else {
- n = s->packet_transfer_size >> 11;
- if (n > (IDE_DMA_BUF_SIZE / 2048))
- n = (IDE_DMA_BUF_SIZE / 2048);
- s->io_buffer_size = n * 2048;
- data_offset = 0;
- }
-#ifdef DEBUG_AIO
- printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
-#endif
- bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
- s->io_buffer + data_offset, n * 4,
- ide_atapi_cmd_read_dma_cb, bm);
- if (!bm->aiocb) {
- /* Note: media not present is the most likely case */
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- goto eot;
- }
-}
-
-/* start a CD-CDROM read command with DMA */
-/* XXX: test if DMA is available */
-static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
- s->lba = lba;
- s->packet_transfer_size = nb_sectors * sector_size;
- s->io_buffer_index = 0;
- s->io_buffer_size = 0;
- s->cd_sector_size = sector_size;
-
- /* XXX: check if BUSY_STAT should be set */
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
- ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
-}
-
-static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
-#ifdef DEBUG_IDE_ATAPI
- printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
- lba, nb_sectors);
-#endif
- if (s->atapi_dma) {
- ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
- } else {
- ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
- }
-}
-
-static void ide_atapi_cmd(IDEState *s)
-{
- const uint8_t *packet;
- uint8_t *buf;
- int max_len;
-
- packet = s->io_buffer;
- buf = s->io_buffer;
-#ifdef DEBUG_IDE_ATAPI
- {
- int i;
- printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
- for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
- printf(" %02x", packet[i]);
- }
- printf("\n");
- }
-#endif
- switch(s->io_buffer[0]) {
- case GPCMD_TEST_UNIT_READY:
- if (bdrv_is_inserted(s->bs)) {
- if (s->is_cdrom && s->sense_key == SENSE_NOT_READY) {
- ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION,
- ASC_MEDIUM_MAY_HAVE_CHANGED);
- break;
- }
- ide_atapi_cmd_ok(s);
- } else {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- xenstore_check_new_media_present(1000);
- }
- break;
- case GPCMD_MODE_SENSE_10:
- {
- int action, code;
- max_len = ube16_to_cpu(packet + 7);
- action = packet[2] >> 6;
- code = packet[2] & 0x3f;
- switch(action) {
- case 0: /* current values */
- switch(code) {
- case 0x01: /* error recovery */
- cpu_to_ube16(&buf[0], 16 + 6);
- buf[2] = 0x70;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 0;
-
- buf[8] = 0x01;
- buf[9] = 0x06;
- buf[10] = 0x00;
- buf[11] = 0x05;
- buf[12] = 0x00;
- buf[13] = 0x00;
- buf[14] = 0x00;
- buf[15] = 0x00;
- ide_atapi_cmd_reply(s, 16, max_len);
- break;
- case 0x2a:
- cpu_to_ube16(&buf[0], 28 + 6);
- buf[2] = 0x70;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 0;
-
- buf[8] = 0x2a;
- buf[9] = 0x12;
- buf[10] = 0x00;
- buf[11] = 0x00;
-
- buf[12] = 0x70;
- buf[13] = 3 << 5;
- buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
- if (bdrv_is_locked(s->bs))
- buf[6] |= 1 << 1;
- buf[15] = 0x00;
- cpu_to_ube16(&buf[16], 706);
- buf[18] = 0;
- buf[19] = 2;
- cpu_to_ube16(&buf[20], 512);
- cpu_to_ube16(&buf[22], 706);
- buf[24] = 0;
- buf[25] = 0;
- buf[26] = 0;
- buf[27] = 0;
- ide_atapi_cmd_reply(s, 28, max_len);
- break;
- default:
- goto error_cmd;
- }
- break;
- case 1: /* changeable values */
- goto error_cmd;
- case 2: /* default values */
- goto error_cmd;
- default:
- case 3: /* saved values */
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
- break;
- }
- }
- break;
- case GPCMD_REQUEST_SENSE:
- max_len = packet[4];
- memset(buf, 0, 18);
- buf[0] = 0x70 | (1 << 7);
- buf[2] = s->sense_key;
- buf[7] = 10;
- buf[12] = s->asc;
- ide_atapi_cmd_reply(s, 18, max_len);
- break;
- case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
- if (bdrv_is_inserted(s->bs)) {
- bdrv_set_locked(s->bs, packet[4] & 1);
- ide_atapi_cmd_ok(s);
- } else {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- }
- break;
- case GPCMD_READ_10:
- case GPCMD_READ_12:
- {
- int nb_sectors, lba;
-
- if (packet[0] == GPCMD_READ_10)
- nb_sectors = ube16_to_cpu(packet + 7);
- else
- nb_sectors = ube32_to_cpu(packet + 6);
- lba = ube32_to_cpu(packet + 2);
- if (nb_sectors == 0) {
- ide_atapi_cmd_ok(s);
- break;
- }
- ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
- }
- break;
- case GPCMD_READ_CD:
- {
- int nb_sectors, lba, transfer_request;
-
- nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
- lba = ube32_to_cpu(packet + 2);
- if (nb_sectors == 0) {
- ide_atapi_cmd_ok(s);
- break;
- }
- transfer_request = packet[9];
- switch(transfer_request & 0xf8) {
- case 0x00:
- /* nothing */
- ide_atapi_cmd_ok(s);
- break;
- case 0x10:
- /* normal read */
- ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
- break;
- case 0xf8:
- /* read all data */
- ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
- break;
- default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
- break;
- case GPCMD_SEEK:
- {
- int lba;
- int64_t total_sectors;
-
- bdrv_get_geometry(s->bs, &total_sectors);
- total_sectors >>= 2;
- if (total_sectors <= 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- lba = ube32_to_cpu(packet + 2);
- if (lba >= total_sectors) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_LOGICAL_BLOCK_OOR);
- break;
- }
- ide_atapi_cmd_ok(s);
- }
- break;
- case GPCMD_START_STOP_UNIT:
- {
- int start, eject;
- start = packet[4] & 1;
- eject = (packet[4] >> 1) & 1;
-
- if (eject && !start) {
- /* eject the disk */
- bdrv_eject(s->bs, 1);
- } else if (eject && start) {
- /* close the tray */
- bdrv_eject(s->bs, 0);
- }
- ide_atapi_cmd_ok(s);
- }
- break;
- case GPCMD_MECHANISM_STATUS:
- {
- max_len = ube16_to_cpu(packet + 8);
- cpu_to_ube16(buf, 0);
- /* no current LBA */
- buf[2] = 0;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 1;
- cpu_to_ube16(buf + 6, 0);
- ide_atapi_cmd_reply(s, 8, max_len);
- }
- break;
- case GPCMD_READ_TOC_PMA_ATIP:
- {
- int format, msf, start_track, len;
- int64_t total_sectors;
-
- bdrv_get_geometry(s->bs, &total_sectors);
- total_sectors >>= 2;
- if (total_sectors <= 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- max_len = ube16_to_cpu(packet + 7);
- format = packet[9] >> 6;
- msf = (packet[1] >> 1) & 1;
- start_track = packet[6];
- switch(format) {
- case 0:
- len = cdrom_read_toc(total_sectors, buf, msf, start_track);
- if (len < 0)
- goto error_cmd;
- ide_atapi_cmd_reply(s, len, max_len);
- break;
- case 1:
- /* multi session : only a single session defined */
- memset(buf, 0, 12);
- buf[1] = 0x0a;
- buf[2] = 0x01;
- buf[3] = 0x01;
- ide_atapi_cmd_reply(s, 12, max_len);
- break;
- case 2:
- len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
- if (len < 0)
- goto error_cmd;
- ide_atapi_cmd_reply(s, len, max_len);
- break;
- default:
- error_cmd:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
- break;
- case GPCMD_READ_CDVD_CAPACITY:
- {
- int64_t total_sectors;
-
- bdrv_get_geometry(s->bs, &total_sectors);
- total_sectors >>= 2;
- if (total_sectors <= 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- /* NOTE: it is really the number of sectors minus 1 */
- cpu_to_ube32(buf, total_sectors - 1);
- cpu_to_ube32(buf + 4, 2048);
- ide_atapi_cmd_reply(s, 8, 8);
- }
- break;
- case GPCMD_INQUIRY:
- max_len = packet[4];
- buf[0] = 0x05; /* CD-ROM */
- buf[1] = 0x80; /* removable */
- buf[2] = 0x00; /* ISO */
- buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
- buf[4] = 31; /* additionnal length */
- buf[5] = 0; /* reserved */
- buf[6] = 0; /* reserved */
- buf[7] = 0; /* reserved */
- padstr8(buf + 8, 8, "QEMU");
- padstr8(buf + 16, 16, "QEMU CD-ROM");
- padstr8(buf + 32, 4, QEMU_VERSION);
- ide_atapi_cmd_reply(s, 36, max_len);
- break;
- default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_ILLEGAL_OPCODE);
- break;
- }
-}
-
-/* called when the inserted state of the media has changed */
-static void cdrom_change_cb(void *opaque)
-{
- IDEState *s = opaque;
- int64_t nb_sectors;
-
- if (!s->bs) return; /* yikes */
-
- /* XXX: send interrupt too */
- bdrv_get_geometry(s->bs, &nb_sectors);
- s->nb_sectors = nb_sectors;
-}
-
-static void ide_cmd_lba48_transform(IDEState *s, int lba48)
-{
- s->lba48 = lba48;
-
- /* handle the 'magic' 0 nsector count conversion here. to avoid
- * fiddling with the rest of the read logic, we just store the
- * full sector count in ->nsector and ignore ->hob_nsector from now
- */
- if (!s->lba48) {
- if (!s->nsector)
- s->nsector = 256;
- } else {
- if (!s->nsector && !s->hob_nsector)
- s->nsector = 65536;
- else {
- int lo = s->nsector;
- int hi = s->hob_nsector;
-
- s->nsector = (hi << 8) | lo;
- }
- }
-}
-
-static void ide_clear_hob(IDEState *ide_if)
-{
- /* any write clears HOB high bit of device control register */
- ide_if[0].select &= ~(1 << 7);
- ide_if[1].select &= ~(1 << 7);
-}
-
-static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *ide_if = opaque;
- IDEState *s;
- int unit, n;
- int lba48 = 0;
- int ret;
-
-#ifdef DEBUG_IDE
- printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
-#endif
-
- addr &= 7;
- switch(addr) {
- case 0:
- break;
- case 1:
- ide_clear_hob(ide_if);
- /* NOTE: data is written to the two drives */
- ide_if[0].hob_feature = ide_if[0].feature;
- ide_if[1].hob_feature = ide_if[1].feature;
- ide_if[0].feature = val;
- ide_if[1].feature = val;
- break;
- case 2:
- ide_clear_hob(ide_if);
- ide_if[0].hob_nsector = ide_if[0].nsector;
- ide_if[1].hob_nsector = ide_if[1].nsector;
- ide_if[0].nsector = val;
- ide_if[1].nsector = val;
- break;
- case 3:
- ide_clear_hob(ide_if);
- ide_if[0].hob_sector = ide_if[0].sector;
- ide_if[1].hob_sector = ide_if[1].sector;
- ide_if[0].sector = val;
- ide_if[1].sector = val;
- break;
- case 4:
- ide_clear_hob(ide_if);
- ide_if[0].hob_lcyl = ide_if[0].lcyl;
- ide_if[1].hob_lcyl = ide_if[1].lcyl;
- ide_if[0].lcyl = val;
- ide_if[1].lcyl = val;
- break;
- case 5:
- ide_clear_hob(ide_if);
- ide_if[0].hob_hcyl = ide_if[0].hcyl;
- ide_if[1].hob_hcyl = ide_if[1].hcyl;
- ide_if[0].hcyl = val;
- ide_if[1].hcyl = val;
- break;
- case 6:
- /* FIXME: HOB readback uses bit 7 */
- ide_if[0].select = (val & ~0x10) | 0xa0;
- ide_if[1].select = (val | 0x10) | 0xa0;
- /* select drive */
- buffered_pio_reset(ide_if->cur_drive);
- unit = (val >> 4) & 1;
- s = ide_if + unit;
- ide_if->cur_drive = s;
- break;
- default:
- case 7:
- /* command */
-#if defined(DEBUG_IDE)
- printf("ide: CMD=%02x\n", val);
-#endif
- s = ide_if->cur_drive;
- /* ignore commands to non existant device */
- if (!s->bs)
- break;
-
- switch(val) {
- case WIN_IDENTIFY:
- if (s->bs && !s->is_cdrom) {
- ide_identify(s);
- s->status = READY_STAT | SEEK_STAT;
- ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
- } else {
- if (s->is_cdrom) {
- ide_set_signature(s);
- }
- ide_abort_command(s);
- }
- ide_set_irq(s);
- break;
- case WIN_SPECIFY:
- case WIN_RECAL:
- s->error = 0;
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case WIN_SETMULT:
- if (s->nsector > MAX_MULT_SECTORS ||
- (s->nsector & (s->nsector - 1)) != 0) {
- ide_abort_command(s);
- } else {
- s->mult_sectors = s->nsector;
- s->status = READY_STAT | SEEK_STAT;
- }
- ide_set_irq(s);
- break;
- case WIN_VERIFY_EXT:
- lba48 = 1;
- case WIN_VERIFY:
- case WIN_VERIFY_ONCE:
- /* do sector number check ? */
- ide_cmd_lba48_transform(s, lba48);
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case WIN_READ_EXT:
- lba48 = 1;
- case WIN_READ:
- case WIN_READ_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- s->req_nb_sectors = 1;
- ide_sector_read(s);
- break;
- case WIN_WRITE_EXT:
- lba48 = 1;
- case WIN_WRITE:
- case WIN_WRITE_ONCE:
- ide_cmd_lba48_transform(s, lba48);
- s->error = 0;
- s->status = SEEK_STAT | READY_STAT;
- s->req_nb_sectors = 1;
- ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
- break;
- case WIN_MULTREAD_EXT:
- lba48 = 1;
- case WIN_MULTREAD:
- if (!s->mult_sectors)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- s->req_nb_sectors = s->mult_sectors;
- ide_sector_read(s);
- break;
- case WIN_MULTWRITE_EXT:
- lba48 = 1;
- case WIN_MULTWRITE:
- if (!s->mult_sectors)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- s->error = 0;
- s->status = SEEK_STAT | READY_STAT;
- s->req_nb_sectors = s->mult_sectors;
- n = s->nsector;
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
- break;
- case WIN_READDMA_EXT:
- lba48 = 1;
- case WIN_READDMA:
- case WIN_READDMA_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- ide_sector_read_dma(s);
- break;
- case WIN_WRITEDMA_EXT:
- lba48 = 1;
- case WIN_WRITEDMA:
- case WIN_WRITEDMA_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- ide_sector_write_dma(s);
- break;
- case WIN_READ_NATIVE_MAX_EXT:
- lba48 = 1;
- case WIN_READ_NATIVE_MAX:
- ide_cmd_lba48_transform(s, lba48);
- ide_set_sector(s, s->nb_sectors - 1);
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case WIN_CHECKPOWERMODE1:
- s->nsector = 0xff; /* device active or idle */
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case WIN_SETFEATURES:
- if (!s->bs)
- goto abort_cmd;
- /* XXX: valid for CDROM ? */
- switch(s->feature) {
- case 0x02: /* write cache enable */
- s->write_cache = 1;
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case 0x82: /* write cache disable */
- s->write_cache = 0;
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case 0xaa: /* read look-ahead enable */
- case 0x55: /* read look-ahead disable */
- case 0x42: /* EN_AAM: enable Automatic Acoustic Mode */
- case 0xc2: /* DIS_AAM: disable Automatic Acoustic Mode */
- case 0x85: /* DIS_APM: disable APM */
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case 0x03: { /* set transfer mode */
- uint8_t val = s->nsector & 0x07;
-
- switch (s->nsector >> 3) {
- case 0x00: /* pio default */
- case 0x01: /* pio mode */
- put_le16(s->identify_data + 63,0x07);
- put_le16(s->identify_data + 88,0x3f);
- break;
- case 0x04: /* mdma mode */
- put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
- put_le16(s->identify_data + 88,0x3f);
- break;
- case 0x08: /* udma mode */
- put_le16(s->identify_data + 63,0x07);
- put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
- break;
- default:
- goto abort_cmd;
- }
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- }
- default:
- goto abort_cmd;
- }
- break;
- case WIN_FLUSH_CACHE:
- case WIN_FLUSH_CACHE_EXT:
- s->status = BUSY_STAT;
- bdrv_aio_flush(s->bs, ide_flush_cb, s);
- break;
- case WIN_IDLEIMMEDIATE:
- case WIN_STANDBY:
- case WIN_SETIDLE1:
- case WIN_STANDBYNOW1:
- case WIN_SLEEPNOW1:
- case WIN_STANDBY2:
- case WIN_SETIDLE2:
- case WIN_STANDBYNOW2:
- case WIN_SLEEPNOW2:
- s->status = READY_STAT;
- ide_set_irq(s);
- break;
- /* ATAPI commands */
- case WIN_PIDENTIFY:
- if (s->is_cdrom) {
- ide_atapi_identify(s);
- s->status = READY_STAT | SEEK_STAT;
- ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
- } else {
- ide_abort_command(s);
- }
- ide_set_irq(s);
- break;
- case WIN_DIAGNOSE:
- ide_set_signature(s);
- s->status = 0x00; /* NOTE: READY is _not_ set */
- s->error = 0x01;
- break;
- case WIN_SRST:
- if (!s->is_cdrom)
- goto abort_cmd;
- ide_set_signature(s);
- s->status = 0x00; /* NOTE: READY is _not_ set */
- s->error = 0x01;
- break;
- case WIN_PACKETCMD:
- if (!s->is_cdrom)
- goto abort_cmd;
- /* overlapping commands not supported */
- if (s->feature & 0x02)
- goto abort_cmd;
- s->status = READY_STAT | SEEK_STAT;
- s->atapi_dma = s->feature & 1;
- s->nsector = 1;
- ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
- ide_atapi_cmd);
- break;
- default:
- abort_cmd:
- ide_abort_command(s);
- ide_set_irq(s);
- break;
- }
- }
-}
-
-static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
-{
- IDEState *ide_if = opaque;
- IDEState *s = ide_if->cur_drive;
- uint32_t addr;
- int ret, hob;
-
- addr = addr1 & 7;
- /* FIXME: HOB readback uses bit 7, but it's always set right now */
- //hob = s->select & (1 << 7);
- hob = 0;
- switch(addr) {
- case 0:
- ret = 0xff;
- break;
- case 1:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else if (!hob)
- ret = s->error;
- else
- ret = s->hob_feature;
- break;
- case 2:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else if (!hob)
- ret = s->nsector & 0xff;
- else
- ret = s->hob_nsector;
- break;
- case 3:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else if (!hob)
- ret = s->sector;
- else
- ret = s->hob_sector;
- break;
- case 4:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else if (!hob)
- ret = s->lcyl;
- else
- ret = s->hob_lcyl;
- break;
- case 5:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else if (!hob)
- ret = s->hcyl;
- else
- ret = s->hob_hcyl;
- break;
- case 6:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else
- ret = s->select;
- break;
- default:
- case 7:
- if ((!ide_if[0].bs && !ide_if[1].bs) ||
- (s != ide_if && !s->bs))
- ret = 0;
- else
- ret = s->status;
- s->set_irq(s->irq_opaque, s->irq, 0);
- break;
- }
-#ifdef DEBUG_IDE
- printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
-#endif
- return ret;
-}
-
-static uint32_t ide_status_read(void *opaque, uint32_t addr)
-{
- IDEState *ide_if = opaque;
- IDEState *s = ide_if->cur_drive;
- int ret;
-
- if ((!ide_if[0].bs && !ide_if[1].bs) ||
- (s != ide_if && !s->bs))
- ret = 0;
- else
- ret = s->status;
-#ifdef DEBUG_IDE
- printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
-#endif
- return ret;
-}
-
-static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *ide_if = opaque;
- IDEState *s;
- int i;
-
-#ifdef DEBUG_IDE
- printf("ide: write control addr=0x%x val=%02x\n", addr, val);
-#endif
- /* common for both drives */
- if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
- (val & IDE_CMD_RESET)) {
- /* reset low to high */
- for(i = 0;i < 2; i++) {
- s = &ide_if[i];
- s->status = BUSY_STAT | SEEK_STAT;
- s->error = 0x01;
- }
- } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
- !(val & IDE_CMD_RESET)) {
- /* high to low */
- for(i = 0;i < 2; i++) {
- s = &ide_if[i];
- if (s->is_cdrom)
- s->status = 0x00; /* NOTE: READY is _not_ set */
- else
- s->status = READY_STAT | SEEK_STAT;
- ide_set_signature(s);
- }
- }
-
- ide_if[0].cmd = val;
- ide_if[1].cmd = val;
-}
-
-static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
-
- buffered_pio_write(s, addr, 2);
- p = s->data_ptr;
- *(uint16_t *)p = le16_to_cpu(val);
- p += 2;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
-}
-
-static uint32_t ide_data_readw(void *opaque, uint32_t addr)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
- int ret;
-
- buffered_pio_read(s, addr, 2);
- p = s->data_ptr;
- ret = cpu_to_le16(*(uint16_t *)p);
- p += 2;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
- return ret;
-}
-
-static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
-
- buffered_pio_write(s, addr, 4);
- p = s->data_ptr;
- *(uint32_t *)p = le32_to_cpu(val);
- p += 4;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
-}
-
-static uint32_t ide_data_readl(void *opaque, uint32_t addr)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
- int ret;
-
- buffered_pio_read(s, addr, 4);
- p = s->data_ptr;
- ret = cpu_to_le32(*(uint32_t *)p);
- p += 4;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
- return ret;
-}
-
-static void ide_dummy_transfer_stop(IDEState *s)
-{
- s->data_ptr = s->io_buffer;
- s->data_end = s->io_buffer;
- s->io_buffer[0] = 0xff;
- s->io_buffer[1] = 0xff;
- s->io_buffer[2] = 0xff;
- s->io_buffer[3] = 0xff;
-}
-
-static void ide_reset(IDEState *s)
-{
- s->mult_sectors = MAX_MULT_SECTORS;
- s->cur_drive = s;
- s->select = 0xa0;
- s->status = READY_STAT | SEEK_STAT;
- ide_set_signature(s);
- /* init the transfer handler so that 0xffff is returned on data
- accesses */
- s->end_transfer_func = ide_dummy_transfer_stop;
- ide_dummy_transfer_stop(s);
-}
-
-struct partition {
- uint8_t boot_ind; /* 0x80 - active */
- uint8_t head; /* starting head */
- uint8_t sector; /* starting sector */
- uint8_t cyl; /* starting cylinder */
- uint8_t sys_ind; /* What partition type */
- uint8_t end_head; /* end head */
- uint8_t end_sector; /* end sector */
- uint8_t end_cyl; /* end cylinder */
- uint32_t start_sect; /* starting sector counting from 0 */
- uint32_t nr_sects; /* nr of sectors in partition */
-} __attribute__((packed));
-
-/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
-static int guess_disk_lchs(IDEState *s,
- int *pcylinders, int *pheads, int *psectors)
-{
- uint8_t buf[512];
- int ret, i, heads, sectors, cylinders;
- struct partition *p;
- uint32_t nr_sects;
-
- ret = bdrv_read(s->bs, 0, buf, 1);
- if (ret < 0)
- return -1;
- /* test msdos magic */
- if (buf[510] != 0x55 || buf[511] != 0xaa)
- return -1;
- for(i = 0; i < 4; i++) {
- p = ((struct partition *)(buf + 0x1be)) + i;
- nr_sects = le32_to_cpu(p->nr_sects);
- if (nr_sects && p->end_head) {
- /* We make the assumption that the partition terminates on
- a cylinder boundary */
- heads = p->end_head + 1;
- sectors = p->end_sector & 63;
- if (sectors == 0)
- continue;
- cylinders = s->nb_sectors / (heads * sectors);
- if (cylinders < 1 || cylinders > 16383)
- continue;
- *pheads = heads;
- *psectors = sectors;
- *pcylinders = cylinders;
-#if 0
- printf("guessed geometry: LCHS=%d %d %d\n",
- cylinders, heads, sectors);
-#endif
- return 0;
- }
- }
- return -1;
-}
-
-static void ide_init2(IDEState *ide_state,
- BlockDriverState *hd0, BlockDriverState *hd1,
- SetIRQFunc *set_irq, void *irq_opaque, int irq)
-{
- IDEState *s;
- static int drive_serial = 1;
- int i, cylinders, heads, secs, translation, lba_detected = 0;
- int64_t nb_sectors;
-
- for(i = 0; i < 2; i++) {
- s = ide_state + i;
- s->io_buffer = qemu_memalign(getpagesize(), IDE_DMA_BUF_SIZE + 4);
- if (i == 0)
- s->bs = hd0;
- else
- s->bs = hd1;
- if (s->bs) {
- bdrv_get_geometry(s->bs, &nb_sectors);
- s->nb_sectors = nb_sectors;
- /* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
- translation = bdrv_get_translation_hint(s->bs);
- if (cylinders != 0) {
- s->cylinders = cylinders;
- s->heads = heads;
- s->sectors = secs;
- } else {
- if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
- if (heads > 16) {
- /* if heads > 16, it means that a BIOS LBA
- translation was active, so the default
- hardware geometry is OK */
- lba_detected = 1;
- goto default_geometry;
- } else {
- s->cylinders = cylinders;
- s->heads = heads;
- s->sectors = secs;
- /* disable any translation to be in sync with
- the logical geometry */
- if (translation == BIOS_ATA_TRANSLATION_AUTO) {
- bdrv_set_translation_hint(s->bs,
- BIOS_ATA_TRANSLATION_NONE);
- }
- }
- } else {
- default_geometry:
- /* if no geometry, use a standard physical disk geometry */
- cylinders = nb_sectors / (16 * 63);
- if (cylinders > 16383)
- cylinders = 16383;
- else if (cylinders < 2)
- cylinders = 2;
- s->cylinders = cylinders;
- s->heads = 16;
- s->sectors = 63;
- if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
- if ((s->cylinders * s->heads) <= 131072) {
- bdrv_set_translation_hint(s->bs,
- BIOS_ATA_TRANSLATION_LARGE);
- } else {
- bdrv_set_translation_hint(s->bs,
- BIOS_ATA_TRANSLATION_LBA);
- }
- }
- }
- bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
- }
- if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
- s->is_cdrom = 1;
- bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
- }
- }
- s->drive_serial = drive_serial++;
- s->set_irq = set_irq;
- s->irq_opaque = irq_opaque;
- s->irq = irq;
- s->sector_write_timer = qemu_new_timer(vm_clock,
- ide_sector_write_timer_cb, s);
- s->write_cache = 0;
- ide_reset(s);
- }
-}
-
-static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
-{
- register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
- register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
- if (iobase2) {
- register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
- register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
- }
-
- /* data ports */
- register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
- register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
- register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
- register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
-}
-
-/***********************************************************/
-/* ISA IDE definitions */
-
-void isa_ide_init(int iobase, int iobase2, int irq,
- BlockDriverState *hd0, BlockDriverState *hd1)
-{
- IDEState *ide_state;
-
- ide_state = qemu_mallocz(sizeof(IDEState) * 2);
- if (!ide_state)
- return;
-
- ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq);
- ide_init_ioport(ide_state, iobase, iobase2);
-}
-
-/***********************************************************/
-/* PCI IDE definitions */
-
-static void cmd646_update_irq(PCIIDEState *d);
-
-static void ide_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIIDEState *d = (PCIIDEState *)pci_dev;
- IDEState *ide_state;
-
- if (region_num <= 3) {
- ide_state = &d->ide_if[(region_num >> 1) * 2];
- if (region_num & 1) {
- register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
- register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
- } else {
- register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
- register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
-
- /* data ports */
- register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
- register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
- register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
- register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
- }
- }
-}
-
-static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
-{
- BMDMAState *bm = s->bmdma;
- if(!bm)
- return;
- bm->ide_if = s;
- bm->dma_cb = dma_cb;
- bm->cur_prd_last = 0;
- bm->cur_prd_addr = 0;
- bm->cur_prd_len = 0;
- if (bm->status & BM_STATUS_DMAING) {
- bm->dma_cb(bm, 0);
- }
-}
-
-static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- BMDMAState *bm = opaque;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- if (!(val & BM_CMD_START)) {
- /* XXX: do it better */
- if (bm->status & BM_STATUS_DMAING) {
- bm->status &= ~BM_STATUS_DMAING;
- /* cancel DMA request */
- bm->ide_if = NULL;
- bm->dma_cb = NULL;
- if (bm->aiocb) {
-#ifdef DEBUG_AIO
- printf("aio_cancel\n");
-#endif
- bdrv_aio_cancel(bm->aiocb);
- bm->aiocb = NULL;
- }
- }
- bm->cmd = val & 0x09;
- } else {
- if (!(bm->status & BM_STATUS_DMAING)) {
- bm->status |= BM_STATUS_DMAING;
- /* start dma transfer if possible */
- if (bm->dma_cb)
- bm->dma_cb(bm, 0);
- }
- bm->cmd = val & 0x09;
- }
-}
-
-static uint32_t bmdma_readb(void *opaque, uint32_t addr)
-{
- BMDMAState *bm = opaque;
- PCIIDEState *pci_dev;
- uint32_t val;
-
- switch(addr & 3) {
- case 0:
- val = bm->cmd;
- break;
- case 1:
- pci_dev = bm->pci_dev;
- if (pci_dev->type == IDE_TYPE_CMD646) {
- val = pci_dev->dev.config[MRDMODE];
- } else {
- val = 0xff;
- }
- break;
- case 2:
- val = bm->status;
- break;
- case 3:
- pci_dev = bm->pci_dev;
- if (pci_dev->type == IDE_TYPE_CMD646) {
- if (bm == &pci_dev->bmdma[0])
- val = pci_dev->dev.config[UDIDETCR0];
- else
- val = pci_dev->dev.config[UDIDETCR1];
- } else {
- val = 0xff;
- }
- break;
- default:
- val = 0xff;
- break;
- }
-#ifdef DEBUG_IDE
- printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- BMDMAState *bm = opaque;
- PCIIDEState *pci_dev;
-#ifdef DEBUG_IDE
- printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
-#endif
- switch(addr & 3) {
- case 1:
- pci_dev = bm->pci_dev;
- if (pci_dev->type == IDE_TYPE_CMD646) {
- pci_dev->dev.config[MRDMODE] =
- (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
- cmd646_update_irq(pci_dev);
- }
- break;
- case 2:
- bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
- break;
- case 3:
- pci_dev = bm->pci_dev;
- if (pci_dev->type == IDE_TYPE_CMD646) {
- if (bm == &pci_dev->bmdma[0])
- pci_dev->dev.config[UDIDETCR0] = val;
- else
- pci_dev->dev.config[UDIDETCR1] = val;
- }
- break;
- }
-}
-
-static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
-{
- BMDMAState *bm = opaque;
- uint32_t val;
- val = bm->addr;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- return val;
-}
-
-static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- BMDMAState *bm = opaque;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- bm->addr = val & ~3;
- bm->cur_addr = bm->addr;
-}
-
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIIDEState *d = (PCIIDEState *)pci_dev;
- int i;
-
- for(i = 0;i < 2; i++) {
- BMDMAState *bm = &d->bmdma[i];
- d->ide_if[2 * i].bmdma = bm;
- d->ide_if[2 * i + 1].bmdma = bm;
- bm->pci_dev = (PCIIDEState *)pci_dev;
-
- register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
-
- register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
- register_ioport_read(addr, 4, 1, bmdma_readb, bm);
-
- register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
- register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
- addr += 8;
- }
-}
-
-/* XXX: call it also when the MRDMODE is changed from the PCI config
- registers */
-static void cmd646_update_irq(PCIIDEState *d)
-{
- int pci_level;
- pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
- !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
- ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
- !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
- pci_set_irq((PCIDevice *)d, 0, pci_level);
-}
-
-/* the PCI irq level is the logical OR of the two channels */
-static void cmd646_set_irq(void *opaque, int channel, int level)
-{
- PCIIDEState *d = opaque;
- int irq_mask;
-
- irq_mask = MRDMODE_INTR_CH0 << channel;
- if (level)
- d->dev.config[MRDMODE] |= irq_mask;
- else
- d->dev.config[MRDMODE] &= ~irq_mask;
- cmd646_update_irq(d);
-}
-
-/* CMD646 PCI IDE controller */
-void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
- int secondary_ide_enabled)
-{
- PCIIDEState *d;
- uint8_t *pci_conf;
- int i;
-
- d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
- sizeof(PCIIDEState),
- -1,
- NULL, NULL);
- d->type = IDE_TYPE_CMD646;
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x95; // CMD646
- pci_conf[0x01] = 0x10;
- pci_conf[0x02] = 0x46;
- pci_conf[0x03] = 0x06;
-
- pci_conf[0x08] = 0x07; // IDE controller revision
- pci_conf[0x09] = 0x8f;
-
- pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
- pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
- pci_conf[0x0e] = 0x00; // header_type
-
- if (secondary_ide_enabled) {
- /* XXX: if not enabled, really disable the seconday IDE controller */
- pci_conf[0x51] = 0x80; /* enable IDE1 */
- }
-
- pci_register_io_region((PCIDevice *)d, 0, 0x8,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 1, 0x4,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 2, 0x8,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 3, 0x4,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
- PCI_ADDRESS_SPACE_IO, bmdma_map);
-
- pci_conf[0x3d] = 0x01; // interrupt on pin 1
-
- for(i = 0; i < 4; i++)
- d->ide_if[i].pci_dev = (PCIDevice *)d;
- ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
- cmd646_set_irq, d, 0);
- ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
- cmd646_set_irq, d, 1);
-}
-
-static void pci_ide_save(QEMUFile* f, void *opaque)
-{
- PCIIDEState *d = opaque;
- int i;
-
- pci_device_save(&d->dev, f);
-
- for(i = 0; i < 2; i++) {
- BMDMAState *bm = &d->bmdma[i];
- qemu_put_8s(f, &bm->cmd);
- qemu_put_8s(f, &bm->status);
- qemu_put_be32s(f, &bm->addr);
- /* XXX: if a transfer is pending, we do not save it yet */
- }
-
- /* per IDE interface data */
- for(i = 0; i < 2; i++) {
- IDEState *s = &d->ide_if[i * 2];
- uint8_t drive1_selected;
- qemu_put_8s(f, &s->cmd);
- drive1_selected = (s->cur_drive != s);
- qemu_put_8s(f, &drive1_selected);
- }
-
- /* per IDE drive data */
- for(i = 0; i < 4; i++) {
- IDEState *s = &d->ide_if[i];
- qemu_put_be32s(f, &s->mult_sectors);
- qemu_put_be32s(f, &s->identify_set);
- if (s->identify_set) {
- qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
- }
- qemu_put_8s(f, &s->write_cache);
- qemu_put_8s(f, &s->feature);
- qemu_put_8s(f, &s->error);
- qemu_put_be32s(f, &s->nsector);
- qemu_put_8s(f, &s->sector);
- qemu_put_8s(f, &s->lcyl);
- qemu_put_8s(f, &s->hcyl);
- qemu_put_8s(f, &s->hob_feature);
- qemu_put_8s(f, &s->hob_nsector);
- qemu_put_8s(f, &s->hob_sector);
- qemu_put_8s(f, &s->hob_lcyl);
- qemu_put_8s(f, &s->hob_hcyl);
- qemu_put_8s(f, &s->select);
- qemu_put_8s(f, &s->status);
- qemu_put_8s(f, &s->lba48);
-
- qemu_put_8s(f, &s->sense_key);
- qemu_put_8s(f, &s->asc);
- /* XXX: if a transfer is pending, we do not save it yet */
- }
-}
-
-static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
-{
- PCIIDEState *d = opaque;
- int ret, i;
-
- if (version_id != 1 && version_id != 2)
- return -EINVAL;
- ret = pci_device_load(&d->dev, f);
- if (ret < 0)
- return ret;
-
- for(i = 0; i < 2; i++) {
- BMDMAState *bm = &d->bmdma[i];
- qemu_get_8s(f, &bm->cmd);
- qemu_get_8s(f, &bm->status);
- qemu_get_be32s(f, &bm->addr);
- /* XXX: if a transfer is pending, we do not save it yet */
- }
-
- /* per IDE interface data */
- for(i = 0; i < 2; i++) {
- IDEState *s = &d->ide_if[i * 2];
- uint8_t drive1_selected;
- qemu_get_8s(f, &s->cmd);
- qemu_get_8s(f, &drive1_selected);
- s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
- }
-
- /* per IDE drive data */
- for(i = 0; i < 4; i++) {
- IDEState *s = &d->ide_if[i];
- qemu_get_be32s(f, &s->mult_sectors);
- qemu_get_be32s(f, &s->identify_set);
- if (s->identify_set) {
- qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
- }
- if (version_id >= 2)
- qemu_get_8s(f, &s->write_cache);
- qemu_get_8s(f, &s->feature);
- qemu_get_8s(f, &s->error);
- qemu_get_be32s(f, &s->nsector);
- qemu_get_8s(f, &s->sector);
- qemu_get_8s(f, &s->lcyl);
- qemu_get_8s(f, &s->hcyl);
- qemu_get_8s(f, &s->hob_feature);
- qemu_get_8s(f, &s->hob_nsector);
- qemu_get_8s(f, &s->hob_sector);
- qemu_get_8s(f, &s->hob_lcyl);
- qemu_get_8s(f, &s->hob_hcyl);
- qemu_get_8s(f, &s->select);
- qemu_get_8s(f, &s->status);
- qemu_get_8s(f, &s->lba48);
-
- qemu_get_8s(f, &s->sense_key);
- qemu_get_8s(f, &s->asc);
- /* XXX: if a transfer is pending, we do not save it yet */
- }
- return 0;
-}
-
-static void piix3_reset(PCIIDEState *d)
-{
- uint8_t *pci_conf = d->dev.config;
-
- pci_conf[0x04] = 0x00;
- pci_conf[0x05] = 0x00;
- pci_conf[0x06] = 0x80; /* FBC */
- pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
- pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
-}
-
-void pci_piix_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
-{
- PCIIDEState *d;
- uint8_t *pci_conf;
-
- /* register a function 1 of PIIX */
- d = (PCIIDEState *)pci_register_device(bus, "PIIX IDE",
- sizeof(PCIIDEState),
- devfn,
- NULL, NULL);
- d->type = IDE_TYPE_PIIX3;
-
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x30;
- pci_conf[0x03] = 0x12;
- pci_conf[0x08] = 0x02; // Step A1
- pci_conf[0x09] = 0x80; // legacy ATA mode
- pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
- pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
- pci_conf[0x2d] = 0x58;
- pci_conf[0x2e] = 0x01; /* subsystem device */
- pci_conf[0x2f] = 0x00;
-
- piix3_reset(d);
-
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
- PCI_ADDRESS_SPACE_IO, bmdma_map);
-
- ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
- pic_set_irq_new, isa_pic, 14);
- ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
- pic_set_irq_new, isa_pic, 15);
- ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
- ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
-
- buffered_pio_init();
-
- register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
-}
-
-/* hd_table must contain 4 block drivers */
-/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
-{
- PCIIDEState *d;
- uint8_t *pci_conf;
-
- /* register a function 1 of PIIX3 */
- d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
- sizeof(PCIIDEState),
- devfn,
- NULL, NULL);
- d->type = IDE_TYPE_PIIX3;
-
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x10;
- pci_conf[0x03] = 0x70;
- pci_conf[0x09] = 0x80; // legacy ATA mode
- pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
- pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
- pci_conf[0x0e] = 0x00; // header_type
-
- piix3_reset(d);
-
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
- PCI_ADDRESS_SPACE_IO, bmdma_map);
-
- ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
- pic_set_irq_new, isa_pic, 14);
- ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
- pic_set_irq_new, isa_pic, 15);
- ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
- ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
-
- buffered_pio_init();
-
- register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
-}
-
-/***********************************************************/
-/* MacIO based PowerPC IDE */
-
-/* PowerMac IDE memory IO */
-static void pmac_ide_writeb (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- addr = (addr & 0xFFF) >> 4;
- switch (addr) {
- case 1 ... 7:
- ide_ioport_write(opaque, addr, val);
- break;
- case 8:
- case 22:
- ide_cmd_write(opaque, 0, val);
- break;
- default:
- break;
- }
-}
-
-static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
-{
- uint8_t retval;
-
- addr = (addr & 0xFFF) >> 4;
- switch (addr) {
- case 1 ... 7:
- retval = ide_ioport_read(opaque, addr);
- break;
- case 8:
- case 22:
- retval = ide_status_read(opaque, 0);
- break;
- default:
- retval = 0xFF;
- break;
- }
- return retval;
-}
-
-static void pmac_ide_writew (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- addr = (addr & 0xFFF) >> 4;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- if (addr == 0) {
- ide_data_writew(opaque, 0, val);
- }
-}
-
-static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
-{
- uint16_t retval;
-
- addr = (addr & 0xFFF) >> 4;
- if (addr == 0) {
- retval = ide_data_readw(opaque, 0);
- } else {
- retval = 0xFFFF;
- }
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap16(retval);
-#endif
- return retval;
-}
-
-static void pmac_ide_writel (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- addr = (addr & 0xFFF) >> 4;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- if (addr == 0) {
- ide_data_writel(opaque, 0, val);
- }
-}
-
-static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
-{
- uint32_t retval;
-
- addr = (addr & 0xFFF) >> 4;
- if (addr == 0) {
- retval = ide_data_readl(opaque, 0);
- } else {
- retval = 0xFFFFFFFF;
- }
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap32(retval);
-#endif
- return retval;
-}
-
-static CPUWriteMemoryFunc *pmac_ide_write[] = {
- pmac_ide_writeb,
- pmac_ide_writew,
- pmac_ide_writel,
-};
-
-static CPUReadMemoryFunc *pmac_ide_read[] = {
- pmac_ide_readb,
- pmac_ide_readw,
- pmac_ide_readl,
-};
-
-/* hd_table must contain 4 block drivers */
-/* PowerMac uses memory mapped registers, not I/O. Return the memory
- I/O index to access the ide. */
-int pmac_ide_init (BlockDriverState **hd_table,
- SetIRQFunc *set_irq, void *irq_opaque, int irq)
-{
- IDEState *ide_if;
- int pmac_ide_memory;
-
- ide_if = qemu_mallocz(sizeof(IDEState) * 2);
- ide_init2(&ide_if[0], hd_table[0], hd_table[1],
- set_irq, irq_opaque, irq);
-
- pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
- pmac_ide_write, &ide_if[0]);
- return pmac_ide_memory;
-}
diff --git a/tools/ioemu/hw/integratorcp.c b/tools/ioemu/hw/integratorcp.c
deleted file mode 100644
index 4e5f4ac9f7..0000000000
--- a/tools/ioemu/hw/integratorcp.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * ARM Integrator CP System emulation.
- *
- * Copyright (c) 2005-2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL
- */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-void DMA_run (void)
-{
-}
-
-typedef struct {
- uint32_t flash_offset;
- uint32_t cm_osc;
- uint32_t cm_ctrl;
- uint32_t cm_lock;
- uint32_t cm_auxosc;
- uint32_t cm_sdram;
- uint32_t cm_init;
- uint32_t cm_flags;
- uint32_t cm_nvflags;
- uint32_t int_level;
- uint32_t irq_enabled;
- uint32_t fiq_enabled;
-} integratorcm_state;
-
-static uint8_t integrator_spd[128] = {
- 128, 8, 4, 11, 9, 1, 64, 0, 2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
- 0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
-};
-
-static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
-{
- integratorcm_state *s = (integratorcm_state *)opaque;
- offset -= 0x10000000;
- if (offset >= 0x100 && offset < 0x200) {
- /* CM_SPD */
- if (offset >= 0x180)
- return 0;
- return integrator_spd[offset >> 2];
- }
- switch (offset >> 2) {
- case 0: /* CM_ID */
- return 0x411a3001;
- case 1: /* CM_PROC */
- return 0;
- case 2: /* CM_OSC */
- return s->cm_osc;
- case 3: /* CM_CTRL */
- return s->cm_ctrl;
- case 4: /* CM_STAT */
- return 0x00100000;
- case 5: /* CM_LOCK */
- if (s->cm_lock == 0xa05f) {
- return 0x1a05f;
- } else {
- return s->cm_lock;
- }
- case 6: /* CM_LMBUSCNT */
- /* ??? High frequency timer. */
- cpu_abort(cpu_single_env, "integratorcm_read: CM_LMBUSCNT");
- case 7: /* CM_AUXOSC */
- return s->cm_auxosc;
- case 8: /* CM_SDRAM */
- return s->cm_sdram;
- case 9: /* CM_INIT */
- return s->cm_init;
- case 10: /* CM_REFCT */
- /* ??? High frequency timer. */
- cpu_abort(cpu_single_env, "integratorcm_read: CM_REFCT");
- case 12: /* CM_FLAGS */
- return s->cm_flags;
- case 14: /* CM_NVFLAGS */
- return s->cm_nvflags;
- case 16: /* CM_IRQ_STAT */
- return s->int_level & s->irq_enabled;
- case 17: /* CM_IRQ_RSTAT */
- return s->int_level;
- case 18: /* CM_IRQ_ENSET */
- return s->irq_enabled;
- case 20: /* CM_SOFT_INTSET */
- return s->int_level & 1;
- case 24: /* CM_FIQ_STAT */
- return s->int_level & s->fiq_enabled;
- case 25: /* CM_FIQ_RSTAT */
- return s->int_level;
- case 26: /* CM_FIQ_ENSET */
- return s->fiq_enabled;
- case 32: /* CM_VOLTAGE_CTL0 */
- case 33: /* CM_VOLTAGE_CTL1 */
- case 34: /* CM_VOLTAGE_CTL2 */
- case 35: /* CM_VOLTAGE_CTL3 */
- /* ??? Voltage control unimplemented. */
- return 0;
- default:
- cpu_abort (cpu_single_env,
- "integratorcm_read: Unimplemented offset 0x%x\n", offset);
- return 0;
- }
-}
-
-static void integratorcm_do_remap(integratorcm_state *s, int flash)
-{
- if (flash) {
- cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
- } else {
- cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
- }
- //??? tlb_flush (cpu_single_env, 1);
-}
-
-static void integratorcm_set_ctrl(integratorcm_state *s, uint32_t value)
-{
- if (value & 8) {
- cpu_abort(cpu_single_env, "Board reset\n");
- }
- if ((s->cm_init ^ value) & 4) {
- integratorcm_do_remap(s, (value & 4) == 0);
- }
- if ((s->cm_init ^ value) & 1) {
- printf("Green LED %s\n", (value & 1) ? "on" : "off");
- }
- s->cm_init = (s->cm_init & ~ 5) | (value ^ 5);
-}
-
-static void integratorcm_update(integratorcm_state *s)
-{
- /* ??? The CPU irq/fiq is raised when either the core module or base PIC
- are active. */
- if (s->int_level & (s->irq_enabled | s->fiq_enabled))
- cpu_abort(cpu_single_env, "Core module interrupt\n");
-}
-
-static void integratorcm_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- integratorcm_state *s = (integratorcm_state *)opaque;
- offset -= 0x10000000;
- switch (offset >> 2) {
- case 2: /* CM_OSC */
- if (s->cm_lock == 0xa05f)
- s->cm_osc = value;
- break;
- case 3: /* CM_CTRL */
- integratorcm_set_ctrl(s, value);
- break;
- case 5: /* CM_LOCK */
- s->cm_lock = value & 0xffff;
- break;
- case 7: /* CM_AUXOSC */
- if (s->cm_lock == 0xa05f)
- s->cm_auxosc = value;
- break;
- case 8: /* CM_SDRAM */
- s->cm_sdram = value;
- break;
- case 9: /* CM_INIT */
- /* ??? This can change the memory bus frequency. */
- s->cm_init = value;
- break;
- case 12: /* CM_FLAGSS */
- s->cm_flags |= value;
- break;
- case 13: /* CM_FLAGSC */
- s->cm_flags &= ~value;
- break;
- case 14: /* CM_NVFLAGSS */
- s->cm_nvflags |= value;
- break;
- case 15: /* CM_NVFLAGSS */
- s->cm_nvflags &= ~value;
- break;
- case 18: /* CM_IRQ_ENSET */
- s->irq_enabled |= value;
- integratorcm_update(s);
- break;
- case 19: /* CM_IRQ_ENCLR */
- s->irq_enabled &= ~value;
- integratorcm_update(s);
- break;
- case 20: /* CM_SOFT_INTSET */
- s->int_level |= (value & 1);
- integratorcm_update(s);
- break;
- case 21: /* CM_SOFT_INTCLR */
- s->int_level &= ~(value & 1);
- integratorcm_update(s);
- break;
- case 26: /* CM_FIQ_ENSET */
- s->fiq_enabled |= value;
- integratorcm_update(s);
- break;
- case 27: /* CM_FIQ_ENCLR */
- s->fiq_enabled &= ~value;
- integratorcm_update(s);
- break;
- case 32: /* CM_VOLTAGE_CTL0 */
- case 33: /* CM_VOLTAGE_CTL1 */
- case 34: /* CM_VOLTAGE_CTL2 */
- case 35: /* CM_VOLTAGE_CTL3 */
- /* ??? Voltage control unimplemented. */
- break;
- default:
- cpu_abort (cpu_single_env,
- "integratorcm_write: Unimplemented offset 0x%x\n", offset);
- break;
- }
-}
-
-/* Integrator/CM control registers. */
-
-static CPUReadMemoryFunc *integratorcm_readfn[] = {
- integratorcm_read,
- integratorcm_read,
- integratorcm_read
-};
-
-static CPUWriteMemoryFunc *integratorcm_writefn[] = {
- integratorcm_write,
- integratorcm_write,
- integratorcm_write
-};
-
-static void integratorcm_init(int memsz, uint32_t flash_offset)
-{
- int iomemtype;
- integratorcm_state *s;
-
- s = (integratorcm_state *)qemu_mallocz(sizeof(integratorcm_state));
- s->cm_osc = 0x01000048;
- /* ??? What should the high bits of this value be? */
- s->cm_auxosc = 0x0007feff;
- s->cm_sdram = 0x00011122;
- if (memsz >= 256) {
- integrator_spd[31] = 64;
- s->cm_sdram |= 0x10;
- } else if (memsz >= 128) {
- integrator_spd[31] = 32;
- s->cm_sdram |= 0x0c;
- } else if (memsz >= 64) {
- integrator_spd[31] = 16;
- s->cm_sdram |= 0x08;
- } else if (memsz >= 32) {
- integrator_spd[31] = 4;
- s->cm_sdram |= 0x04;
- } else {
- integrator_spd[31] = 2;
- }
- memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
- s->cm_init = 0x00000112;
- s->flash_offset = flash_offset;
-
- iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
- integratorcm_writefn, s);
- cpu_register_physical_memory(0x10000000, 0x007fffff, iomemtype);
- integratorcm_do_remap(s, 1);
- /* ??? Save/restore. */
-}
-
-/* Integrator/CP hardware emulation. */
-/* Primary interrupt controller. */
-
-typedef struct icp_pic_state
-{
- arm_pic_handler handler;
- uint32_t base;
- uint32_t level;
- uint32_t irq_enabled;
- uint32_t fiq_enabled;
- void *parent;
- int parent_irq;
- int parent_fiq;
-} icp_pic_state;
-
-static void icp_pic_update(icp_pic_state *s)
-{
- uint32_t flags;
-
- if (s->parent_irq != -1) {
- flags = (s->level & s->irq_enabled);
- pic_set_irq_new(s->parent, s->parent_irq, flags != 0);
- }
- if (s->parent_fiq != -1) {
- flags = (s->level & s->fiq_enabled);
- pic_set_irq_new(s->parent, s->parent_fiq, flags != 0);
- }
-}
-
-static void icp_pic_set_irq(void *opaque, int irq, int level)
-{
- icp_pic_state *s = (icp_pic_state *)opaque;
- if (level)
- s->level |= 1 << irq;
- else
- s->level &= ~(1 << irq);
- icp_pic_update(s);
-}
-
-static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
-{
- icp_pic_state *s = (icp_pic_state *)opaque;
-
- offset -= s->base;
- switch (offset >> 2) {
- case 0: /* IRQ_STATUS */
- return s->level & s->irq_enabled;
- case 1: /* IRQ_RAWSTAT */
- return s->level;
- case 2: /* IRQ_ENABLESET */
- return s->irq_enabled;
- case 4: /* INT_SOFTSET */
- return s->level & 1;
- case 8: /* FRQ_STATUS */
- return s->level & s->fiq_enabled;
- case 9: /* FRQ_RAWSTAT */
- return s->level;
- case 10: /* FRQ_ENABLESET */
- return s->fiq_enabled;
- case 3: /* IRQ_ENABLECLR */
- case 5: /* INT_SOFTCLR */
- case 11: /* FRQ_ENABLECLR */
- default:
- printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static void icp_pic_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- icp_pic_state *s = (icp_pic_state *)opaque;
- offset -= s->base;
-
- switch (offset >> 2) {
- case 2: /* IRQ_ENABLESET */
- s->irq_enabled |= value;
- break;
- case 3: /* IRQ_ENABLECLR */
- s->irq_enabled &= ~value;
- break;
- case 4: /* INT_SOFTSET */
- if (value & 1)
- pic_set_irq_new(s, 0, 1);
- break;
- case 5: /* INT_SOFTCLR */
- if (value & 1)
- pic_set_irq_new(s, 0, 0);
- break;
- case 10: /* FRQ_ENABLESET */
- s->fiq_enabled |= value;
- break;
- case 11: /* FRQ_ENABLECLR */
- s->fiq_enabled &= ~value;
- break;
- case 0: /* IRQ_STATUS */
- case 1: /* IRQ_RAWSTAT */
- case 8: /* FRQ_STATUS */
- case 9: /* FRQ_RAWSTAT */
- default:
- printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
- return;
- }
- icp_pic_update(s);
-}
-
-static CPUReadMemoryFunc *icp_pic_readfn[] = {
- icp_pic_read,
- icp_pic_read,
- icp_pic_read
-};
-
-static CPUWriteMemoryFunc *icp_pic_writefn[] = {
- icp_pic_write,
- icp_pic_write,
- icp_pic_write
-};
-
-static icp_pic_state *icp_pic_init(uint32_t base, void *parent,
- int parent_irq, int parent_fiq)
-{
- icp_pic_state *s;
- int iomemtype;
-
- s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
- if (!s)
- return NULL;
- s->handler = icp_pic_set_irq;
- s->base = base;
- s->parent = parent;
- s->parent_irq = parent_irq;
- s->parent_fiq = parent_fiq;
- iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
- icp_pic_writefn, s);
- cpu_register_physical_memory(base, 0x007fffff, iomemtype);
- /* ??? Save/restore. */
- return s;
-}
-
-/* CP control registers. */
-typedef struct {
- uint32_t base;
-} icp_control_state;
-
-static uint32_t icp_control_read(void *opaque, target_phys_addr_t offset)
-{
- icp_control_state *s = (icp_control_state *)opaque;
- offset -= s->base;
- switch (offset >> 2) {
- case 0: /* CP_IDFIELD */
- return 0x41034003;
- case 1: /* CP_FLASHPROG */
- return 0;
- case 2: /* CP_INTREG */
- return 0;
- case 3: /* CP_DECODE */
- return 0x11;
- default:
- cpu_abort (cpu_single_env, "icp_control_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void icp_control_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- icp_control_state *s = (icp_control_state *)opaque;
- offset -= s->base;
- switch (offset >> 2) {
- case 1: /* CP_FLASHPROG */
- case 2: /* CP_INTREG */
- case 3: /* CP_DECODE */
- /* Nothing interesting implemented yet. */
- break;
- default:
- cpu_abort (cpu_single_env, "icp_control_write: Bad offset %x\n", offset);
- }
-}
-static CPUReadMemoryFunc *icp_control_readfn[] = {
- icp_control_read,
- icp_control_read,
- icp_control_read
-};
-
-static CPUWriteMemoryFunc *icp_control_writefn[] = {
- icp_control_write,
- icp_control_write,
- icp_control_write
-};
-
-static void icp_control_init(uint32_t base)
-{
- int iomemtype;
- icp_control_state *s;
-
- s = (icp_control_state *)qemu_mallocz(sizeof(icp_control_state));
- iomemtype = cpu_register_io_memory(0, icp_control_readfn,
- icp_control_writefn, s);
- cpu_register_physical_memory(base, 0x007fffff, iomemtype);
- s->base = base;
- /* ??? Save/restore. */
-}
-
-
-/* Board init. */
-
-static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, uint32_t cpuid)
-{
- CPUState *env;
- uint32_t bios_offset;
- icp_pic_state *pic;
- void *cpu_pic;
-
- env = cpu_init();
- cpu_arm_set_model(env, cpuid);
- bios_offset = ram_size + vga_ram_size;
- /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
- /* ??? RAM shoud repeat to fill physical memory space. */
- /* SDRAM at address zero*/
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
- /* And again at address 0x80000000 */
- cpu_register_physical_memory(0x80000000, ram_size, IO_MEM_RAM);
-
- integratorcm_init(ram_size >> 20, bios_offset);
- cpu_pic = arm_pic_init_cpu(env);
- pic = icp_pic_init(0x14000000, cpu_pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
- icp_pic_init(0xca000000, pic, 26, -1);
- icp_pit_init(0x13000000, pic, 5);
- pl011_init(0x16000000, pic, 1, serial_hds[0]);
- pl011_init(0x17000000, pic, 2, serial_hds[1]);
- icp_control_init(0xcb000000);
- pl050_init(0x18000000, pic, 3, 0);
- pl050_init(0x19000000, pic, 4, 1);
- if (nd_table[0].vlan) {
- if (nd_table[0].model == NULL
- || strcmp(nd_table[0].model, "smc91c111") == 0) {
- smc91c111_init(&nd_table[0], 0xc8000000, pic, 27);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
- exit (1);
- }
- }
- pl110_init(ds, 0xc0000000, pic, 22, 0);
-
- arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
- initrd_filename, 0x113);
-}
-
-static void integratorcp926_init(int ram_size, int vga_ram_size,
- int boot_device, DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- integratorcp_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
- snapshot, kernel_filename, kernel_cmdline,
- initrd_filename, ARM_CPUID_ARM926);
-}
-
-static void integratorcp1026_init(int ram_size, int vga_ram_size,
- int boot_device, DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- integratorcp_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
- snapshot, kernel_filename, kernel_cmdline,
- initrd_filename, ARM_CPUID_ARM1026);
-}
-
-QEMUMachine integratorcp926_machine = {
- "integratorcp926",
- "ARM Integrator/CP (ARM926EJ-S)",
- integratorcp926_init,
-};
-
-QEMUMachine integratorcp1026_machine = {
- "integratorcp1026",
- "ARM Integrator/CP (ARM1026EJ-S)",
- integratorcp1026_init,
-};
diff --git a/tools/ioemu/hw/iommu.c b/tools/ioemu/hw/iommu.c
deleted file mode 100644
index e264f0cadf..0000000000
--- a/tools/ioemu/hw/iommu.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * QEMU SPARC iommu emulation
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug iommu */
-//#define DEBUG_IOMMU
-
-#ifdef DEBUG_IOMMU
-#define DPRINTF(fmt, args...) \
-do { printf("IOMMU: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...)
-#endif
-
-#define IOMMU_NREGS (3*4096/4)
-#define IOMMU_CTRL (0x0000 >> 2)
-#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */
-#define IOMMU_CTRL_VERS 0x0f000000 /* Version */
-#define IOMMU_VERSION 0x04000000
-#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */
-#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */
-#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */
-#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */
-#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */
-#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */
-#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */
-#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */
-#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */
-#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */
-#define IOMMU_CTRL_MASK 0x0000001d
-
-#define IOMMU_BASE (0x0004 >> 2)
-#define IOMMU_BASE_MASK 0x07fffc00
-
-#define IOMMU_TLBFLUSH (0x0014 >> 2)
-#define IOMMU_TLBFLUSH_MASK 0xffffffff
-
-#define IOMMU_PGFLUSH (0x0018 >> 2)
-#define IOMMU_PGFLUSH_MASK 0xffffffff
-
-#define IOMMU_SBCFG0 (0x1010 >> 2) /* SBUS configration per-slot */
-#define IOMMU_SBCFG1 (0x1014 >> 2) /* SBUS configration per-slot */
-#define IOMMU_SBCFG2 (0x1018 >> 2) /* SBUS configration per-slot */
-#define IOMMU_SBCFG3 (0x101c >> 2) /* SBUS configration per-slot */
-#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */
-#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */
-#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */
-#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses
- produced by this device as pure
- physical. */
-#define IOMMU_SBCFG_MASK 0x00010003
-
-#define IOMMU_ARBEN (0x2000 >> 2) /* SBUS arbitration enable */
-#define IOMMU_ARBEN_MASK 0x001f0000
-#define IOMMU_MID 0x00000008
-
-/* The format of an iopte in the page tables */
-#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */
-#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
-#define IOPTE_WRITE 0x00000004 /* Writeable */
-#define IOPTE_VALID 0x00000002 /* IOPTE is valid */
-#define IOPTE_WAZ 0x00000001 /* Write as zeros */
-
-#if defined(__i386__) || defined(__x86_64__)
-#define PAGE_SHIFT 12
-#elif defined(__ia64__)
-#define PAGE_SHIFT 14
-#endif
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define PAGE_MASK (PAGE_SIZE - 1)
-
-typedef struct IOMMUState {
- uint32_t addr;
- uint32_t regs[IOMMU_NREGS];
- uint32_t iostart;
-} IOMMUState;
-
-static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- IOMMUState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- switch (saddr) {
- default:
- DPRINTF("read reg[%d] = %x\n", saddr, s->regs[saddr]);
- return s->regs[saddr];
- break;
- }
- return 0;
-}
-
-static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- IOMMUState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- DPRINTF("write reg[%d] = %x\n", saddr, val);
- switch (saddr) {
- case IOMMU_CTRL:
- switch (val & IOMMU_CTRL_RNGE) {
- case IOMMU_RNGE_16MB:
- s->iostart = 0xff000000;
- break;
- case IOMMU_RNGE_32MB:
- s->iostart = 0xfe000000;
- break;
- case IOMMU_RNGE_64MB:
- s->iostart = 0xfc000000;
- break;
- case IOMMU_RNGE_128MB:
- s->iostart = 0xf8000000;
- break;
- case IOMMU_RNGE_256MB:
- s->iostart = 0xf0000000;
- break;
- case IOMMU_RNGE_512MB:
- s->iostart = 0xe0000000;
- break;
- case IOMMU_RNGE_1GB:
- s->iostart = 0xc0000000;
- break;
- default:
- case IOMMU_RNGE_2GB:
- s->iostart = 0x80000000;
- break;
- }
- DPRINTF("iostart = %x\n", s->iostart);
- s->regs[saddr] = ((val & IOMMU_CTRL_MASK) | IOMMU_VERSION);
- break;
- case IOMMU_BASE:
- s->regs[saddr] = val & IOMMU_BASE_MASK;
- break;
- case IOMMU_TLBFLUSH:
- DPRINTF("tlb flush %x\n", val);
- s->regs[saddr] = val & IOMMU_TLBFLUSH_MASK;
- break;
- case IOMMU_PGFLUSH:
- DPRINTF("page flush %x\n", val);
- s->regs[saddr] = val & IOMMU_PGFLUSH_MASK;
- break;
- case IOMMU_SBCFG0:
- case IOMMU_SBCFG1:
- case IOMMU_SBCFG2:
- case IOMMU_SBCFG3:
- s->regs[saddr] = val & IOMMU_SBCFG_MASK;
- break;
- case IOMMU_ARBEN:
- // XXX implement SBus probing: fault when reading unmapped
- // addresses, fault cause and address stored to MMU/IOMMU
- s->regs[saddr] = (val & IOMMU_ARBEN_MASK) | IOMMU_MID;
- break;
- default:
- s->regs[saddr] = val;
- break;
- }
-}
-
-static CPUReadMemoryFunc *iommu_mem_read[3] = {
- iommu_mem_readw,
- iommu_mem_readw,
- iommu_mem_readw,
-};
-
-static CPUWriteMemoryFunc *iommu_mem_write[3] = {
- iommu_mem_writew,
- iommu_mem_writew,
- iommu_mem_writew,
-};
-
-static uint32_t iommu_page_get_flags(IOMMUState *s, uint32_t addr)
-{
- uint32_t iopte;
-
- iopte = s->regs[1] << 4;
- addr &= ~s->iostart;
- iopte += (addr >> (PAGE_SHIFT - 2)) & ~3;
- return ldl_phys(iopte);
-}
-
-static uint32_t iommu_translate_pa(IOMMUState *s, uint32_t addr, uint32_t pa)
-{
- uint32_t tmppte;
-
- tmppte = pa;
- pa = ((pa & IOPTE_PAGE) << 4) + (addr & PAGE_MASK);
- DPRINTF("xlate dva %x => pa %x (iopte = %x)\n", addr, pa, tmppte);
- return pa;
-}
-
-void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int is_write)
-{
- int l, flags;
- target_ulong page, phys_addr;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- flags = iommu_page_get_flags(opaque, page);
- if (!(flags & IOPTE_VALID))
- return;
- phys_addr = iommu_translate_pa(opaque, addr, flags);
- if (is_write) {
- if (!(flags & IOPTE_WRITE))
- return;
- cpu_physical_memory_write(phys_addr, buf, len);
- } else {
- cpu_physical_memory_read(phys_addr, buf, len);
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-
-static void iommu_save(QEMUFile *f, void *opaque)
-{
- IOMMUState *s = opaque;
- int i;
-
- qemu_put_be32s(f, &s->addr);
- for (i = 0; i < IOMMU_NREGS; i++)
- qemu_put_be32s(f, &s->regs[i]);
- qemu_put_be32s(f, &s->iostart);
-}
-
-static int iommu_load(QEMUFile *f, void *opaque, int version_id)
-{
- IOMMUState *s = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->addr);
- for (i = 0; i < IOMMU_NREGS; i++)
- qemu_put_be32s(f, &s->regs[i]);
- qemu_get_be32s(f, &s->iostart);
-
- return 0;
-}
-
-static void iommu_reset(void *opaque)
-{
- IOMMUState *s = opaque;
-
- memset(s->regs, 0, IOMMU_NREGS * 4);
- s->iostart = 0;
- s->regs[0] = IOMMU_VERSION;
-}
-
-void *iommu_init(uint32_t addr)
-{
- IOMMUState *s;
- int iommu_io_memory;
-
- s = qemu_mallocz(sizeof(IOMMUState));
- if (!s)
- return NULL;
-
- s->addr = addr;
-
- iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s);
- cpu_register_physical_memory(addr, IOMMU_NREGS * 4, iommu_io_memory);
-
- register_savevm("iommu", addr, 1, iommu_save, iommu_load, s);
- qemu_register_reset(iommu_reset, s);
- return s;
-}
-
diff --git a/tools/ioemu/hw/isa_mmio.c b/tools/ioemu/hw/isa_mmio.c
deleted file mode 100644
index 070f6f587a..0000000000
--- a/tools/ioemu/hw/isa_mmio.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Memory mapped access to ISA IO space.
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-
-static void isa_mmio_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cpu_outb(NULL, addr & 0xffff, val);
-}
-
-static void isa_mmio_writew (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- cpu_outw(NULL, addr & 0xffff, val);
-}
-
-static void isa_mmio_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- cpu_outl(NULL, addr & 0xffff, val);
-}
-
-static uint32_t isa_mmio_readb (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
-
- val = cpu_inb(NULL, addr & 0xffff);
- return val;
-}
-
-static uint32_t isa_mmio_readw (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
-
- val = cpu_inw(NULL, addr & 0xffff);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t isa_mmio_readl (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
-
- val = cpu_inl(NULL, addr & 0xffff);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
-static CPUWriteMemoryFunc *isa_mmio_write[] = {
- &isa_mmio_writeb,
- &isa_mmio_writew,
- &isa_mmio_writel,
-};
-
-static CPUReadMemoryFunc *isa_mmio_read[] = {
- &isa_mmio_readb,
- &isa_mmio_readw,
- &isa_mmio_readl,
-};
-
-static int isa_mmio_iomemtype = 0;
-
-void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size)
-{
- if (!isa_mmio_iomemtype) {
- isa_mmio_iomemtype = cpu_register_io_memory(0, isa_mmio_read,
- isa_mmio_write, NULL);
- }
- cpu_register_physical_memory(base, size, isa_mmio_iomemtype);
-}
diff --git a/tools/ioemu/hw/lsi53c895a.c b/tools/ioemu/hw/lsi53c895a.c
deleted file mode 100644
index 7aa70bfa70..0000000000
--- a/tools/ioemu/hw/lsi53c895a.c
+++ /dev/null
@@ -1,1869 +0,0 @@
-/*
- * QEMU LSI53C895A SCSI Host Bus Adapter emulation
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- */
-
-/* ??? Need to check if the {read,write}[wl] routines work properly on
- big-endian targets. */
-
-#include "vl.h"
-
-//#define DEBUG_LSI
-//#define DEBUG_LSI_REG
-
-#ifdef DEBUG_LSI
-#define DPRINTF(fmt, args...) \
-do { printf("lsi_scsi: " fmt , ##args); } while (0)
-#define BADF(fmt, args...) \
-do { fprintf(stderr, "lsi_scsi: error: " fmt , ##args); exit(1);} while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#define BADF(fmt, args...) \
-do { fprintf(stderr, "lsi_scsi: error: " fmt , ##args);} while (0)
-#endif
-
-#define LSI_SCNTL0_TRG 0x01
-#define LSI_SCNTL0_AAP 0x02
-#define LSI_SCNTL0_EPC 0x08
-#define LSI_SCNTL0_WATN 0x10
-#define LSI_SCNTL0_START 0x20
-
-#define LSI_SCNTL1_SST 0x01
-#define LSI_SCNTL1_IARB 0x02
-#define LSI_SCNTL1_AESP 0x04
-#define LSI_SCNTL1_RST 0x08
-#define LSI_SCNTL1_CON 0x10
-#define LSI_SCNTL1_DHP 0x20
-#define LSI_SCNTL1_ADB 0x40
-#define LSI_SCNTL1_EXC 0x80
-
-#define LSI_SCNTL2_WSR 0x01
-#define LSI_SCNTL2_VUE0 0x02
-#define LSI_SCNTL2_VUE1 0x04
-#define LSI_SCNTL2_WSS 0x08
-#define LSI_SCNTL2_SLPHBEN 0x10
-#define LSI_SCNTL2_SLPMD 0x20
-#define LSI_SCNTL2_CHM 0x40
-#define LSI_SCNTL2_SDU 0x80
-
-#define LSI_ISTAT0_DIP 0x01
-#define LSI_ISTAT0_SIP 0x02
-#define LSI_ISTAT0_INTF 0x04
-#define LSI_ISTAT0_CON 0x08
-#define LSI_ISTAT0_SEM 0x10
-#define LSI_ISTAT0_SIGP 0x20
-#define LSI_ISTAT0_SRST 0x40
-#define LSI_ISTAT0_ABRT 0x80
-
-#define LSI_ISTAT1_SI 0x01
-#define LSI_ISTAT1_SRUN 0x02
-#define LSI_ISTAT1_FLSH 0x04
-
-#define LSI_SSTAT0_SDP0 0x01
-#define LSI_SSTAT0_RST 0x02
-#define LSI_SSTAT0_WOA 0x04
-#define LSI_SSTAT0_LOA 0x08
-#define LSI_SSTAT0_AIP 0x10
-#define LSI_SSTAT0_OLF 0x20
-#define LSI_SSTAT0_ORF 0x40
-#define LSI_SSTAT0_ILF 0x80
-
-#define LSI_SIST0_PAR 0x01
-#define LSI_SIST0_RST 0x02
-#define LSI_SIST0_UDC 0x04
-#define LSI_SIST0_SGE 0x08
-#define LSI_SIST0_RSL 0x10
-#define LSI_SIST0_SEL 0x20
-#define LSI_SIST0_CMP 0x40
-#define LSI_SIST0_MA 0x80
-
-#define LSI_SIST1_HTH 0x01
-#define LSI_SIST1_GEN 0x02
-#define LSI_SIST1_STO 0x04
-#define LSI_SIST1_SBMC 0x10
-
-#define LSI_SOCL_IO 0x01
-#define LSI_SOCL_CD 0x02
-#define LSI_SOCL_MSG 0x04
-#define LSI_SOCL_ATN 0x08
-#define LSI_SOCL_SEL 0x10
-#define LSI_SOCL_BSY 0x20
-#define LSI_SOCL_ACK 0x40
-#define LSI_SOCL_REQ 0x80
-
-#define LSI_DSTAT_IID 0x01
-#define LSI_DSTAT_SIR 0x04
-#define LSI_DSTAT_SSI 0x08
-#define LSI_DSTAT_ABRT 0x10
-#define LSI_DSTAT_BF 0x20
-#define LSI_DSTAT_MDPE 0x40
-#define LSI_DSTAT_DFE 0x80
-
-#define LSI_DCNTL_COM 0x01
-#define LSI_DCNTL_IRQD 0x02
-#define LSI_DCNTL_STD 0x04
-#define LSI_DCNTL_IRQM 0x08
-#define LSI_DCNTL_SSM 0x10
-#define LSI_DCNTL_PFEN 0x20
-#define LSI_DCNTL_PFF 0x40
-#define LSI_DCNTL_CLSE 0x80
-
-#define LSI_DMODE_MAN 0x01
-#define LSI_DMODE_BOF 0x02
-#define LSI_DMODE_ERMP 0x04
-#define LSI_DMODE_ERL 0x08
-#define LSI_DMODE_DIOM 0x10
-#define LSI_DMODE_SIOM 0x20
-
-#define LSI_CTEST2_DACK 0x01
-#define LSI_CTEST2_DREQ 0x02
-#define LSI_CTEST2_TEOP 0x04
-#define LSI_CTEST2_PCICIE 0x08
-#define LSI_CTEST2_CM 0x10
-#define LSI_CTEST2_CIO 0x20
-#define LSI_CTEST2_SIGP 0x40
-#define LSI_CTEST2_DDIR 0x80
-
-#define LSI_CTEST5_BL2 0x04
-#define LSI_CTEST5_DDIR 0x08
-#define LSI_CTEST5_MASR 0x10
-#define LSI_CTEST5_DFSN 0x20
-#define LSI_CTEST5_BBCK 0x40
-#define LSI_CTEST5_ADCK 0x80
-
-#define LSI_CCNTL0_DILS 0x01
-#define LSI_CCNTL0_DISFC 0x10
-#define LSI_CCNTL0_ENNDJ 0x20
-#define LSI_CCNTL0_PMJCTL 0x40
-#define LSI_CCNTL0_ENPMJ 0x80
-
-#define PHASE_DO 0
-#define PHASE_DI 1
-#define PHASE_CMD 2
-#define PHASE_ST 3
-#define PHASE_MO 6
-#define PHASE_MI 7
-#define PHASE_MASK 7
-
-/* The HBA is ID 7, so for simplicitly limit to 7 devices. */
-#define LSI_MAX_DEVS 7
-
-/* Maximum length of MSG IN data. */
-#define LSI_MAX_MSGIN_LEN 8
-
-/* Flag set if this is a tagged command. */
-#define LSI_TAG_VALID (1 << 16)
-
-typedef struct {
- uint32_t tag;
- uint32_t pending;
- int out;
-} lsi_queue;
-
-typedef struct {
- PCIDevice pci_dev;
- int mmio_io_addr;
- int ram_io_addr;
- uint32_t script_ram_base;
-
- int carry; /* ??? Should this be an a visible register somewhere? */
- int sense;
- /* Action to take at the end of a MSG IN phase.
- 0 = COMMAND, 1 = disconect, 2 = DATA OUT, 3 = DATA IN. */
- int msg_action;
- int msg_len;
- uint8_t msg[LSI_MAX_MSGIN_LEN];
- /* 0 if SCRIPTS are running or stopped.
- * 1 if a Wait Reselect instruction has been issued.
- * 2 if processing DMA from lsi_execute_script.
- * 3 if a DMA operation is in progress. */
- int waiting;
- SCSIDevice *scsi_dev[LSI_MAX_DEVS];
- SCSIDevice *current_dev;
- int current_lun;
- /* The tag is a combination of the device ID and the SCSI tag. */
- uint32_t current_tag;
- uint32_t current_dma_len;
- uint8_t *dma_buf;
- lsi_queue *queue;
- int queue_len;
- int active_commands;
-
- uint32_t dsa;
- uint32_t temp;
- uint32_t dnad;
- uint32_t dbc;
- uint8_t istat0;
- uint8_t istat1;
- uint8_t dcmd;
- uint8_t dstat;
- uint8_t dien;
- uint8_t sist0;
- uint8_t sist1;
- uint8_t sien0;
- uint8_t sien1;
- uint8_t mbox0;
- uint8_t mbox1;
- uint8_t dfifo;
- uint8_t ctest3;
- uint8_t ctest4;
- uint8_t ctest5;
- uint8_t ccntl0;
- uint8_t ccntl1;
- uint32_t dsp;
- uint32_t dsps;
- uint8_t dmode;
- uint8_t dcntl;
- uint8_t scntl0;
- uint8_t scntl1;
- uint8_t scntl2;
- uint8_t scntl3;
- uint8_t sstat0;
- uint8_t sstat1;
- uint8_t scid;
- uint8_t sxfer;
- uint8_t socl;
- uint8_t sdid;
- uint8_t ssid;
- uint8_t sfbr;
- uint8_t stest1;
- uint8_t stest2;
- uint8_t stest3;
- uint8_t sidl;
- uint8_t stime0;
- uint8_t respid0;
- uint8_t respid1;
- uint32_t mmrs;
- uint32_t mmws;
- uint32_t sfs;
- uint32_t drs;
- uint32_t sbms;
- uint32_t dmbs;
- uint32_t dnad64;
- uint32_t pmjad1;
- uint32_t pmjad2;
- uint32_t rbc;
- uint32_t ua;
- uint32_t ia;
- uint32_t sbc;
- uint32_t csbc;
- uint32_t scratch[13]; /* SCRATCHA-SCRATCHR */
-
- /* Script ram is stored as 32-bit words in host byteorder. */
- uint32_t script_ram[2048];
-} LSIState;
-
-static void lsi_soft_reset(LSIState *s)
-{
- DPRINTF("Reset\n");
- s->carry = 0;
-
- s->waiting = 0;
- s->dsa = 0;
- s->dnad = 0;
- s->dbc = 0;
- s->temp = 0;
- memset(s->scratch, 0, sizeof(s->scratch));
- s->istat0 = 0;
- s->istat1 = 0;
- s->dcmd = 0;
- s->dstat = 0;
- s->dien = 0;
- s->sist0 = 0;
- s->sist1 = 0;
- s->sien0 = 0;
- s->sien1 = 0;
- s->mbox0 = 0;
- s->mbox1 = 0;
- s->dfifo = 0;
- s->ctest3 = 0;
- s->ctest4 = 0;
- s->ctest5 = 0;
- s->ccntl0 = 0;
- s->ccntl1 = 0;
- s->dsp = 0;
- s->dsps = 0;
- s->dmode = 0;
- s->dcntl = 0;
- s->scntl0 = 0xc0;
- s->scntl1 = 0;
- s->scntl2 = 0;
- s->scntl3 = 0;
- s->sstat0 = 0;
- s->sstat1 = 0;
- s->scid = 7;
- s->sxfer = 0;
- s->socl = 0;
- s->stest1 = 0;
- s->stest2 = 0;
- s->stest3 = 0;
- s->sidl = 0;
- s->stime0 = 0;
- s->respid0 = 0x80;
- s->respid1 = 0;
- s->mmrs = 0;
- s->mmws = 0;
- s->sfs = 0;
- s->drs = 0;
- s->sbms = 0;
- s->dmbs = 0;
- s->dnad64 = 0;
- s->pmjad1 = 0;
- s->pmjad2 = 0;
- s->rbc = 0;
- s->ua = 0;
- s->ia = 0;
- s->sbc = 0;
- s->csbc = 0;
-}
-
-static uint8_t lsi_reg_readb(LSIState *s, int offset);
-static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
-static void lsi_execute_script(LSIState *s);
-
-static inline uint32_t read_dword(LSIState *s, uint32_t addr)
-{
- uint32_t buf;
-
- /* Optimize reading from SCRIPTS RAM. */
- if ((addr & 0xffffe000) == s->script_ram_base) {
- return s->script_ram[(addr & 0x1fff) >> 2];
- }
- cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
- return cpu_to_le32(buf);
-}
-
-static void lsi_stop_script(LSIState *s)
-{
- s->istat1 &= ~LSI_ISTAT1_SRUN;
-}
-
-static void lsi_update_irq(LSIState *s)
-{
- int level;
- static int last_level;
-
- /* It's unclear whether the DIP/SIP bits should be cleared when the
- Interrupt Status Registers are cleared or when istat0 is read.
- We currently do the formwer, which seems to work. */
- level = 0;
- if (s->dstat) {
- if (s->dstat & s->dien)
- level = 1;
- s->istat0 |= LSI_ISTAT0_DIP;
- } else {
- s->istat0 &= ~LSI_ISTAT0_DIP;
- }
-
- if (s->sist0 || s->sist1) {
- if ((s->sist0 & s->sien0) || (s->sist1 & s->sien1))
- level = 1;
- s->istat0 |= LSI_ISTAT0_SIP;
- } else {
- s->istat0 &= ~LSI_ISTAT0_SIP;
- }
- if (s->istat0 & LSI_ISTAT0_INTF)
- level = 1;
-
- if (level != last_level) {
- DPRINTF("Update IRQ level %d dstat %02x sist %02x%02x\n",
- level, s->dstat, s->sist1, s->sist0);
- last_level = level;
- }
- pci_set_irq(&s->pci_dev, 0, level);
-}
-
-/* Stop SCRIPTS execution and raise a SCSI interrupt. */
-static void lsi_script_scsi_interrupt(LSIState *s, int stat0, int stat1)
-{
- uint32_t mask0;
- uint32_t mask1;
-
- DPRINTF("SCSI Interrupt 0x%02x%02x prev 0x%02x%02x\n",
- stat1, stat0, s->sist1, s->sist0);
- s->sist0 |= stat0;
- s->sist1 |= stat1;
- /* Stop processor on fatal or unmasked interrupt. As a special hack
- we don't stop processing when raising STO. Instead continue
- execution and stop at the next insn that accesses the SCSI bus. */
- mask0 = s->sien0 | ~(LSI_SIST0_CMP | LSI_SIST0_SEL | LSI_SIST0_RSL);
- mask1 = s->sien1 | ~(LSI_SIST1_GEN | LSI_SIST1_HTH);
- mask1 &= ~LSI_SIST1_STO;
- if (s->sist0 & mask0 || s->sist1 & mask1) {
- lsi_stop_script(s);
- }
- lsi_update_irq(s);
-}
-
-/* Stop SCRIPTS execution and raise a DMA interrupt. */
-static void lsi_script_dma_interrupt(LSIState *s, int stat)
-{
- DPRINTF("DMA Interrupt 0x%x prev 0x%x\n", stat, s->dstat);
- s->dstat |= stat;
- lsi_update_irq(s);
- lsi_stop_script(s);
-}
-
-static inline void lsi_set_phase(LSIState *s, int phase)
-{
- s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
-}
-
-static void lsi_bad_phase(LSIState *s, int out, int new_phase)
-{
- /* Trigger a phase mismatch. */
- if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
- if ((s->ccntl0 & LSI_CCNTL0_PMJCTL) || out) {
- s->dsp = s->pmjad1;
- } else {
- s->dsp = s->pmjad2;
- }
- DPRINTF("Data phase mismatch jump to %08x\n", s->dsp);
- } else {
- DPRINTF("Phase mismatch interrupt\n");
- lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
- lsi_stop_script(s);
- }
- lsi_set_phase(s, new_phase);
-}
-
-
-/* Resume SCRIPTS execution after a DMA operation. */
-static void lsi_resume_script(LSIState *s)
-{
- if (s->waiting != 2) {
- s->waiting = 0;
- lsi_execute_script(s);
- } else {
- s->waiting = 0;
- }
-}
-
-/* Initiate a SCSI layer data transfer. */
-static void lsi_do_dma(LSIState *s, int out)
-{
- uint32_t count;
- uint32_t addr;
-
- if (!s->current_dma_len) {
- /* Wait until data is available. */
- DPRINTF("DMA no data available\n");
- return;
- }
-
- count = s->dbc;
- if (count > s->current_dma_len)
- count = s->current_dma_len;
- DPRINTF("DMA addr=0x%08x len=%d\n", s->dnad, count);
-
- addr = s->dnad;
- s->csbc += count;
- s->dnad += count;
- s->dbc -= count;
-
- if (s->dma_buf == NULL) {
- s->dma_buf = scsi_get_buf(s->current_dev, s->current_tag);
- }
-
- /* ??? Set SFBR to first data byte. */
- if (out) {
- cpu_physical_memory_read(addr, s->dma_buf, count);
- } else {
- cpu_physical_memory_write(addr, s->dma_buf, count);
- }
- s->current_dma_len -= count;
- if (s->current_dma_len == 0) {
- s->dma_buf = NULL;
- if (out) {
- /* Write the data. */
- scsi_write_data(s->current_dev, s->current_tag);
- } else {
- /* Request any remaining data. */
- scsi_read_data(s->current_dev, s->current_tag);
- }
- } else {
- s->dma_buf += count;
- lsi_resume_script(s);
- }
-}
-
-
-/* Add a command to the queue. */
-static void lsi_queue_command(LSIState *s)
-{
- lsi_queue *p;
-
- DPRINTF("Queueing tag=0x%x\n", s->current_tag);
- if (s->queue_len == s->active_commands) {
- s->queue_len++;
- s->queue = realloc(s->queue, s->queue_len * sizeof(lsi_queue));
- }
- p = &s->queue[s->active_commands++];
- p->tag = s->current_tag;
- p->pending = 0;
- p->out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
-}
-
-/* Queue a byte for a MSG IN phase. */
-static void lsi_add_msg_byte(LSIState *s, uint8_t data)
-{
- if (s->msg_len >= LSI_MAX_MSGIN_LEN) {
- BADF("MSG IN data too long\n");
- } else {
- DPRINTF("MSG IN 0x%02x\n", data);
- s->msg[s->msg_len++] = data;
- }
-}
-
-/* Perform reselection to continue a command. */
-static void lsi_reselect(LSIState *s, uint32_t tag)
-{
- lsi_queue *p;
- int n;
- int id;
-
- p = NULL;
- for (n = 0; n < s->active_commands; n++) {
- p = &s->queue[n];
- if (p->tag == tag)
- break;
- }
- if (n == s->active_commands) {
- BADF("Reselected non-existant command tag=0x%x\n", tag);
- return;
- }
- id = (tag >> 8) & 0xf;
- s->ssid = id | 0x80;
- DPRINTF("Reselected target %d\n", id);
- s->current_dev = s->scsi_dev[id];
- s->current_tag = tag;
- s->scntl1 |= LSI_SCNTL1_CON;
- lsi_set_phase(s, PHASE_MI);
- s->msg_action = p->out ? 2 : 3;
- s->current_dma_len = p->pending;
- s->dma_buf = NULL;
- lsi_add_msg_byte(s, 0x80);
- if (s->current_tag & LSI_TAG_VALID) {
- lsi_add_msg_byte(s, 0x20);
- lsi_add_msg_byte(s, tag & 0xff);
- }
-
- s->active_commands--;
- if (n != s->active_commands) {
- s->queue[n] = s->queue[s->active_commands];
- }
-}
-
-/* Record that data is available for a queued command. Returns zero if
- the device was reselected, nonzero if the IO is deferred. */
-static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
-{
- lsi_queue *p;
- int i;
- for (i = 0; i < s->active_commands; i++) {
- p = &s->queue[i];
- if (p->tag == tag) {
- if (p->pending) {
- BADF("Multiple IO pending for tag %d\n", tag);
- }
- p->pending = arg;
- if (s->waiting == 1) {
- /* Reselect device. */
- lsi_reselect(s, tag);
- return 0;
- } else {
- DPRINTF("Queueing IO tag=0x%x\n", tag);
- p->pending = arg;
- return 1;
- }
- }
- }
- BADF("IO with unknown tag %d\n", tag);
- return 1;
-}
-
-/* Callback to indicate that the SCSI layer has completed a transfer. */
-static void lsi_command_complete(void *opaque, int reason, uint32_t tag,
- uint32_t arg)
-{
- LSIState *s = (LSIState *)opaque;
- int out;
-
- out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
- if (reason == SCSI_REASON_DONE) {
- DPRINTF("Command complete sense=%d\n", (int)arg);
- s->sense = arg;
- if (s->waiting && s->dbc != 0) {
- /* Raise phase mismatch for short transfers. */
- lsi_bad_phase(s, out, PHASE_ST);
- } else {
- lsi_set_phase(s, PHASE_ST);
- }
- lsi_resume_script(s);
- return;
- }
-
- if (s->waiting == 1 || tag != s->current_tag) {
- if (lsi_queue_tag(s, tag, arg))
- return;
- }
- DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg);
- s->current_dma_len = arg;
- if (!s->waiting)
- return;
- if (s->waiting == 1 || s->dbc == 0) {
- lsi_resume_script(s);
- } else {
- lsi_do_dma(s, out);
- }
-}
-
-static void lsi_do_command(LSIState *s)
-{
- uint8_t buf[16];
- int n;
-
- DPRINTF("Send command len=%d\n", s->dbc);
- if (s->dbc > 16)
- s->dbc = 16;
- cpu_physical_memory_read(s->dnad, buf, s->dbc);
- s->sfbr = buf[0];
- n = scsi_send_command(s->current_dev, s->current_tag, buf, s->current_lun);
- if (n > 0) {
- lsi_set_phase(s, PHASE_DI);
- scsi_read_data(s->current_dev, s->current_tag);
- } else if (n < 0) {
- lsi_set_phase(s, PHASE_DO);
- scsi_write_data(s->current_dev, s->current_tag);
- }
- if (n && s->current_dma_len == 0) {
- /* Command did not complete immediately so disconnect. */
- lsi_add_msg_byte(s, 2); /* SAVE DATA POINTER */
- lsi_add_msg_byte(s, 4); /* DISCONNECT */
- lsi_set_phase(s, PHASE_MI);
- s->msg_action = 1;
- lsi_queue_command(s);
- }
-}
-
-static void lsi_do_status(LSIState *s)
-{
- uint8_t sense;
- DPRINTF("Get status len=%d sense=%d\n", s->dbc, s->sense);
- if (s->dbc != 1)
- BADF("Bad Status move\n");
- s->dbc = 1;
- sense = s->sense;
- s->sfbr = sense;
- cpu_physical_memory_write(s->dnad, &sense, 1);
- lsi_set_phase(s, PHASE_MI);
- s->msg_action = 1;
- lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
-}
-
-static void lsi_disconnect(LSIState *s)
-{
- s->scntl1 &= ~LSI_SCNTL1_CON;
- s->sstat1 &= ~PHASE_MASK;
-}
-
-static void lsi_do_msgin(LSIState *s)
-{
- int len;
- DPRINTF("Message in len=%d/%d\n", s->dbc, s->msg_len);
- s->sfbr = s->msg[0];
- len = s->msg_len;
- if (len > s->dbc)
- len = s->dbc;
- cpu_physical_memory_write(s->dnad, s->msg, len);
- /* Linux drivers rely on the last byte being in the SIDL. */
- s->sidl = s->msg[len - 1];
- s->msg_len -= len;
- if (s->msg_len) {
- memmove(s->msg, s->msg + len, s->msg_len);
- } else {
- /* ??? Check if ATN (not yet implemented) is asserted and maybe
- switch to PHASE_MO. */
- switch (s->msg_action) {
- case 0:
- lsi_set_phase(s, PHASE_CMD);
- break;
- case 1:
- lsi_disconnect(s);
- break;
- case 2:
- lsi_set_phase(s, PHASE_DO);
- break;
- case 3:
- lsi_set_phase(s, PHASE_DI);
- break;
- default:
- abort();
- }
- }
-}
-
-/* Read the next byte during a MSGOUT phase. */
-static uint8_t lsi_get_msgbyte(LSIState *s)
-{
- uint8_t data;
- cpu_physical_memory_read(s->dnad, &data, 1);
- s->dnad++;
- s->dbc--;
- return data;
-}
-
-static void lsi_do_msgout(LSIState *s)
-{
- uint8_t msg;
- int len;
-
- DPRINTF("MSG out len=%d\n", s->dbc);
- while (s->dbc) {
- msg = lsi_get_msgbyte(s);
- s->sfbr = msg;
-
- switch (msg) {
- case 0x00:
- DPRINTF("MSG: Disconnect\n");
- lsi_disconnect(s);
- break;
- case 0x08:
- DPRINTF("MSG: No Operation\n");
- lsi_set_phase(s, PHASE_CMD);
- break;
- case 0x01:
- len = lsi_get_msgbyte(s);
- msg = lsi_get_msgbyte(s);
- DPRINTF("Extended message 0x%x (len %d)\n", msg, len);
- switch (msg) {
- case 1:
- DPRINTF("SDTR (ignored)\n");
- s->dbc -= 2;
- break;
- case 3:
- DPRINTF("WDTR (ignored)\n");
- s->dbc -= 1;
- break;
- default:
- goto bad;
- }
- break;
- case 0x20: /* SIMPLE queue */
- s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
- DPRINTF("SIMPLE queue tag=0x%x\n", s->current_tag & 0xff);
- break;
- case 0x21: /* HEAD of queue */
- BADF("HEAD queue not implemented\n");
- s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
- break;
- case 0x22: /* ORDERED queue */
- BADF("ORDERED queue not implemented\n");
- s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
- break;
- default:
- if ((msg & 0x80) == 0) {
- goto bad;
- }
- s->current_lun = msg & 7;
- DPRINTF("Select LUN %d\n", s->current_lun);
- lsi_set_phase(s, PHASE_CMD);
- break;
- }
- }
- return;
-bad:
- BADF("Unimplemented message 0x%02x\n", msg);
- lsi_set_phase(s, PHASE_MI);
- lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */
- s->msg_action = 0;
-}
-
-/* Sign extend a 24-bit value. */
-static inline int32_t sxt24(int32_t n)
-{
- return (n << 8) >> 8;
-}
-
-static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count)
-{
- int n;
- uint8_t buf[TARGET_PAGE_SIZE];
-
- DPRINTF("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count);
- while (count) {
- n = (count > TARGET_PAGE_SIZE) ? TARGET_PAGE_SIZE : count;
- cpu_physical_memory_read(src, buf, n);
- cpu_physical_memory_write(dest, buf, n);
- src += n;
- dest += n;
- count -= n;
- }
-}
-
-static void lsi_wait_reselect(LSIState *s)
-{
- int i;
- DPRINTF("Wait Reselect\n");
- if (s->current_dma_len)
- BADF("Reselect with pending DMA\n");
- for (i = 0; i < s->active_commands; i++) {
- if (s->queue[i].pending) {
- lsi_reselect(s, s->queue[i].tag);
- break;
- }
- }
- if (s->current_dma_len == 0) {
- s->waiting = 1;
- }
-}
-
-static void lsi_execute_script(LSIState *s)
-{
- uint32_t insn;
- uint32_t addr;
- int opcode;
-
- s->istat1 |= LSI_ISTAT1_SRUN;
-again:
- insn = read_dword(s, s->dsp);
- addr = read_dword(s, s->dsp + 4);
- DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);
- s->dsps = addr;
- s->dcmd = insn >> 24;
- s->dsp += 8;
- switch (insn >> 30) {
- case 0: /* Block move. */
- if (s->sist1 & LSI_SIST1_STO) {
- DPRINTF("Delayed select timeout\n");
- lsi_stop_script(s);
- break;
- }
- s->dbc = insn & 0xffffff;
- s->rbc = s->dbc;
- if (insn & (1 << 29)) {
- /* Indirect addressing. */
- addr = read_dword(s, addr);
- } else if (insn & (1 << 28)) {
- uint32_t buf[2];
- int32_t offset;
- /* Table indirect addressing. */
- offset = sxt24(addr);
- cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);
- s->dbc = cpu_to_le32(buf[0]);
- addr = cpu_to_le32(buf[1]);
- }
- if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
- DPRINTF("Wrong phase got %d expected %d\n",
- s->sstat1 & PHASE_MASK, (insn >> 24) & 7);
- lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
- break;
- }
- s->dnad = addr;
- switch (s->sstat1 & 0x7) {
- case PHASE_DO:
- s->waiting = 2;
- lsi_do_dma(s, 1);
- if (s->waiting)
- s->waiting = 3;
- break;
- case PHASE_DI:
- s->waiting = 2;
- lsi_do_dma(s, 0);
- if (s->waiting)
- s->waiting = 3;
- break;
- case PHASE_CMD:
- lsi_do_command(s);
- break;
- case PHASE_ST:
- lsi_do_status(s);
- break;
- case PHASE_MO:
- lsi_do_msgout(s);
- break;
- case PHASE_MI:
- lsi_do_msgin(s);
- break;
- default:
- BADF("Unimplemented phase %d\n", s->sstat1 & PHASE_MASK);
- exit(1);
- }
- s->dfifo = s->dbc & 0xff;
- s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
- s->sbc = s->dbc;
- s->rbc -= s->dbc;
- s->ua = addr + s->dbc;
- /* ??? Set ESA. */
- s->ia = s->dsp - 8;
- break;
-
- case 1: /* IO or Read/Write instruction. */
- opcode = (insn >> 27) & 7;
- if (opcode < 5) {
- uint32_t id;
-
- if (insn & (1 << 25)) {
- id = read_dword(s, s->dsa + sxt24(insn));
- } else {
- id = addr;
- }
- id = (id >> 16) & 0xf;
- if (insn & (1 << 26)) {
- addr = s->dsp + sxt24(addr);
- }
- s->dnad = addr;
- switch (opcode) {
- case 0: /* Select */
- s->sdid = id;
- if (s->current_dma_len && (s->ssid & 0xf) == id) {
- DPRINTF("Already reselected by target %d\n", id);
- break;
- }
- s->sstat0 |= LSI_SSTAT0_WOA;
- s->scntl1 &= ~LSI_SCNTL1_IARB;
- if (id >= LSI_MAX_DEVS || !s->scsi_dev[id]) {
- DPRINTF("Selected absent target %d\n", id);
- lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
- lsi_disconnect(s);
- break;
- }
- DPRINTF("Selected target %d%s\n",
- id, insn & (1 << 3) ? " ATN" : "");
- /* ??? Linux drivers compain when this is set. Maybe
- it only applies in low-level mode (unimplemented).
- lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
- s->current_dev = s->scsi_dev[id];
- s->current_tag = id << 8;
- s->scntl1 |= LSI_SCNTL1_CON;
- if (insn & (1 << 3)) {
- s->socl |= LSI_SOCL_ATN;
- }
- lsi_set_phase(s, PHASE_MO);
- break;
- case 1: /* Disconnect */
- DPRINTF("Wait Disconect\n");
- s->scntl1 &= ~LSI_SCNTL1_CON;
- break;
- case 2: /* Wait Reselect */
- lsi_wait_reselect(s);
- break;
- case 3: /* Set */
- DPRINTF("Set%s%s%s%s\n",
- insn & (1 << 3) ? " ATN" : "",
- insn & (1 << 6) ? " ACK" : "",
- insn & (1 << 9) ? " TM" : "",
- insn & (1 << 10) ? " CC" : "");
- if (insn & (1 << 3)) {
- s->socl |= LSI_SOCL_ATN;
- lsi_set_phase(s, PHASE_MO);
- }
- if (insn & (1 << 9)) {
- BADF("Target mode not implemented\n");
- exit(1);
- }
- if (insn & (1 << 10))
- s->carry = 1;
- break;
- case 4: /* Clear */
- DPRINTF("Clear%s%s%s%s\n",
- insn & (1 << 3) ? " ATN" : "",
- insn & (1 << 6) ? " ACK" : "",
- insn & (1 << 9) ? " TM" : "",
- insn & (1 << 10) ? " CC" : "");
- if (insn & (1 << 3)) {
- s->socl &= ~LSI_SOCL_ATN;
- }
- if (insn & (1 << 10))
- s->carry = 0;
- break;
- }
- } else {
- uint8_t op0;
- uint8_t op1;
- uint8_t data8;
- int reg;
- int operator;
-#ifdef DEBUG_LSI
- static const char *opcode_names[3] =
- {"Write", "Read", "Read-Modify-Write"};
- static const char *operator_names[8] =
- {"MOV", "SHL", "OR", "XOR", "AND", "SHR", "ADD", "ADC"};
-#endif
-
- reg = ((insn >> 16) & 0x7f) | (insn & 0x80);
- data8 = (insn >> 8) & 0xff;
- opcode = (insn >> 27) & 7;
- operator = (insn >> 24) & 7;
- DPRINTF("%s reg 0x%x %s data8=0x%02x sfbr=0x%02x%s\n",
- opcode_names[opcode - 5], reg,
- operator_names[operator], data8, s->sfbr,
- (insn & (1 << 23)) ? " SFBR" : "");
- op0 = op1 = 0;
- switch (opcode) {
- case 5: /* From SFBR */
- op0 = s->sfbr;
- op1 = data8;
- break;
- case 6: /* To SFBR */
- if (operator)
- op0 = lsi_reg_readb(s, reg);
- op1 = data8;
- break;
- case 7: /* Read-modify-write */
- if (operator)
- op0 = lsi_reg_readb(s, reg);
- if (insn & (1 << 23)) {
- op1 = s->sfbr;
- } else {
- op1 = data8;
- }
- break;
- }
-
- switch (operator) {
- case 0: /* move */
- op0 = op1;
- break;
- case 1: /* Shift left */
- op1 = op0 >> 7;
- op0 = (op0 << 1) | s->carry;
- s->carry = op1;
- break;
- case 2: /* OR */
- op0 |= op1;
- break;
- case 3: /* XOR */
- op0 |= op1;
- break;
- case 4: /* AND */
- op0 &= op1;
- break;
- case 5: /* SHR */
- op1 = op0 & 1;
- op0 = (op0 >> 1) | (s->carry << 7);
- break;
- case 6: /* ADD */
- op0 += op1;
- s->carry = op0 < op1;
- break;
- case 7: /* ADC */
- op0 += op1 + s->carry;
- if (s->carry)
- s->carry = op0 <= op1;
- else
- s->carry = op0 < op1;
- break;
- }
-
- switch (opcode) {
- case 5: /* From SFBR */
- case 7: /* Read-modify-write */
- lsi_reg_writeb(s, reg, op0);
- break;
- case 6: /* To SFBR */
- s->sfbr = op0;
- break;
- }
- }
- break;
-
- case 2: /* Transfer Control. */
- {
- int cond;
- int jmp;
-
- if ((insn & 0x002e0000) == 0) {
- DPRINTF("NOP\n");
- break;
- }
- if (s->sist1 & LSI_SIST1_STO) {
- DPRINTF("Delayed select timeout\n");
- lsi_stop_script(s);
- break;
- }
- cond = jmp = (insn & (1 << 19)) != 0;
- if (cond == jmp && (insn & (1 << 21))) {
- DPRINTF("Compare carry %d\n", s->carry == jmp);
- cond = s->carry != 0;
- }
- if (cond == jmp && (insn & (1 << 17))) {
- DPRINTF("Compare phase %d %c= %d\n",
- (s->sstat1 & PHASE_MASK),
- jmp ? '=' : '!',
- ((insn >> 24) & 7));
- cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
- }
- if (cond == jmp && (insn & (1 << 18))) {
- uint8_t mask;
-
- mask = (~insn >> 8) & 0xff;
- DPRINTF("Compare data 0x%x & 0x%x %c= 0x%x\n",
- s->sfbr, mask, jmp ? '=' : '!', insn & mask);
- cond = (s->sfbr & mask) == (insn & mask);
- }
- if (cond == jmp) {
- if (insn & (1 << 23)) {
- /* Relative address. */
- addr = s->dsp + sxt24(addr);
- }
- switch ((insn >> 27) & 7) {
- case 0: /* Jump */
- DPRINTF("Jump to 0x%08x\n", addr);
- s->dsp = addr;
- break;
- case 1: /* Call */
- DPRINTF("Call 0x%08x\n", addr);
- s->temp = s->dsp;
- s->dsp = addr;
- break;
- case 2: /* Return */
- DPRINTF("Return to 0x%08x\n", s->temp);
- s->dsp = s->temp;
- break;
- case 3: /* Interrupt */
- DPRINTF("Interrupt 0x%08x\n", s->dsps);
- if ((insn & (1 << 20)) != 0) {
- s->istat0 |= LSI_ISTAT0_INTF;
- lsi_update_irq(s);
- } else {
- lsi_script_dma_interrupt(s, LSI_DSTAT_SIR);
- }
- break;
- default:
- DPRINTF("Illegal transfer control\n");
- lsi_script_dma_interrupt(s, LSI_DSTAT_IID);
- break;
- }
- } else {
- DPRINTF("Control condition failed\n");
- }
- }
- break;
-
- case 3:
- if ((insn & (1 << 29)) == 0) {
- /* Memory move. */
- uint32_t dest;
- /* ??? The docs imply the destination address is loaded into
- the TEMP register. However the Linux drivers rely on
- the value being presrved. */
- dest = read_dword(s, s->dsp);
- s->dsp += 4;
- lsi_memcpy(s, dest, addr, insn & 0xffffff);
- } else {
- uint8_t data[7];
- int reg;
- int n;
- int i;
-
- if (insn & (1 << 28)) {
- addr = s->dsa + sxt24(addr);
- }
- n = (insn & 7);
- reg = (insn >> 16) & 0xff;
- if (insn & (1 << 24)) {
- cpu_physical_memory_read(addr, data, n);
- DPRINTF("Load reg 0x%x size %d addr 0x%08x = %08x\n", reg, n,
- addr, *(int *)data);
- for (i = 0; i < n; i++) {
- lsi_reg_writeb(s, reg + i, data[i]);
- }
- } else {
- DPRINTF("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr);
- for (i = 0; i < n; i++) {
- data[i] = lsi_reg_readb(s, reg + i);
- }
- cpu_physical_memory_write(addr, data, n);
- }
- }
- }
- /* ??? Need to avoid infinite loops. */
- if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
- if (s->dcntl & LSI_DCNTL_SSM) {
- lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
- } else {
- goto again;
- }
- }
- DPRINTF("SCRIPTS execution stopped\n");
-}
-
-static uint8_t lsi_reg_readb(LSIState *s, int offset)
-{
- uint8_t tmp;
-#define CASE_GET_REG32(name, addr) \
- case addr: return s->name & 0xff; \
- case addr + 1: return (s->name >> 8) & 0xff; \
- case addr + 2: return (s->name >> 16) & 0xff; \
- case addr + 3: return (s->name >> 24) & 0xff;
-
-#ifdef DEBUG_LSI_REG
- DPRINTF("Read reg %x\n", offset);
-#endif
- switch (offset) {
- case 0x00: /* SCNTL0 */
- return s->scntl0;
- case 0x01: /* SCNTL1 */
- return s->scntl1;
- case 0x02: /* SCNTL2 */
- return s->scntl2;
- case 0x03: /* SCNTL3 */
- return s->scntl3;
- case 0x04: /* SCID */
- return s->scid;
- case 0x05: /* SXFER */
- return s->sxfer;
- case 0x06: /* SDID */
- return s->sdid;
- case 0x07: /* GPREG0 */
- return 0x7f;
- case 0xa: /* SSID */
- return s->ssid;
- case 0xb: /* SBCL */
- /* ??? This is not correct. However it's (hopefully) only
- used for diagnostics, so should be ok. */
- return 0;
- case 0xc: /* DSTAT */
- tmp = s->dstat | 0x80;
- if ((s->istat0 & LSI_ISTAT0_INTF) == 0)
- s->dstat = 0;
- lsi_update_irq(s);
- return tmp;
- case 0x0d: /* SSTAT0 */
- return s->sstat0;
- case 0x0e: /* SSTAT1 */
- return s->sstat1;
- case 0x0f: /* SSTAT2 */
- return s->scntl1 & LSI_SCNTL1_CON ? 0 : 2;
- CASE_GET_REG32(dsa, 0x10)
- case 0x14: /* ISTAT0 */
- return s->istat0;
- case 0x16: /* MBOX0 */
- return s->mbox0;
- case 0x17: /* MBOX1 */
- return s->mbox1;
- case 0x18: /* CTEST0 */
- return 0xff;
- case 0x19: /* CTEST1 */
- return 0;
- case 0x1a: /* CTEST2 */
- tmp = LSI_CTEST2_DACK | LSI_CTEST2_CM;
- if (s->istat0 & LSI_ISTAT0_SIGP) {
- s->istat0 &= ~LSI_ISTAT0_SIGP;
- tmp |= LSI_CTEST2_SIGP;
- }
- return tmp;
- case 0x1b: /* CTEST3 */
- return s->ctest3;
- CASE_GET_REG32(temp, 0x1c)
- case 0x20: /* DFIFO */
- return 0;
- case 0x21: /* CTEST4 */
- return s->ctest4;
- case 0x22: /* CTEST5 */
- return s->ctest5;
- case 0x24: /* DBC[0:7] */
- return s->dbc & 0xff;
- case 0x25: /* DBC[8:15] */
- return (s->dbc >> 8) & 0xff;
- case 0x26: /* DBC[16->23] */
- return (s->dbc >> 16) & 0xff;
- case 0x27: /* DCMD */
- return s->dcmd;
- CASE_GET_REG32(dsp, 0x2c)
- CASE_GET_REG32(dsps, 0x30)
- CASE_GET_REG32(scratch[0], 0x34)
- case 0x38: /* DMODE */
- return s->dmode;
- case 0x39: /* DIEN */
- return s->dien;
- case 0x3b: /* DCNTL */
- return s->dcntl;
- case 0x40: /* SIEN0 */
- return s->sien0;
- case 0x41: /* SIEN1 */
- return s->sien1;
- case 0x42: /* SIST0 */
- tmp = s->sist0;
- s->sist0 = 0;
- lsi_update_irq(s);
- return tmp;
- case 0x43: /* SIST1 */
- tmp = s->sist1;
- s->sist1 = 0;
- lsi_update_irq(s);
- return tmp;
- case 0x47: /* GPCNTL0 */
- return 0x0f;
- case 0x48: /* STIME0 */
- return s->stime0;
- case 0x4a: /* RESPID0 */
- return s->respid0;
- case 0x4b: /* RESPID1 */
- return s->respid1;
- case 0x4d: /* STEST1 */
- return s->stest1;
- case 0x4e: /* STEST2 */
- return s->stest2;
- case 0x4f: /* STEST3 */
- return s->stest3;
- case 0x50: /* SIDL */
- /* This is needed by the linux drivers. We currently only update it
- during the MSG IN phase. */
- return s->sidl;
- case 0x52: /* STEST4 */
- return 0xe0;
- case 0x56: /* CCNTL0 */
- return s->ccntl0;
- case 0x57: /* CCNTL1 */
- return s->ccntl1;
- case 0x58: /* SBDL */
- /* Some drivers peek at the data bus during the MSG IN phase. */
- if ((s->sstat1 & PHASE_MASK) == PHASE_MI)
- return s->msg[0];
- return 0;
- case 0x59: /* SBDL high */
- return 0;
- CASE_GET_REG32(mmrs, 0xa0)
- CASE_GET_REG32(mmws, 0xa4)
- CASE_GET_REG32(sfs, 0xa8)
- CASE_GET_REG32(drs, 0xac)
- CASE_GET_REG32(sbms, 0xb0)
- CASE_GET_REG32(dmbs, 0xb4)
- CASE_GET_REG32(dnad64, 0xb8)
- CASE_GET_REG32(pmjad1, 0xc0)
- CASE_GET_REG32(pmjad2, 0xc4)
- CASE_GET_REG32(rbc, 0xc8)
- CASE_GET_REG32(ua, 0xcc)
- CASE_GET_REG32(ia, 0xd4)
- CASE_GET_REG32(sbc, 0xd8)
- CASE_GET_REG32(csbc, 0xdc)
- }
- if (offset >= 0x5c && offset < 0xa0) {
- int n;
- int shift;
- n = (offset - 0x58) >> 2;
- shift = (offset & 3) * 8;
- return (s->scratch[n] >> shift) & 0xff;
- }
-#ifndef CONFIG_DM
- BADF("readb 0x%x\n", offset);
- exit(1);
-#else
- /* XEN: This path can be triggered (e.g. ASPI8DOS.SYS reads 0x8). */
- return 0;
-#endif
-#undef CASE_GET_REG32
-}
-
-static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
-{
-#define CASE_SET_REG32(name, addr) \
- case addr : s->name &= 0xffffff00; s->name |= val; break; \
- case addr + 1: s->name &= 0xffff00ff; s->name |= val << 8; break; \
- case addr + 2: s->name &= 0xff00ffff; s->name |= val << 16; break; \
- case addr + 3: s->name &= 0x00ffffff; s->name |= val << 24; break;
-
-#ifdef DEBUG_LSI_REG
- DPRINTF("Write reg %x = %02x\n", offset, val);
-#endif
- switch (offset) {
- case 0x00: /* SCNTL0 */
- s->scntl0 = val;
- if (val & LSI_SCNTL0_START) {
- BADF("Start sequence not implemented\n");
- }
- break;
- case 0x01: /* SCNTL1 */
- s->scntl1 = val & ~LSI_SCNTL1_SST;
- if (val & LSI_SCNTL1_IARB) {
- BADF("Immediate Arbritration not implemented\n");
- }
- if (val & LSI_SCNTL1_RST) {
- s->sstat0 |= LSI_SSTAT0_RST;
- lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);
- } else {
- s->sstat0 &= ~LSI_SSTAT0_RST;
- }
- break;
- case 0x02: /* SCNTL2 */
- val &= ~(LSI_SCNTL2_WSR | LSI_SCNTL2_WSS);
- s->scntl3 = val;
- break;
- case 0x03: /* SCNTL3 */
- s->scntl3 = val;
- break;
- case 0x04: /* SCID */
- s->scid = val;
- break;
- case 0x05: /* SXFER */
- s->sxfer = val;
- break;
- case 0x06: /* SDID */
- if ((val & 0xf) != (s->ssid & 0xf))
- BADF("Destination ID does not match SSID\n");
- s->sdid = val & 0xf;
- break;
- case 0x07: /* GPREG0 */
- break;
- case 0x08: /* SFBR */
- /* The CPU is not allowed to write to this register. However the
- SCRIPTS register move instructions are. */
- s->sfbr = val;
- break;
- case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- /* Linux writes to these readonly registers on startup. */
- return;
- CASE_SET_REG32(dsa, 0x10)
- case 0x14: /* ISTAT0 */
- s->istat0 = (s->istat0 & 0x0f) | (val & 0xf0);
- if (val & LSI_ISTAT0_ABRT) {
- lsi_script_dma_interrupt(s, LSI_DSTAT_ABRT);
- }
- if (val & LSI_ISTAT0_INTF) {
- s->istat0 &= ~LSI_ISTAT0_INTF;
- lsi_update_irq(s);
- }
- if (s->waiting == 1 && val & LSI_ISTAT0_SIGP) {
- DPRINTF("Woken by SIGP\n");
- s->waiting = 0;
- s->dsp = s->dnad;
- lsi_execute_script(s);
- }
- if (val & LSI_ISTAT0_SRST) {
- lsi_soft_reset(s);
- }
- case 0x16: /* MBOX0 */
- s->mbox0 = val;
- case 0x17: /* MBOX1 */
- s->mbox1 = val;
- case 0x1b: /* CTEST3 */
- s->ctest3 = val & 0x0f;
- break;
- CASE_SET_REG32(temp, 0x1c)
- case 0x21: /* CTEST4 */
- if (val & 7) {
- BADF("Unimplemented CTEST4-FBL 0x%x\n", val);
- }
- s->ctest4 = val;
- break;
- case 0x22: /* CTEST5 */
- if (val & (LSI_CTEST5_ADCK | LSI_CTEST5_BBCK)) {
- BADF("CTEST5 DMA increment not implemented\n");
- }
- s->ctest5 = val;
- break;
- case 0x2c: /* DSPS[0:7] */
- s->dsp &= 0xffffff00;
- s->dsp |= val;
- break;
- case 0x2d: /* DSPS[8:15] */
- s->dsp &= 0xffff00ff;
- s->dsp |= val << 8;
- break;
- case 0x2e: /* DSPS[16:23] */
- s->dsp &= 0xff00ffff;
- s->dsp |= val << 16;
- break;
- case 0x2f: /* DSPS[14:31] */
- s->dsp &= 0x00ffffff;
- s->dsp |= val << 24;
- if ((s->dmode & LSI_DMODE_MAN) == 0
- && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
- lsi_execute_script(s);
- break;
- CASE_SET_REG32(dsps, 0x30)
- CASE_SET_REG32(scratch[0], 0x34)
- case 0x38: /* DMODE */
- if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) {
- BADF("IO mappings not implemented\n");
- }
- s->dmode = val;
- break;
- case 0x39: /* DIEN */
- s->dien = val;
- lsi_update_irq(s);
- break;
- case 0x3b: /* DCNTL */
- s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);
- if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
- lsi_execute_script(s);
- break;
- case 0x40: /* SIEN0 */
- s->sien0 = val;
- lsi_update_irq(s);
- break;
- case 0x41: /* SIEN1 */
- s->sien1 = val;
- lsi_update_irq(s);
- break;
- case 0x47: /* GPCNTL0 */
- break;
- case 0x48: /* STIME0 */
- s->stime0 = val;
- break;
- case 0x49: /* STIME1 */
- if (val & 0xf) {
- DPRINTF("General purpose timer not implemented\n");
- /* ??? Raising the interrupt immediately seems to be sufficient
- to keep the FreeBSD driver happy. */
- lsi_script_scsi_interrupt(s, 0, LSI_SIST1_GEN);
- }
- break;
- case 0x4a: /* RESPID0 */
- s->respid0 = val;
- break;
- case 0x4b: /* RESPID1 */
- s->respid1 = val;
- break;
- case 0x4d: /* STEST1 */
- s->stest1 = val;
- break;
- case 0x4e: /* STEST2 */
- if (val & 1) {
- BADF("Low level mode not implemented\n");
- }
- s->stest2 = val;
- break;
- case 0x4f: /* STEST3 */
- if (val & 0x41) {
- BADF("SCSI FIFO test mode not implemented\n");
- }
- s->stest3 = val;
- break;
- case 0x56: /* CCNTL0 */
- s->ccntl0 = val;
- break;
- case 0x57: /* CCNTL1 */
- s->ccntl1 = val;
- break;
- CASE_SET_REG32(mmrs, 0xa0)
- CASE_SET_REG32(mmws, 0xa4)
- CASE_SET_REG32(sfs, 0xa8)
- CASE_SET_REG32(drs, 0xac)
- CASE_SET_REG32(sbms, 0xb0)
- CASE_SET_REG32(dmbs, 0xb4)
- CASE_SET_REG32(dnad64, 0xb8)
- CASE_SET_REG32(pmjad1, 0xc0)
- CASE_SET_REG32(pmjad2, 0xc4)
- CASE_SET_REG32(rbc, 0xc8)
- CASE_SET_REG32(ua, 0xcc)
- CASE_SET_REG32(ia, 0xd4)
- CASE_SET_REG32(sbc, 0xd8)
- CASE_SET_REG32(csbc, 0xdc)
- default:
- if (offset >= 0x5c && offset < 0xa0) {
- int n;
- int shift;
- n = (offset - 0x58) >> 2;
- shift = (offset & 3) * 8;
- s->scratch[n] &= ~(0xff << shift);
- s->scratch[n] |= (val & 0xff) << shift;
- } else {
- BADF("Unhandled writeb 0x%x = 0x%x\n", offset, val);
- }
- }
-#undef CASE_SET_REG32
-}
-
-static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
-
- lsi_reg_writeb(s, addr & 0xff, val);
-}
-
-static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
-
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
-
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
- lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
- lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = (LSIState *)opaque;
-
- return lsi_reg_readb(s, addr & 0xff);
-}
-
-static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t val;
-
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- return val;
-}
-
-static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t val;
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- val |= lsi_reg_readb(s, addr + 2) << 16;
- val |= lsi_reg_readb(s, addr + 3) << 24;
- return val;
-}
-
-static CPUReadMemoryFunc *lsi_mmio_readfn[3] = {
- lsi_mmio_readb,
- lsi_mmio_readw,
- lsi_mmio_readl,
-};
-
-static CPUWriteMemoryFunc *lsi_mmio_writefn[3] = {
- lsi_mmio_writeb,
- lsi_mmio_writew,
- lsi_mmio_writel,
-};
-
-static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t newval;
- int shift;
-
- addr &= 0x1fff;
- newval = s->script_ram[addr >> 2];
- shift = (addr & 3) * 8;
- newval &= ~(0xff << shift);
- newval |= val << shift;
- s->script_ram[addr >> 2] = newval;
-}
-
-static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t newval;
-
- addr &= 0x1fff;
- newval = s->script_ram[addr >> 2];
- if (addr & 2) {
- newval = (newval & 0xffff) | (val << 16);
- } else {
- newval = (newval & 0xffff0000) | val;
- }
- s->script_ram[addr >> 2] = newval;
-}
-
-
-static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
-
- addr &= 0x1fff;
- s->script_ram[addr >> 2] = val;
-}
-
-static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t val;
-
- addr &= 0x1fff;
- val = s->script_ram[addr >> 2];
- val >>= (addr & 3) * 8;
- return val & 0xff;
-}
-
-static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t val;
-
- addr &= 0x1fff;
- val = s->script_ram[addr >> 2];
- if (addr & 2)
- val >>= 16;
- return le16_to_cpu(val);
-}
-
-static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = (LSIState *)opaque;
-
- addr &= 0x1fff;
- return le32_to_cpu(s->script_ram[addr >> 2]);
-}
-
-static CPUReadMemoryFunc *lsi_ram_readfn[3] = {
- lsi_ram_readb,
- lsi_ram_readw,
- lsi_ram_readl,
-};
-
-static CPUWriteMemoryFunc *lsi_ram_writefn[3] = {
- lsi_ram_writeb,
- lsi_ram_writew,
- lsi_ram_writel,
-};
-
-static uint32_t lsi_io_readb(void *opaque, uint32_t addr)
-{
- LSIState *s = (LSIState *)opaque;
- return lsi_reg_readb(s, addr & 0xff);
-}
-
-static uint32_t lsi_io_readw(void *opaque, uint32_t addr)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t val;
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- return val;
-}
-
-static uint32_t lsi_io_readl(void *opaque, uint32_t addr)
-{
- LSIState *s = (LSIState *)opaque;
- uint32_t val;
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- val |= lsi_reg_readb(s, addr + 2) << 16;
- val |= lsi_reg_readb(s, addr + 3) << 24;
- return val;
-}
-
-static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
- lsi_reg_writeb(s, addr & 0xff, val);
-}
-
-static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- LSIState *s = (LSIState *)opaque;
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
- lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
- lsi_reg_writeb(s, addr + 2, (val >> 24) & 0xff);
-}
-
-static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- LSIState *s = (LSIState *)pci_dev;
-
- DPRINTF("Mapping IO at %08x\n", addr);
-
- register_ioport_write(addr, 256, 1, lsi_io_writeb, s);
- register_ioport_read(addr, 256, 1, lsi_io_readb, s);
- register_ioport_write(addr, 256, 2, lsi_io_writew, s);
- register_ioport_read(addr, 256, 2, lsi_io_readw, s);
- register_ioport_write(addr, 256, 4, lsi_io_writel, s);
- register_ioport_read(addr, 256, 4, lsi_io_readl, s);
-}
-
-static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- LSIState *s = (LSIState *)pci_dev;
-
- DPRINTF("Mapping ram at %08x\n", addr);
- s->script_ram_base = addr;
- cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);
-}
-
-static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- LSIState *s = (LSIState *)pci_dev;
-
- DPRINTF("Mapping registers at %08x\n", addr);
- cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr);
-}
-
-void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id)
-{
- LSIState *s = (LSIState *)opaque;
-
- if (id < 0) {
- for (id = 0; id < LSI_MAX_DEVS; id++) {
- if (s->scsi_dev[id] == NULL)
- break;
- }
- }
- if (id >= LSI_MAX_DEVS) {
- BADF("Bad Device ID %d\n", id);
- return;
- }
- if (s->scsi_dev[id]) {
- DPRINTF("Destroying device %d\n", id);
- scsi_disk_destroy(s->scsi_dev[id]);
- }
- DPRINTF("Attaching block device %d\n", id);
- s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);
-}
-
-void *lsi_scsi_init(PCIBus *bus, int devfn)
-{
- LSIState *s;
-
- s = (LSIState *)pci_register_device(bus, "LSI53C895A SCSI HBA",
- sizeof(*s), devfn, NULL, NULL);
- if (s == NULL) {
- fprintf(stderr, "lsi-scsi: Failed to register PCI device\n");
- return NULL;
- }
-
- s->pci_dev.config[0x00] = 0x00;
- s->pci_dev.config[0x01] = 0x10;
- s->pci_dev.config[0x02] = 0x12;
- s->pci_dev.config[0x03] = 0x00;
- s->pci_dev.config[0x0b] = 0x01;
- s->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
-
- s->mmio_io_addr = cpu_register_io_memory(0, lsi_mmio_readfn,
- lsi_mmio_writefn, s);
- s->ram_io_addr = cpu_register_io_memory(0, lsi_ram_readfn,
- lsi_ram_writefn, s);
-
- pci_register_io_region((struct PCIDevice *)s, 0, 256,
- PCI_ADDRESS_SPACE_IO, lsi_io_mapfunc);
- pci_register_io_region((struct PCIDevice *)s, 1, 0x400,
- PCI_ADDRESS_SPACE_MEM, lsi_mmio_mapfunc);
- pci_register_io_region((struct PCIDevice *)s, 2, 0x2000,
- PCI_ADDRESS_SPACE_MEM, lsi_ram_mapfunc);
- s->queue = qemu_malloc(sizeof(lsi_queue));
- s->queue_len = 1;
- s->active_commands = 0;
-
- lsi_soft_reset(s);
-
- return s;
-}
-
diff --git a/tools/ioemu/hw/m48t59.c b/tools/ioemu/hw/m48t59.c
deleted file mode 100644
index daa1c524db..0000000000
--- a/tools/ioemu/hw/m48t59.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
- *
- * Copyright (c) 2003-2005 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "m48t59.h"
-
-//#define DEBUG_NVRAM
-
-#if defined(DEBUG_NVRAM)
-#define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
-#else
-#define NVRAM_PRINTF(fmt, args...) do { } while (0)
-#endif
-
-/*
- * The M48T08 and M48T59 chips are very similar. The newer '59 has
- * alarm and a watchdog timer and related control registers. In the
- * PPC platform there is also a nvram lock function.
- */
-struct m48t59_t {
- /* Model parameters */
- int type; // 8 = m48t08, 59 = m48t59
- /* Hardware parameters */
- int IRQ;
- int mem_index;
- uint32_t mem_base;
- uint32_t io_base;
- uint16_t size;
- /* RTC management */
- time_t time_offset;
- time_t stop_time;
- /* Alarm & watchdog */
- time_t alarm;
- struct QEMUTimer *alrm_timer;
- struct QEMUTimer *wd_timer;
- /* NVRAM storage */
- uint8_t lock;
- uint16_t addr;
- uint8_t *buffer;
-};
-
-/* Fake timer functions */
-/* Generic helpers for BCD */
-static inline uint8_t toBCD (uint8_t value)
-{
- return (((value / 10) % 10) << 4) | (value % 10);
-}
-
-static inline uint8_t fromBCD (uint8_t BCD)
-{
- return ((BCD >> 4) * 10) + (BCD & 0x0F);
-}
-
-/* RTC management helpers */
-static void get_time (m48t59_t *NVRAM, struct tm *tm)
-{
- time_t t;
-
- t = time(NULL) + NVRAM->time_offset;
-#ifdef _WIN32
- memcpy(tm,localtime(&t),sizeof(*tm));
-#else
- localtime_r (&t, tm) ;
-#endif
-}
-
-static void set_time (m48t59_t *NVRAM, struct tm *tm)
-{
- time_t now, new_time;
-
- new_time = mktime(tm);
- now = time(NULL);
- NVRAM->time_offset = new_time - now;
-}
-
-/* Alarm management */
-static void alarm_cb (void *opaque)
-{
- struct tm tm, tm_now;
- uint64_t next_time;
- m48t59_t *NVRAM = opaque;
-
- pic_set_irq(NVRAM->IRQ, 1);
- if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a month */
- get_time(NVRAM, &tm_now);
- memcpy(&tm, &tm_now, sizeof(struct tm));
- tm.tm_mon++;
- if (tm.tm_mon == 13) {
- tm.tm_mon = 1;
- tm.tm_year++;
- }
- next_time = mktime(&tm);
- } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a day */
- next_time = 24 * 60 * 60 + mktime(&tm_now);
- } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once an hour */
- next_time = 60 * 60 + mktime(&tm_now);
- } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a minute */
- next_time = 60 + mktime(&tm_now);
- } else {
- /* Repeat once a second */
- next_time = 1 + mktime(&tm_now);
- }
- qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
- pic_set_irq(NVRAM->IRQ, 0);
-}
-
-
-static void get_alarm (m48t59_t *NVRAM, struct tm *tm)
-{
-#ifdef _WIN32
- memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));
-#else
- localtime_r (&NVRAM->alarm, tm);
-#endif
-}
-
-static void set_alarm (m48t59_t *NVRAM, struct tm *tm)
-{
- NVRAM->alarm = mktime(tm);
- if (NVRAM->alrm_timer != NULL) {
- qemu_del_timer(NVRAM->alrm_timer);
- NVRAM->alrm_timer = NULL;
- }
- if (NVRAM->alarm - time(NULL) > 0)
- qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
-}
-
-/* Watchdog management */
-static void watchdog_cb (void *opaque)
-{
- m48t59_t *NVRAM = opaque;
-
- NVRAM->buffer[0x1FF0] |= 0x80;
- if (NVRAM->buffer[0x1FF7] & 0x80) {
- NVRAM->buffer[0x1FF7] = 0x00;
- NVRAM->buffer[0x1FFC] &= ~0x40;
- /* May it be a hw CPU Reset instead ? */
- qemu_system_reset_request();
- } else {
- pic_set_irq(NVRAM->IRQ, 1);
- pic_set_irq(NVRAM->IRQ, 0);
- }
-}
-
-static void set_up_watchdog (m48t59_t *NVRAM, uint8_t value)
-{
- uint64_t interval; /* in 1/16 seconds */
-
- if (NVRAM->wd_timer != NULL) {
- qemu_del_timer(NVRAM->wd_timer);
- NVRAM->wd_timer = NULL;
- }
- NVRAM->buffer[0x1FF0] &= ~0x80;
- if (value != 0) {
- interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
- qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
- ((interval * 1000) >> 4));
- }
-}
-
-/* Direct access to NVRAM */
-void m48t59_write (m48t59_t *NVRAM, uint32_t addr, uint32_t val)
-{
- struct tm tm;
- int tmp;
-
- if (addr > 0x1FF8 && addr < 0x2000)
- NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
- if (NVRAM->type == 8 &&
- (addr >= 0x1ff0 && addr <= 0x1ff7))
- goto do_write;
- switch (addr) {
- case 0x1FF0:
- /* flags register : read-only */
- break;
- case 0x1FF1:
- /* unused */
- break;
- case 0x1FF2:
- /* alarm seconds */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_alarm(NVRAM, &tm);
- tm.tm_sec = tmp;
- NVRAM->buffer[0x1FF2] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF3:
- /* alarm minutes */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_alarm(NVRAM, &tm);
- tm.tm_min = tmp;
- NVRAM->buffer[0x1FF3] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF4:
- /* alarm hours */
- tmp = fromBCD(val & 0x3F);
- if (tmp >= 0 && tmp <= 23) {
- get_alarm(NVRAM, &tm);
- tm.tm_hour = tmp;
- NVRAM->buffer[0x1FF4] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF5:
- /* alarm date */
- tmp = fromBCD(val & 0x1F);
- if (tmp != 0) {
- get_alarm(NVRAM, &tm);
- tm.tm_mday = tmp;
- NVRAM->buffer[0x1FF5] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF6:
- /* interrupts */
- NVRAM->buffer[0x1FF6] = val;
- break;
- case 0x1FF7:
- /* watchdog */
- NVRAM->buffer[0x1FF7] = val;
- set_up_watchdog(NVRAM, val);
- break;
- case 0x1FF8:
- /* control */
- NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
- break;
- case 0x1FF9:
- /* seconds (BCD) */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_time(NVRAM, &tm);
- tm.tm_sec = tmp;
- set_time(NVRAM, &tm);
- }
- if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
- if (val & 0x80) {
- NVRAM->stop_time = time(NULL);
- } else {
- NVRAM->time_offset += NVRAM->stop_time - time(NULL);
- NVRAM->stop_time = 0;
- }
- }
- NVRAM->buffer[0x1FF9] = val & 0x80;
- break;
- case 0x1FFA:
- /* minutes (BCD) */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_time(NVRAM, &tm);
- tm.tm_min = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFB:
- /* hours (BCD) */
- tmp = fromBCD(val & 0x3F);
- if (tmp >= 0 && tmp <= 23) {
- get_time(NVRAM, &tm);
- tm.tm_hour = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFC:
- /* day of the week / century */
- tmp = fromBCD(val & 0x07);
- get_time(NVRAM, &tm);
- tm.tm_wday = tmp;
- set_time(NVRAM, &tm);
- NVRAM->buffer[0x1FFC] = val & 0x40;
- break;
- case 0x1FFD:
- /* date */
- tmp = fromBCD(val & 0x1F);
- if (tmp != 0) {
- get_time(NVRAM, &tm);
- tm.tm_mday = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFE:
- /* month */
- tmp = fromBCD(val & 0x1F);
- if (tmp >= 1 && tmp <= 12) {
- get_time(NVRAM, &tm);
- tm.tm_mon = tmp - 1;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFF:
- /* year */
- tmp = fromBCD(val);
- if (tmp >= 0 && tmp <= 99) {
- get_time(NVRAM, &tm);
- if (NVRAM->type == 8)
- tm.tm_year = fromBCD(val) + 68; // Base year is 1968
- else
- tm.tm_year = fromBCD(val);
- set_time(NVRAM, &tm);
- }
- break;
- default:
- /* Check lock registers state */
- if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
- break;
- if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
- break;
- do_write:
- if (addr < NVRAM->size) {
- NVRAM->buffer[addr] = val & 0xFF;
- }
- break;
- }
-}
-
-uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr)
-{
- struct tm tm;
- uint32_t retval = 0xFF;
-
- if (NVRAM->type == 8 &&
- (addr >= 0x1ff0 && addr <= 0x1ff7))
- goto do_read;
- switch (addr) {
- case 0x1FF0:
- /* flags register */
- goto do_read;
- case 0x1FF1:
- /* unused */
- retval = 0;
- break;
- case 0x1FF2:
- /* alarm seconds */
- goto do_read;
- case 0x1FF3:
- /* alarm minutes */
- goto do_read;
- case 0x1FF4:
- /* alarm hours */
- goto do_read;
- case 0x1FF5:
- /* alarm date */
- goto do_read;
- case 0x1FF6:
- /* interrupts */
- goto do_read;
- case 0x1FF7:
- /* A read resets the watchdog */
- set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
- goto do_read;
- case 0x1FF8:
- /* control */
- goto do_read;
- case 0x1FF9:
- /* seconds (BCD) */
- get_time(NVRAM, &tm);
- retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
- break;
- case 0x1FFA:
- /* minutes (BCD) */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_min);
- break;
- case 0x1FFB:
- /* hours (BCD) */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_hour);
- break;
- case 0x1FFC:
- /* day of the week / century */
- get_time(NVRAM, &tm);
- retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
- break;
- case 0x1FFD:
- /* date */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mday);
- break;
- case 0x1FFE:
- /* month */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mon + 1);
- break;
- case 0x1FFF:
- /* year */
- get_time(NVRAM, &tm);
- if (NVRAM->type == 8)
- retval = toBCD(tm.tm_year - 68); // Base year is 1968
- else
- retval = toBCD(tm.tm_year);
- break;
- default:
- /* Check lock registers state */
- if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
- break;
- if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
- break;
- do_read:
- if (addr < NVRAM->size) {
- retval = NVRAM->buffer[addr];
- }
- break;
- }
- if (addr > 0x1FF9 && addr < 0x2000)
- NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval);
-
- return retval;
-}
-
-void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr)
-{
- NVRAM->addr = addr;
-}
-
-void m48t59_toggle_lock (m48t59_t *NVRAM, int lock)
-{
- NVRAM->lock ^= 1 << lock;
-}
-
-/* IO access to NVRAM */
-static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->io_base;
- NVRAM_PRINTF("0x%08x => 0x%08x\n", addr, val);
- switch (addr) {
- case 0:
- NVRAM->addr &= ~0x00FF;
- NVRAM->addr |= val;
- break;
- case 1:
- NVRAM->addr &= ~0xFF00;
- NVRAM->addr |= val << 8;
- break;
- case 3:
- m48t59_write(NVRAM, val, NVRAM->addr);
- NVRAM->addr = 0x0000;
- break;
- default:
- break;
- }
-}
-
-static uint32_t NVRAM_readb (void *opaque, uint32_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval;
-
- addr -= NVRAM->io_base;
- switch (addr) {
- case 3:
- retval = m48t59_read(NVRAM, NVRAM->addr);
- break;
- default:
- retval = -1;
- break;
- }
- NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval);
-
- return retval;
-}
-
-static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- m48t59_write(NVRAM, addr, value & 0xff);
-}
-
-static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
- m48t59_write(NVRAM, addr + 1, value & 0xff);
-}
-
-static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
- m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
- m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);
- m48t59_write(NVRAM, addr + 3, value & 0xff);
-}
-
-static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval;
-
- addr -= NVRAM->mem_base;
- retval = m48t59_read(NVRAM, addr);
- return retval;
-}
-
-static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval;
-
- addr -= NVRAM->mem_base;
- retval = m48t59_read(NVRAM, addr) << 8;
- retval |= m48t59_read(NVRAM, addr + 1);
- return retval;
-}
-
-static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval;
-
- addr -= NVRAM->mem_base;
- retval = m48t59_read(NVRAM, addr) << 24;
- retval |= m48t59_read(NVRAM, addr + 1) << 16;
- retval |= m48t59_read(NVRAM, addr + 2) << 8;
- retval |= m48t59_read(NVRAM, addr + 3);
- return retval;
-}
-
-static CPUWriteMemoryFunc *nvram_write[] = {
- &nvram_writeb,
- &nvram_writew,
- &nvram_writel,
-};
-
-static CPUReadMemoryFunc *nvram_read[] = {
- &nvram_readb,
- &nvram_readw,
- &nvram_readl,
-};
-
-/* Initialisation routine */
-m48t59_t *m48t59_init (int IRQ, target_ulong mem_base,
- uint32_t io_base, uint16_t size,
- int type)
-{
- m48t59_t *s;
-
- s = qemu_mallocz(sizeof(m48t59_t));
- if (!s)
- return NULL;
- s->buffer = qemu_mallocz(size);
- if (!s->buffer) {
- qemu_free(s);
- return NULL;
- }
- s->IRQ = IRQ;
- s->size = size;
- s->mem_base = mem_base;
- s->io_base = io_base;
- s->addr = 0;
- s->type = type;
- if (io_base != 0) {
- register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);
- register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
- }
- if (mem_base != 0) {
- s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
- cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
- }
- if (type == 59) {
- s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);
- s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
- }
- s->lock = 0;
-
- return s;
-}
diff --git a/tools/ioemu/hw/m48t59.h b/tools/ioemu/hw/m48t59.h
deleted file mode 100644
index af22dc1123..0000000000
--- a/tools/ioemu/hw/m48t59.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#if !defined (__M48T59_H__)
-#define __M48T59_H__
-
-typedef struct m48t59_t m48t59_t;
-
-void m48t59_write (m48t59_t *NVRAM, uint32_t addr, uint32_t val);
-uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr);
-void m48t59_toggle_lock (m48t59_t *NVRAM, int lock);
-m48t59_t *m48t59_init (int IRQ, target_ulong mem_base,
- uint32_t io_base, uint16_t size,
- int type);
-
-#endif /* !defined (__M48T59_H__) */
diff --git a/tools/ioemu/hw/mc146818rtc.c b/tools/ioemu/hw/mc146818rtc.c
deleted file mode 100644
index bad4cbd864..0000000000
--- a/tools/ioemu/hw/mc146818rtc.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * QEMU MC146818 RTC emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_CMOS
-
-#define RTC_SECONDS 0
-#define RTC_SECONDS_ALARM 1
-#define RTC_MINUTES 2
-#define RTC_MINUTES_ALARM 3
-#define RTC_HOURS 4
-#define RTC_HOURS_ALARM 5
-#define RTC_ALARM_DONT_CARE 0xC0
-
-#define RTC_DAY_OF_WEEK 6
-#define RTC_DAY_OF_MONTH 7
-#define RTC_MONTH 8
-#define RTC_YEAR 9
-
-#define RTC_REG_A 10
-#define RTC_REG_B 11
-#define RTC_REG_C 12
-#define RTC_REG_D 13
-
-#define REG_A_UIP 0x80
-
-#define REG_B_SET 0x80
-#define REG_B_PIE 0x40
-#define REG_B_AIE 0x20
-#define REG_B_UIE 0x10
-
-struct RTCState {
- uint8_t cmos_data[128];
- uint8_t cmos_index;
- struct tm current_tm;
- int irq;
- /* periodic timer */
- QEMUTimer *periodic_timer;
- int64_t next_periodic_time;
- /* second update */
- int64_t next_second_time;
- QEMUTimer *second_timer;
- QEMUTimer *second_timer2;
-};
-
-static void rtc_set_time(RTCState *s);
-static void rtc_copy_date(RTCState *s);
-
-static void rtc_timer_update(RTCState *s, int64_t current_time)
-{
- int period_code, period;
- int64_t cur_clock, next_irq_clock;
-
- period_code = s->cmos_data[RTC_REG_A] & 0x0f;
- if (period_code != 0 &&
- (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
- if (period_code <= 2)
- period_code += 7;
- /* period in 32 Khz cycles */
- period = 1 << (period_code - 1);
- /* compute 32 khz clock */
- cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
- next_irq_clock = (cur_clock & ~(period - 1)) + period;
- s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
- qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
- } else {
- qemu_del_timer(s->periodic_timer);
- }
-}
-
-static void rtc_periodic_timer(void *opaque)
-{
- RTCState *s = opaque;
-
- rtc_timer_update(s, s->next_periodic_time);
- s->cmos_data[RTC_REG_C] |= 0xc0;
- pic_set_irq(s->irq, 1);
-}
-
-static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
-{
- RTCState *s = opaque;
-
- if ((addr & 1) == 0) {
- s->cmos_index = data & 0x7f;
- } else {
-#ifdef DEBUG_CMOS
- printf("cmos: write index=0x%02x val=0x%02x\n",
- s->cmos_index, data);
-#endif
- switch(s->cmos_index) {
- case RTC_SECONDS_ALARM:
- case RTC_MINUTES_ALARM:
- case RTC_HOURS_ALARM:
- /* XXX: not supported */
- s->cmos_data[s->cmos_index] = data;
- break;
- case RTC_SECONDS:
- case RTC_MINUTES:
- case RTC_HOURS:
- case RTC_DAY_OF_WEEK:
- case RTC_DAY_OF_MONTH:
- case RTC_MONTH:
- case RTC_YEAR:
- s->cmos_data[s->cmos_index] = data;
- /* if in set mode, do not update the time */
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- rtc_set_time(s);
- }
- break;
- case RTC_REG_A:
- /* UIP bit is read only */
- s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
- (s->cmos_data[RTC_REG_A] & REG_A_UIP);
- rtc_timer_update(s, qemu_get_clock(vm_clock));
- break;
- case RTC_REG_B:
- if (data & REG_B_SET) {
- /* set mode: reset UIP mode */
- s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
- data &= ~REG_B_UIE;
- } else {
- /* if disabling set mode, update the time */
- if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
- rtc_set_time(s);
- }
- }
- s->cmos_data[RTC_REG_B] = data;
- rtc_timer_update(s, qemu_get_clock(vm_clock));
- break;
- case RTC_REG_C:
- case RTC_REG_D:
- /* cannot write to them */
- break;
- default:
- s->cmos_data[s->cmos_index] = data;
- break;
- }
- }
-}
-
-static inline int to_bcd(RTCState *s, int a)
-{
- if (s->cmos_data[RTC_REG_B] & 0x04) {
- return a;
- } else {
- return ((a / 10) << 4) | (a % 10);
- }
-}
-
-static inline int from_bcd(RTCState *s, int a)
-{
- if (s->cmos_data[RTC_REG_B] & 0x04) {
- return a;
- } else {
- return ((a >> 4) * 10) + (a & 0x0f);
- }
-}
-
-static void rtc_set_time(RTCState *s)
-{
- struct tm *tm = &s->current_tm;
-
- tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
- tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
- tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
- if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
- (s->cmos_data[RTC_HOURS] & 0x80)) {
- tm->tm_hour += 12;
- }
- tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
- tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
- tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
- tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
-}
-
-static void rtc_copy_date(RTCState *s)
-{
- const struct tm *tm = &s->current_tm;
-
- s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
- s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
- if (s->cmos_data[RTC_REG_B] & 0x02) {
- /* 24 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
- } else {
- /* 12 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
- if (tm->tm_hour >= 12)
- s->cmos_data[RTC_HOURS] |= 0x80;
- }
- s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
- s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
- s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
- s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
-}
-
-/* month is between 0 and 11. */
-static int get_days_in_month(int month, int year)
-{
- static const int days_tab[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- int d;
- if ((unsigned )month >= 12)
- return 31;
- d = days_tab[month];
- if (month == 1) {
- if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
- d++;
- }
- return d;
-}
-
-/* update 'tm' to the next second */
-static void rtc_next_second(struct tm *tm)
-{
- int days_in_month;
-
- tm->tm_sec++;
- if ((unsigned)tm->tm_sec >= 60) {
- tm->tm_sec = 0;
- tm->tm_min++;
- if ((unsigned)tm->tm_min >= 60) {
- tm->tm_min = 0;
- tm->tm_hour++;
- if ((unsigned)tm->tm_hour >= 24) {
- tm->tm_hour = 0;
- /* next day */
- tm->tm_wday++;
- if ((unsigned)tm->tm_wday >= 7)
- tm->tm_wday = 0;
- days_in_month = get_days_in_month(tm->tm_mon,
- tm->tm_year + 1900);
- tm->tm_mday++;
- if (tm->tm_mday < 1) {
- tm->tm_mday = 1;
- } else if (tm->tm_mday > days_in_month) {
- tm->tm_mday = 1;
- tm->tm_mon++;
- if (tm->tm_mon >= 12) {
- tm->tm_mon = 0;
- tm->tm_year++;
- }
- }
- }
- }
- }
-}
-
-
-static void rtc_update_second(void *opaque)
-{
- RTCState *s = opaque;
- int64_t delay;
-
- /* if the oscillator is not in normal operation, we do not update */
- if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
- s->next_second_time += ticks_per_sec;
- qemu_mod_timer(s->second_timer, s->next_second_time);
- } else {
- rtc_next_second(&s->current_tm);
-
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- /* update in progress bit */
- s->cmos_data[RTC_REG_A] |= REG_A_UIP;
- }
- /* should be 244 us = 8 / 32768 seconds, but currently the
- timers do not have the necessary resolution. */
- delay = (ticks_per_sec * 1) / 100;
- if (delay < 1)
- delay = 1;
- qemu_mod_timer(s->second_timer2,
- s->next_second_time + delay);
- }
-}
-
-static void rtc_update_second2(void *opaque)
-{
- RTCState *s = opaque;
-
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- rtc_copy_date(s);
- }
-
- /* check alarm */
- if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
- if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
- s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
- ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
- s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
- ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
- s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
-
- s->cmos_data[RTC_REG_C] |= 0xa0;
- pic_set_irq(s->irq, 1);
- }
- }
-
- /* update ended interrupt */
- if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
- s->cmos_data[RTC_REG_C] |= 0x90;
- pic_set_irq(s->irq, 1);
- }
-
- /* clear update in progress bit */
- s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
-
- s->next_second_time += ticks_per_sec;
- qemu_mod_timer(s->second_timer, s->next_second_time);
-}
-
-static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
-{
- RTCState *s = opaque;
- int ret;
- if ((addr & 1) == 0) {
- return 0xff;
- } else {
- switch(s->cmos_index) {
- case RTC_SECONDS:
- case RTC_MINUTES:
- case RTC_HOURS:
- case RTC_DAY_OF_WEEK:
- case RTC_DAY_OF_MONTH:
- case RTC_MONTH:
- case RTC_YEAR:
- ret = s->cmos_data[s->cmos_index];
- break;
- case RTC_REG_A:
- ret = s->cmos_data[s->cmos_index];
- break;
- case RTC_REG_C:
- ret = s->cmos_data[s->cmos_index];
- pic_set_irq(s->irq, 0);
- s->cmos_data[RTC_REG_C] = 0x00;
- break;
- default:
- ret = s->cmos_data[s->cmos_index];
- break;
- }
-#ifdef DEBUG_CMOS
- printf("cmos: read index=0x%02x val=0x%02x\n",
- s->cmos_index, ret);
-#endif
- return ret;
- }
-}
-
-void rtc_set_memory(RTCState *s, int addr, int val)
-{
- if (addr >= 0 && addr <= 127)
- s->cmos_data[addr] = val;
-}
-
-void rtc_set_date(RTCState *s, const struct tm *tm)
-{
- s->current_tm = *tm;
- rtc_copy_date(s);
-}
-
-/* PC cmos mappings */
-#define REG_IBM_CENTURY_BYTE 0x32
-#define REG_IBM_PS2_CENTURY_BYTE 0x37
-
-void rtc_set_date_from_host(RTCState *s)
-{
- time_t ti;
- struct tm *tm;
- int val;
-
- /* set the CMOS date */
- time(&ti);
- if (rtc_utc)
- tm = gmtime(&ti);
- else
- tm = localtime(&ti);
- rtc_set_date(s, tm);
-
- val = to_bcd(s, (tm->tm_year / 100) + 19);
- rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
- rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
-}
-
-static void rtc_save(QEMUFile *f, void *opaque)
-{
- RTCState *s = opaque;
-
- qemu_put_buffer(f, s->cmos_data, 128);
- qemu_put_8s(f, &s->cmos_index);
-
- qemu_put_be32s(f, &s->current_tm.tm_sec);
- qemu_put_be32s(f, &s->current_tm.tm_min);
- qemu_put_be32s(f, &s->current_tm.tm_hour);
- qemu_put_be32s(f, &s->current_tm.tm_wday);
- qemu_put_be32s(f, &s->current_tm.tm_mday);
- qemu_put_be32s(f, &s->current_tm.tm_mon);
- qemu_put_be32s(f, &s->current_tm.tm_year);
-
- qemu_put_timer(f, s->periodic_timer);
- qemu_put_be64s(f, &s->next_periodic_time);
-
- qemu_put_be64s(f, &s->next_second_time);
- qemu_put_timer(f, s->second_timer);
- qemu_put_timer(f, s->second_timer2);
-}
-
-static int rtc_load(QEMUFile *f, void *opaque, int version_id)
-{
- RTCState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_buffer(f, s->cmos_data, 128);
- qemu_get_8s(f, &s->cmos_index);
-
- qemu_get_be32s(f, &s->current_tm.tm_sec);
- qemu_get_be32s(f, &s->current_tm.tm_min);
- qemu_get_be32s(f, &s->current_tm.tm_hour);
- qemu_get_be32s(f, &s->current_tm.tm_wday);
- qemu_get_be32s(f, &s->current_tm.tm_mday);
- qemu_get_be32s(f, &s->current_tm.tm_mon);
- qemu_get_be32s(f, &s->current_tm.tm_year);
-
- qemu_get_timer(f, s->periodic_timer);
- qemu_get_be64s(f, &s->next_periodic_time);
-
- qemu_get_be64s(f, &s->next_second_time);
- qemu_get_timer(f, s->second_timer);
- qemu_get_timer(f, s->second_timer2);
- return 0;
-}
-
-RTCState *rtc_init(int base, int irq)
-{
- RTCState *s;
-
- s = qemu_mallocz(sizeof(RTCState));
- if (!s)
- return NULL;
-
- s->irq = irq;
- s->cmos_data[RTC_REG_A] = 0x26;
- s->cmos_data[RTC_REG_B] = 0x02;
- s->cmos_data[RTC_REG_C] = 0x00;
- s->cmos_data[RTC_REG_D] = 0x80;
-
- rtc_set_date_from_host(s);
-
- s->periodic_timer = qemu_new_timer(vm_clock,
- rtc_periodic_timer, s);
- s->second_timer = qemu_new_timer(vm_clock,
- rtc_update_second, s);
- s->second_timer2 = qemu_new_timer(vm_clock,
- rtc_update_second2, s);
-
- s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
- qemu_mod_timer(s->second_timer2, s->next_second_time);
-
- register_ioport_write(base, 2, 1, cmos_ioport_write, s);
- register_ioport_read(base, 2, 1, cmos_ioport_read, s);
-
- register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
- return s;
-}
-
diff --git a/tools/ioemu/hw/mips_int.c b/tools/ioemu/hw/mips_int.c
deleted file mode 100644
index 93d599fc60..0000000000
--- a/tools/ioemu/hw/mips_int.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "vl.h"
-#include "cpu.h"
-
-/* Raise IRQ to CPU if necessary. It must be called every time the active
- IRQ may change */
-void cpu_mips_update_irq(CPUState *env)
-{
- if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
- (env->CP0_Status & (1 << CP0St_IE)) &&
- !(env->hflags & MIPS_HFLAG_EXL) &&
- !(env->hflags & MIPS_HFLAG_ERL) &&
- !(env->hflags & MIPS_HFLAG_DM)) {
- if (! (env->interrupt_request & CPU_INTERRUPT_HARD)) {
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- }
- } else {
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
- }
-}
-
-void cpu_mips_irq_request(void *opaque, int irq, int level)
-{
- CPUState *env = first_cpu;
-
- uint32_t mask;
-
- if (irq >= 16)
- return;
-
- mask = 1 << (irq + CP0Ca_IP);
-
- if (level) {
- env->CP0_Cause |= mask;
- } else {
- env->CP0_Cause &= ~mask;
- }
- cpu_mips_update_irq(env);
-}
-
diff --git a/tools/ioemu/hw/mips_malta.c b/tools/ioemu/hw/mips_malta.c
deleted file mode 100644
index 029e18e685..0000000000
--- a/tools/ioemu/hw/mips_malta.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * QEMU Malta board support
- *
- * Copyright (c) 2006 Aurelien Jarno
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-
-#ifdef TARGET_WORDS_BIGENDIAN
-#define BIOS_FILENAME "mips_bios.bin"
-#else
-#define BIOS_FILENAME "mipsel_bios.bin"
-#endif
-
-#ifdef MIPS_HAS_MIPS64
-#define INITRD_LOAD_ADDR (int64_t)0x80800000
-#else
-#define INITRD_LOAD_ADDR (int32_t)0x80800000
-#endif
-
-#define ENVP_ADDR (int32_t)0x80002000
-#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
-
-#define ENVP_NB_ENTRIES 16
-#define ENVP_ENTRY_SIZE 256
-
-
-extern FILE *logfile;
-
-typedef struct {
- uint32_t leds;
- uint32_t brk;
- uint32_t gpout;
- uint32_t i2coe;
- uint32_t i2cout;
- uint32_t i2csel;
- CharDriverState *display;
- char display_text[9];
-} MaltaFPGAState;
-
-static PITState *pit;
-
-/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
-static void pic_irq_request(void *opaque, int level)
-{
- cpu_mips_irq_request(opaque, 2, level);
-}
-
-/* Malta FPGA */
-static void malta_fpga_update_display(void *opaque)
-{
- char leds_text[9];
- int i;
- MaltaFPGAState *s = opaque;
-
- for (i = 7 ; i >= 0 ; i--) {
- if (s->leds & (1 << i))
- leds_text[i] = '#';
- else
- leds_text[i] = ' ';
- }
- leds_text[8] = '\0';
-
- qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
- qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
-}
-
-static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
-{
- MaltaFPGAState *s = opaque;
- uint32_t val = 0;
- uint32_t saddr;
-
- saddr = (addr & 0xfffff);
-
- switch (saddr) {
-
- /* SWITCH Register */
- case 0x00200:
- val = 0x00000000; /* All switches closed */
- break;
-
- /* STATUS Register */
- case 0x00208:
-#ifdef TARGET_WORDS_BIGENDIAN
- val = 0x00000012;
-#else
- val = 0x00000010;
-#endif
- break;
-
- /* JMPRS Register */
- case 0x00210:
- val = 0x00;
- break;
-
- /* LEDBAR Register */
- case 0x00408:
- val = s->leds;
- break;
-
- /* BRKRES Register */
- case 0x00508:
- val = s->brk;
- break;
-
- /* GPOUT Register */
- case 0x00a00:
- val = s->gpout;
- break;
-
- /* XXX: implement a real I2C controller */
-
- /* GPINP Register */
- case 0x00a08:
- /* IN = OUT until a real I2C control is implemented */
- if (s->i2csel)
- val = s->i2cout;
- else
- val = 0x00;
- break;
-
- /* I2CINP Register */
- case 0x00b00:
- val = 0x00000003;
- break;
-
- /* I2COE Register */
- case 0x00b08:
- val = s->i2coe;
- break;
-
- /* I2COUT Register */
- case 0x00b10:
- val = s->i2cout;
- break;
-
- /* I2CSEL Register */
- case 0x00b18:
- val = s->i2cout;
- break;
-
- default:
-#if 0
- printf ("malta_fpga_read: Bad register offset 0x" TLSZ "\n",
- addr);
-#endif
- break;
- }
- return val;
-}
-
-static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- MaltaFPGAState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & 0xfffff);
-
- switch (saddr) {
-
- /* SWITCH Register */
- case 0x00200:
- break;
-
- /* JMPRS Register */
- case 0x00210:
- break;
-
- /* LEDBAR Register */
- /* XXX: implement a 8-LED array */
- case 0x00408:
- s->leds = val & 0xff;
- break;
-
- /* ASCIIWORD Register */
- case 0x00410:
- snprintf(s->display_text, 9, "%08X", val);
- malta_fpga_update_display(s);
- break;
-
- /* ASCIIPOS0 to ASCIIPOS7 Registers */
- case 0x00418:
- case 0x00420:
- case 0x00428:
- case 0x00430:
- case 0x00438:
- case 0x00440:
- case 0x00448:
- case 0x00450:
- s->display_text[(saddr - 0x00418) >> 3] = (char) val;
- malta_fpga_update_display(s);
- break;
-
- /* SOFTRES Register */
- case 0x00500:
- if (val == 0x42)
- qemu_system_reset_request ();
- break;
-
- /* BRKRES Register */
- case 0x00508:
- s->brk = val & 0xff;
- break;
-
- /* GPOUT Register */
- case 0x00a00:
- s->gpout = val & 0xff;
- break;
-
- /* I2COE Register */
- case 0x00b08:
- s->i2coe = val & 0x03;
- break;
-
- /* I2COUT Register */
- case 0x00b10:
- s->i2cout = val & 0x03;
- break;
-
- /* I2CSEL Register */
- case 0x00b18:
- s->i2cout = val & 0x01;
- break;
-
- default:
-#if 0
- printf ("malta_fpga_write: Bad register offset 0x" TLSZ "\n",
- addr);
-#endif
- break;
- }
-}
-
-static CPUReadMemoryFunc *malta_fpga_read[] = {
- malta_fpga_readl,
- malta_fpga_readl,
- malta_fpga_readl
-};
-
-static CPUWriteMemoryFunc *malta_fpga_write[] = {
- malta_fpga_writel,
- malta_fpga_writel,
- malta_fpga_writel
-};
-
-void malta_fpga_reset(void *opaque)
-{
- MaltaFPGAState *s = opaque;
-
- s->leds = 0x00;
- s->brk = 0x0a;
- s->gpout = 0x00;
- s->i2coe = 0x0;
- s->i2cout = 0x3;
- s->i2csel = 0x1;
-
- s->display_text[8] = '\0';
- snprintf(s->display_text, 9, " ");
- malta_fpga_update_display(s);
-}
-
-MaltaFPGAState *malta_fpga_init(target_phys_addr_t base)
-{
- MaltaFPGAState *s;
- int malta;
-
- s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
-
- malta = cpu_register_io_memory(0, malta_fpga_read,
- malta_fpga_write, s);
- cpu_register_physical_memory(base, 0x100000, malta);
-
- s->display = qemu_chr_open("vc");
- qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
- qemu_chr_printf(s->display, "+ +\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
- qemu_chr_printf(s->display, "\n");
- qemu_chr_printf(s->display, "Malta ASCII\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
- qemu_chr_printf(s->display, "+ +\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
-
- malta_fpga_reset(s);
- qemu_register_reset(malta_fpga_reset, s);
-
- return s;
-}
-
-/* Audio support */
-#ifdef HAS_AUDIO
-static void audio_init (PCIBus *pci_bus)
-{
- struct soundhw *c;
- int audio_enabled = 0;
-
- for (c = soundhw; !audio_enabled && c->name; ++c) {
- audio_enabled = c->enabled;
- }
-
- if (audio_enabled) {
- AudioState *s;
-
- s = AUD_init ();
- if (s) {
- for (c = soundhw; c->name; ++c) {
- if (c->enabled) {
- if (c->isa) {
- fprintf(stderr, "qemu: Unsupported Sound Card: %s\n", c->name);
- exit(1);
- }
- else {
- if (pci_bus) {
- c->init.init_pci (pci_bus, s);
- }
- }
- }
- }
- }
- }
-}
-#endif
-
-/* Network support */
-static void network_init (PCIBus *pci_bus)
-{
- int i;
- NICInfo *nd;
-
- for(i = 0; i < nb_nics; i++) {
- nd = &nd_table[i];
- if (!nd->model) {
- nd->model = "pcnet";
- }
- if (i == 0 && strcmp(nd->model, "pcnet") == 0) {
- /* The malta board has a PCNet card using PCI SLOT 11 */
- pci_nic_init(pci_bus, nd, 88);
- } else {
- pci_nic_init(pci_bus, nd, -1);
- }
- }
-}
-
-/* ROM and pseudo bootloader
-
- The following code implements a very very simple bootloader. It first
- loads the registers a0 to a3 to the values expected by the OS, and
- then jump at the kernel address.
-
- The bootloader should pass the locations of the kernel arguments and
- environment variables tables. Those tables contain the 32-bit address
- of NULL terminated strings. The environment variables table should be
- terminated by a NULL address.
-
- For a simpler implementation, the number of kernel arguments is fixed
- to two (the name of the kernel and the command line), and the two
- tables are actually the same one.
-
- The registers a0 to a3 should contain the following values:
- a0 - number of kernel arguments
- a1 - 32-bit address of the kernel arguments table
- a2 - 32-bit address of the environment variables table
- a3 - RAM size in bytes
-*/
-
-static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_addr)
-{
- uint32_t *p;
-
- /* Small bootloader */
- p = (uint32_t *) (phys_ram_base + bios_offset);
- stl_raw(p++, 0x0bf00010); /* j 0x1fc00040 */
- stl_raw(p++, 0x00000000); /* nop */
-
- /* Second part of the bootloader */
- p = (uint32_t *) (phys_ram_base + bios_offset + 0x040);
- stl_raw(p++, 0x3c040000); /* lui a0, 0 */
- stl_raw(p++, 0x34840002); /* ori a0, a0, 2 */
- stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
- stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a0, low(ENVP_ADDR) */
- stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
- stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
- stl_raw(p++, 0x3c070000 | (env->ram_size >> 16)); /* lui a3, high(env->ram_size) */
- stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff)); /* ori a3, a3, low(env->ram_size) */
- stl_raw(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff)); /* lui ra, high(kernel_addr) */;
- stl_raw(p++, 0x37ff0000 | (kernel_addr & 0xffff)); /* ori ra, ra, low(kernel_addr) */
- stl_raw(p++, 0x03e00008); /* jr ra */
- stl_raw(p++, 0x00000000); /* nop */
-}
-
-static void prom_set(int index, const char *string, ...)
-{
- va_list ap;
- int32_t *p;
- int32_t table_addr;
- char *s;
-
- if (index >= ENVP_NB_ENTRIES)
- return;
-
- p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
- p += index;
-
- if (string == NULL) {
- stl_raw(p, 0);
- return;
- }
-
- table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
- s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
-
- stl_raw(p, table_addr);
-
- va_start(ap, string);
- vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
- va_end(ap);
-}
-
-/* Kernel */
-static int64_t load_kernel (CPUState *env)
-{
- int64_t kernel_addr = 0;
- int index = 0;
- long initrd_size;
-
- if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND, &kernel_addr) < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- env->kernel_filename);
- exit(1);
- }
-
- /* load initrd */
- initrd_size = 0;
- if (env->initrd_filename) {
- initrd_size = load_image(env->initrd_filename,
- phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
- if (initrd_size == (target_ulong) -1) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- env->initrd_filename);
- exit(1);
- }
- }
-
- /* Store command line. */
- prom_set(index++, env->kernel_filename);
- if (initrd_size > 0)
- prom_set(index++, "rd_start=0x" TLSZ " rd_size=%li %s", INITRD_LOAD_ADDR, initrd_size, env->kernel_cmdline);
- else
- prom_set(index++, env->kernel_cmdline);
-
- /* Setup minimum environment variables */
- prom_set(index++, "memsize");
- prom_set(index++, "%i", env->ram_size);
- prom_set(index++, "modetty0");
- prom_set(index++, "38400n8r");
- prom_set(index++, NULL);
-
- return kernel_addr;
-}
-
-static void main_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
- cpu_reset(env);
-
- /* The bootload does not need to be rewritten as it is located in a
- read only location. The kernel location and the arguments table
- location does not change. */
- if (env->kernel_filename)
- load_kernel (env);
-}
-
-void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- char buf[1024];
- unsigned long bios_offset;
- int64_t kernel_addr;
- PCIBus *pci_bus;
- CPUState *env;
- RTCState *rtc_state;
- /* fdctrl_t *floppy_controller; */
- MaltaFPGAState *malta_fpga;
- int ret;
-
- env = cpu_init();
- register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
- qemu_register_reset(main_cpu_reset, env);
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- /* Map the bios at two physical locations, as on the real board */
- bios_offset = ram_size + vga_ram_size;
- cpu_register_physical_memory(0x1e000000LL,
- BIOS_SIZE, bios_offset | IO_MEM_ROM);
- cpu_register_physical_memory(0x1fc00000LL,
- BIOS_SIZE, bios_offset | IO_MEM_ROM);
-
- /* Load a BIOS image except if a kernel image has been specified. In
- the later case, just write a small bootloader to the flash
- location. */
- if (kernel_filename) {
- env->ram_size = ram_size;
- env->kernel_filename = kernel_filename;
- env->kernel_cmdline = kernel_cmdline;
- env->initrd_filename = initrd_filename;
- kernel_addr = load_kernel(env);
- write_bootloader(env, bios_offset, kernel_addr);
- } else {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- ret = load_image(buf, phys_ram_base + bios_offset);
- if (ret != BIOS_SIZE) {
- fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
- buf);
- exit(1);
- }
- }
-
- /* Board ID = 0x420 (Malta Board with CoreLV)
- XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
- map to the board ID. */
- stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
-
- /* Init internal devices */
- cpu_mips_clock_init(env);
- cpu_mips_irqctrl_init();
-
- /* FPGA */
- malta_fpga = malta_fpga_init(0x1f000000LL);
-
- /* Interrupt controller */
- isa_pic = pic_init(pic_irq_request, env);
-
- /* Northbridge */
- pci_bus = pci_gt64120_init(isa_pic);
-
- /* Southbridge */
- piix4_init(pci_bus, 80);
- pci_piix3_ide_init(pci_bus, bs_table, 81);
- usb_uhci_init(pci_bus, 82);
- piix4_pm_init(pci_bus, 83);
- pit = pit_init(0x40, 0);
- DMA_init(0);
-
- /* Super I/O */
- kbd_init();
- rtc_state = rtc_init(0x70, 8);
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
- parallel_init(0x378, 7, parallel_hds[0]);
- /* XXX: The floppy controller does not work correctly, something is
- probably wrong.
- floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
-
- /* Sound card */
-#ifdef HAS_AUDIO
- audio_init(pci_bus);
-#endif
-
- /* Network card */
- network_init(pci_bus);
-}
-
-QEMUMachine mips_malta_machine = {
- "malta",
- "MIPS Malta Core LV",
- mips_malta_init,
-};
diff --git a/tools/ioemu/hw/mips_r4k.c b/tools/ioemu/hw/mips_r4k.c
deleted file mode 100644
index 8d1cac9392..0000000000
--- a/tools/ioemu/hw/mips_r4k.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * QEMU/MIPS pseudo-board
- *
- * emulates a simple machine with ISA-like bus.
- * ISA IO space mapped to the 0x14000000 (PHYS) and
- * ISA memory at the 0x10000000 (PHYS, 16Mb in size).
- * All peripherial devices are attached to this "bus" with
- * the standard PC ISA addresses.
-*/
-#include "vl.h"
-
-#ifdef TARGET_WORDS_BIGENDIAN
-#define BIOS_FILENAME "mips_bios.bin"
-#else
-#define BIOS_FILENAME "mipsel_bios.bin"
-#endif
-
-#ifdef MIPS_HAS_MIPS64
-#define INITRD_LOAD_ADDR (int64_t)(int32_t)0x80800000
-#else
-#define INITRD_LOAD_ADDR (int32_t)0x80800000
-#endif
-
-#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
-
-static const int ide_iobase[2] = { 0x1f0, 0x170 };
-static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 14, 15 };
-
-static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
-extern FILE *logfile;
-
-static PITState *pit; /* PIT i8254 */
-
-/*i8254 PIT is attached to the IRQ0 at PIC i8259 */
-/*The PIC is attached to the MIPS CPU INT0 pin */
-static void pic_irq_request(void *opaque, int level)
-{
- cpu_mips_irq_request(opaque, 2, level);
-}
-
-static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- if ((addr & 0xffff) == 0 && val == 42)
- qemu_system_reset_request ();
- else if ((addr & 0xffff) == 4 && val == 42)
- qemu_system_shutdown_request ();
-}
-
-static uint32_t mips_qemu_readl (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static CPUWriteMemoryFunc *mips_qemu_write[] = {
- &mips_qemu_writel,
- &mips_qemu_writel,
- &mips_qemu_writel,
-};
-
-static CPUReadMemoryFunc *mips_qemu_read[] = {
- &mips_qemu_readl,
- &mips_qemu_readl,
- &mips_qemu_readl,
-};
-
-static int mips_qemu_iomemtype = 0;
-
-void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename)
-{
- int64_t entry = 0;
- long kernel_size, initrd_size;
-
- kernel_size = load_elf(kernel_filename, VIRT_TO_PHYS_ADDEND, &entry);
- if (kernel_size >= 0) {
- if ((entry & ~0x7fffffffULL) == 0x80000000)
- entry = (int32_t)entry;
- env->PC = entry;
- } else {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
-
- /* load initrd */
- initrd_size = 0;
- if (initrd_filename) {
- initrd_size = load_image(initrd_filename,
- phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
- if (initrd_size == (target_ulong) -1) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- }
-
- /* Store command line. */
- if (initrd_size > 0) {
- int ret;
- ret = sprintf(phys_ram_base + (16 << 20) - 256,
- "rd_start=0x" TLSZ " rd_size=%li ",
- INITRD_LOAD_ADDR,
- initrd_size);
- strcpy (phys_ram_base + (16 << 20) - 256 + ret, kernel_cmdline);
- }
- else {
- strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline);
- }
-
- *(int32_t *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678);
- *(int32_t *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size);
-}
-
-static void main_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
- cpu_reset(env);
-
- if (env->kernel_filename)
- load_kernel (env, env->ram_size, env->kernel_filename,
- env->kernel_cmdline, env->initrd_filename);
-}
-
-void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- char buf[1024];
- unsigned long bios_offset;
- int bios_size;
- CPUState *env;
- static RTCState *rtc_state;
- int i;
-
- env = cpu_init();
- register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
- qemu_register_reset(main_cpu_reset, env);
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- if (!mips_qemu_iomemtype) {
- mips_qemu_iomemtype = cpu_register_io_memory(0, mips_qemu_read,
- mips_qemu_write, NULL);
- }
- cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype);
-
- /* Try to load a BIOS image. If this fails, we continue regardless,
- but initialize the hardware ourselves. When a kernel gets
- preloaded we also initialize the hardware, since the BIOS wasn't
- run. */
- bios_offset = ram_size + vga_ram_size;
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- bios_size = load_image(buf, phys_ram_base + bios_offset);
- if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
- cpu_register_physical_memory(0x1fc00000,
- BIOS_SIZE, bios_offset | IO_MEM_ROM);
- } else {
- /* not fatal */
- fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
- buf);
- }
-
- if (kernel_filename) {
- load_kernel (env, ram_size, kernel_filename, kernel_cmdline,
- initrd_filename);
- env->ram_size = ram_size;
- env->kernel_filename = kernel_filename;
- env->kernel_cmdline = kernel_cmdline;
- env->initrd_filename = initrd_filename;
- }
-
- /* Init CPU internal devices */
- cpu_mips_clock_init(env);
- cpu_mips_irqctrl_init();
-
- rtc_state = rtc_init(0x70, 8);
-
- /* Register 64 KB of ISA IO space at 0x14000000 */
- isa_mmio_init(0x14000000, 0x00010000);
- isa_mem_base = 0x10000000;
-
- isa_pic = pic_init(pic_irq_request, env);
- pit = pit_init(0x40, 0);
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_hds[i]) {
- serial_init(&pic_set_irq_new, isa_pic,
- serial_io[i], serial_irq[i], serial_hds[i]);
- }
- }
-
- isa_vga_init(ds, phys_ram_base + ram_size, ram_size,
- vga_ram_size);
-
- if (nd_table[0].vlan) {
- if (nd_table[0].model == NULL
- || strcmp(nd_table[0].model, "ne2k_isa") == 0) {
- isa_ne2000_init(0x300, 9, &nd_table[0]);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
- exit (1);
- }
- }
-
- for(i = 0; i < 2; i++)
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
- bs_table[2 * i], bs_table[2 * i + 1]);
-}
-
-QEMUMachine mips_machine = {
- "mips",
- "mips r4k platform",
- mips_r4k_init,
-};
diff --git a/tools/ioemu/hw/mips_timer.c b/tools/ioemu/hw/mips_timer.c
deleted file mode 100644
index bc83036b34..0000000000
--- a/tools/ioemu/hw/mips_timer.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "vl.h"
-
-void cpu_mips_irqctrl_init (void)
-{
-}
-
-/* XXX: do not use a global */
-uint32_t cpu_mips_get_random (CPUState *env)
-{
- static uint32_t seed = 0;
- uint32_t idx;
- seed = seed * 314159 + 1;
- idx = (seed >> 16) % (MIPS_TLB_NB - env->CP0_Wired) + env->CP0_Wired;
- return idx;
-}
-
-/* MIPS R4K timer */
-uint32_t cpu_mips_get_count (CPUState *env)
-{
- return env->CP0_Count +
- (uint32_t)muldiv64(qemu_get_clock(vm_clock),
- 100 * 1000 * 1000, ticks_per_sec);
-}
-
-static void cpu_mips_update_count (CPUState *env, uint32_t count,
- uint32_t compare)
-{
- uint64_t now, next;
- uint32_t tmp;
-
- tmp = count;
- if (count == compare)
- tmp++;
- now = qemu_get_clock(vm_clock);
- next = now + muldiv64(compare - tmp, ticks_per_sec, 100 * 1000 * 1000);
- if (next == now)
- next++;
-#if 0
- if (logfile) {
- fprintf(logfile, "%s: 0x%08" PRIx64 " %08x %08x => 0x%08" PRIx64 "\n",
- __func__, now, count, compare, next - now);
- }
-#endif
- /* Store new count and compare registers */
- env->CP0_Compare = compare;
- env->CP0_Count =
- count - (uint32_t)muldiv64(now, 100 * 1000 * 1000, ticks_per_sec);
- /* Adjust timer */
- qemu_mod_timer(env->timer, next);
-}
-
-void cpu_mips_store_count (CPUState *env, uint32_t value)
-{
- cpu_mips_update_count(env, value, env->CP0_Compare);
-}
-
-void cpu_mips_store_compare (CPUState *env, uint32_t value)
-{
- cpu_mips_update_count(env, cpu_mips_get_count(env), value);
- cpu_mips_irq_request(env, 7, 0);
-}
-
-static void mips_timer_cb (void *opaque)
-{
- CPUState *env;
-
- env = opaque;
-#if 0
- if (logfile) {
- fprintf(logfile, "%s\n", __func__);
- }
-#endif
- cpu_mips_update_count(env, cpu_mips_get_count(env), env->CP0_Compare);
- cpu_mips_irq_request(env, 7, 1);
-}
-
-void cpu_mips_clock_init (CPUState *env)
-{
- env->timer = qemu_new_timer(vm_clock, &mips_timer_cb, env);
- env->CP0_Compare = 0;
- cpu_mips_update_count(env, 1, 0);
-}
-
diff --git a/tools/ioemu/hw/ne2000.c b/tools/ioemu/hw/ne2000.c
deleted file mode 100644
index 977d202921..0000000000
--- a/tools/ioemu/hw/ne2000.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * QEMU NE2000 emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug NE2000 card */
-//#define DEBUG_NE2000
-
-#define MAX_ETH_FRAME_SIZE 1514
-
-#define E8390_CMD 0x00 /* The command register (for all pages) */
-/* Page 0 register offsets. */
-#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
-#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
-#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
-#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
-#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
-#define EN0_TSR 0x04 /* Transmit status reg RD */
-#define EN0_TPSR 0x04 /* Transmit starting page WR */
-#define EN0_NCR 0x05 /* Number of collision reg RD */
-#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
-#define EN0_FIFO 0x06 /* FIFO RD */
-#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
-#define EN0_ISR 0x07 /* Interrupt status reg RD WR */
-#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
-#define EN0_RSARLO 0x08 /* Remote start address reg 0 */
-#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
-#define EN0_RSARHI 0x09 /* Remote start address reg 1 */
-#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
-#define EN0_RTL8029ID0 0x0a /* Realtek ID byte #1 RD */
-#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
-#define EN0_RTL8029ID1 0x0b /* Realtek ID byte #2 RD */
-#define EN0_RSR 0x0c /* rx status reg RD */
-#define EN0_RXCR 0x0c /* RX configuration reg WR */
-#define EN0_TXCR 0x0d /* TX configuration reg WR */
-#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
-#define EN0_DCFG 0x0e /* Data configuration reg WR */
-#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
-#define EN0_IMR 0x0f /* Interrupt mask reg WR */
-#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
-
-#define EN1_PHYS 0x11
-#define EN1_CURPAG 0x17
-#define EN1_MULT 0x18
-
-#define EN2_STARTPG 0x21 /* Starting page of ring bfr RD */
-#define EN2_STOPPG 0x22 /* Ending page +1 of ring bfr RD */
-
-#define EN3_CONFIG0 0x33
-#define EN3_CONFIG1 0x34
-#define EN3_CONFIG2 0x35
-#define EN3_CONFIG3 0x36
-
-/* Register accessed at EN_CMD, the 8390 base addr. */
-#define E8390_STOP 0x01 /* Stop and reset the chip */
-#define E8390_START 0x02 /* Start the chip, clear reset */
-#define E8390_TRANS 0x04 /* Transmit a frame */
-#define E8390_RREAD 0x08 /* Remote read */
-#define E8390_RWRITE 0x10 /* Remote write */
-#define E8390_NODMA 0x20 /* Remote DMA */
-#define E8390_PAGE0 0x00 /* Select page chip registers */
-#define E8390_PAGE1 0x40 /* using the two high-order bits */
-#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
-
-/* Bits in EN0_ISR - Interrupt status register */
-#define ENISR_RX 0x01 /* Receiver, no error */
-#define ENISR_TX 0x02 /* Transmitter, no error */
-#define ENISR_RX_ERR 0x04 /* Receiver, with error */
-#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
-#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
-#define ENISR_COUNTERS 0x20 /* Counters need emptying */
-#define ENISR_RDC 0x40 /* remote dma complete */
-#define ENISR_RESET 0x80 /* Reset completed */
-#define ENISR_ALL 0x3f /* Interrupts we will enable */
-
-/* Bits in received packet status byte and EN0_RSR*/
-#define ENRSR_RXOK 0x01 /* Received a good packet */
-#define ENRSR_CRC 0x02 /* CRC error */
-#define ENRSR_FAE 0x04 /* frame alignment error */
-#define ENRSR_FO 0x08 /* FIFO overrun */
-#define ENRSR_MPA 0x10 /* missed pkt */
-#define ENRSR_PHY 0x20 /* physical/multicast address */
-#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
-#define ENRSR_DEF 0x80 /* deferring */
-
-/* Transmitted packet status, EN0_TSR. */
-#define ENTSR_PTX 0x01 /* Packet transmitted without error */
-#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
-#define ENTSR_COL 0x04 /* The transmit collided at least once. */
-#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
-#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
-#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
-#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
-#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
-
-#define NE2000_PMEM_SIZE (32*1024)
-#define NE2000_PMEM_START (16*1024)
-#define NE2000_PMEM_END (NE2000_PMEM_SIZE+NE2000_PMEM_START)
-#define NE2000_MEM_SIZE NE2000_PMEM_END
-
-typedef struct NE2000State {
- uint8_t cmd;
- uint32_t start;
- uint32_t stop;
- uint8_t boundary;
- uint8_t tsr;
- uint8_t tpsr;
- uint16_t tcnt;
- uint16_t rcnt;
- uint32_t rsar;
- uint8_t rsr;
- uint8_t rxcr;
- uint8_t isr;
- uint8_t dcfg;
- uint8_t imr;
- uint8_t phys[6]; /* mac address */
- uint8_t curpag;
- uint8_t mult[8]; /* multicast mask array */
- int irq;
- int tainted;
- PCIDevice *pci_dev;
- VLANClientState *vc;
- uint8_t macaddr[6];
- uint8_t mem[NE2000_MEM_SIZE];
-} NE2000State;
-
-static void ne2000_reset(NE2000State *s)
-{
- int i;
-
- s->isr = ENISR_RESET;
- memcpy(s->mem, s->macaddr, 6);
- s->mem[14] = 0x57;
- s->mem[15] = 0x57;
-
- /* duplicate prom data */
- for(i = 15;i >= 0; i--) {
- s->mem[2 * i] = s->mem[i];
- s->mem[2 * i + 1] = s->mem[i];
- }
-}
-
-static void ne2000_update_irq(NE2000State *s)
-{
- int isr;
- isr = (s->isr & s->imr) & 0x7f;
-#if defined(DEBUG_NE2000)
- printf("NE2000: Set IRQ line %d to %d (%02x %02x)\n",
- s->irq, isr ? 1 : 0, s->isr, s->imr);
-#endif
- if (s->irq == 16) {
- /* PCI irq */
- pci_set_irq(s->pci_dev, 0, (isr != 0));
- } else {
- /* ISA irq */
- pic_set_irq(s->irq, (isr != 0));
- }
-}
-
-#define POLYNOMIAL 0x04c11db6
-
-/* From FreeBSD */
-/* XXX: optimize */
-static int compute_mcast_idx(const uint8_t *ep)
-{
- uint32_t crc;
- int carry, i, j;
- uint8_t b;
-
- crc = 0xffffffff;
- for (i = 0; i < 6; i++) {
- b = *ep++;
- for (j = 0; j < 8; j++) {
- carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
- crc <<= 1;
- b >>= 1;
- if (carry)
- crc = ((crc ^ POLYNOMIAL) | carry);
- }
- }
- return (crc >> 26);
-}
-
-static int ne2000_buffer_full(NE2000State *s)
-{
- int avail, index, boundary;
-
- index = s->curpag << 8;
- boundary = s->boundary << 8;
- if (index < boundary)
- avail = boundary - index;
- else
- avail = (s->stop - s->start) - (index - boundary);
- if (avail < (MAX_ETH_FRAME_SIZE + 4))
- return 1;
- return 0;
-}
-
-static int ne2000_can_receive(void *opaque)
-{
- NE2000State *s = opaque;
-
- if (s->cmd & E8390_STOP)
- return 1;
- return !ne2000_buffer_full(s);
-}
-
-#define MIN_BUF_SIZE 60
-
-static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr)
-{
- addr <<= 8;
- return addr < s->stop && addr >= s->start;
-}
-
-static inline int ne2000_check_state(NE2000State *s)
-{
- if (!s->tainted)
- return 0;
-
- if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE)
- return -EINVAL;
-
- if (!ne2000_valid_ring_addr(s, s->curpag))
- return -EINVAL;
-
- s->tainted = 0;
- return 0;
-}
-
-static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
-{
- NE2000State *s = opaque;
- uint8_t *p;
- unsigned int total_len, next, avail, len, index, mcast_idx;
- uint8_t buf1[60];
- static const uint8_t broadcast_macaddr[6] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-#if defined(DEBUG_NE2000)
- printf("NE2000: received len=%d\n", size);
-#endif
-
- if (ne2000_check_state(s))
- return;
-
- if (!ne2000_valid_ring_addr(s, s->boundary))
- return;
-
- if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
- return;
-
- /* XXX: check this */
- if (s->rxcr & 0x10) {
- /* promiscuous: receive all */
- } else {
- if (!memcmp(buf, broadcast_macaddr, 6)) {
- /* broadcast address */
- if (!(s->rxcr & 0x04))
- return;
- } else if (buf[0] & 0x01) {
- /* multicast */
- if (!(s->rxcr & 0x08))
- return;
- mcast_idx = compute_mcast_idx(buf);
- if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
- return;
- } else if (s->mem[0] == buf[0] &&
- s->mem[2] == buf[1] &&
- s->mem[4] == buf[2] &&
- s->mem[6] == buf[3] &&
- s->mem[8] == buf[4] &&
- s->mem[10] == buf[5]) {
- /* match */
- } else {
- return;
- }
- }
-
-
- /* if too small buffer, then expand it */
- if (size < MIN_BUF_SIZE) {
- memcpy(buf1, buf, size);
- memset(buf1 + size, 0, MIN_BUF_SIZE - size);
- buf = buf1;
- size = MIN_BUF_SIZE;
- }
-
- index = s->curpag << 8;
- /* 4 bytes for header */
- total_len = size + 4;
- /* address for next packet (4 bytes for CRC) */
- next = index + ((total_len + 4 + 255) & ~0xff);
- if (next >= s->stop)
- next -= (s->stop - s->start);
- /* prepare packet header */
- p = s->mem + index;
- s->rsr = ENRSR_RXOK; /* receive status */
- /* XXX: check this */
- if (buf[0] & 0x01)
- s->rsr |= ENRSR_PHY;
- p[0] = s->rsr;
- p[1] = next >> 8;
- p[2] = total_len;
- p[3] = total_len >> 8;
- index += 4;
-
- /* write packet data */
- while (size > 0) {
- /* taviso: this can wrap, so check its okay. */
- if (index <= s->stop)
- avail = s->stop - index;
- else
- avail = 0;
- len = size;
- if (len > avail)
- len = avail;
- memcpy(s->mem + index, buf, len);
- buf += len;
- index += len;
- if (index == s->stop)
- index = s->start;
- size -= len;
- }
- s->curpag = next >> 8;
-
- /* now we can signal we have received something */
- s->isr |= ENISR_RX;
- ne2000_update_irq(s);
-}
-
-static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- NE2000State *s = opaque;
- int offset, page, index;
-
- addr &= 0xf;
-#ifdef DEBUG_NE2000
- printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
-#endif
- if (addr == E8390_CMD) {
- /* control register */
- s->cmd = val;
- if (!(val & E8390_STOP)) { /* START bit makes no sense on RTL8029... */
- s->isr &= ~ENISR_RESET;
- /* test specific case: zero length transfert */
- if ((val & (E8390_RREAD | E8390_RWRITE)) &&
- s->rcnt == 0) {
- s->isr |= ENISR_RDC;
- ne2000_update_irq(s);
- }
- if (val & E8390_TRANS) {
- index = (s->tpsr << 8);
- /* XXX: next 2 lines are a hack to make netware 3.11 work */
- if (index >= NE2000_PMEM_END)
- index -= NE2000_PMEM_SIZE;
- /* fail safe: check range on the transmitted length */
- if (index + s->tcnt <= NE2000_PMEM_END) {
- qemu_send_packet(s->vc, s->mem + index, s->tcnt);
- }
- /* signal end of transfert */
- s->tsr = ENTSR_PTX;
- s->isr |= ENISR_TX;
- s->cmd &= ~E8390_TRANS;
- ne2000_update_irq(s);
- }
- }
- } else {
- page = s->cmd >> 6;
- offset = addr | (page << 4);
- switch(offset) {
- case EN0_STARTPG:
- s->start = val << 8;
- s->tainted = 1;
- break;
- case EN0_STOPPG:
- s->stop = val << 8;
- s->tainted = 1;
- break;
- case EN0_BOUNDARY:
- s->boundary = val;
- break;
- case EN0_IMR:
- s->imr = val;
- ne2000_update_irq(s);
- break;
- case EN0_TPSR:
- s->tpsr = val;
- break;
- case EN0_TCNTLO:
- s->tcnt = (s->tcnt & 0xff00) | val;
- break;
- case EN0_TCNTHI:
- s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
- break;
- case EN0_RSARLO:
- s->rsar = (s->rsar & 0xff00) | val;
- break;
- case EN0_RSARHI:
- s->rsar = (s->rsar & 0x00ff) | (val << 8);
- break;
- case EN0_RCNTLO:
- s->rcnt = (s->rcnt & 0xff00) | val;
- break;
- case EN0_RCNTHI:
- s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
- break;
- case EN0_RXCR:
- s->rxcr = val;
- break;
- case EN0_DCFG:
- s->dcfg = val;
- break;
- case EN0_ISR:
- s->isr &= ~(val & 0x7f);
- ne2000_update_irq(s);
- break;
- case EN1_PHYS ... EN1_PHYS + 5:
- s->phys[offset - EN1_PHYS] = val;
- break;
- case EN1_CURPAG:
- s->curpag = val;
- s->tainted = 1;
- break;
- case EN1_MULT ... EN1_MULT + 7:
- s->mult[offset - EN1_MULT] = val;
- break;
- }
- }
-}
-
-static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- int offset, page, ret;
-
- addr &= 0xf;
- if (addr == E8390_CMD) {
- ret = s->cmd;
- } else {
- page = s->cmd >> 6;
- offset = addr | (page << 4);
- switch(offset) {
- case EN0_TSR:
- ret = s->tsr;
- break;
- case EN0_BOUNDARY:
- ret = s->boundary;
- break;
- case EN0_ISR:
- ret = s->isr;
- break;
- case EN0_RSARLO:
- ret = s->rsar & 0x00ff;
- break;
- case EN0_RSARHI:
- ret = s->rsar >> 8;
- break;
- case EN1_PHYS ... EN1_PHYS + 5:
- ret = s->phys[offset - EN1_PHYS];
- break;
- case EN1_CURPAG:
- ret = s->curpag;
- break;
- case EN1_MULT ... EN1_MULT + 7:
- ret = s->mult[offset - EN1_MULT];
- break;
- case EN0_RSR:
- ret = s->rsr;
- break;
- case EN2_STARTPG:
- ret = s->start >> 8;
- break;
- case EN2_STOPPG:
- ret = s->stop >> 8;
- break;
- case EN0_RTL8029ID0:
- ret = 0x50;
- break;
- case EN0_RTL8029ID1:
- ret = 0x43;
- break;
- case EN3_CONFIG0:
- ret = 0; /* 10baseT media */
- break;
- case EN3_CONFIG2:
- ret = 0x40; /* 10baseT active */
- break;
- case EN3_CONFIG3:
- ret = 0x40; /* Full duplex */
- break;
- default:
- ret = 0x00;
- break;
- }
- }
-#ifdef DEBUG_NE2000
- printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
-#endif
- return ret;
-}
-
-static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
- uint32_t val)
-{
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- s->mem[addr] = val;
- }
-}
-
-static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
- uint32_t val)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- *(uint16_t *)(s->mem + addr) = cpu_to_le16(val);
- }
-}
-
-static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
- uint32_t val)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
- cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
- }
-}
-
-static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
-{
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- return s->mem[addr];
- } else {
- return 0xff;
- }
-}
-
-static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- return le16_to_cpu(*(uint16_t *)(s->mem + addr));
- } else {
- return 0xffff;
- }
-}
-
-static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
- return le32_to_cpupu((uint32_t *)(s->mem + addr));
- } else {
- return 0xffffffff;
- }
-}
-
-static inline void ne2000_dma_update(NE2000State *s, int len)
-{
- s->rsar += len;
- /* wrap */
- /* XXX: check what to do if rsar > stop */
- if (s->rsar == s->stop)
- s->rsar = s->start;
-
- if (s->rcnt <= len) {
- s->rcnt = 0;
- /* signal end of transfert */
- s->isr |= ENISR_RDC;
- ne2000_update_irq(s);
- } else {
- s->rcnt -= len;
- }
-}
-
-static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- NE2000State *s = opaque;
-
-#ifdef DEBUG_NE2000
- printf("NE2000: asic write val=0x%04x\n", val);
-#endif
- if (s->rcnt == 0)
- return;
- if (s->dcfg & 0x01) {
- /* 16 bit access */
- ne2000_mem_writew(s, s->rsar, val);
- ne2000_dma_update(s, 2);
- } else {
- /* 8 bit access */
- ne2000_mem_writeb(s, s->rsar, val);
- ne2000_dma_update(s, 1);
- }
-}
-
-static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- int ret;
-
- if (s->dcfg & 0x01) {
- /* 16 bit access */
- ret = ne2000_mem_readw(s, s->rsar);
- ne2000_dma_update(s, 2);
- } else {
- /* 8 bit access */
- ret = ne2000_mem_readb(s, s->rsar);
- ne2000_dma_update(s, 1);
- }
-#ifdef DEBUG_NE2000
- printf("NE2000: asic read val=0x%04x\n", ret);
-#endif
- return ret;
-}
-
-static void ne2000_asic_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- NE2000State *s = opaque;
-
-#ifdef DEBUG_NE2000
- printf("NE2000: asic writel val=0x%04x\n", val);
-#endif
- if (s->rcnt == 0)
- return;
- /* 32 bit access */
- ne2000_mem_writel(s, s->rsar, val);
- ne2000_dma_update(s, 4);
-}
-
-static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- int ret;
-
- /* 32 bit access */
- ret = ne2000_mem_readl(s, s->rsar);
- ne2000_dma_update(s, 4);
-#ifdef DEBUG_NE2000
- printf("NE2000: asic readl val=0x%04x\n", ret);
-#endif
- return ret;
-}
-
-static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- /* nothing to do (end of reset pulse) */
-}
-
-static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- ne2000_reset(s);
- return 0;
-}
-
-static void ne2000_save(QEMUFile* f,void* opaque)
-{
- NE2000State* s=(NE2000State*)opaque;
-
- if (s->pci_dev)
- pci_device_save(s->pci_dev, f);
-
- qemu_put_8s(f, &s->rxcr);
-
- qemu_put_8s(f, &s->cmd);
- qemu_put_be32s(f, &s->start);
- qemu_put_be32s(f, &s->stop);
- qemu_put_8s(f, &s->boundary);
- qemu_put_8s(f, &s->tsr);
- qemu_put_8s(f, &s->tpsr);
- qemu_put_be16s(f, &s->tcnt);
- qemu_put_be16s(f, &s->rcnt);
- qemu_put_be32s(f, &s->rsar);
- qemu_put_8s(f, &s->rsr);
- qemu_put_8s(f, &s->isr);
- qemu_put_8s(f, &s->dcfg);
- qemu_put_8s(f, &s->imr);
- qemu_put_buffer(f, s->phys, 6);
- qemu_put_8s(f, &s->curpag);
- qemu_put_buffer(f, s->mult, 8);
- qemu_put_be32s(f, &s->irq);
- qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE);
-}
-
-static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
-{
- NE2000State* s=(NE2000State*)opaque;
- int ret;
-
- if (version_id > 3)
- return -EINVAL;
-
- if (s->pci_dev && version_id >= 3) {
- ret = pci_device_load(s->pci_dev, f);
- if (ret < 0)
- return ret;
- }
-
- if (version_id >= 2) {
- qemu_get_8s(f, &s->rxcr);
- } else {
- s->rxcr = 0x0c;
- }
-
- qemu_get_8s(f, &s->cmd);
- qemu_get_be32s(f, &s->start);
- qemu_get_be32s(f, &s->stop);
- qemu_get_8s(f, &s->boundary);
- qemu_get_8s(f, &s->tsr);
- qemu_get_8s(f, &s->tpsr);
- qemu_get_be16s(f, &s->tcnt);
- qemu_get_be16s(f, &s->rcnt);
- qemu_get_be32s(f, &s->rsar);
- qemu_get_8s(f, &s->rsr);
- qemu_get_8s(f, &s->isr);
- qemu_get_8s(f, &s->dcfg);
- qemu_get_8s(f, &s->imr);
- qemu_get_buffer(f, s->phys, 6);
- qemu_get_8s(f, &s->curpag);
- qemu_get_buffer(f, s->mult, 8);
- qemu_get_be32s(f, &s->irq);
- qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE);
-
- return 0;
-}
-
-void isa_ne2000_init(int base, int irq, NICInfo *nd)
-{
- NE2000State *s;
-
- s = qemu_mallocz(sizeof(NE2000State));
- if (!s)
- return;
-
- register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
- register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
-
- register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s);
- register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s);
- register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s);
- register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s);
-
- register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
- register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
- s->irq = irq;
- memcpy(s->macaddr, nd->macaddr, 6);
-
- ne2000_reset(s);
-
- s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive,
- ne2000_can_receive, s);
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "ne2000 macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- s->macaddr[0],
- s->macaddr[1],
- s->macaddr[2],
- s->macaddr[3],
- s->macaddr[4],
- s->macaddr[5]);
-
- register_savevm("ne2000", base, 2, ne2000_save, ne2000_load, s);
-}
-
-/***********************************************************/
-/* PCI NE2000 definitions */
-
-typedef struct PCINE2000State {
- PCIDevice dev;
- NE2000State ne2000;
-} PCINE2000State;
-
-static void ne2000_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCINE2000State *d = (PCINE2000State *)pci_dev;
- NE2000State *s = &d->ne2000;
-
- register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
- register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
-
- register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
- register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
- register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
- register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
- register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
- register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
-
- register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
- register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
-}
-
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
-{
- PCINE2000State *d;
- NE2000State *s;
- uint8_t *pci_conf;
-
- d = (PCINE2000State *)pci_register_device(bus,
- "NE2000", sizeof(PCINE2000State),
- devfn,
- NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0xec; // Realtek 8029
- pci_conf[0x01] = 0x10;
- pci_conf[0x02] = 0x29;
- pci_conf[0x03] = 0x80;
- pci_conf[0x0a] = 0x00; // ethernet network controller
- pci_conf[0x0b] = 0x02;
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
- pci_conf[0x2d] = 0x58;
- pci_conf[0x2e] = 0x01; /* subsystem device */
- pci_conf[0x2f] = 0x00;
- pci_conf[0x3d] = 1; // interrupt pin 0
-
- pci_register_io_region(&d->dev, 0, 0x100,
- PCI_ADDRESS_SPACE_IO, ne2000_map);
- s = &d->ne2000;
- s->irq = 16; // PCI interrupt
- s->pci_dev = (PCIDevice *)d;
- memcpy(s->macaddr, nd->macaddr, 6);
- ne2000_reset(s);
- s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive,
- ne2000_can_receive, s);
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- s->macaddr[0],
- s->macaddr[1],
- s->macaddr[2],
- s->macaddr[3],
- s->macaddr[4],
- s->macaddr[5]);
-
- /* XXX: instance number ? */
- register_savevm("ne2000", 0, 3, ne2000_save, ne2000_load, s);
-}
diff --git a/tools/ioemu/hw/openpic.c b/tools/ioemu/hw/openpic.c
deleted file mode 100644
index 31773373ac..0000000000
--- a/tools/ioemu/hw/openpic.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * OpenPIC emulation
- *
- * Copyright (c) 2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- *
- * Based on OpenPic implementations:
- * - Intel GW80314 I/O compagnion chip developper's manual
- * - Motorola MPC8245 & MPC8540 user manuals.
- * - Motorola MCP750 (aka Raven) programmer manual.
- * - Motorola Harrier programmer manuel
- *
- * Serial interrupts, as implemented in Raven chipset are not supported yet.
- *
- */
-#include "vl.h"
-
-//#define DEBUG_OPENPIC
-
-#ifdef DEBUG_OPENPIC
-#define DPRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do { } while (0)
-#endif
-#define ERROR(fmr, args...) do { printf("ERROR: " fmr , ##args); } while (0)
-
-#define USE_MPCxxx /* Intel model is broken, for now */
-
-#if defined (USE_INTEL_GW80314)
-/* Intel GW80314 I/O Companion chip */
-
-#define MAX_CPU 4
-#define MAX_IRQ 32
-#define MAX_DBL 4
-#define MAX_MBX 4
-#define MAX_TMR 4
-#define VECTOR_BITS 8
-#define MAX_IPI 0
-
-#define VID (0x00000000)
-
-#define OPENPIC_LITTLE_ENDIAN 1
-#define OPENPIC_BIG_ENDIAN 0
-
-#elif defined(USE_MPCxxx)
-
-#define MAX_CPU 2
-#define MAX_IRQ 64
-#define EXT_IRQ 48
-#define MAX_DBL 0
-#define MAX_MBX 0
-#define MAX_TMR 4
-#define VECTOR_BITS 8
-#define MAX_IPI 4
-#define VID 0x03 /* MPIC version ID */
-#define VENI 0x00000000 /* Vendor ID */
-
-enum {
- IRQ_IPVP = 0,
- IRQ_IDE,
-};
-
-#define OPENPIC_LITTLE_ENDIAN 1
-#define OPENPIC_BIG_ENDIAN 0
-
-#else
-#error "Please select which OpenPic implementation is to be emulated"
-#endif
-
-#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
- (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
-#define OPENPIC_SWAP
-#endif
-
-/* Interrupt definitions */
-#define IRQ_FE (EXT_IRQ) /* Internal functional IRQ */
-#define IRQ_ERR (EXT_IRQ + 1) /* Error IRQ */
-#define IRQ_TIM0 (EXT_IRQ + 2) /* First timer IRQ */
-#if MAX_IPI > 0
-#define IRQ_IPI0 (IRQ_TIM0 + MAX_TMR) /* First IPI IRQ */
-#define IRQ_DBL0 (IRQ_IPI0 + (MAX_CPU * MAX_IPI)) /* First doorbell IRQ */
-#else
-#define IRQ_DBL0 (IRQ_TIM0 + MAX_TMR) /* First doorbell IRQ */
-#define IRQ_MBX0 (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
-#endif
-
-#define BF_WIDTH(_bits_) \
-(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
-
-static inline void set_bit (uint32_t *field, int bit)
-{
- field[bit >> 5] |= 1 << (bit & 0x1F);
-}
-
-static inline void reset_bit (uint32_t *field, int bit)
-{
- field[bit >> 5] &= ~(1 << (bit & 0x1F));
-}
-
-static inline int test_bit (uint32_t *field, int bit)
-{
- return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0;
-}
-
-enum {
- IRQ_EXTERNAL = 0x01,
- IRQ_INTERNAL = 0x02,
- IRQ_TIMER = 0x04,
- IRQ_SPECIAL = 0x08,
-} IRQ_src_type;
-
-typedef struct IRQ_queue_t {
- uint32_t queue[BF_WIDTH(MAX_IRQ)];
- int next;
- int priority;
-} IRQ_queue_t;
-
-typedef struct IRQ_src_t {
- uint32_t ipvp; /* IRQ vector/priority register */
- uint32_t ide; /* IRQ destination register */
- int type;
- int last_cpu;
- int pending; /* TRUE if IRQ is pending */
-} IRQ_src_t;
-
-enum IPVP_bits {
- IPVP_MASK = 31,
- IPVP_ACTIVITY = 30,
- IPVP_MODE = 29,
- IPVP_POLARITY = 23,
- IPVP_SENSE = 22,
-};
-#define IPVP_PRIORITY_MASK (0x1F << 16)
-#define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))
-#define IPVP_VECTOR_MASK ((1 << VECTOR_BITS) - 1)
-#define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK)
-
-typedef struct IRQ_dst_t {
- uint32_t pctp; /* CPU current task priority */
- uint32_t pcsr; /* CPU sensitivity register */
- IRQ_queue_t raised;
- IRQ_queue_t servicing;
- CPUState *env;
-} IRQ_dst_t;
-
-struct openpic_t {
- PCIDevice pci_dev;
- int mem_index;
- /* Global registers */
- uint32_t frep; /* Feature reporting register */
- uint32_t glbc; /* Global configuration register */
- uint32_t micr; /* MPIC interrupt configuration register */
- uint32_t veni; /* Vendor identification register */
- uint32_t spve; /* Spurious vector register */
- uint32_t tifr; /* Timer frequency reporting register */
- /* Source registers */
- IRQ_src_t src[MAX_IRQ];
- /* Local registers per output pin */
- IRQ_dst_t dst[MAX_CPU];
- int nb_cpus;
- /* Timer registers */
- struct {
- uint32_t ticc; /* Global timer current count register */
- uint32_t tibc; /* Global timer base count register */
- } timers[MAX_TMR];
-#if MAX_DBL > 0
- /* Doorbell registers */
- uint32_t dar; /* Doorbell activate register */
- struct {
- uint32_t dmr; /* Doorbell messaging register */
- } doorbells[MAX_DBL];
-#endif
-#if MAX_MBX > 0
- /* Mailbox registers */
- struct {
- uint32_t mbr; /* Mailbox register */
- } mailboxes[MAX_MAILBOXES];
-#endif
-};
-
-static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
-{
- set_bit(q->queue, n_IRQ);
-}
-
-static inline void IRQ_resetbit (IRQ_queue_t *q, int n_IRQ)
-{
- reset_bit(q->queue, n_IRQ);
-}
-
-static inline int IRQ_testbit (IRQ_queue_t *q, int n_IRQ)
-{
- return test_bit(q->queue, n_IRQ);
-}
-
-static void IRQ_check (openpic_t *opp, IRQ_queue_t *q)
-{
- int next, i;
- int priority;
-
- next = -1;
- priority = -1;
- for (i = 0; i < MAX_IRQ; i++) {
- if (IRQ_testbit(q, i)) {
- DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
- i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
- if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {
- next = i;
- priority = IPVP_PRIORITY(opp->src[i].ipvp);
- }
- }
- }
- q->next = next;
- q->priority = priority;
-}
-
-static int IRQ_get_next (openpic_t *opp, IRQ_queue_t *q)
-{
- if (q->next == -1) {
- /* XXX: optimize */
- IRQ_check(opp, q);
- }
-
- return q->next;
-}
-
-static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
-{
- IRQ_dst_t *dst;
- IRQ_src_t *src;
- int priority;
-
- dst = &opp->dst[n_CPU];
- src = &opp->src[n_IRQ];
- priority = IPVP_PRIORITY(src->ipvp);
- if (priority <= dst->pctp) {
- /* Too low priority */
- return;
- }
- if (IRQ_testbit(&dst->raised, n_IRQ)) {
- /* Interrupt miss */
- return;
- }
- set_bit(&src->ipvp, IPVP_ACTIVITY);
- IRQ_setbit(&dst->raised, n_IRQ);
- if (priority > dst->raised.priority) {
- IRQ_get_next(opp, &dst->raised);
- DPRINTF("Raise CPU IRQ\n");
- cpu_interrupt(dst->env, CPU_INTERRUPT_HARD);
- }
-}
-
-/* update pic state because registers for n_IRQ have changed value */
-static void openpic_update_irq(openpic_t *opp, int n_IRQ)
-{
- IRQ_src_t *src;
- int i;
-
- src = &opp->src[n_IRQ];
-
- if (!src->pending) {
- /* no irq pending */
- return;
- }
- if (test_bit(&src->ipvp, IPVP_MASK)) {
- /* Interrupt source is disabled */
- return;
- }
- if (IPVP_PRIORITY(src->ipvp) == 0) {
- /* Priority set to zero */
- return;
- }
- if (test_bit(&src->ipvp, IPVP_ACTIVITY)) {
- /* IRQ already active */
- return;
- }
- if (src->ide == 0x00000000) {
- /* No target */
- return;
- }
-
- if (!test_bit(&src->ipvp, IPVP_MODE) ||
- src->ide == (1 << src->last_cpu)) {
- /* Directed delivery mode */
- for (i = 0; i < opp->nb_cpus; i++) {
- if (test_bit(&src->ide, i))
- IRQ_local_pipe(opp, i, n_IRQ);
- }
- } else {
- /* Distributed delivery mode */
- /* XXX: incorrect code */
- for (i = src->last_cpu; i < src->last_cpu; i++) {
- if (i == MAX_IRQ)
- i = 0;
- if (test_bit(&src->ide, i)) {
- IRQ_local_pipe(opp, i, n_IRQ);
- src->last_cpu = i;
- break;
- }
- }
- }
-}
-
-void openpic_set_irq(void *opaque, int n_IRQ, int level)
-{
- openpic_t *opp = opaque;
- IRQ_src_t *src;
-
- src = &opp->src[n_IRQ];
- DPRINTF("openpic: set irq %d = %d ipvp=%08x\n",
- n_IRQ, level, src->ipvp);
- if (test_bit(&src->ipvp, IPVP_SENSE)) {
- /* level-sensitive irq */
- src->pending = level;
- if (!level)
- reset_bit(&src->ipvp, IPVP_ACTIVITY);
- } else {
- /* edge-sensitive irq */
- if (level)
- src->pending = 1;
- }
- openpic_update_irq(opp, n_IRQ);
-}
-
-static void openpic_reset (openpic_t *opp)
-{
- int i;
-
- opp->glbc = 0x80000000;
- /* Initialise controller registers */
- opp->frep = ((EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
- opp->veni = VENI;
- opp->spve = 0x000000FF;
- opp->tifr = 0x003F7A00;
- /* ? */
- opp->micr = 0x00000000;
- /* Initialise IRQ sources */
- for (i = 0; i < MAX_IRQ; i++) {
- opp->src[i].ipvp = 0xA0000000;
- opp->src[i].ide = 0x00000000;
- }
- /* Initialise IRQ destinations */
- for (i = 0; i < opp->nb_cpus; i++) {
- opp->dst[i].pctp = 0x0000000F;
- opp->dst[i].pcsr = 0x00000000;
- memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));
- memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
- }
- /* Initialise timers */
- for (i = 0; i < MAX_TMR; i++) {
- opp->timers[i].ticc = 0x00000000;
- opp->timers[i].tibc = 0x80000000;
- }
- /* Initialise doorbells */
-#if MAX_DBL > 0
- opp->dar = 0x00000000;
- for (i = 0; i < MAX_DBL; i++) {
- opp->doorbells[i].dmr = 0x00000000;
- }
-#endif
- /* Initialise mailboxes */
-#if MAX_MBX > 0
- for (i = 0; i < MAX_MBX; i++) { /* ? */
- opp->mailboxes[i].mbr = 0x00000000;
- }
-#endif
- /* Go out of RESET state */
- opp->glbc = 0x00000000;
-}
-
-static inline uint32_t read_IRQreg (openpic_t *opp, int n_IRQ, uint32_t reg)
-{
- uint32_t retval;
-
- switch (reg) {
- case IRQ_IPVP:
- retval = opp->src[n_IRQ].ipvp;
- break;
- case IRQ_IDE:
- retval = opp->src[n_IRQ].ide;
- break;
- }
-
- return retval;
-}
-
-static inline void write_IRQreg (openpic_t *opp, int n_IRQ,
- uint32_t reg, uint32_t val)
-{
- uint32_t tmp;
-
- switch (reg) {
- case IRQ_IPVP:
- /* NOTE: not fully accurate for special IRQs, but simple and
- sufficient */
- /* ACTIVITY bit is read-only */
- opp->src[n_IRQ].ipvp =
- (opp->src[n_IRQ].ipvp & 0x40000000) |
- (val & 0x800F00FF);
- openpic_update_irq(opp, n_IRQ);
- DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n",
- n_IRQ, val, opp->src[n_IRQ].ipvp);
- break;
- case IRQ_IDE:
- tmp = val & 0xC0000000;
- tmp |= val & ((1 << MAX_CPU) - 1);
- opp->src[n_IRQ].ide = tmp;
- DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);
- break;
- }
-}
-
-#if 0 // Code provision for Intel model
-#if MAX_DBL > 0
-static uint32_t read_doorbell_register (openpic_t *opp,
- int n_dbl, uint32_t offset)
-{
- uint32_t retval;
-
- switch (offset) {
- case DBL_IPVP_OFFSET:
- retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP);
- break;
- case DBL_IDE_OFFSET:
- retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE);
- break;
- case DBL_DMR_OFFSET:
- retval = opp->doorbells[n_dbl].dmr;
- break;
- }
-
- return retval;
-}
-
-static void write_doorbell_register (penpic_t *opp, int n_dbl,
- uint32_t offset, uint32_t value)
-{
- switch (offset) {
- case DBL_IVPR_OFFSET:
- write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP, value);
- break;
- case DBL_IDE_OFFSET:
- write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE, value);
- break;
- case DBL_DMR_OFFSET:
- opp->doorbells[n_dbl].dmr = value;
- break;
- }
-}
-#endif
-
-#if MAX_MBX > 0
-static uint32_t read_mailbox_register (openpic_t *opp,
- int n_mbx, uint32_t offset)
-{
- uint32_t retval;
-
- switch (offset) {
- case MBX_MBR_OFFSET:
- retval = opp->mailboxes[n_mbx].mbr;
- break;
- case MBX_IVPR_OFFSET:
- retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP);
- break;
- case MBX_DMR_OFFSET:
- retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE);
- break;
- }
-
- return retval;
-}
-
-static void write_mailbox_register (openpic_t *opp, int n_mbx,
- uint32_t address, uint32_t value)
-{
- switch (offset) {
- case MBX_MBR_OFFSET:
- opp->mailboxes[n_mbx].mbr = value;
- break;
- case MBX_IVPR_OFFSET:
- write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP, value);
- break;
- case MBX_DMR_OFFSET:
- write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE, value);
- break;
- }
-}
-#endif
-#endif /* 0 : Code provision for Intel model */
-
-static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = bswap32(val);
-#endif
- addr &= 0xFF;
- switch (addr) {
- case 0x00: /* FREP */
- break;
- case 0x20: /* GLBC */
- if (val & 0x80000000)
- openpic_reset(opp);
- opp->glbc = val & ~0x80000000;
- break;
- case 0x80: /* VENI */
- break;
- case 0x90: /* PINT */
- /* XXX: Should be able to reset any CPU */
- if (val & 1) {
- DPRINTF("Reset CPU IRQ\n");
- // cpu_interrupt(first_cpu, CPU_INTERRUPT_RESET);
- }
- break;
-#if MAX_IPI > 0
- case 0xA0: /* IPI_IPVP */
- case 0xB0:
- case 0xC0:
- case 0xD0:
- {
- int idx;
- idx = (addr - 0xA0) >> 4;
- write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP, val);
- }
- break;
-#endif
- case 0xE0: /* SPVE */
- opp->spve = val & 0x000000FF;
- break;
- case 0xF0: /* TIFR */
- opp->tifr = val;
- break;
- default:
- break;
- }
-}
-
-static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr &= 0xFF;
- switch (addr) {
- case 0x00: /* FREP */
- retval = opp->frep;
- break;
- case 0x20: /* GLBC */
- retval = opp->glbc;
- break;
- case 0x80: /* VENI */
- retval = opp->veni;
- break;
- case 0x90: /* PINT */
- retval = 0x00000000;
- break;
-#if MAX_IPI > 0
- case 0xA0: /* IPI_IPVP */
- case 0xB0:
- case 0xC0:
- case 0xD0:
- {
- int idx;
- idx = (addr - 0xA0) >> 4;
- retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP);
- }
- break;
-#endif
- case 0xE0: /* SPVE */
- retval = opp->spve;
- break;
- case 0xF0: /* TIFR */
- retval = opp->tifr;
- break;
- default:
- break;
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval = bswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
- int idx;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = bswap32(val);
-#endif
- addr -= 0x1100;
- addr &= 0xFFFF;
- idx = (addr & 0xFFF0) >> 6;
- addr = addr & 0x30;
- switch (addr) {
- case 0x00: /* TICC */
- break;
- case 0x10: /* TIBC */
- if ((opp->timers[idx].ticc & 0x80000000) != 0 &&
- (val & 0x80000000) == 0 &&
- (opp->timers[idx].tibc & 0x80000000) != 0)
- opp->timers[idx].ticc &= ~0x80000000;
- opp->timers[idx].tibc = val;
- break;
- case 0x20: /* TIVP */
- write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP, val);
- break;
- case 0x30: /* TIDE */
- write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE, val);
- break;
- }
-}
-
-static uint32_t openpic_timer_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
- int idx;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr -= 0x1100;
- addr &= 0xFFFF;
- idx = (addr & 0xFFF0) >> 6;
- addr = addr & 0x30;
- switch (addr) {
- case 0x00: /* TICC */
- retval = opp->timers[idx].ticc;
- break;
- case 0x10: /* TIBC */
- retval = opp->timers[idx].tibc;
- break;
- case 0x20: /* TIPV */
- retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP);
- break;
- case 0x30: /* TIDE */
- retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE);
- break;
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval = bswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_src_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
- int idx;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = tswap32(val);
-#endif
- addr = addr & 0xFFF0;
- idx = addr >> 5;
- if (addr & 0x10) {
- /* EXDE / IFEDE / IEEDE */
- write_IRQreg(opp, idx, IRQ_IDE, val);
- } else {
- /* EXVP / IFEVP / IEEVP */
- write_IRQreg(opp, idx, IRQ_IPVP, val);
- }
-}
-
-static uint32_t openpic_src_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
- int idx;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr = addr & 0xFFF0;
- idx = addr >> 5;
- if (addr & 0x10) {
- /* EXDE / IFEDE / IEEDE */
- retval = read_IRQreg(opp, idx, IRQ_IDE);
- } else {
- /* EXVP / IFEVP / IEEVP */
- retval = read_IRQreg(opp, idx, IRQ_IPVP);
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval = tswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
- IRQ_src_t *src;
- IRQ_dst_t *dst;
- int idx, n_IRQ;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = bswap32(val);
-#endif
- addr &= 0x1FFF0;
- idx = addr / 0x1000;
- dst = &opp->dst[idx];
- addr &= 0xFF0;
- switch (addr) {
-#if MAX_IPI > 0
- case 0x40: /* PIPD */
- case 0x50:
- case 0x60:
- case 0x70:
- idx = (addr - 0x40) >> 4;
- write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE, val);
- openpic_set_irq(opp, IRQ_IPI0 + idx, 1);
- openpic_set_irq(opp, IRQ_IPI0 + idx, 0);
- break;
-#endif
- case 0x80: /* PCTP */
- dst->pctp = val & 0x0000000F;
- break;
- case 0x90: /* WHOAMI */
- /* Read-only register */
- break;
- case 0xA0: /* PIAC */
- /* Read-only register */
- break;
- case 0xB0: /* PEOI */
- DPRINTF("PEOI\n");
- n_IRQ = IRQ_get_next(opp, &dst->servicing);
- IRQ_resetbit(&dst->servicing, n_IRQ);
- dst->servicing.next = -1;
- src = &opp->src[n_IRQ];
- /* Set up next servicing IRQ */
- IRQ_get_next(opp, &dst->servicing);
- /* Check queued interrupts. */
- n_IRQ = IRQ_get_next(opp, &dst->raised);
- if (n_IRQ != -1) {
- src = &opp->src[n_IRQ];
- if (IPVP_PRIORITY(src->ipvp) > dst->servicing.priority) {
- DPRINTF("Raise CPU IRQ\n");
- cpu_interrupt(dst->env, CPU_INTERRUPT_HARD);
- }
- }
- break;
- default:
- break;
- }
-}
-
-static uint32_t openpic_cpu_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- IRQ_src_t *src;
- IRQ_dst_t *dst;
- uint32_t retval;
- int idx, n_IRQ;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr &= 0x1FFF0;
- idx = addr / 0x1000;
- dst = &opp->dst[idx];
- addr &= 0xFF0;
- switch (addr) {
- case 0x80: /* PCTP */
- retval = dst->pctp;
- break;
- case 0x90: /* WHOAMI */
- retval = idx;
- break;
- case 0xA0: /* PIAC */
- n_IRQ = IRQ_get_next(opp, &dst->raised);
- DPRINTF("PIAC: irq=%d\n", n_IRQ);
- if (n_IRQ == -1) {
- /* No more interrupt pending */
- retval = opp->spve;
- } else {
- src = &opp->src[n_IRQ];
- if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||
- !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {
- /* - Spurious level-sensitive IRQ
- * - Priorities has been changed
- * and the pending IRQ isn't allowed anymore
- */
- reset_bit(&src->ipvp, IPVP_ACTIVITY);
- retval = IPVP_VECTOR(opp->spve);
- } else {
- /* IRQ enter servicing state */
- IRQ_setbit(&dst->servicing, n_IRQ);
- retval = IPVP_VECTOR(src->ipvp);
- }
- IRQ_resetbit(&dst->raised, n_IRQ);
- dst->raised.next = -1;
- if (!test_bit(&src->ipvp, IPVP_SENSE)) {
- /* edge-sensitive IRQ */
- reset_bit(&src->ipvp, IPVP_ACTIVITY);
- src->pending = 0;
- }
- }
- break;
- case 0xB0: /* PEOI */
- retval = 0;
- break;
-#if MAX_IPI > 0
- case 0x40: /* IDE */
- case 0x50:
- idx = (addr - 0x40) >> 4;
- retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE);
- break;
-#endif
- default:
- break;
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval= bswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_buggy_write (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- printf("Invalid OPENPIC write access !\n");
-}
-
-static uint32_t openpic_buggy_read (void *opaque, target_phys_addr_t addr)
-{
- printf("Invalid OPENPIC read access !\n");
-
- return -1;
-}
-
-static void openpic_writel (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
-
- addr &= 0x3FFFF;
- DPRINTF("%s: offset %08x val: %08x\n", __func__, (int)addr, val);
- if (addr < 0x1100) {
- /* Global registers */
- openpic_gbl_write(opp, addr, val);
- } else if (addr < 0x10000) {
- /* Timers registers */
- openpic_timer_write(opp, addr, val);
- } else if (addr < 0x20000) {
- /* Source registers */
- openpic_src_write(opp, addr, val);
- } else {
- /* CPU registers */
- openpic_cpu_write(opp, addr, val);
- }
-}
-
-static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
-
- addr &= 0x3FFFF;
- DPRINTF("%s: offset %08x\n", __func__, (int)addr);
- if (addr < 0x1100) {
- /* Global registers */
- retval = openpic_gbl_read(opp, addr);
- } else if (addr < 0x10000) {
- /* Timers registers */
- retval = openpic_timer_read(opp, addr);
- } else if (addr < 0x20000) {
- /* Source registers */
- retval = openpic_src_read(opp, addr);
- } else {
- /* CPU registers */
- retval = openpic_cpu_read(opp, addr);
- }
-
- return retval;
-}
-
-static CPUWriteMemoryFunc *openpic_write[] = {
- &openpic_buggy_write,
- &openpic_buggy_write,
- &openpic_writel,
-};
-
-static CPUReadMemoryFunc *openpic_read[] = {
- &openpic_buggy_read,
- &openpic_buggy_read,
- &openpic_readl,
-};
-
-static void openpic_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- openpic_t *opp;
-
- DPRINTF("Map OpenPIC\n");
- opp = (openpic_t *)pci_dev;
- /* Global registers */
- DPRINTF("Register OPENPIC gbl %08x => %08x\n",
- addr + 0x1000, addr + 0x1000 + 0x100);
- /* Timer registers */
- DPRINTF("Register OPENPIC timer %08x => %08x\n",
- addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
- /* Interrupt source registers */
- DPRINTF("Register OPENPIC src %08x => %08x\n",
- addr + 0x10000, addr + 0x10000 + 0x20 * (EXT_IRQ + 2));
- /* Per CPU registers */
- DPRINTF("Register OPENPIC dst %08x => %08x\n",
- addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
- cpu_register_physical_memory(addr, 0x40000, opp->mem_index);
-#if 0 // Don't implement ISU for now
- opp_io_memory = cpu_register_io_memory(0, openpic_src_read,
- openpic_src_write);
- cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
- opp_io_memory);
-#endif
-}
-
-openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
- CPUPPCState **envp)
-{
- openpic_t *opp;
- uint8_t *pci_conf;
- int i, m;
-
- /* XXX: for now, only one CPU is supported */
- if (nb_cpus != 1)
- return NULL;
- if (bus) {
- opp = (openpic_t *)pci_register_device(bus, "OpenPIC", sizeof(openpic_t),
- -1, NULL, NULL);
- if (opp == NULL)
- return NULL;
- pci_conf = opp->pci_dev.config;
- pci_conf[0x00] = 0x14; // IBM MPIC2
- pci_conf[0x01] = 0x10;
- pci_conf[0x02] = 0xFF;
- pci_conf[0x03] = 0xFF;
- pci_conf[0x0a] = 0x80; // PIC
- pci_conf[0x0b] = 0x08;
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x3d] = 0x00; // no interrupt pin
-
- /* Register I/O spaces */
- pci_register_io_region((PCIDevice *)opp, 0, 0x40000,
- PCI_ADDRESS_SPACE_MEM, &openpic_map);
- } else {
- opp = qemu_mallocz(sizeof(openpic_t));
- }
-
- opp->mem_index = cpu_register_io_memory(0, openpic_read,
- openpic_write, opp);
-
- // isu_base &= 0xFFFC0000;
- opp->nb_cpus = nb_cpus;
- /* Set IRQ types */
- for (i = 0; i < EXT_IRQ; i++) {
- opp->src[i].type = IRQ_EXTERNAL;
- }
- for (; i < IRQ_TIM0; i++) {
- opp->src[i].type = IRQ_SPECIAL;
- }
-#if MAX_IPI > 0
- m = IRQ_IPI0;
-#else
- m = IRQ_DBL0;
-#endif
- for (; i < m; i++) {
- opp->src[i].type = IRQ_TIMER;
- }
- for (; i < MAX_IRQ; i++) {
- opp->src[i].type = IRQ_INTERNAL;
- }
- for (i = 0; i < nb_cpus; i++)
- opp->dst[i].env = envp[i];
- openpic_reset(opp);
- if (pmem_index)
- *pmem_index = opp->mem_index;
- return opp;
-}
diff --git a/tools/ioemu/hw/parallel.c b/tools/ioemu/hw/parallel.c
deleted file mode 100644
index cba95610ef..0000000000
--- a/tools/ioemu/hw/parallel.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * QEMU Parallel PORT emulation
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_PARALLEL
-
-/*
- * These are the definitions for the Printer Status Register
- */
-#define PARA_STS_BUSY 0x80 /* Busy complement */
-#define PARA_STS_ACK 0x40 /* Acknowledge */
-#define PARA_STS_PAPER 0x20 /* Out of paper */
-#define PARA_STS_ONLINE 0x10 /* Online */
-#define PARA_STS_ERROR 0x08 /* Error complement */
-
-/*
- * These are the definitions for the Printer Control Register
- */
-#define PARA_CTR_INTEN 0x10 /* IRQ Enable */
-#define PARA_CTR_SELECT 0x08 /* Select In complement */
-#define PARA_CTR_INIT 0x04 /* Initialize Printer complement */
-#define PARA_CTR_AUTOLF 0x02 /* Auto linefeed complement */
-#define PARA_CTR_STROBE 0x01 /* Strobe complement */
-
-struct ParallelState {
- uint8_t data;
- uint8_t status; /* read only register */
- uint8_t control;
- int irq;
- int irq_pending;
- CharDriverState *chr;
- int hw_driver;
-};
-
-static void parallel_update_irq(ParallelState *s)
-{
- if (s->irq_pending)
- pic_set_irq(s->irq, 1);
- else
- pic_set_irq(s->irq, 0);
-}
-
-static void parallel_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- ParallelState *s = opaque;
-
- addr &= 7;
-#ifdef DEBUG_PARALLEL
- printf("parallel: write addr=0x%02x val=0x%02x\n", addr, val);
-#endif
- switch(addr) {
- case 0:
- if (s->hw_driver) {
- s->data = val;
- qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &s->data);
- } else {
- s->data = val;
- parallel_update_irq(s);
- }
- break;
- case 2:
- if (s->hw_driver) {
- s->control = val;
- qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &s->control);
- } else {
- if ((val & PARA_CTR_INIT) == 0 ) {
- s->status = PARA_STS_BUSY;
- s->status |= PARA_STS_ACK;
- s->status |= PARA_STS_ONLINE;
- s->status |= PARA_STS_ERROR;
- }
- else if (val & PARA_CTR_SELECT) {
- if (val & PARA_CTR_STROBE) {
- s->status &= ~PARA_STS_BUSY;
- if ((s->control & PARA_CTR_STROBE) == 0)
- qemu_chr_write(s->chr, &s->data, 1);
- } else {
- if (s->control & PARA_CTR_INTEN) {
- s->irq_pending = 1;
- }
- }
- }
- parallel_update_irq(s);
- s->control = val;
- }
- break;
- }
-}
-
-static uint32_t parallel_ioport_read(void *opaque, uint32_t addr)
-{
- ParallelState *s = opaque;
- uint32_t ret = 0xff;
-
- addr &= 7;
- switch(addr) {
- case 0:
- if (s->hw_driver) {
- qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &s->data);
- }
- ret = s->data;
- break;
- case 1:
- if (s->hw_driver) {
- qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &s->status);
- ret = s->status;
- } else {
- ret = s->status;
- s->irq_pending = 0;
- if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
- /* XXX Fixme: wait 5 microseconds */
- if (s->status & PARA_STS_ACK)
- s->status &= ~PARA_STS_ACK;
- else {
- /* XXX Fixme: wait 5 microseconds */
- s->status |= PARA_STS_ACK;
- s->status |= PARA_STS_BUSY;
- }
- }
- parallel_update_irq(s);
- }
- break;
- case 2:
- if (s->hw_driver) {
- qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &s->control);
- }
- ret = s->control;
- break;
- }
-#ifdef DEBUG_PARALLEL
- printf("parallel: read addr=0x%02x val=0x%02x\n", addr, ret);
-#endif
- return ret;
-}
-
-/* If fd is zero, it means that the parallel device uses the console */
-ParallelState *parallel_init(int base, int irq, CharDriverState *chr)
-{
- ParallelState *s;
- uint8_t dummy;
-
- s = qemu_mallocz(sizeof(ParallelState));
- if (!s)
- return NULL;
- s->chr = chr;
- s->hw_driver = 0;
- if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0)
- s->hw_driver = 1;
-
- s->irq = irq;
- s->data = 0;
- s->status = PARA_STS_BUSY;
- s->status |= PARA_STS_ACK;
- s->status |= PARA_STS_ONLINE;
- s->status |= PARA_STS_ERROR;
- s->control = PARA_CTR_SELECT;
- s->control |= PARA_CTR_INIT;
-
- register_ioport_write(base, 8, 1, parallel_ioport_write, s);
- register_ioport_read(base, 8, 1, parallel_ioport_read, s);
- return s;
-}
diff --git a/tools/ioemu/hw/pass-through.c b/tools/ioemu/hw/pass-through.c
deleted file mode 100644
index 875f9e1ab6..0000000000
--- a/tools/ioemu/hw/pass-through.c
+++ /dev/null
@@ -1,3146 +0,0 @@
-/*
- * Copyright (c) 2007, Neocleus Corporation.
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Alex Novik <alex@neocleus.com>
- * Allen Kay <allen.m.kay@intel.com>
- * Guy Zana <guy@neocleus.com>
- *
- * This file implements direct PCI assignment to a HVM guest
- */
-
-#include "vl.h"
-#include "pass-through.h"
-#include "pci/header.h"
-#include "pci/pci.h"
-#include "pt-msi.h"
-
-extern FILE *logfile;
-
-struct php_dev {
- struct pt_dev *pt_dev;
- uint8_t valid;
- uint8_t r_bus;
- uint8_t r_dev;
- uint8_t r_func;
-};
-struct dpci_infos {
-
- struct php_dev php_devs[PHP_SLOT_LEN];
-
- PCIBus *e_bus;
- struct pci_access *pci_access;
-
-} dpci_infos;
-
-/* prototype */
-static uint32_t pt_common_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_ptr_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_status_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_irqpin_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_bar_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_linkctrl_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_devctrl2_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_linkctrl2_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_msgctrl_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_msgaddr32_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_msgaddr64_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_msgdata_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset);
-static uint8_t pt_reg_grp_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
-static uint8_t pt_msi_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
-static uint8_t pt_msix_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
-static uint8_t pt_vendor_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
-static uint8_t pt_pcie_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
-static int pt_byte_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint8_t *valueu, uint8_t valid_mask);
-static int pt_word_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask);
-static int pt_long_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t valid_mask);
-static int pt_bar_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t valid_mask);
-static int pt_byte_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint8_t *value, uint8_t dev_value, uint8_t valid_mask);
-static int pt_word_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_long_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask);
-static int pt_cmd_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_bar_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask);
-static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask);
-static int pt_pmcsr_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_devctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_linkctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_devctrl2_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_linkctrl2_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_msgctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_msgaddr32_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask);
-static int pt_msgaddr64_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask);
-static int pt_msgdata_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-static int pt_msixctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
-
-/* pt_reg_info_tbl declaration
- * - only for emulated register (either a part or whole bit).
- * - for passthrough register that need special behavior (like interacting with
- * other component), set emu_mask to all 0 and specify r/w func properly.
- * - do NOT use ALL F for init_val, otherwise the tbl will not be registered.
- */
-
-/* Header Type0 reg static infomation table */
-static struct pt_reg_info_tbl pt_emu_reg_header0_tbl[] = {
- /* Command reg */
- {
- .offset = PCI_COMMAND,
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0xF880,
- .emu_mask = 0x0340,
- .init = pt_common_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_cmd_reg_write,
- },
- /* Capabilities Pointer reg */
- {
- .offset = PCI_CAPABILITY_LIST,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_ptr_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Status reg */
- /* use emulated Cap Ptr value to initialize,
- * so need to be declared after Cap Ptr reg
- */
- {
- .offset = PCI_STATUS,
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x06FF,
- .emu_mask = 0x0010,
- .init = pt_status_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_word_reg_write,
- },
- /* Cache Line Size reg */
- {
- .offset = PCI_CACHE_LINE_SIZE,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0x00,
- .emu_mask = 0xFF,
- .init = pt_common_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Latency Timer reg */
- {
- .offset = PCI_LATENCY_TIMER,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0x00,
- .emu_mask = 0xFF,
- .init = pt_common_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Header Type reg */
- {
- .offset = PCI_HEADER_TYPE,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0x80,
- .init = pt_common_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Interrupt Line reg */
- {
- .offset = PCI_INTERRUPT_LINE,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0x00,
- .emu_mask = 0xFF,
- .init = pt_common_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Interrupt Pin reg */
- {
- .offset = PCI_INTERRUPT_PIN,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_irqpin_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* BAR 0 reg */
- /* mask of BAR need to be decided later, depends on IO/MEM type */
- {
- .offset = PCI_BASE_ADDRESS_0,
- .size = 4,
- .init_val = 0x00000000,
- .init = pt_bar_reg_init,
- .u.dw.read = pt_bar_reg_read,
- .u.dw.write = pt_bar_reg_write,
- },
- /* BAR 1 reg */
- {
- .offset = PCI_BASE_ADDRESS_1,
- .size = 4,
- .init_val = 0x00000000,
- .init = pt_bar_reg_init,
- .u.dw.read = pt_bar_reg_read,
- .u.dw.write = pt_bar_reg_write,
- },
- /* BAR 2 reg */
- {
- .offset = PCI_BASE_ADDRESS_2,
- .size = 4,
- .init_val = 0x00000000,
- .init = pt_bar_reg_init,
- .u.dw.read = pt_bar_reg_read,
- .u.dw.write = pt_bar_reg_write,
- },
- /* BAR 3 reg */
- {
- .offset = PCI_BASE_ADDRESS_3,
- .size = 4,
- .init_val = 0x00000000,
- .init = pt_bar_reg_init,
- .u.dw.read = pt_bar_reg_read,
- .u.dw.write = pt_bar_reg_write,
- },
- /* BAR 4 reg */
- {
- .offset = PCI_BASE_ADDRESS_4,
- .size = 4,
- .init_val = 0x00000000,
- .init = pt_bar_reg_init,
- .u.dw.read = pt_bar_reg_read,
- .u.dw.write = pt_bar_reg_write,
- },
- /* BAR 5 reg */
- {
- .offset = PCI_BASE_ADDRESS_5,
- .size = 4,
- .init_val = 0x00000000,
- .init = pt_bar_reg_init,
- .u.dw.read = pt_bar_reg_read,
- .u.dw.write = pt_bar_reg_write,
- },
- /* Expansion ROM BAR reg */
- {
- .offset = PCI_ROM_ADDRESS,
- .size = 4,
- .init_val = 0x00000000,
- .ro_mask = 0x000007FE,
- .emu_mask = 0xFFFFF800,
- .init = pt_bar_reg_init,
- .u.dw.read = pt_long_reg_read,
- .u.dw.write = pt_exp_rom_bar_reg_write,
- },
- {
- .size = 0,
- },
-};
-
-/* Power Management Capability reg static infomation table */
-static struct pt_reg_info_tbl pt_emu_reg_pm_tbl[] = {
- /* Next Pointer reg */
- {
- .offset = PCI_CAP_LIST_NEXT,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_ptr_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Power Management Capabilities reg */
- {
- .offset = PCI_CAP_FLAGS,
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0xFFFF,
- .emu_mask = 0xFFE8,
- .init = pt_common_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_word_reg_write,
- },
- /* PCI Power Management Control/Status reg */
- {
- .offset = PCI_PM_CTRL,
- .size = 2,
- .init_val = 0x0008,
- .ro_mask = 0x60FC,
- .emu_mask = 0xFF0B,
- .init = pt_common_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_pmcsr_reg_write,
- },
- /* Data reg */
- {
- .offset = PCI_PM_DATA_REGISTER,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_common_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- {
- .size = 0,
- },
-};
-
-/* Vital Product Data Capability Structure reg static infomation table */
-static struct pt_reg_info_tbl pt_emu_reg_vpd_tbl[] = {
- /* Next Pointer reg */
- {
- .offset = PCI_CAP_LIST_NEXT,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_ptr_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- {
- .size = 0,
- },
-};
-
-/* Vendor Specific Capability Structure reg static infomation table */
-static struct pt_reg_info_tbl pt_emu_reg_vendor_tbl[] = {
- /* Next Pointer reg */
- {
- .offset = PCI_CAP_LIST_NEXT,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_ptr_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- {
- .size = 0,
- },
-};
-
-/* PCI Express Capability Structure reg static infomation table */
-static struct pt_reg_info_tbl pt_emu_reg_pcie_tbl[] = {
- /* Next Pointer reg */
- {
- .offset = PCI_CAP_LIST_NEXT,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_ptr_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Device Capabilities reg */
- {
- .offset = PCI_EXP_DEVCAP,
- .size = 4,
- .init_val = 0x00000000,
- .ro_mask = 0x1FFCFFFF,
- .emu_mask = 0x10000000,
- .init = pt_common_reg_init,
- .u.dw.read = pt_long_reg_read,
- .u.dw.write = pt_long_reg_write,
- },
- /* Device Control reg */
- {
- .offset = PCI_EXP_DEVCTL,
- .size = 2,
- .init_val = 0x2810,
- .ro_mask = 0x0000,
- .emu_mask = 0xFFFF,
- .init = pt_common_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_devctrl_reg_write,
- },
- /* Link Control reg */
- {
- .offset = PCI_EXP_LNKCTL,
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x0000,
- .emu_mask = 0xFFFF,
- .init = pt_linkctrl_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_linkctrl_reg_write,
- },
- /* Device Control 2 reg */
- {
- .offset = 0x28,
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x0000,
- .emu_mask = 0xFFFF,
- .init = pt_devctrl2_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_devctrl2_reg_write,
- },
- /* Link Control 2 reg */
- {
- .offset = 0x30,
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x0000,
- .emu_mask = 0xFFFF,
- .init = pt_linkctrl2_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_linkctrl2_reg_write,
- },
- {
- .size = 0,
- },
-};
-
-/* MSI Capability Structure reg static infomation table */
-static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
- /* Next Pointer reg */
- {
- .offset = PCI_CAP_LIST_NEXT,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_ptr_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Message Control reg */
- {
- .offset = PCI_MSI_FLAGS, // 2
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x018E,
- .emu_mask = 0xFFFE,
- .init = pt_msgctrl_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_msgctrl_reg_write,
- },
- /* Message Address reg */
- {
- .offset = PCI_MSI_ADDRESS_LO, // 4
- .size = 4,
- .init_val = 0x00000000,
- .ro_mask = 0x00000FF0, /* bit 4~11 is reserved for MSI in x86 */
- .emu_mask = 0xFFFFFFFF,
- .init = pt_msgaddr32_reg_init,
- .u.dw.read = pt_long_reg_read,
- .u.dw.write = pt_msgaddr32_reg_write,
- },
- /* Message Upper Address reg (if PCI_MSI_FLAGS_64BIT set) */
- {
- .offset = PCI_MSI_ADDRESS_HI, // 8
- .size = 4,
- .init_val = 0x00000000,
- .ro_mask = 0x00000000,
- .emu_mask = 0xFFFFFFFF,
- .init = pt_msgaddr64_reg_init,
- .u.dw.read = pt_long_reg_read,
- .u.dw.write = pt_msgaddr64_reg_write,
- },
- /* Message Data reg (16 bits of data for 32-bit devices) */
- {
- .offset = PCI_MSI_DATA_32, // 8
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x3800,
- .emu_mask = 0xFFFF,
- .init = pt_msgdata_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_msgdata_reg_write,
- },
- /* Message Data reg (16 bits of data for 64-bit devices) */
- {
- .offset = PCI_MSI_DATA_64, // 12
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x3800,
- .emu_mask = 0xFFFF,
- .init = pt_msgdata_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_msgdata_reg_write,
- },
- {
- .size = 0,
- },
-};
-
-/* MSI-X Capability Structure reg static infomation table */
-static struct pt_reg_info_tbl pt_emu_reg_msix_tbl[] = {
- /* Next Pointer reg */
- {
- .offset = PCI_CAP_LIST_NEXT,
- .size = 1,
- .init_val = 0x00,
- .ro_mask = 0xFF,
- .emu_mask = 0xFF,
- .init = pt_ptr_reg_init,
- .u.b.read = pt_byte_reg_read,
- .u.b.write = pt_byte_reg_write,
- },
- /* Message Control reg */
- {
- .offset = PCI_MSI_FLAGS, // 2
- .size = 2,
- .init_val = 0x0000,
- .ro_mask = 0x3FFF,
- .emu_mask = 0x0000,
- .init = pt_msixctrl_reg_init,
- .u.w.read = pt_word_reg_read,
- .u.w.write = pt_msixctrl_reg_write,
- },
- {
- .size = 0,
- },
-};
-
-/* pt_reg_grp_info_tbl declaration
- * - only for emulated or zero-hardwired register group.
- * - for register group with dynamic size, just set grp_size to 0xFF and
- * specify size_init func properly.
- * - no need to specify emu_reg_tbl for zero-hardwired type.
- */
-
-/* emul reg group static infomation table */
-static const struct pt_reg_grp_info_tbl pt_emu_reg_grp_tbl[] = {
- /* Header Type0 reg group */
- {
- .grp_id = 0xFF,
- .grp_type = GRP_TYPE_EMU,
- .grp_size = 0x40,
- .size_init = pt_reg_grp_size_init,
- .emu_reg_tbl= pt_emu_reg_header0_tbl,
- },
- /* PCI PowerManagement Capability reg group */
- {
- .grp_id = PCI_CAP_ID_PM,
- .grp_type = GRP_TYPE_EMU,
- .grp_size = PCI_PM_SIZEOF,
- .size_init = pt_reg_grp_size_init,
- .emu_reg_tbl= pt_emu_reg_pm_tbl,
- },
- /* AGP Capability Structure reg group */
- {
- .grp_id = PCI_CAP_ID_AGP,
- .grp_type = GRP_TYPE_HARDWIRED,
- .grp_size = 0x30,
- .size_init = pt_reg_grp_size_init,
- },
- /* Vital Product Data Capability Structure reg group */
- {
- .grp_id = PCI_CAP_ID_VPD,
- .grp_type = GRP_TYPE_EMU,
- .grp_size = 0x08,
- .size_init = pt_reg_grp_size_init,
- .emu_reg_tbl= pt_emu_reg_vpd_tbl,
- },
- /* Slot Identification reg group */
- {
- .grp_id = PCI_CAP_ID_SLOTID,
- .grp_type = GRP_TYPE_HARDWIRED,
- .grp_size = 0x04,
- .size_init = pt_reg_grp_size_init,
- },
- /* MSI Capability Structure reg group */
- {
- .grp_id = PCI_CAP_ID_MSI,
- .grp_type = GRP_TYPE_EMU,
- .grp_size = 0xFF,
- .size_init = pt_msi_size_init,
- .emu_reg_tbl= pt_emu_reg_msi_tbl,
- },
- /* PCI-X Capabilities List Item reg group */
- {
- .grp_id = PCI_CAP_ID_PCIX,
- .grp_type = GRP_TYPE_HARDWIRED,
- .grp_size = 0x18,
- .size_init = pt_reg_grp_size_init,
- },
- /* Vendor Specific Capability Structure reg group */
- {
- .grp_id = PCI_CAP_ID_VNDR,
- .grp_type = GRP_TYPE_EMU,
- .grp_size = 0xFF,
- .size_init = pt_vendor_size_init,
- .emu_reg_tbl= pt_emu_reg_vendor_tbl,
- },
- /* SHPC Capability List Item reg group */
- {
- .grp_id = PCI_CAP_ID_HOTPLUG,
- .grp_type = GRP_TYPE_HARDWIRED,
- .grp_size = 0x08,
- .size_init = pt_reg_grp_size_init,
- },
- /* Subsystem ID and Subsystem Vendor ID Capability List Item reg group */
- {
- .grp_id = PCI_CAP_ID_SSVID,
- .grp_type = GRP_TYPE_HARDWIRED,
- .grp_size = 0x08,
- .size_init = pt_reg_grp_size_init,
- },
- /* AGP 8x Capability Structure reg group */
- {
- .grp_id = PCI_CAP_ID_AGP3,
- .grp_type = GRP_TYPE_HARDWIRED,
- .grp_size = 0x30,
- .size_init = pt_reg_grp_size_init,
- },
- /* PCI Express Capability Structure reg group */
- {
- .grp_id = PCI_CAP_ID_EXP,
- .grp_type = GRP_TYPE_EMU,
- .grp_size = 0xFF,
- .size_init = pt_pcie_size_init,
- .emu_reg_tbl= pt_emu_reg_pcie_tbl,
- },
- /* MSI-X Capability Structure reg group */
- {
- .grp_id = PCI_CAP_ID_MSIX,
- .grp_type = GRP_TYPE_EMU,
- .grp_size = 0x0C,
- .size_init = pt_msix_size_init,
- .emu_reg_tbl= pt_emu_reg_msix_tbl,
- },
- {
- .grp_size = 0,
- },
-};
-
-static int token_value(char *token)
-{
- return strtol(token, NULL, 16);
-}
-
-static int next_bdf(char **str, int *seg, int *bus, int *dev, int *func)
-{
- char *token, *delim = ":.-";
-
- if ( !(*str) ||
- ( !strchr(*str, ':') && !strchr(*str, '.')) )
- return 0;
-
- token = strsep(str, delim);
- *seg = token_value(token);
-
- token = strsep(str, delim);
- *bus = token_value(token);
-
- token = strsep(str, delim);
- *dev = token_value(token);
-
- token = strsep(str, delim);
- *func = token_value(token);
-
- return 1;
-}
-
-/* Insert a new pass-through device into a specific pci slot.
- * input dom:bus:dev.func@slot, chose free one if slot == 0
- * return -1: required slot not available
- * 0: no free hotplug slots, but normal slot should okay
- * >0: the new hotplug slot
- */
-static int __insert_to_pci_slot(int bus, int dev, int func, int slot)
-{
- int i, php_slot;
-
- /* preferred virt pci slot */
- if ( slot >= PHP_SLOT_START && slot < PHP_SLOT_END )
- {
- php_slot = PCI_TO_PHP_SLOT(slot);
- if ( !dpci_infos.php_devs[php_slot].valid )
- {
- goto found;
- }
- else
- return -1;
- }
-
- if ( slot != 0 )
- return -1;
-
- /* slot == 0, pick up a free one */
- for ( i = 0; i < PHP_SLOT_LEN; i++ )
- {
- if ( !dpci_infos.php_devs[i].valid )
- {
- php_slot = i;
- goto found;
- }
- }
-
- /* not found */
- return 0;
-
-found:
- dpci_infos.php_devs[php_slot].valid = 1;
- dpci_infos.php_devs[php_slot].r_bus = bus;
- dpci_infos.php_devs[php_slot].r_dev = dev;
- dpci_infos.php_devs[php_slot].r_func = func;
- return PHP_TO_PCI_SLOT(php_slot);
-}
-
-/* Insert a new pass-through device into a specific pci slot.
- * input dom:bus:dev.func@slot
- */
-int insert_to_pci_slot(char *bdf_slt)
-{
- int seg, bus, dev, func, slot;
- char *bdf_str, *slt_str, *delim="@";
-
- bdf_str = strsep(&bdf_slt, delim);
- slt_str = bdf_slt;
- slot = token_value(slt_str);
-
- if ( !next_bdf(&bdf_str, &seg, &bus, &dev, &func))
- {
- return -1;
- }
-
- return __insert_to_pci_slot(bus, dev, func, slot);
-
-}
-
-/* Test if a pci slot has a device
- * 1: present
- * 0: not present
- * -1: invalide pci slot input
- */
-int test_pci_slot(int slot)
-{
- int php_slot;
-
- if ( slot < PHP_SLOT_START || slot >= PHP_SLOT_END )
- return -1;
-
- php_slot = PCI_TO_PHP_SLOT(slot);
- if ( dpci_infos.php_devs[php_slot].valid )
- return 1;
- else
- return 0;
-}
-
-/* find the pci slot for pass-through dev with specified BDF */
-int bdf_to_slot(char *bdf_str)
-{
- int seg, bus, dev, func, i;
-
- if ( !next_bdf(&bdf_str, &seg, &bus, &dev, &func))
- {
- return -1;
- }
-
- /* locate the virtual pci slot for this VTd device */
- for ( i = 0; i < PHP_SLOT_LEN; i++ )
- {
- if ( dpci_infos.php_devs[i].valid &&
- dpci_infos.php_devs[i].r_bus == bus &&
- dpci_infos.php_devs[i].r_dev == dev &&
- dpci_infos.php_devs[i].r_func == func )
- {
- return PHP_TO_PCI_SLOT(i);
- }
- }
-
- return -1;
-}
-
-/* Being called each time a mmio region has been updated */
-void pt_iomem_map(PCIDevice *d, int i, uint32_t e_phys, uint32_t e_size,
- int type)
-{
- struct pt_dev *assigned_device = (struct pt_dev *)d;
- uint32_t old_ebase = assigned_device->bases[i].e_physbase;
- int first_map = ( assigned_device->bases[i].e_size == 0 );
- int ret = 0;
-
- assigned_device->bases[i].e_physbase = e_phys;
- assigned_device->bases[i].e_size= e_size;
-
- PT_LOG("e_phys=%08x maddr=%lx type=%d len=%d index=%d first_map=%d\n",
- e_phys, (unsigned long)assigned_device->bases[i].access.maddr,
- type, e_size, i, first_map);
-
- if ( e_size == 0 )
- return;
-
- if ( !first_map && old_ebase != -1 )
- {
- add_msix_mapping(assigned_device, i);
- /* Remove old mapping */
- ret = xc_domain_memory_mapping(xc_handle, domid,
- old_ebase >> XC_PAGE_SHIFT,
- assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,
- (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT,
- DPCI_REMOVE_MAPPING);
- if ( ret != 0 )
- {
- PT_LOG("Error: remove old mapping failed!\n");
- return;
- }
- }
-
- /* map only valid guest address */
- if (e_phys != -1)
- {
- /* Create new mapping */
- ret = xc_domain_memory_mapping(xc_handle, domid,
- assigned_device->bases[i].e_physbase >> XC_PAGE_SHIFT,
- assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,
- (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT,
- DPCI_ADD_MAPPING);
-
- if ( ret != 0 )
- {
- PT_LOG("Error: create new mapping failed!\n");
- }
-
- ret = remove_msix_mapping(assigned_device, i);
- if ( ret != 0 )
- PT_LOG("Error: remove MSI-X mmio mapping failed!\n");
- }
-}
-
-/* Being called each time a pio region has been updated */
-void pt_ioport_map(PCIDevice *d, int i,
- uint32_t e_phys, uint32_t e_size, int type)
-{
- struct pt_dev *assigned_device = (struct pt_dev *)d;
- uint32_t old_ebase = assigned_device->bases[i].e_physbase;
- int first_map = ( assigned_device->bases[i].e_size == 0 );
- int ret = 0;
-
- assigned_device->bases[i].e_physbase = e_phys;
- assigned_device->bases[i].e_size= e_size;
-
- PT_LOG("e_phys=%04x pio_base=%04x len=%d index=%d first_map=%d\n",
- (uint16_t)e_phys, (uint16_t)assigned_device->bases[i].access.pio_base,
- (uint16_t)e_size, i, first_map);
-
- if ( e_size == 0 )
- return;
-
- if ( !first_map && old_ebase != -1 )
- {
- /* Remove old mapping */
- ret = xc_domain_ioport_mapping(xc_handle, domid, old_ebase,
- assigned_device->bases[i].access.pio_base, e_size,
- DPCI_REMOVE_MAPPING);
- if ( ret != 0 )
- {
- PT_LOG("Error: remove old mapping failed!\n");
- return;
- }
- }
-
- /* map only valid guest address (include 0) */
- if (e_phys != -1)
- {
- /* Create new mapping */
- ret = xc_domain_ioport_mapping(xc_handle, domid, e_phys,
- assigned_device->bases[i].access.pio_base, e_size,
- DPCI_ADD_MAPPING);
- if ( ret != 0 )
- {
- PT_LOG("Error: create new mapping failed!\n");
- }
- }
-}
-
-/* find emulate register group entry */
-struct pt_reg_grp_tbl* pt_find_reg_grp(
- struct pt_dev *ptdev, uint32_t address)
-{
- struct pt_reg_grp_tbl* reg_grp_entry = NULL;
-
- /* find register group entry */
- for (reg_grp_entry = ptdev->reg_grp_tbl_head.lh_first; reg_grp_entry;
- reg_grp_entry = reg_grp_entry->entries.le_next)
- {
- /* check address */
- if ((reg_grp_entry->base_offset <= address) &&
- ((reg_grp_entry->base_offset + reg_grp_entry->size) > address))
- goto out;
- }
- /* group entry not found */
- reg_grp_entry = NULL;
-
-out:
- return reg_grp_entry;
-}
-
-/* find emulate register entry */
-struct pt_reg_tbl* pt_find_reg(
- struct pt_reg_grp_tbl* reg_grp, uint32_t address)
-{
- struct pt_reg_tbl* reg_entry = NULL;
- struct pt_reg_info_tbl* reg = NULL;
- uint32_t real_offset = 0;
-
- /* find register entry */
- for (reg_entry = reg_grp->reg_tbl_head.lh_first; reg_entry;
- reg_entry = reg_entry->entries.le_next)
- {
- reg = reg_entry->reg;
- real_offset = (reg_grp->base_offset + reg->offset);
- /* check address */
- if ((real_offset <= address) && ((real_offset + reg->size) > address))
- goto out;
- }
- /* register entry not found */
- reg_entry = NULL;
-
-out:
- return reg_entry;
-}
-
-/* get BAR index */
-static int pt_bar_offset_to_index(uint32_t offset)
-{
- int index = 0;
-
- /* check Exp ROM BAR */
- if (offset == PCI_ROM_ADDRESS)
- {
- index = PCI_ROM_SLOT;
- goto out;
- }
-
- /* calculate BAR index */
- index = ((offset - PCI_BASE_ADDRESS_0) >> 2);
- if (index >= PCI_NUM_REGIONS)
- index = -1;
-
-out:
- return index;
-}
-
-static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val,
- int len)
-{
- struct pt_dev *assigned_device = (struct pt_dev *)d;
- struct pci_dev *pci_dev = assigned_device->pci_dev;
- struct pt_reg_grp_tbl *reg_grp_entry = NULL;
- struct pt_reg_grp_info_tbl *reg_grp = NULL;
- struct pt_reg_tbl *reg_entry = NULL;
- struct pt_reg_info_tbl *reg = NULL;
- uint32_t find_addr = address;
- uint32_t real_offset = 0;
- uint32_t valid_mask = 0xFFFFFFFF;
- uint32_t read_val = 0;
- uint8_t *ptr_val = NULL;
- int emul_len = 0;
- int index = 0;
- int ret = 0;
-
-#ifdef PT_DEBUG_PCI_CONFIG_ACCESS
- PT_LOG("[%02x:%02x.%x]: address=%04x val=0x%08x len=%d\n",
- pci_bus_num(d->bus), (d->devfn >> 3) & 0x1F, (d->devfn & 0x7),
- address, val, len);
-#endif
-
- /* check offset range */
- if (address >= 0xFF)
- {
- PT_LOG("Failed to write register with offset exceeding FFh. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- goto exit;
- }
-
- /* check write size */
- if ((len != 1) && (len != 2) && (len != 4))
- {
- PT_LOG("Failed to write register with invalid access length. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- goto exit;
- }
-
- /* check offset alignment */
- if (address & (len-1))
- {
- PT_LOG("Failed to write register with invalid access size alignment. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- goto exit;
- }
-
- /* check unused BAR register */
- index = pt_bar_offset_to_index(address);
- if ((index >= 0) && (val > 0 && val < PT_BAR_ALLF) &&
- (assigned_device->bases[index].bar_flag == PT_BAR_FLAG_UNUSED))
- {
- PT_LOG("Guest attempt to set address to unused Base Address Register. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F),
- (d->devfn & 0x7), address, len);
- }
-
- /* find register group entry */
- reg_grp_entry = pt_find_reg_grp(assigned_device, address);
- if (reg_grp_entry)
- {
- reg_grp = reg_grp_entry->reg_grp;
- /* check 0 Hardwired register group */
- if (reg_grp->grp_type == GRP_TYPE_HARDWIRED)
- {
- /* ignore silently */
- PT_LOG("Access to 0 Hardwired register. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F),
- (d->devfn & 0x7), address, len);
- goto exit;
- }
- }
-
- /* read I/O device register value */
- switch (len) {
- case 1:
- read_val = pci_read_byte(pci_dev, address);
- break;
- case 2:
- read_val = pci_read_word(pci_dev, address);
- break;
- case 4:
- read_val = pci_read_long(pci_dev, address);
- break;
- }
-
- /* check libpci result */
- valid_mask = (0xFFFFFFFF >> ((4 - len) << 3));
- if ((read_val & valid_mask) == valid_mask)
- {
- PT_LOG("Warning: Return ALL F from libpci read. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- }
-
- /* pass directly to libpci for passthrough type register group */
- if (reg_grp_entry == NULL)
- goto out;
-
- /* adjust the read and write value to appropriate CFC-CFF window */
- read_val <<= ((address & 3) << 3);
- val <<= ((address & 3) << 3);
- emul_len = len;
-
- /* loop Guest request size */
- while (0 < emul_len)
- {
- /* find register entry to be emulated */
- reg_entry = pt_find_reg(reg_grp_entry, find_addr);
- if (reg_entry)
- {
- reg = reg_entry->reg;
- real_offset = (reg_grp_entry->base_offset + reg->offset);
- valid_mask = (0xFFFFFFFF >> ((4 - emul_len) << 3));
- valid_mask <<= ((find_addr - real_offset) << 3);
- ptr_val = ((uint8_t *)&val + (real_offset & 3));
-
- /* do emulation depend on register size */
- switch (reg->size) {
- case 1:
- /* emulate write to byte register */
- if (reg->u.b.write)
- ret = reg->u.b.write(assigned_device, reg_entry,
- (uint8_t *)ptr_val,
- (uint8_t)(read_val >> ((real_offset & 3) << 3)),
- (uint8_t)valid_mask);
- break;
- case 2:
- /* emulate write to word register */
- if (reg->u.w.write)
- ret = reg->u.w.write(assigned_device, reg_entry,
- (uint16_t *)ptr_val,
- (uint16_t)(read_val >> ((real_offset & 3) << 3)),
- (uint16_t)valid_mask);
- break;
- case 4:
- /* emulate write to double word register */
- if (reg->u.dw.write)
- ret = reg->u.dw.write(assigned_device, reg_entry,
- (uint32_t *)ptr_val,
- (uint32_t)(read_val >> ((real_offset & 3) << 3)),
- (uint32_t)valid_mask);
- break;
- }
-
- /* write emulation error */
- if (ret < 0)
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Invalid write emulation "
- "return value[%d]. I/O emulator exit.\n", ret);
- exit(1);
- }
-
- /* calculate next address to find */
- emul_len -= reg->size;
- if (emul_len > 0)
- find_addr = real_offset + reg->size;
- }
- else
- {
- /* nothing to do with passthrough type register,
- * continue to find next byte
- */
- emul_len--;
- find_addr++;
- }
- }
-
- /* need to shift back before passing them to libpci */
- val >>= ((address & 3) << 3);
-
-out:
- switch (len){
- case 1:
- pci_write_byte(pci_dev, address, val);
- break;
- case 2:
- pci_write_word(pci_dev, address, val);
- break;
- case 4:
- pci_write_long(pci_dev, address, val);
- break;
- }
-
-exit:
- return;
-}
-
-static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len)
-{
- struct pt_dev *assigned_device = (struct pt_dev *)d;
- struct pci_dev *pci_dev = assigned_device->pci_dev;
- uint32_t val = 0xFFFFFFFF;
- struct pt_reg_grp_tbl *reg_grp_entry = NULL;
- struct pt_reg_grp_info_tbl *reg_grp = NULL;
- struct pt_reg_tbl *reg_entry = NULL;
- struct pt_reg_info_tbl *reg = NULL;
- uint32_t find_addr = address;
- uint32_t real_offset = 0;
- uint32_t valid_mask = 0xFFFFFFFF;
- uint8_t *ptr_val = NULL;
- int emul_len = 0;
- int ret = 0;
-
- /* check offset range */
- if (address >= 0xFF)
- {
- PT_LOG("Failed to read register with offset exceeding FFh. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- goto exit;
- }
-
- /* check read size */
- if ((len != 1) && (len != 2) && (len != 4))
- {
- PT_LOG("Failed to read register with invalid access length. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- goto exit;
- }
-
- /* check offset alignment */
- if (address & (len-1))
- {
- PT_LOG("Failed to read register with invalid access size alignment. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- goto exit;
- }
-
- /* find register group entry */
- reg_grp_entry = pt_find_reg_grp(assigned_device, address);
- if (reg_grp_entry)
- {
- reg_grp = reg_grp_entry->reg_grp;
- /* check 0 Hardwired register group */
- if (reg_grp->grp_type == GRP_TYPE_HARDWIRED)
- {
- /* no need to emulate, just return 0 */
- val = 0;
- goto exit;
- }
- }
-
- /* read I/O device register value */
- switch (len) {
- case 1:
- val = pci_read_byte(pci_dev, address);
- break;
- case 2:
- val = pci_read_word(pci_dev, address);
- break;
- case 4:
- val = pci_read_long(pci_dev, address);
- break;
- }
-
- /* check libpci result */
- valid_mask = (0xFFFFFFFF >> ((4 - len) << 3));
- if ((val & valid_mask) == valid_mask)
- {
- PT_LOG("Warning: Return ALL F from libpci read. "
- "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
- pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- address, len);
- }
-
- /* just return the I/O device register value for
- * passthrough type register group
- */
- if (reg_grp_entry == NULL)
- goto exit;
-
- /* adjust the read value to appropriate CFC-CFF window */
- val <<= ((address & 3) << 3);
- emul_len = len;
-
- /* loop Guest request size */
- while (0 < emul_len)
- {
- /* find register entry to be emulated */
- reg_entry = pt_find_reg(reg_grp_entry, find_addr);
- if (reg_entry)
- {
- reg = reg_entry->reg;
- real_offset = (reg_grp_entry->base_offset + reg->offset);
- valid_mask = (0xFFFFFFFF >> ((4 - emul_len) << 3));
- valid_mask <<= ((find_addr - real_offset) << 3);
- ptr_val = ((uint8_t *)&val + (real_offset & 3));
-
- /* do emulation depend on register size */
- switch (reg->size) {
- case 1:
- /* emulate read to byte register */
- if (reg->u.b.read)
- ret = reg->u.b.read(assigned_device, reg_entry,
- (uint8_t *)ptr_val,
- (uint8_t)valid_mask);
- break;
- case 2:
- /* emulate read to word register */
- if (reg->u.w.read)
- ret = reg->u.w.read(assigned_device, reg_entry,
- (uint16_t *)ptr_val,
- (uint16_t)valid_mask);
- break;
- case 4:
- /* emulate read to double word register */
- if (reg->u.dw.read)
- ret = reg->u.dw.read(assigned_device, reg_entry,
- (uint32_t *)ptr_val,
- (uint32_t)valid_mask);
- break;
- }
-
- /* read emulation error */
- if (ret < 0)
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Invalid read emulation "
- "return value[%d]. I/O emulator exit.\n", ret);
- exit(1);
- }
-
- /* calculate next address to find */
- emul_len -= reg->size;
- if (emul_len > 0)
- find_addr = real_offset + reg->size;
- }
- else
- {
- /* nothing to do with passthrough type register,
- * continue to find next byte
- */
- emul_len--;
- find_addr++;
- }
- }
-
- /* need to shift back before returning them to pci bus emulator */
- val >>= ((address & 3) << 3);
-
-exit:
-
-#ifdef PT_DEBUG_PCI_CONFIG_ACCESS
- PT_LOG("[%02x:%02x.%x]: address=%04x val=0x%08x len=%d\n",
- pci_bus_num(d->bus), (d->devfn >> 3) & 0x1F, (d->devfn & 0x7),
- address, val, len);
-#endif
-
- return val;
-}
-
-static int pt_register_regions(struct pt_dev *assigned_device)
-{
- int i = 0;
- uint32_t bar_data = 0;
- struct pci_dev *pci_dev = assigned_device->pci_dev;
- PCIDevice *d = &assigned_device->dev;
-
- /* Register PIO/MMIO BARs */
- for ( i = 0; i < PCI_BAR_ENTRIES; i++ )
- {
- if ( pci_dev->base_addr[i] )
- {
- assigned_device->bases[i].e_physbase = pci_dev->base_addr[i];
- assigned_device->bases[i].access.u = pci_dev->base_addr[i];
-
- /* Register current region */
- bar_data = *((uint32_t*)(d->config + PCI_BASE_ADDRESS_0) + i);
- if ( bar_data & PCI_ADDRESS_SPACE_IO )
- pci_register_io_region((PCIDevice *)assigned_device, i,
- (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_IO,
- pt_ioport_map);
- else if ( bar_data & PCI_ADDRESS_SPACE_MEM_PREFETCH )
- pci_register_io_region((PCIDevice *)assigned_device, i,
- (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM_PREFETCH,
- pt_iomem_map);
- else
- pci_register_io_region((PCIDevice *)assigned_device, i,
- (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM,
- pt_iomem_map);
-
- PT_LOG("IO region registered (size=0x%08x base_addr=0x%08x)\n",
- (uint32_t)(pci_dev->size[i]),
- (uint32_t)(pci_dev->base_addr[i]));
- }
- }
-
- /* Register expansion ROM address */
- if ( pci_dev->rom_base_addr && pci_dev->rom_size )
- {
- assigned_device->bases[PCI_ROM_SLOT].e_physbase =
- pci_dev->rom_base_addr;
- assigned_device->bases[PCI_ROM_SLOT].access.maddr =
- pci_dev->rom_base_addr;
- pci_register_io_region((PCIDevice *)assigned_device, PCI_ROM_SLOT,
- pci_dev->rom_size, PCI_ADDRESS_SPACE_MEM_PREFETCH,
- pt_iomem_map);
-
- PT_LOG("Expansion ROM registered (size=0x%08x base_addr=0x%08x)\n",
- (uint32_t)(pci_dev->rom_size), (uint32_t)(pci_dev->rom_base_addr));
- }
-
- return 0;
-}
-
-static void pt_unregister_regions(struct pt_dev *assigned_device)
-{
- int i, type, ret;
- uint32_t e_size;
- PCIDevice *d = (PCIDevice*)assigned_device;
-
- for ( i = 0; i < PCI_NUM_REGIONS; i++ )
- {
- e_size = assigned_device->bases[i].e_size;
- if ( (e_size == 0) || (assigned_device->bases[i].e_physbase == -1) )
- continue;
-
- type = d->io_regions[i].type;
-
- if ( type == PCI_ADDRESS_SPACE_MEM ||
- type == PCI_ADDRESS_SPACE_MEM_PREFETCH )
- {
- ret = xc_domain_memory_mapping(xc_handle, domid,
- assigned_device->bases[i].e_physbase >> XC_PAGE_SHIFT,
- assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,
- (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT,
- DPCI_REMOVE_MAPPING);
- if ( ret != 0 )
- {
- PT_LOG("Error: remove old mem mapping failed!\n");
- continue;
- }
-
- }
- else if ( type == PCI_ADDRESS_SPACE_IO )
- {
- ret = xc_domain_ioport_mapping(xc_handle, domid,
- assigned_device->bases[i].e_physbase,
- assigned_device->bases[i].access.pio_base,
- e_size,
- DPCI_REMOVE_MAPPING);
- if ( ret != 0 )
- {
- PT_LOG("Error: remove old io mapping failed!\n");
- continue;
- }
-
- }
-
- }
-
-}
-
-uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
-{
- int id;
- int max_cap = 48;
- int pos = PCI_CAPABILITY_LIST;
- int status;
-
- status = pci_read_byte(pci_dev, PCI_STATUS);
- if ( (status & PCI_STATUS_CAP_LIST) == 0 )
- return 0;
-
- while ( max_cap-- )
- {
- pos = pci_read_byte(pci_dev, pos);
- if ( pos < 0x40 )
- break;
-
- pos &= ~3;
- id = pci_read_byte(pci_dev, pos + PCI_CAP_LIST_ID);
-
- if ( id == 0xff )
- break;
- if ( id == cap )
- return pos;
-
- pos += PCI_CAP_LIST_NEXT;
- }
- return 0;
-}
-
-/* parse BAR */
-static int pt_bar_reg_parse(
- struct pt_dev *ptdev, struct pt_reg_info_tbl *reg)
-{
- PCIDevice *d = &ptdev->dev;
- struct pt_region *region = NULL;
- PCIIORegion *r;
- uint32_t bar_64 = (reg->offset - 4);
- int bar_flag = PT_BAR_FLAG_UNUSED;
- int index = 0;
- int i;
-
- /* set again the BAR config because it has been overwritten
- * by pci_register_io_region()
- */
- for (i=reg->offset; i<(reg->offset + 4); i++)
- d->config[i] = pci_read_byte(ptdev->pci_dev, i);
-
- /* check 64bit BAR */
- index = pt_bar_offset_to_index(reg->offset);
- if ((index > 0) && (index < PCI_ROM_SLOT) &&
- ((d->config[bar_64] & (PCI_BASE_ADDRESS_SPACE |
- PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
- (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)))
- {
- region = &ptdev->bases[index-1];
- if (region->bar_flag != PT_BAR_FLAG_UPPER)
- {
- bar_flag = PT_BAR_FLAG_UPPER;
- goto out;
- }
- }
-
- /* check unused BAR */
- r = &d->io_regions[index];
- if (!r->size)
- goto out;
-
- /* for ExpROM BAR */
- if (index == PCI_ROM_SLOT)
- {
- bar_flag = PT_BAR_FLAG_MEM;
- goto out;
- }
-
- /* check BAR I/O indicator */
- if (d->config[reg->offset] & PCI_BASE_ADDRESS_SPACE_IO)
- bar_flag = PT_BAR_FLAG_IO;
- else
- bar_flag = PT_BAR_FLAG_MEM;
-
-out:
- return bar_flag;
-}
-
-/* mapping BAR */
-static void pt_bar_mapping(struct pt_dev *ptdev, int io_enable, int mem_enable)
-{
- PCIDevice *dev = (PCIDevice *)&ptdev->dev;
- PCIIORegion *r;
- struct pt_region *base = NULL;
- uint32_t r_size = 0, r_addr = -1;
- int ret = 0;
- int i;
-
- for (i=0; i<PCI_NUM_REGIONS; i++)
- {
- r = &dev->io_regions[i];
-
- /* check valid region */
- if (!r->size)
- continue;
-
- base = &ptdev->bases[i];
- /* skip unused BAR or upper 64bit BAR */
- if ((base->bar_flag == PT_BAR_FLAG_UNUSED) ||
- (base->bar_flag == PT_BAR_FLAG_UPPER))
- continue;
-
- /* copy region address to temporary */
- r_addr = r->addr;
-
- /* need unmapping in case I/O Space or Memory Space disable */
- if (((base->bar_flag == PT_BAR_FLAG_IO) && !io_enable ) ||
- ((base->bar_flag == PT_BAR_FLAG_MEM) && !mem_enable ))
- r_addr = -1;
-
- /* prevent guest software mapping memory resource to 00000000h */
- if ((base->bar_flag == PT_BAR_FLAG_MEM) && (r_addr == 0))
- r_addr = -1;
-
- /* align resource size (memory type only) */
- r_size = r->size;
- PT_GET_EMUL_SIZE(base->bar_flag, r_size);
-
- /* check overlapped address */
- ret = pt_chk_bar_overlap(dev->bus, dev->devfn, r_addr, r_size);
- if (ret > 0)
- PT_LOG("ptdev[%02x:%02x.%x][Region:%d][Address:%08xh][Size:%08xh] "
- "is overlapped.\n", pci_bus_num(dev->bus),
- (dev->devfn >> 3) & 0x1F, (dev->devfn & 0x7),
- i, r_addr, r_size);
-
- /* check whether we need to update the mapping or not */
- if (r_addr != ptdev->bases[i].e_physbase)
- {
- /* mapping BAR */
- r->map_func((PCIDevice *)ptdev, i, r_addr,
- r_size, r->type);
- }
- }
-
- return;
-}
-
-/* initialize emulate register */
-static int pt_config_reg_init(struct pt_dev *ptdev,
- struct pt_reg_grp_tbl *reg_grp,
- struct pt_reg_info_tbl *reg)
-{
- struct pt_reg_tbl *reg_entry;
- uint32_t data = 0;
- int err = 0;
-
- /* allocate register entry */
- reg_entry = qemu_mallocz(sizeof(struct pt_reg_tbl));
- if (reg_entry == NULL)
- {
- PT_LOG("Failed to allocate memory.\n");
- err = -1;
- goto out;
- }
-
- /* initialize register entry */
- reg_entry->reg = reg;
- reg_entry->data = 0;
-
- if (reg->init)
- {
- /* initialize emulate register */
- data = reg->init(ptdev, reg_entry->reg,
- (reg_grp->base_offset + reg->offset));
- if (data == PT_INVALID_REG)
- {
- /* free unused BAR register entry */
- free(reg_entry);
- goto out;
- }
- /* set register value */
- reg_entry->data = data;
- }
- /* list add register entry */
- LIST_INSERT_HEAD(&reg_grp->reg_tbl_head, reg_entry, entries);
-
-out:
- return err;
-}
-
-/* initialize emulate register group */
-static int pt_config_init(struct pt_dev *ptdev)
-{
- struct pt_reg_grp_tbl *reg_grp_entry = NULL;
- struct pt_reg_info_tbl *reg_tbl = NULL;
- uint32_t reg_grp_offset = 0;
- int i, j, err = 0;
-
- /* initialize register group list */
- LIST_INIT(&ptdev->reg_grp_tbl_head);
-
- /* initialize register group */
- for (i=0; pt_emu_reg_grp_tbl[i].grp_size != 0; i++)
- {
- if (pt_emu_reg_grp_tbl[i].grp_id != 0xFF)
- {
- reg_grp_offset = (uint32_t)find_cap_offset(ptdev->pci_dev,
- pt_emu_reg_grp_tbl[i].grp_id);
- if (!reg_grp_offset)
- continue;
- }
-
- /* allocate register group table */
- reg_grp_entry = qemu_mallocz(sizeof(struct pt_reg_grp_tbl));
- if (reg_grp_entry == NULL)
- {
- PT_LOG("Failed to allocate memory.\n");
- err = -1;
- goto out;
- }
-
- /* initialize register group entry */
- LIST_INIT(&reg_grp_entry->reg_tbl_head);
-
- /* need to declare here, to enable searching Cap Ptr reg
- * (which is in the same reg group) when initializing Status reg
- */
- LIST_INSERT_HEAD(&ptdev->reg_grp_tbl_head, reg_grp_entry, entries);
-
- reg_grp_entry->base_offset = reg_grp_offset;
- reg_grp_entry->reg_grp =
- (struct pt_reg_grp_info_tbl*)&pt_emu_reg_grp_tbl[i];
- if (pt_emu_reg_grp_tbl[i].size_init)
- {
- /* get register group size */
- reg_grp_entry->size = pt_emu_reg_grp_tbl[i].size_init(ptdev,
- reg_grp_entry->reg_grp,
- reg_grp_offset);
- }
-
- if (pt_emu_reg_grp_tbl[i].grp_type == GRP_TYPE_EMU)
- {
- if (pt_emu_reg_grp_tbl[i].emu_reg_tbl)
- {
- reg_tbl = pt_emu_reg_grp_tbl[i].emu_reg_tbl;
- /* initialize capability register */
- for (j=0; reg_tbl->size != 0; j++, reg_tbl++)
- {
- /* initialize capability register */
- err = pt_config_reg_init(ptdev, reg_grp_entry, reg_tbl);
- if (err < 0)
- goto out;
- }
- }
- }
- reg_grp_offset = 0;
- }
-
-out:
- return err;
-}
-
-/* delete all emulate register */
-static void pt_config_delete(struct pt_dev *ptdev)
-{
- struct pt_reg_grp_tbl *reg_grp_entry = NULL;
- struct pt_reg_tbl *reg_entry = NULL;
-
- /* free MSI/MSI-X info table */
- if (ptdev->msix)
- pt_msix_delete(ptdev);
- if (ptdev->msi)
- free(ptdev->msi);
-
- /* free all register group entry */
- while ((reg_grp_entry = ptdev->reg_grp_tbl_head.lh_first) != NULL)
- {
- /* free all register entry */
- while ((reg_entry = reg_grp_entry->reg_tbl_head.lh_first) != NULL)
- {
- LIST_REMOVE(reg_entry, entries);
- qemu_free(reg_entry);
- }
-
- LIST_REMOVE(reg_grp_entry, entries);
- qemu_free(reg_grp_entry);
- }
-}
-
-/* initialize common register value */
-static uint32_t pt_common_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- return reg->init_val;
-}
-
-/* initialize Capabilities Pointer or Next Pointer register */
-static uint32_t pt_ptr_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- uint32_t reg_field = (uint32_t)ptdev->dev.config[real_offset];
- int i;
-
- /* find capability offset */
- while (reg_field)
- {
- for (i=0; pt_emu_reg_grp_tbl[i].grp_size != 0; i++)
- {
- /* check whether the next capability
- * should be exported to guest or not
- */
- if (pt_emu_reg_grp_tbl[i].grp_id == ptdev->dev.config[reg_field])
- {
- if (pt_emu_reg_grp_tbl[i].grp_type == GRP_TYPE_EMU)
- goto out;
- /* ignore the 0 hardwired capability, find next one */
- break;
- }
- }
- /* next capability */
- reg_field = (uint32_t)ptdev->dev.config[reg_field + 1];
- }
-
-out:
- return reg_field;
-}
-
-/* initialize Status register */
-static uint32_t pt_status_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- struct pt_reg_grp_tbl *reg_grp_entry = NULL;
- struct pt_reg_tbl *reg_entry = NULL;
- int reg_field = 0;
-
- /* find Header register group */
- reg_grp_entry = pt_find_reg_grp(ptdev, PCI_CAPABILITY_LIST);
- if (reg_grp_entry)
- {
- /* find Capabilities Pointer register */
- reg_entry = pt_find_reg(reg_grp_entry, PCI_CAPABILITY_LIST);
- if (reg_entry)
- {
- /* check Capabilities Pointer register */
- if (reg_entry->data)
- reg_field |= PCI_STATUS_CAP_LIST;
- else
- reg_field &= ~PCI_STATUS_CAP_LIST;
- }
- else
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Couldn't find pt_reg_tbl for "
- "Capabilities Pointer register. I/O emulator exit.\n");
- exit(1);
- }
- }
- else
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Couldn't find pt_reg_grp_tbl for Header. "
- "I/O emulator exit.\n");
- exit(1);
- }
-
- return reg_field;
-}
-
-/* initialize Interrupt Pin register */
-static uint32_t pt_irqpin_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- int reg_field = 0;
-
- /* set Interrupt Pin register to use INTA# if it has */
- if (ptdev->dev.config[real_offset])
- reg_field = 0x01;
-
- return reg_field;
-}
-
-/* initialize BAR */
-static uint32_t pt_bar_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- int reg_field = 0;
- int index;
-
- /* get BAR index */
- index = pt_bar_offset_to_index(reg->offset);
- if (index < 0)
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Invalid BAR index[%d]. "
- "I/O emulator exit.\n", index);
- exit(1);
- }
-
- /* set initial guest physical base address to -1 */
- ptdev->bases[index].e_physbase = -1;
-
- /* set BAR flag */
- ptdev->bases[index].bar_flag = pt_bar_reg_parse(ptdev, reg);
- if (ptdev->bases[index].bar_flag == PT_BAR_FLAG_UNUSED)
- reg_field = PT_INVALID_REG;
-
- return reg_field;
-}
-
-/* initialize Link Control register */
-static uint32_t pt_linkctrl_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- uint8_t cap_ver = 0;
- uint8_t dev_type = 0;
-
- cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
- (uint8_t)PCI_EXP_FLAGS_VERS);
- dev_type = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
- (uint8_t)PCI_EXP_FLAGS_TYPE) >> 4;
-
- /* no need to initialize in case of Root Complex Integrated Endpoint
- * with cap_ver 1.x
- */
- if ((dev_type == PCI_EXP_TYPE_ROOT_INT_EP) && (cap_ver == 1))
- return PT_INVALID_REG;
-
- return reg->init_val;
-}
-
-/* initialize Device Control 2 register */
-static uint32_t pt_devctrl2_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- uint8_t cap_ver = 0;
-
- cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
- (uint8_t)PCI_EXP_FLAGS_VERS);
-
- /* no need to initialize in case of cap_ver 1.x */
- if (cap_ver == 1)
- return PT_INVALID_REG;
-
- return reg->init_val;
-}
-
-/* initialize Link Control 2 register */
-static uint32_t pt_linkctrl2_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- int reg_field = 0;
- uint8_t cap_ver = 0;
-
- cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
- (uint8_t)PCI_EXP_FLAGS_VERS);
-
- /* no need to initialize in case of cap_ver 1.x */
- if (cap_ver == 1)
- return PT_INVALID_REG;
-
- /* set Supported Link Speed */
- reg_field |=
- (0x0F &
- ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_LNKCAP]);
-
- return reg_field;
-}
-
-/* initialize Message Control register */
-static uint32_t pt_msgctrl_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- PCIDevice *d = (struct PCIDevice *)ptdev;
- struct pci_dev *pdev = ptdev->pci_dev;
- uint32_t reg_field = 0;
-
- /* use I/O device register's value as initial value */
- reg_field |= *((uint16_t*)(d->config + real_offset));
-
- if (reg_field & PCI_MSI_FLAGS_ENABLE)
- {
- PT_LOG("MSI enabled already, disable first\n");
- pci_write_word(pdev, real_offset, reg_field & ~PCI_MSI_FLAGS_ENABLE);
- }
- ptdev->msi->flags |= (reg_field | MSI_FLAG_UNINIT);
-
- /* All register is 0 after reset, except first 4 byte */
- reg_field &= reg->ro_mask;
-
- return reg_field;
-}
-
-/* initialize Message Address register */
-static uint32_t pt_msgaddr32_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- PCIDevice *d = (struct PCIDevice *)ptdev;
- uint32_t reg_field = 0;
-
- /* use I/O device register's value as initial value */
- reg_field |= *((uint32_t*)(d->config + real_offset));
-
- return reg_field;
-}
-
-/* initialize Message Upper Address register */
-static uint32_t pt_msgaddr64_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- PCIDevice *d = (struct PCIDevice *)ptdev;
- uint32_t reg_field = 0;
-
- /* no need to initialize in case of 32 bit type */
- if (!(ptdev->msi->flags & PCI_MSI_FLAGS_64BIT))
- return PT_INVALID_REG;
-
- /* use I/O device register's value as initial value */
- reg_field |= *((uint32_t*)(d->config + real_offset));
-
- return reg_field;
-}
-
-/* this function will be called twice (for 32 bit and 64 bit type) */
-/* initialize Message Data register */
-static uint32_t pt_msgdata_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- PCIDevice *d = (struct PCIDevice *)ptdev;
- uint32_t flags = ptdev->msi->flags;
- uint32_t offset = reg->offset;
-
- /* check the offset whether matches the type or not */
- if (((offset == PCI_MSI_DATA_64) && (flags & PCI_MSI_FLAGS_64BIT)) ||
- ((offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT)))
- return *((uint16_t*)(d->config + real_offset));
- else
- return PT_INVALID_REG;
-}
-
-/* initialize Message Control register for MSI-X */
-static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg, uint32_t real_offset)
-{
- PCIDevice *d = (struct PCIDevice *)ptdev;
- struct pci_dev *pdev = ptdev->pci_dev;
- uint16_t reg_field = 0;
-
- /* use I/O device register's value as initial value */
- reg_field |= *((uint16_t*)(d->config + real_offset));
-
- if (reg_field & PCI_MSIX_ENABLE)
- {
- PT_LOG("MSIX enabled already, disable first\n");
- pci_write_word(pdev, real_offset, reg_field & ~PCI_MSIX_ENABLE);
- reg_field &= ~(PCI_MSIX_ENABLE | PCI_MSIX_MASK);
- }
-
- return reg_field;
-}
-
-/* get register group size */
-static uint8_t pt_reg_grp_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset)
-{
- return grp_reg->grp_size;
-}
-
-/* get MSI Capability Structure register group size */
-static uint8_t pt_msi_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset)
-{
- PCIDevice *d = &ptdev->dev;
- uint16_t msg_ctrl = 0;
- uint8_t msi_size = 0xa;
-
- msg_ctrl = *((uint16_t*)(d->config + (base_offset + PCI_MSI_FLAGS)));
-
- /* check 64 bit address capable & Per-vector masking capable */
- if (msg_ctrl & PCI_MSI_FLAGS_64BIT)
- msi_size += 4;
- if (msg_ctrl & PCI_MSI_FLAGS_MASK_BIT)
- msi_size += 10;
-
- ptdev->msi = malloc(sizeof(struct pt_msi_info));
- if ( !ptdev->msi )
- {
- /* exit I/O emulator */
- PT_LOG("error allocation pt_msi_info. I/O emulator exit.\n");
- exit(1);
- }
- memset(ptdev->msi, 0, sizeof(struct pt_msi_info));
-
- return msi_size;
-}
-
-/* get MSI-X Capability Structure register group size */
-static uint8_t pt_msix_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset)
-{
- int ret = 0;
-
- ret = pt_msix_init(ptdev, base_offset);
-
- if (ret == -1)
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Invalid pt_msix_init return value[%d]. "
- "I/O emulator exit.\n", ret);
- exit(1);
- }
-
- return grp_reg->grp_size;
-}
-
-/* get Vendor Specific Capability Structure register group size */
-static uint8_t pt_vendor_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset)
-{
- return ptdev->dev.config[base_offset + 0x02];
-}
-
-/* get PCI Express Capability Structure register group size */
-static uint8_t pt_pcie_size_init(struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset)
-{
- PCIDevice *d = &ptdev->dev;
- uint16_t exp_flag = 0;
- uint16_t type = 0;
- uint16_t vers = 0;
- uint8_t pcie_size = 0;
-
- exp_flag = *((uint16_t*)(d->config + (base_offset + PCI_EXP_FLAGS)));
- type = (exp_flag & PCI_EXP_FLAGS_TYPE) >> 4;
- vers = (exp_flag & PCI_EXP_FLAGS_VERS);
-
- /* calculate size depend on capability version and device/port type */
- /* in case of PCI Express Base Specification Rev 1.x */
- if (vers == 1)
- {
- /* The PCI Express Capabilities, Device Capabilities, and Device
- * Status/Control registers are required for all PCI Express devices.
- * The Link Capabilities and Link Status/Control are required for all
- * Endpoints that are not Root Complex Integrated Endpoints. Endpoints
- * are not required to implement registers other than those listed
- * above and terminate the capability structure.
- */
- switch (type) {
- case PCI_EXP_TYPE_ENDPOINT:
- case PCI_EXP_TYPE_LEG_END:
- pcie_size = 0x14;
- break;
- case PCI_EXP_TYPE_ROOT_INT_EP:
- /* has no link */
- pcie_size = 0x0C;
- break;
- /* only EndPoint passthrough is supported */
- case PCI_EXP_TYPE_ROOT_PORT:
- case PCI_EXP_TYPE_UPSTREAM:
- case PCI_EXP_TYPE_DOWNSTREAM:
- case PCI_EXP_TYPE_PCI_BRIDGE:
- case PCI_EXP_TYPE_PCIE_BRIDGE:
- case PCI_EXP_TYPE_ROOT_EC:
- default:
- /* exit I/O emulator */
- PT_LOG("Internal error: Unsupported device/port type[%d]. "
- "I/O emulator exit.\n", type);
- exit(1);
- }
- }
- /* in case of PCI Express Base Specification Rev 2.0 */
- else if (vers == 2)
- {
- switch (type) {
- case PCI_EXP_TYPE_ENDPOINT:
- case PCI_EXP_TYPE_LEG_END:
- case PCI_EXP_TYPE_ROOT_INT_EP:
- /* For Functions that do not implement the registers,
- * these spaces must be hardwired to 0b.
- */
- pcie_size = 0x3C;
- break;
- /* only EndPoint passthrough is supported */
- case PCI_EXP_TYPE_ROOT_PORT:
- case PCI_EXP_TYPE_UPSTREAM:
- case PCI_EXP_TYPE_DOWNSTREAM:
- case PCI_EXP_TYPE_PCI_BRIDGE:
- case PCI_EXP_TYPE_PCIE_BRIDGE:
- case PCI_EXP_TYPE_ROOT_EC:
- default:
- /* exit I/O emulator */
- PT_LOG("Internal error: Unsupported device/port type[%d]. "
- "I/O emulator exit.\n", type);
- exit(1);
- }
- }
- else
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Unsupported capability version[%d]. "
- "I/O emulator exit.\n", vers);
- exit(1);
- }
-
- return pcie_size;
-}
-
-/* read byte size emulate register */
-static int pt_byte_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint8_t *value, uint8_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint8_t valid_emu_mask = 0;
-
- /* emulate byte register */
- valid_emu_mask = reg->emu_mask & valid_mask;
- *value = ((*value & ~valid_emu_mask) |
- (cfg_entry->data & valid_emu_mask));
-
- return 0;
-}
-
-/* read word size emulate register */
-static int pt_word_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t valid_emu_mask = 0;
-
- /* emulate word register */
- valid_emu_mask = reg->emu_mask & valid_mask;
- *value = ((*value & ~valid_emu_mask) |
- (cfg_entry->data & valid_emu_mask));
-
- return 0;
-}
-
-/* read long size emulate register */
-static int pt_long_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint32_t valid_emu_mask = 0;
-
- /* emulate long register */
- valid_emu_mask = reg->emu_mask & valid_mask;
- *value = ((*value & ~valid_emu_mask) |
- (cfg_entry->data & valid_emu_mask));
-
- return 0;
-}
-
-/* read BAR */
-static int pt_bar_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint32_t valid_emu_mask = 0;
- uint32_t bar_emu_mask = 0;
- int index;
-
- /* get BAR index */
- index = pt_bar_offset_to_index(reg->offset);
- if (index < 0)
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Invalid BAR index[%d]. "
- "I/O emulator exit.\n", index);
- exit(1);
- }
-
- /* set emulate mask depend on BAR flag */
- switch (ptdev->bases[index].bar_flag)
- {
- case PT_BAR_FLAG_MEM:
- bar_emu_mask = PT_BAR_MEM_EMU_MASK;
- break;
- case PT_BAR_FLAG_IO:
- bar_emu_mask = PT_BAR_IO_EMU_MASK;
- break;
- case PT_BAR_FLAG_UPPER:
- bar_emu_mask = PT_BAR_ALLF;
- break;
- default:
- break;
- }
-
- /* emulate BAR */
- valid_emu_mask = bar_emu_mask & valid_mask;
- *value = ((*value & ~valid_emu_mask) |
- (cfg_entry->data & valid_emu_mask));
-
- return 0;
-}
-
-/* write byte size emulate register */
-static int pt_byte_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint8_t *value, uint8_t dev_value, uint8_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint8_t writable_mask = 0;
- uint8_t throughable_mask = 0;
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write word size emulate register */
-static int pt_word_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write long size emulate register */
-static int pt_long_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Command register */
-static int pt_cmd_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t wr_value = *value;
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask));
-
- /* mapping BAR */
- pt_bar_mapping(ptdev, wr_value & PCI_COMMAND_IO,
- wr_value & PCI_COMMAND_MEMORY);
-
- return 0;
-}
-
-/* write BAR */
-static int pt_bar_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- struct pt_reg_grp_tbl *reg_grp_entry = NULL;
- struct pt_reg_tbl *reg_entry = NULL;
- struct pt_region *base = NULL;
- PCIDevice *d = (PCIDevice *)&ptdev->dev;
- PCIIORegion *r;
- uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
- uint32_t bar_emu_mask = 0;
- uint32_t bar_ro_mask = 0;
- uint32_t new_addr, last_addr;
- uint32_t prev_offset;
- uint32_t r_size = 0;
- int index = 0;
-
- /* get BAR index */
- index = pt_bar_offset_to_index(reg->offset);
- if (index < 0)
- {
- /* exit I/O emulator */
- PT_LOG("Internal error: Invalid BAR index[%d]. "
- "I/O emulator exit.\n", index);
- exit(1);
- }
-
- r = &d->io_regions[index];
- r_size = r->size;
- base = &ptdev->bases[index];
- /* align resource size (memory type only) */
- PT_GET_EMUL_SIZE(base->bar_flag, r_size);
-
- /* set emulate mask and read-only mask depend on BAR flag */
- switch (ptdev->bases[index].bar_flag)
- {
- case PT_BAR_FLAG_MEM:
- bar_emu_mask = PT_BAR_MEM_EMU_MASK;
- bar_ro_mask = PT_BAR_MEM_RO_MASK | (r_size - 1);
- break;
- case PT_BAR_FLAG_IO:
- bar_emu_mask = PT_BAR_IO_EMU_MASK;
- bar_ro_mask = PT_BAR_IO_RO_MASK | (r_size - 1);
- break;
- case PT_BAR_FLAG_UPPER:
- bar_emu_mask = PT_BAR_ALLF;
- bar_ro_mask = 0; /* all upper 32bit are R/W */
- break;
- default:
- break;
- }
-
- /* modify emulate register */
- writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* check whether we need to update the virtual region address or not */
- switch (ptdev->bases[index].bar_flag)
- {
- case PT_BAR_FLAG_MEM:
- /* nothing to do */
- break;
- case PT_BAR_FLAG_IO:
- new_addr = cfg_entry->data;
- last_addr = new_addr + r_size - 1;
- /* check invalid address */
- if (last_addr <= new_addr || !new_addr || last_addr >= 0x10000)
- {
- /* check 64K range */
- if ((last_addr >= 0x10000) &&
- (cfg_entry->data != (PT_BAR_ALLF & ~bar_ro_mask)))
- {
- PT_LOG("Guest attempt to set Base Address over the 64KB. "
- "[%02x:%02x.%x][Offset:%02xh][Address:%08xh][Size:%08xh]\n",
- pci_bus_num(d->bus),
- ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- reg->offset, new_addr, r_size);
- }
- /* just remove mapping */
- r->addr = -1;
- goto exit;
- }
- break;
- case PT_BAR_FLAG_UPPER:
- if (cfg_entry->data)
- {
- if (cfg_entry->data != (PT_BAR_ALLF & ~bar_ro_mask))
- {
- PT_LOG("Guest attempt to set high MMIO Base Address. "
- "Ignore mapping. "
- "[%02x:%02x.%x][Offset:%02xh][High Address:%08xh]\n",
- pci_bus_num(d->bus),
- ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
- reg->offset, cfg_entry->data);
- }
- /* clear lower address */
- d->io_regions[index-1].addr = -1;
- }
- else
- {
- /* find lower 32bit BAR */
- prev_offset = (reg->offset - 4);
- reg_grp_entry = pt_find_reg_grp(ptdev, prev_offset);
- if (reg_grp_entry)
- {
- reg_entry = pt_find_reg(reg_grp_entry, prev_offset);
- if (reg_entry)
- /* restore lower address */
- d->io_regions[index-1].addr = reg_entry->data;
- else
- return -1;
- }
- else
- return -1;
- }
-
- /* never mapping the 'empty' upper region,
- * because we'll do it enough for the lower region.
- */
- r->addr = -1;
- goto exit;
- default:
- break;
- }
-
- /* update the corresponding virtual region address */
- r->addr = cfg_entry->data;
-
-exit:
- /* create value for writing to I/O device register */
- throughable_mask = ~bar_emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Exp ROM BAR */
-static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- struct pt_region *base = NULL;
- PCIDevice *d = (PCIDevice *)&ptdev->dev;
- PCIIORegion *r;
- uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
- uint32_t r_size = 0;
- uint32_t bar_emu_mask = 0;
- uint32_t bar_ro_mask = 0;
-
- r = &d->io_regions[PCI_ROM_SLOT];
- r_size = r->size;
- base = &ptdev->bases[PCI_ROM_SLOT];
- /* align memory type resource size */
- PT_GET_EMUL_SIZE(base->bar_flag, r_size);
-
- /* set emulate mask and read-only mask */
- bar_emu_mask = reg->emu_mask;
- bar_ro_mask = reg->ro_mask | (r_size - 1);
-
- /* modify emulate register */
- writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* update the corresponding virtual region address */
- r->addr = cfg_entry->data;
-
- /* create value for writing to I/O device register */
- throughable_mask = ~bar_emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Power Management Control/Status register */
-static int pt_pmcsr_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t pmcsr_mask = (PCI_PM_CTRL_PME_ENABLE |
- PCI_PM_CTRL_DATA_SEL_MASK |
- PCI_PM_CTRL_PME_STATUS);
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~pmcsr_mask;
- /* ignore it when the requested state neither D3 nor D0 */
- if (((*value & PCI_PM_CTRL_STATE_MASK) != PCI_PM_CTRL_STATE_MASK) &&
- ((*value & PCI_PM_CTRL_STATE_MASK) != 0))
- writable_mask &= ~PCI_PM_CTRL_STATE_MASK;
-
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Device Control register */
-static int pt_devctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t devctrl_mask = (PCI_EXP_DEVCTL_AUX_PME | 0x8000);
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~devctrl_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Link Control register */
-static int pt_linkctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t linkctrl_mask = (PCI_EXP_LNKCTL_ASPM | 0x04 |
- PCI_EXP_LNKCTL_DISABLE |
- PCI_EXP_LNKCTL_RETRAIN |
- 0x0400 | 0x0800 | 0xF000);
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~linkctrl_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Device Control2 register */
-static int pt_devctrl2_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t devctrl2_mask = 0xFFE0;
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~devctrl2_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Link Control2 register */
-static int pt_linkctrl2_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t linkctrl2_mask = (0x0040 | 0xE000);
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask &
- ~linkctrl2_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) |
- (dev_value & ~throughable_mask));
-
- return 0;
-}
-
-/* write Message Control register */
-static int pt_msgctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t old_ctrl = cfg_entry->data;
- PCIDevice *pd = (PCIDevice *)ptdev;
-
- /* Currently no support for multi-vector */
- if ((*value & PCI_MSI_FLAGS_QSIZE) != 0x0)
- PT_LOG("try to set more than 1 vector ctrl %x\n", *value);
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
- /* update the msi_info too */
- ptdev->msi->flags |= cfg_entry->data &
- ~(MSI_FLAG_UNINIT | PT_MSI_MAPPED | PCI_MSI_FLAGS_ENABLE);
-
- PT_LOG("old_ctrl:%04xh new_ctrl:%04xh\n", old_ctrl, cfg_entry->data);
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask));
-
- /* update MSI */
- if (*value & PCI_MSI_FLAGS_ENABLE)
- {
- /* setup MSI pirq for the first time */
- if (ptdev->msi->flags & MSI_FLAG_UNINIT)
- {
- /* Init physical one */
- PT_LOG("setup msi for dev %x\n", pd->devfn);
- if (pt_msi_setup(ptdev))
- {
- PT_LOG("pt_msi_setup error!!!\n");
- return -1;
- }
- pt_msi_update(ptdev);
-
- ptdev->msi->flags &= ~MSI_FLAG_UNINIT;
- ptdev->msi->flags |= PT_MSI_MAPPED;
- }
- ptdev->msi->flags |= PCI_MSI_FLAGS_ENABLE;
- }
- else
- ptdev->msi->flags &= ~PCI_MSI_FLAGS_ENABLE;
-
- return 0;
-}
-
-/* write Message Address register */
-static int pt_msgaddr32_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
- uint32_t old_addr = cfg_entry->data;
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
- /* update the msi_info too */
- ptdev->msi->addr_lo = cfg_entry->data;
-
- PT_LOG("old_addr_lo:%08xh new_addr_lo:%08xh\n", old_addr, cfg_entry->data);
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask));
-
- /* update MSI */
- if (cfg_entry->data != old_addr)
- {
- if (ptdev->msi->flags & PCI_MSI_FLAGS_ENABLE)
- pt_msi_update(ptdev);
- }
-
- return 0;
-}
-
-/* write Message Upper Address register */
-static int pt_msgaddr64_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value, uint32_t dev_value, uint32_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
- uint32_t old_addr = cfg_entry->data;
-
- /* check whether the type is 64 bit or not */
- if (!(ptdev->msi->flags & PCI_MSI_FLAGS_64BIT))
- {
- /* exit I/O emulator */
- PT_LOG("why comes to Upper Address without 64 bit support??\n");
- return -1;
- }
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
- /* update the msi_info too */
- ptdev->msi->addr_hi = cfg_entry->data;
-
- PT_LOG("old_addr_hi:%08xh new_addr_hi:%08xh\n", old_addr, cfg_entry->data);
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask));
-
- /* update MSI */
- if (cfg_entry->data != old_addr)
- {
- if (ptdev->msi->flags & PCI_MSI_FLAGS_ENABLE)
- pt_msi_update(ptdev);
- }
-
- return 0;
-}
-
-/* this function will be called twice (for 32 bit and 64 bit type) */
-/* write Message Data register */
-static int pt_msgdata_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t old_data = cfg_entry->data;
- uint32_t flags = ptdev->msi->flags;
- uint32_t offset = reg->offset;
-
- /* check the offset whether matches the type or not */
- if (!((offset == PCI_MSI_DATA_64) && (flags & PCI_MSI_FLAGS_64BIT)) &&
- !((offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT)))
- {
- /* exit I/O emulator */
- PT_LOG("Error: the offset is not match with the 32/64 bit type!!\n");
- return -1;
- }
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
- /* update the msi_info too */
- ptdev->msi->data = cfg_entry->data;
-
- PT_LOG("old_data:%04xh new_data:%04xh\n", old_data, cfg_entry->data);
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask));
-
- /* update MSI */
- if (cfg_entry->data != old_data)
- {
- if (flags & PCI_MSI_FLAGS_ENABLE)
- pt_msi_update(ptdev);
- }
-
- return 0;
-}
-
-/* write Message Control register for MSI-X */
-static int pt_msixctrl_reg_write(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t dev_value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
- uint16_t old_ctrl = cfg_entry->data;
-
- /* modify emulate register */
- writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
- cfg_entry->data = ((*value & writable_mask) |
- (cfg_entry->data & ~writable_mask));
-
- PT_LOG("old_ctrl:%04xh new_ctrl:%04xh\n", old_ctrl, cfg_entry->data);
-
- /* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask));
-
- /* update MSI-X */
- if ((*value & PCI_MSIX_ENABLE) && !(*value & PCI_MSIX_MASK))
- pt_msix_update(ptdev);
-
- ptdev->msix->enabled = !!(*value & PCI_MSIX_ENABLE);
-
- return 0;
-}
-
-struct pt_dev * register_real_device(PCIBus *e_bus,
- const char *e_dev_name, int e_devfn, uint8_t r_bus, uint8_t r_dev,
- uint8_t r_func, uint32_t machine_irq, struct pci_access *pci_access)
-{
- int rc = -1, i;
- struct pt_dev *assigned_device = NULL;
- struct pci_dev *pci_dev;
- uint8_t e_device, e_intx;
- struct pci_config_cf8 machine_bdf;
- int free_pci_slot = -1;
-
- PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
- r_bus, r_dev, r_func);
-
- /* Find real device structure */
- for (pci_dev = pci_access->devices; pci_dev != NULL;
- pci_dev = pci_dev->next)
- {
- if ((r_bus == pci_dev->bus) && (r_dev == pci_dev->dev)
- && (r_func == pci_dev->func))
- break;
- }
- if ( pci_dev == NULL )
- {
- PT_LOG("Error: couldn't locate device in libpci structures\n");
- return NULL;
- }
- pci_fill_info(pci_dev, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES);
-
- if ( e_devfn == PT_VIRT_DEVFN_AUTO ) {
- /*indicate a static assignment(not hotplug), so find a free PCI hot plug slot */
- free_pci_slot = __insert_to_pci_slot(r_bus, r_dev, r_func, 0);
- if ( free_pci_slot > 0 )
- e_devfn = free_pci_slot << 3;
- else
- PT_LOG("Error: no free virtual PCI hot plug slot, thus no live migration.\n");
- }
-
- /* Register device */
- assigned_device = (struct pt_dev *) pci_register_device(e_bus, e_dev_name,
- sizeof(struct pt_dev), e_devfn,
- pt_pci_read_config, pt_pci_write_config);
- if ( assigned_device == NULL )
- {
- PT_LOG("Error: couldn't register real device\n");
- return NULL;
- }
-
- if ( free_pci_slot > 0 )
- dpci_infos.php_devs[PCI_TO_PHP_SLOT(free_pci_slot)].pt_dev = assigned_device;
-
- assigned_device->pci_dev = pci_dev;
-
- /* Assign device */
- machine_bdf.reg = 0;
- machine_bdf.bus = r_bus;
- machine_bdf.dev = r_dev;
- machine_bdf.func = r_func;
- rc = xc_assign_device(xc_handle, domid, machine_bdf.value);
- if ( rc < 0 )
- PT_LOG("Error: xc_assign_device error %d\n", rc);
-
- /* Initialize virtualized PCI configuration (Extended 256 Bytes) */
- for ( i = 0; i < PCI_CONFIG_SIZE; i++ )
- assigned_device->dev.config[i] = pci_read_byte(pci_dev, i);
-
- /* Handle real device's MMIO/PIO BARs */
- pt_register_regions(assigned_device);
-
- /* reinitialize each config register to be emulated */
- rc = pt_config_init(assigned_device);
- if ( rc < 0 ) {
- return NULL;
- }
-
- /* Bind interrupt */
- if (!assigned_device->dev.config[0x3d])
- goto out;
-
- e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
- /* fix virtual interrupt pin to INTA# */
- e_intx = 0;
-
- if ( PT_MACHINE_IRQ_AUTO == machine_irq )
- {
- int pirq = pci_dev->irq;
-
- machine_irq = pci_dev->irq;
- rc = xc_physdev_map_pirq(xc_handle, domid, machine_irq, &pirq);
-
- if ( rc )
- {
- /* TBD: unregister device in case of an error */
- PT_LOG("Error: Mapping irq failed, rc = %d\n", rc);
- }
- else
- machine_irq = pirq;
- }
-
- /* bind machine_irq to device */
- if ( 0 != machine_irq )
- {
- rc = xc_domain_bind_pt_pci_irq(xc_handle, domid, machine_irq, 0,
- e_device, e_intx);
- if ( rc < 0 )
- {
- /* TBD: unregister device in case of an error */
- PT_LOG("Error: Binding of interrupt failed! rc=%d\n", rc);
- }
- }
- else {
- /* Disable PCI intx assertion (turn on bit10 of devctl) */
- assigned_device->dev.config[0x05] |= 0x04;
- pci_write_word(pci_dev, 0x04,
- *(uint16_t *)(&assigned_device->dev.config[0x04]));
- }
-
-out:
- PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n",
- r_bus, r_dev, r_func);
-
- return assigned_device;
-}
-
-int unregister_real_device(int php_slot)
-{
- struct php_dev *php_dev;
- struct pci_dev *pci_dev;
- uint8_t e_device, e_intx;
- struct pt_dev *assigned_device = NULL;
- uint32_t machine_irq;
- uint32_t bdf = 0;
- int rc = -1;
-
- if ( php_slot < 0 || php_slot >= PHP_SLOT_LEN )
- return -1;
-
- php_dev = &dpci_infos.php_devs[php_slot];
- assigned_device = php_dev->pt_dev;
-
- if ( !assigned_device || !php_dev->valid )
- return -1;
-
- pci_dev = assigned_device->pci_dev;
-
- /* hide pci dev from qemu */
- pci_hide_device((PCIDevice*)assigned_device);
-
- /* Unbind interrupt */
- e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
- /* fix virtual interrupt pin to INTA# */
- e_intx = 0;
- machine_irq = pci_dev->irq;
-
- if ( machine_irq != 0 ) {
- rc = xc_domain_unbind_pt_irq(xc_handle, domid, machine_irq, PT_IRQ_TYPE_PCI, 0,
- e_device, e_intx, 0);
- if ( rc < 0 )
- {
- /* TBD: unregister device in case of an error */
- PT_LOG("Error: Unbinding of interrupt failed! rc=%d\n", rc);
- }
- }
-
- /* delete all emulated config registers */
- pt_config_delete(assigned_device);
-
- /* unregister real device's MMIO/PIO BARs */
- pt_unregister_regions(assigned_device);
-
- /* deassign the dev to dom0 */
- bdf |= (pci_dev->bus & 0xff) << 16;
- bdf |= (pci_dev->dev & 0x1f) << 11;
- bdf |= (pci_dev->func & 0x1f) << 8;
- if ( (rc = xc_deassign_device(xc_handle, domid, bdf)) != 0)
- PT_LOG("Error: Revoking the device failed! rc=%d\n", rc);
-
- /* mark this slot as free */
- php_dev->valid = 0;
- php_dev->pt_dev = NULL;
- qemu_free(assigned_device);
-
- return 0;
-}
-
-int power_on_php_slot(int php_slot)
-{
- struct php_dev *php_dev = &dpci_infos.php_devs[php_slot];
- int pci_slot = php_slot + PHP_SLOT_START;
- struct pt_dev *pt_dev;
- pt_dev =
- register_real_device(dpci_infos.e_bus,
- "DIRECT PCI",
- pci_slot << 3,
- php_dev->r_bus,
- php_dev->r_dev,
- php_dev->r_func,
- PT_MACHINE_IRQ_AUTO,
- dpci_infos.pci_access);
-
- php_dev->pt_dev = pt_dev;
-
- return 0;
-
-}
-
-int power_off_php_slot(int php_slot)
-{
- return unregister_real_device(php_slot);
-}
-
-int pt_init(PCIBus *e_bus, char *direct_pci)
-{
- int seg, b, d, f, php_slot = 0;
- struct pt_dev *pt_dev;
- struct pci_access *pci_access;
- char *vslots;
- char slot_str[8];
-
- /* Initialize libpci */
- pci_access = pci_alloc();
- if ( pci_access == NULL )
- {
- PT_LOG("pci_access is NULL\n");
- return -1;
- }
- pci_init(pci_access);
- pci_scan_bus(pci_access);
-
- memset(&dpci_infos, 0, sizeof(struct dpci_infos));
- dpci_infos.pci_access = pci_access;
- dpci_infos.e_bus = e_bus;
-
- if ( strlen(direct_pci) == 0 ) {
- return 0;
- }
-
- /* the virtual pci slots of all pass-through devs
- * with hex format: xx;xx...;
- */
- vslots = qemu_mallocz ( strlen(direct_pci) / 3 );
-
- /* Assign given devices to guest */
- while ( next_bdf(&direct_pci, &seg, &b, &d, &f) )
- {
- /* Register real device with the emulated bus */
- pt_dev = register_real_device(e_bus, "DIRECT PCI", PT_VIRT_DEVFN_AUTO,
- b, d, f, PT_MACHINE_IRQ_AUTO, pci_access);
- if ( pt_dev == NULL )
- {
- PT_LOG("Error: Registration failed (%02x:%02x.%x)\n", b, d, f);
- return -1;
- }
-
- /* Record the virtual slot info */
- if ( php_slot < PHP_SLOT_LEN &&
- dpci_infos.php_devs[php_slot].pt_dev == pt_dev )
- {
- sprintf(slot_str, "0x%x;", PHP_TO_PCI_SLOT(php_slot));
- }
- else
- sprintf(slot_str, "0x%x;", 0);
-
- strcat(vslots, slot_str);
- php_slot++;
- }
-
- /* Write virtual slots info to xenstore for Control panel use */
- xenstore_write_vslots(vslots);
-
- qemu_free(vslots);
-
- /* Success */
- return 0;
-}
-
diff --git a/tools/ioemu/hw/pass-through.h b/tools/ioemu/hw/pass-through.h
deleted file mode 100644
index dab660c76c..0000000000
--- a/tools/ioemu/hw/pass-through.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2007, Neocleus Corporation.
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __PASSTHROUGH_H__
-#define __PASSTHROUGH_H__
-
-#include "vl.h"
-#include "pci/header.h"
-#include "pci/pci.h"
-#include "audio/sys-queue.h"
-
-/* Log acesss */
-#define PT_LOGGING_ENABLED
-
-#ifdef PT_LOGGING_ENABLED
-#define PT_LOG(_f, _a...) fprintf(logfile, "%s: " _f, __func__, ##_a)
-#else
-#define PT_LOG(_f, _a...)
-#endif
-
-/* Some compilation flags */
-// #define PT_DEBUG_PCI_CONFIG_ACCESS
-
-#define PT_MACHINE_IRQ_AUTO (0xFFFFFFFF)
-#define PT_VIRT_DEVFN_AUTO (-1)
-
-/* Misc PCI constants that should be moved to a separate library :) */
-#define PCI_CONFIG_SIZE (256)
-#define PCI_EXP_DEVCAP_FLR (1 << 28)
-#define PCI_EXP_DEVCTL_FLR (1 << 15)
-#define PCI_BAR_ENTRIES (6)
-
-/* because the current version of libpci (2.2.0) doesn't define these ID,
- * so we define Capability ID here.
- */
-#ifndef PCI_CAP_ID_HOTPLUG
-/* SHPC Capability List Item reg group */
-#define PCI_CAP_ID_HOTPLUG 0x0C
-#endif
-
-#ifndef PCI_CAP_ID_SSVID
-/* Subsystem ID and Subsystem Vendor ID Capability List Item reg group */
-#define PCI_CAP_ID_SSVID 0x0D
-#endif
-
-#ifndef PCI_MSI_FLAGS_MASK_BIT
-/* interrupt masking & reporting supported */
-#define PCI_MSI_FLAGS_MASK_BIT 0x0100
-#endif
-
-#ifndef PCI_EXP_TYPE_PCIE_BRIDGE
-/* PCI/PCI-X to PCIE Bridge */
-#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8
-#endif
-
-#ifndef PCI_EXP_TYPE_ROOT_INT_EP
-/* Root Complex Integrated Endpoint */
-#define PCI_EXP_TYPE_ROOT_INT_EP 0x9
-#endif
-
-#ifndef PCI_EXP_TYPE_ROOT_EC
-/* Root Complex Event Collector */
-#define PCI_EXP_TYPE_ROOT_EC 0xa
-#endif
-
-#define PT_INVALID_REG 0xFFFFFFFF /* invalid register value */
-#define PT_BAR_ALLF 0xFFFFFFFF /* BAR ALLF value */
-#define PT_BAR_MEM_RO_MASK 0x0000000F /* BAR ReadOnly mask(Memory) */
-#define PT_BAR_MEM_EMU_MASK 0xFFFFFFF0 /* BAR emul mask(Memory) */
-#define PT_BAR_IO_RO_MASK 0x00000003 /* BAR ReadOnly mask(I/O) */
-#define PT_BAR_IO_EMU_MASK 0xFFFFFFFC /* BAR emul mask(I/O) */
-enum {
- PT_BAR_FLAG_MEM = 0, /* Memory type BAR */
- PT_BAR_FLAG_IO, /* I/O type BAR */
- PT_BAR_FLAG_UPPER, /* upper 64bit BAR */
- PT_BAR_FLAG_UNUSED, /* unused BAR */
-};
-enum {
- GRP_TYPE_HARDWIRED = 0, /* 0 Hardwired reg group */
- GRP_TYPE_EMU, /* emul reg group */
-};
-
-#define PT_GET_EMUL_SIZE(flag, r_size) do { \
- if (flag == PT_BAR_FLAG_MEM) {\
- r_size = (((r_size) + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1)); \
- }\
-} while(0)
-
-
-struct pt_region {
- /* Virtual phys base & size */
- uint32_t e_physbase;
- uint32_t e_size;
- /* Index of region in qemu */
- uint32_t memory_index;
- /* BAR flag */
- uint32_t bar_flag;
- /* Translation of the emulated address */
- union {
- uint64_t maddr;
- uint64_t pio_base;
- uint64_t u;
- } access;
-};
-
-struct pt_msi_info {
- uint32_t flags;
- int pirq; /* guest pirq corresponding */
- uint32_t addr_lo; /* guest message address */
- uint32_t addr_hi; /* guest message upper address */
- uint16_t data; /* guest message data */
-};
-
-struct msix_entry_info {
- int pirq; /* -1 means unmapped */
- int flags; /* flags indicting whether MSI ADDR or DATA is updated */
- uint32_t io_mem[4];
-};
-
-struct pt_msix_info {
- int enabled;
- int total_entries;
- int bar_index;
- uint64_t table_base;
- uint32_t table_off;
- uint64_t mmio_base_addr;
- int mmio_index;
- int fd;
- void *phys_iomem_base;
- struct msix_entry_info msix_entry[0];
-};
-
-/*
- This structure holds the context of the mapping functions
- and data that is relevant for qemu device management.
-*/
-struct pt_dev {
- PCIDevice dev;
- struct pci_dev *pci_dev; /* libpci struct */
- struct pt_region bases[PCI_NUM_REGIONS]; /* Access regions */
- LIST_HEAD (reg_grp_tbl_listhead, pt_reg_grp_tbl) reg_grp_tbl_head;
- /* emul reg group list */
- struct pt_msi_info *msi; /* MSI virtualization */
- struct pt_msix_info *msix; /* MSI-X virtualization */
-};
-
-/* Used for formatting PCI BDF into cf8 format */
-struct pci_config_cf8 {
- union {
- unsigned int value;
- struct {
- unsigned int reserved1:2;
- unsigned int reg:6;
- unsigned int func:3;
- unsigned int dev:5;
- unsigned int bus:8;
- unsigned int reserved2:7;
- unsigned int enable:1;
- };
- };
-};
-
-int pt_init(PCIBus * e_bus, char * direct_pci);
-
-/* emul reg group management table */
-struct pt_reg_grp_tbl {
- /* emul reg group list */
- LIST_ENTRY (pt_reg_grp_tbl) entries;
- /* emul reg group info table */
- struct pt_reg_grp_info_tbl *reg_grp;
- /* emul reg group base offset */
- uint32_t base_offset;
- /* emul reg group size */
- uint8_t size;
- /* emul reg management table list */
- LIST_HEAD (reg_tbl_listhead, pt_reg_tbl) reg_tbl_head;
-};
-
-/* emul reg group size initialize method */
-typedef uint8_t (*pt_reg_size_init) (struct pt_dev *ptdev,
- struct pt_reg_grp_info_tbl *grp_reg,
- uint32_t base_offset);
-/* emul reg group infomation table */
-struct pt_reg_grp_info_tbl {
- /* emul reg group ID */
- uint8_t grp_id;
- /* emul reg group type */
- uint8_t grp_type;
- /* emul reg group size */
- uint8_t grp_size;
- /* emul reg get size method */
- pt_reg_size_init size_init;
- /* emul reg info table */
- struct pt_reg_info_tbl *emu_reg_tbl;
-};
-
-/* emul reg management table */
-struct pt_reg_tbl {
- /* emul reg table list */
- LIST_ENTRY (pt_reg_tbl) entries;
- /* emul reg info table */
- struct pt_reg_info_tbl *reg;
- /* emul reg value */
- uint32_t data;
-};
-
-/* emul reg initialize method */
-typedef uint32_t (*conf_reg_init) (struct pt_dev *ptdev,
- struct pt_reg_info_tbl *reg,
- uint32_t real_offset);
-/* emul reg long write method */
-typedef int (*conf_dword_write) (struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value,
- uint32_t dev_value,
- uint32_t valid_mask);
-/* emul reg word write method */
-typedef int (*conf_word_write) (struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value,
- uint16_t dev_value,
- uint16_t valid_mask);
-/* emul reg byte write method */
-typedef int (*conf_byte_write) (struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint8_t *value,
- uint8_t dev_value,
- uint8_t valid_mask);
-/* emul reg long read methods */
-typedef int (*conf_dword_read) (struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint32_t *value,
- uint32_t valid_mask);
-/* emul reg word read method */
-typedef int (*conf_word_read) (struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value,
- uint16_t valid_mask);
-/* emul reg byte read method */
-typedef int (*conf_byte_read) (struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint8_t *value,
- uint8_t valid_mask);
-
-/* emul reg infomation table */
-struct pt_reg_info_tbl {
- /* reg relative offset */
- uint32_t offset;
- /* reg size */
- uint32_t size;
- /* reg initial value */
- uint32_t init_val;
- /* reg read only field mask (ON:RO/ROS, OFF:other) */
- uint32_t ro_mask;
- /* reg emulate field mask (ON:emu, OFF:passthrough) */
- uint32_t emu_mask;
- /* emul reg initialize method */
- conf_reg_init init;
- union {
- struct {
- /* emul reg long write method */
- conf_dword_write write;
- /* emul reg long read method */
- conf_dword_read read;
- } dw;
- struct {
- /* emul reg word write method */
- conf_word_write write;
- /* emul reg word read method */
- conf_word_read read;
- } w;
- struct {
- /* emul reg byte write method */
- conf_byte_write write;
- /* emul reg byte read method */
- conf_byte_read read;
- } b;
- } u;
-};
-
-#endif /* __PASSTHROUGH_H__ */
-
diff --git a/tools/ioemu/hw/pc.c b/tools/ioemu/hw/pc.c
deleted file mode 100644
index 999b4f4e9e..0000000000
--- a/tools/ioemu/hw/pc.c
+++ /dev/null
@@ -1,1146 +0,0 @@
-/*
- * QEMU PC System Emulator
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* output Bochs bios info messages */
-//#define DEBUG_BIOS
-
-#define BIOS_FILENAME "bios.bin"
-#define VGABIOS_FILENAME "vgabios.bin"
-#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
-#define LINUX_BOOT_FILENAME "linux_boot.bin"
-
-static fdctrl_t *floppy_controller;
-static RTCState *rtc_state;
-#ifndef CONFIG_DM
-static PITState *pit;
-#endif /* !CONFIG_DM */
-#ifndef CONFIG_DM
-static IOAPICState *ioapic;
-#endif /* !CONFIG_DM */
-static PCIDevice *i440fx_state;
-
-static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
-{
-}
-
-/* MSDOS compatibility mode FPU exception support */
-/* XXX: add IGNNE support */
-void cpu_set_ferr(CPUX86State *s)
-{
- pic_set_irq(13, 1);
-}
-
-static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
-{
- pic_set_irq(13, 0);
-}
-
-/* TSC handling */
-uint64_t cpu_get_tsc(CPUX86State *env)
-{
- /* Note: when using kqemu, it is more logical to return the host TSC
- because kqemu does not trap the RDTSC instruction for
- performance reasons */
-#if USE_KQEMU
- if (env->kqemu_enabled) {
- return cpu_get_real_ticks();
- } else
-#endif
- {
- return cpu_get_ticks();
- }
-}
-
-#ifndef CONFIG_DM
-/* SMM support */
-void cpu_smm_update(CPUState *env)
-{
- if (i440fx_state && env == first_cpu)
- i440fx_set_smm(i440fx_state, (env->hflags >> HF_SMM_SHIFT) & 1);
-}
-
-
-/* IRQ handling */
-int cpu_get_pic_interrupt(CPUState *env)
-{
- int intno;
-
- intno = apic_get_interrupt(env);
- if (intno >= 0) {
- /* set irq request if a PIC irq is still pending */
- /* XXX: improve that */
- pic_update_irq(isa_pic);
- return intno;
- }
- /* read the irq from the PIC */
- intno = pic_read_irq(isa_pic);
- return intno;
-}
-#endif /* CONFIG_DM */
-
-static void pic_irq_request(void *opaque, int level)
-{
- CPUState *env = opaque;
- if (level)
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- else
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
-}
-
-/* PC cmos mappings */
-
-#define REG_EQUIPMENT_BYTE 0x14
-
-static int cmos_get_fd_drive_type(int fd0)
-{
- int val;
-
- switch (fd0) {
- case 0:
- /* 1.44 Mb 3"5 drive */
- val = 4;
- break;
- case 1:
- /* 2.88 Mb 3"5 drive */
- val = 5;
- break;
- case 2:
- /* 1.2 Mb 5"5 drive */
- val = 2;
- break;
- default:
- val = 0;
- break;
- }
- return val;
-}
-
-static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
-{
- RTCState *s = rtc_state;
- int cylinders, heads, sectors;
- bdrv_get_geometry_hint(hd, &cylinders, &heads, &sectors);
- rtc_set_memory(s, type_ofs, 47);
- rtc_set_memory(s, info_ofs, cylinders);
- rtc_set_memory(s, info_ofs + 1, cylinders >> 8);
- rtc_set_memory(s, info_ofs + 2, heads);
- rtc_set_memory(s, info_ofs + 3, 0xff);
- rtc_set_memory(s, info_ofs + 4, 0xff);
- rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3));
- rtc_set_memory(s, info_ofs + 6, cylinders);
- rtc_set_memory(s, info_ofs + 7, cylinders >> 8);
- rtc_set_memory(s, info_ofs + 8, sectors);
-}
-
-static int get_bios_disk(char *boot_device, int index) {
-
- if (index < strlen(boot_device)) {
- switch (boot_device[index]) {
- case 'a':
- return 0x01; /* floppy */
- case 'c':
- return 0x02; /* hard drive */
- case 'd':
- return 0x03; /* cdrom */
- case 'n':
- return 0x04; /* network */
- }
- }
- return 0x00; /* no device */
-}
-
-/* hd_table must contain 4 block drivers */
-static void cmos_init(uint64_t ram_size, char *boot_device, BlockDriverState **hd_table)
-{
- RTCState *s = rtc_state;
- int val;
- int fd0, fd1, nb;
- int i;
-
- /* various important CMOS locations needed by PC/Bochs bios */
-
- /* memory size */
- val = 640; /* base memory in K */
- rtc_set_memory(s, 0x15, val);
- rtc_set_memory(s, 0x16, val >> 8);
-
- val = (ram_size / 1024) - 1024;
- if (val > 65535)
- val = 65535;
- rtc_set_memory(s, 0x17, val);
- rtc_set_memory(s, 0x18, val >> 8);
- rtc_set_memory(s, 0x30, val);
- rtc_set_memory(s, 0x31, val >> 8);
-
- if (ram_size > (16 * 1024 * 1024))
- val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
- else
- val = 0;
- if (val > 65535)
- val = 65535;
- rtc_set_memory(s, 0x34, val);
- rtc_set_memory(s, 0x35, val >> 8);
-
- if (boot_device == NULL) {
- /* default to hd, then cd, then floppy. */
- boot_device = "cda";
- }
- rtc_set_memory(s, 0x3d, get_bios_disk(boot_device, 0) |
- (get_bios_disk(boot_device, 1) << 4));
- rtc_set_memory(s, 0x38, (get_bios_disk(boot_device, 2) << 4) |
- (!fd_bootchk ? 0x01 : 0x00));
-
- /* floppy type */
-
- fd0 = fdctrl_get_drive_type(floppy_controller, 0);
- fd1 = fdctrl_get_drive_type(floppy_controller, 1);
-
- val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1);
- rtc_set_memory(s, 0x10, val);
-
- val = 0;
- nb = 0;
- if (fd0 < 3)
- nb++;
- if (fd1 < 3)
- nb++;
- switch (nb) {
- case 0:
- break;
- case 1:
- val |= 0x01; /* 1 drive, ready for boot */
- break;
- case 2:
- val |= 0x41; /* 2 drives, ready for boot */
- break;
- }
- val |= 0x02; /* FPU is there */
- val |= 0x04; /* PS/2 mouse installed */
- rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);
-
- /* hard drives */
-
- rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
- if (hd_table[0])
- cmos_init_hd(0x19, 0x1b, hd_table[0]);
- if (hd_table[1])
- cmos_init_hd(0x1a, 0x24, hd_table[1]);
-
- val = 0;
- for (i = 0; i < 4; i++) {
- if (hd_table[i]) {
- int cylinders, heads, sectors, translation;
- /* NOTE: bdrv_get_geometry_hint() returns the physical
- geometry. It is always such that: 1 <= sects <= 63, 1
- <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
- geometry can be different if a translation is done. */
- translation = bdrv_get_translation_hint(hd_table[i]);
- if (translation == BIOS_ATA_TRANSLATION_AUTO) {
- bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
- if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
- /* No translation. */
- translation = 0;
- } else {
- /* LBA translation. */
- translation = 1;
- }
- } else {
- translation--;
- }
- val |= translation << (i * 2);
- }
- }
- rtc_set_memory(s, 0x39, val);
-}
-
-void ioport_set_a20(int enable)
-{
- /* XXX: send to all CPUs ? */
- cpu_x86_set_a20(first_cpu, enable);
-}
-
-int ioport_get_a20(void)
-{
- return ((first_cpu->a20_mask >> 20) & 1);
-}
-
-static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
-{
- ioport_set_a20((val >> 1) & 1);
- /* XXX: bit 0 is fast reset */
-}
-
-static uint32_t ioport92_read(void *opaque, uint32_t addr)
-{
- return ioport_get_a20() << 1;
-}
-
-/***********************************************************/
-/* Bochs BIOS debug ports */
-
-void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
-{
- static const char shutdown_str[8] = "Shutdown";
- static int shutdown_index = 0;
-
- switch(addr) {
- /* Bochs BIOS messages */
- case 0x400:
- case 0x401:
- fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
- exit(1);
- case 0x402:
- case 0x403:
-#ifdef DEBUG_BIOS
- fprintf(stderr, "%c", val);
-#endif
- break;
- case 0x8900:
- /* same as Bochs power off */
- if (val == shutdown_str[shutdown_index]) {
- shutdown_index++;
- if (shutdown_index == 8) {
- shutdown_index = 0;
- qemu_system_shutdown_request();
- }
- } else {
- shutdown_index = 0;
- }
- break;
-
- /* LGPL'ed VGA BIOS messages */
- case 0x501:
- case 0x502:
- fprintf(stderr, "VGA BIOS panic, line %d\n", val);
- exit(1);
- case 0x500:
- case 0x503:
-#ifdef DEBUG_BIOS
- fprintf(stderr, "%c", val);
-#endif
- break;
- }
-}
-
-void bochs_bios_init(void)
-{
- register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL);
- register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
- register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
-
- register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
- register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
-}
-
-#if defined(__i386__) || defined(__x86_64__)
-/* Generate an initial boot sector which sets state and jump to
- a specified vector */
-static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip)
-{
- uint8_t bootsect[512], *p;
- int i;
-
- if (bs_table[0] == NULL) {
- fprintf(stderr, "A disk image must be given for 'hda' when booting "
- "a Linux kernel\n");
- exit(1);
- }
-
- memset(bootsect, 0, sizeof(bootsect));
-
- /* Copy the MSDOS partition table if possible */
- bdrv_read(bs_table[0], 0, bootsect, 1);
-
- /* Make sure we have a partition signature */
- bootsect[510] = 0x55;
- bootsect[511] = 0xaa;
-
- /* Actual code */
- p = bootsect;
- *p++ = 0xfa; /* CLI */
- *p++ = 0xfc; /* CLD */
-
- for (i = 0; i < 6; i++) {
- if (i == 1) /* Skip CS */
- continue;
-
- *p++ = 0xb8; /* MOV AX,imm16 */
- *p++ = segs[i];
- *p++ = segs[i] >> 8;
- *p++ = 0x8e; /* MOV <seg>,AX */
- *p++ = 0xc0 + (i << 3);
- }
-
- for (i = 0; i < 8; i++) {
- *p++ = 0x66; /* 32-bit operand size */
- *p++ = 0xb8 + i; /* MOV <reg>,imm32 */
- *p++ = gpr[i];
- *p++ = gpr[i] >> 8;
- *p++ = gpr[i] >> 16;
- *p++ = gpr[i] >> 24;
- }
-
- *p++ = 0xea; /* JMP FAR */
- *p++ = ip; /* IP */
- *p++ = ip >> 8;
- *p++ = segs[1]; /* CS */
- *p++ = segs[1] >> 8;
-
- bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
-}
-
-/*
- * Evil helper for non-relocatable kernels
- *
- * So it works out like this:
- *
- * 0x100000 - Xen HVM firmware lives here. Kernel wants to boot here
- *
- * You can't both live there and HVM firmware is needed first, thus
- * our plan is
- *
- * 0x200000 - kernel is loaded here by QEMU
- * 0x200000+kernel_size - helper code is put here by QEMU
- *
- * code32_switch in kernel header is set to point at out helper
- * code at 0x200000+kernel_size
- *
- * Our helper basically does memmove(0x100000,0x200000,kernel_size)
- * and then jmps to 0x1000000.
- *
- * So we've overwritten the HVM firmware (which was no longer
- * needed) and the non-relocatable kernel can happily boot
- * at its usual address.
- *
- * Simple, eh ?
- *
- * Well the assembler needed to do this is fairly short:
- *
- * # Load segments
- * cld
- * cli
- * movl $0x18,%eax
- * mov %ax,%ds
- * mov %ax,%es
- * mov %ax,%fs
- * mov %ax,%gs
- * mov %ax,%ss
- *
- * # Move the kernel into position
- * xor %edx,%edx
- *_doloop:
- * movzbl 0x600000(%edx),%eax
- * mov %al,0x100000(%edx)
- * add $0x1,%edx
- * cmp $0x500000,%edx
- * jne _doloop
- *
- * # start kernel
- * xorl %ebx,%ebx
- * mov $0x100000,%ecx
- * jmp *%ecx
- *
- */
-static void setup_relocator(target_phys_addr_t addr, target_phys_addr_t src, target_phys_addr_t dst, size_t len)
-{
- /* Now this assembler corresponds to follow machine code, with our args from QEMU spliced in :-) */
- unsigned char buf[] = {
- /* Load segments */
- 0xfc, /* cld */
- 0xfa, /* cli */
- 0xb8, 0x18, 0x00, 0x00, 0x00, /* mov $0x18,%eax */
- 0x8e, 0xd8, /* mov %eax,%ds */
- 0x8e, 0xc0, /* mov %eax,%es */
- 0x8e, 0xe0, /* mov %eax,%fs */
- 0x8e, 0xe8, /* mov %eax,%gs */
- 0x8e, 0xd0, /* mov %eax,%ss */
- 0x31, 0xd2, /* xor %edx,%edx */
-
- /* Move the kernel into position */
- 0x0f, 0xb6, 0x82, (src&0xff), ((src>>8)&0xff), ((src>>16)&0xff), ((src>>24)&0xff), /* movzbl $src(%edx),%eax */
- 0x88, 0x82, (dst&0xff), ((dst>>8)&0xff), ((dst>>16)&0xff), ((dst>>24)&0xff), /* mov %al,$dst(%edx) */
- 0x83, 0xc2, 0x01, /* add $0x1,%edx */
- 0x81, 0xfa, (len&0xff), ((len>>8)&0xff), ((len>>16)&0xff), ((len>>24)&0xff), /* cmp $len,%edx */
- 0x75, 0xe8, /* jne 13 <_doloop> */
-
- /* Start kernel */
- 0x31, 0xdb, /* xor %ebx,%ebx */
- 0xb9, (dst&0xff), ((dst>>8)&0xff), ((dst>>16)&0xff), ((dst>>24)&0xff), /* mov $dst,%ecx */
- 0xff, 0xe1, /* jmp *%ecx */
- };
- cpu_physical_memory_rw(addr, buf, sizeof(buf), 1);
- fprintf(stderr, "qemu: helper at 0x%x of size %d bytes, to move kernel of %d bytes from 0x%x to 0x%x\n",
- (int)addr, (int)sizeof(buf), (int)len, (int)src, (int)dst);
-}
-
-
-static long get_file_size(FILE *f)
-{
- long where, size;
-
- /* XXX: on Unix systems, using fstat() probably makes more sense */
-
- where = ftell(f);
- fseek(f, 0, SEEK_END);
- size = ftell(f);
- fseek(f, where, SEEK_SET);
-
- return size;
-}
-
-static int fread2guest(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)
-{
- size_t offset = 0;
- while (nbytes) {
- uint8_t buf[4096];
- size_t count = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
- if (fread(buf, 1, count, f) != count)
- return -1;
-
- cpu_physical_memory_rw(dst_addr+offset, buf, count, 1);
- offset += count;
- nbytes -= count;
- }
- return 0;
-}
-
-static void load_linux(const char *kernel_filename,
- const char *initrd_filename,
- const char *kernel_cmdline)
-{
- uint16_t protocol;
- uint32_t gpr[8];
- uint16_t seg[6];
- uint16_t real_seg;
- int setup_size, kernel_size, initrd_size, cmdline_size;
- unsigned long end_low_ram;
- uint32_t initrd_max;
- uint8_t header[1024];
- target_phys_addr_t real_addr, reloc_prot_addr, prot_addr, cmdline_addr, initrd_addr;
- size_t ncmdline;
- FILE *f, *fi;
-
- /* Align to 16 bytes as a paranoia measure */
- cmdline_size = (strlen(kernel_cmdline)+16) & ~15;
-
- /* load the kernel header */
- f = fopen(kernel_filename, "rb");
- if (!f || !(kernel_size = get_file_size(f)) ||
- fread(header, 1, 1024, f) != 1024) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
-
- /* kernel protocol version */
- fprintf(stderr, "header magic: %#x\n", ldl_p(header+0x202));
- if (ldl_p(header+0x202) == 0x53726448)
- protocol = lduw_p(header+0x206);
- else
- protocol = 0;
- fprintf(stderr, "header protocol: %x\n", protocol);
- if (protocol < 0x200 || !(header[0x211] & 0x01)) {
- /* Low kernel */
- real_addr = 0x90000;
- cmdline_addr = 0x9a000 - cmdline_size;
- prot_addr = 0x10000;
- reloc_prot_addr = prot_addr;
- } else if (protocol < 0x202) {
- /* High but ancient kernel */
- real_addr = 0x90000;
- cmdline_addr = 0x9a000 - cmdline_size;
- prot_addr = 0x100000;
- reloc_prot_addr = 0x200000;
- } else {
- /* High and recent kernel */
- real_addr = 0x10000;
- cmdline_addr = 0x20000;
- prot_addr = 0x100000;
- reloc_prot_addr = 0x200000;
- }
-
- fprintf(stderr,
- "qemu: real_addr = %#zx\n"
- "qemu: cmdline_addr = %#zx\n"
- "qemu: prot_addr = %#zx\n",
- (size_t)real_addr,
- (size_t)cmdline_addr,
- (size_t)prot_addr);
-
- /* Special pages are placed at end of low RAM: pick an arbitrary one and
- * subtract a suitably large amount of padding (64kB) to skip BIOS data. */
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram);
- end_low_ram = (end_low_ram << 12) - (64*1024);
-
- /* highest address for loading the initrd */
- initrd_max = (protocol >= 0x203) ? ldl_p(header+0x22c) : 0x37ffffff;
- initrd_max = MIN(initrd_max, (uint32_t)end_low_ram);
-
- /* kernel command line */
- ncmdline = strlen(kernel_cmdline);
- if (ncmdline > 4095) {
- ncmdline = 4095;
- ((uint8_t*)kernel_cmdline)[4095] = '\0';
- }
- fprintf(stderr, "qemu: kernel_cmdline: %#zx ('%s')\n", ncmdline, kernel_cmdline);
- cpu_physical_memory_rw(cmdline_addr, (uint8_t*)kernel_cmdline, ncmdline+1, 1);
-
- if (protocol >= 0x202) {
- stl_p(header+0x228, cmdline_addr);
- } else {
- stw_p(header+0x20, 0xA33F);
- stw_p(header+0x22, cmdline_addr-real_addr);
- }
-
- /* loader type */
- /* High nybble = B reserved for Qemu; low nybble is revision number.
- If this code is substantially changed, you may want to consider
- incrementing the revision. */
- if (protocol >= 0x200)
- header[0x210] = 0xB0;
-
- /* heap */
- if (protocol >= 0x201) {
- header[0x211] |= 0x80; /* CAN_USE_HEAP */
- stw_p(header+0x224, cmdline_addr-real_addr-0x200);
- }
-
- /* load initrd */
- if (initrd_filename) {
- if (protocol < 0x200) {
- fprintf(stderr, "qemu: linux kernel too old to load a ram disk\n");
- exit(1);
- }
-
- fi = fopen(initrd_filename, "rb");
- if (!fi) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
-
- initrd_size = get_file_size(fi);
- initrd_addr = ((initrd_max-initrd_size) & ~4095);
-
- fprintf(stderr, "qemu: loading initrd (%#x bytes) at %#zx\n",
- initrd_size, initrd_addr);
-
- if (fread2guest(initrd_addr, initrd_size, fi) < 0) {
- fprintf(stderr, "qemu: read error on initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- fclose(fi);
-
- stl_p(header+0x218, initrd_addr);
- stl_p(header+0x21c, initrd_size);
- }
-
-
- setup_size = header[0x1f1];
- if (setup_size == 0)
- setup_size = 4;
-
- setup_size = (setup_size+1)*512;
- kernel_size -= setup_size; /* Size of protected-mode code */
-
- /* Urgh, Xen's HVM firmware lives at 0x100000, but that's also the
- * address Linux wants to start life at prior to relocatable support
- */
- if (prot_addr != reloc_prot_addr) {
- if (protocol >= 0x205 && (header[0x234] & 1)) {
- /* Relocatable automatically */
- stl_p(header+0x214, reloc_prot_addr);
- fprintf(stderr, "qemu: kernel is relocatable\n");
- } else {
- /* Setup a helper which moves kernel back to
- * its expected addr after firmware has got out
- * of the way. We put a helper at reloc_prot_addr+kernel_size.
- * It moves kernel from reloc_prot_addr to prot_addr and
- * then jumps to prot_addr. Yes this is sick.
- */
- fprintf(stderr, "qemu: kernel is NOT relocatable\n");
- stl_p(header+0x214, reloc_prot_addr + kernel_size);
- setup_relocator(reloc_prot_addr + kernel_size, reloc_prot_addr, prot_addr, kernel_size);
- }
- }
-
-
- fprintf(stderr, "qemu: loading kernel real mode (%#x bytes) at %#zx\n",
- setup_size-1024, real_addr);
- fprintf(stderr, "qemu: loading kernel protected mode (%#x bytes) at %#zx\n",
- kernel_size, reloc_prot_addr);
-
- /* store the finalized header and load the rest of the kernel */
- cpu_physical_memory_rw(real_addr, header, 1024, 1);
- if (fread2guest(real_addr+1024, setup_size-1024, f) < 0 ||
- fread2guest(reloc_prot_addr, kernel_size, f) < 0) {
- fprintf(stderr, "qemu: loading kernel protected mode (%#x bytes) at %#zx\n",
- kernel_size, reloc_prot_addr);
- exit(1);
- }
- fclose(f);
-
- /* generate bootsector to set up the initial register state */
- real_seg = (real_addr) >> 4;
- seg[0] = seg[2] = seg[3] = seg[4] = seg[4] = real_seg;
- seg[1] = real_seg+0x20; /* CS */
- memset(gpr, 0, sizeof gpr);
- gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
-
- generate_bootsect(gpr, seg, 0);
-}
-#else /* __ia64__ */
-static void load_linux(const char *kernel_filename,
- const char *initrd_filename,
- const char *kernel_cmdline)
-{
- /* Direct Linux boot is unsupported. */
-}
-#endif
-
-static void main_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
- cpu_reset(env);
-}
-
-static const int ide_iobase[2] = { 0x1f0, 0x170 };
-static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 14, 15 };
-
-#define NE2000_NB_MAX 6
-
-static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
-static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
-
-static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
-static int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
-static int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
-
-#ifdef HAS_AUDIO
-static void audio_init (PCIBus *pci_bus)
-{
- struct soundhw *c;
- int audio_enabled = 0;
-
- for (c = soundhw; !audio_enabled && c->name; ++c) {
- audio_enabled = c->enabled;
- }
-
- if (audio_enabled) {
- AudioState *s;
-
- s = AUD_init ();
- if (s) {
- for (c = soundhw; c->name; ++c) {
- if (c->enabled) {
- if (c->isa) {
- c->init.init_isa (s);
- }
- else {
- if (pci_bus) {
- c->init.init_pci (pci_bus, s);
- }
- }
- }
- }
- }
- }
-}
-#endif
-
-static void pc_init_ne2k_isa(NICInfo *nd)
-{
- static int nb_ne2k = 0;
-
- if (nb_ne2k == NE2000_NB_MAX)
- return;
- isa_ne2000_init(ne2000_io[nb_ne2k], ne2000_irq[nb_ne2k], nd);
- nb_ne2k++;
-}
-
-#define NOBIOS 1
-
-/* PC hardware initialisation */
-static void pc_init1(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename,
- int pci_enabled, const char *direct_pci)
-{
-#ifndef NOBIOS
- char buf[1024];
- int ret, initrd_size;
-#endif /* !NOBIOS */
- int linux_boot, i;
-#ifndef NOBIOS
- unsigned long bios_offset, vga_bios_offset, option_rom_offset;
- int bios_size, isa_bios_size;
-#endif /* !NOBIOS */
- PCIBus *pci_bus;
- int piix3_devfn = -1;
- CPUState *env;
- NICInfo *nd;
- int rc;
-
- linux_boot = (kernel_filename != NULL);
-
- /* init CPUs */
- for(i = 0; i < smp_cpus; i++) {
- env = cpu_init();
-#ifndef CONFIG_DM
- if (i != 0)
- env->hflags |= HF_HALTED_MASK;
- if (smp_cpus > 1) {
- /* XXX: enable it in all cases */
- env->cpuid_features |= CPUID_APIC;
- }
-#endif /* !CONFIG_DM */
- register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
- qemu_register_reset(main_cpu_reset, env);
-#ifndef CONFIG_DM
- if (pci_enabled) {
- apic_init(env);
- }
-#endif /* !CONFIG_DM */
- }
-
- /* allocate RAM */
-#ifndef CONFIG_DM /* HVM domain owns memory */
- cpu_register_physical_memory(0, ram_size, 0);
-#endif
-
-#ifndef NOBIOS
- /* BIOS load */
- bios_offset = ram_size + vga_ram_size;
- vga_bios_offset = bios_offset + 256 * 1024;
-
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- bios_size = get_image_size(buf);
- if (bios_size <= 0 ||
- (bios_size % 65536) != 0 ||
- bios_size > (256 * 1024)) {
- goto bios_error;
- }
- ret = load_image(buf, phys_ram_base + bios_offset);
- if (ret != bios_size) {
- bios_error:
- fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
- exit(1);
- }
-
- /* VGA BIOS load */
- if (cirrus_vga_enabled) {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
- } else {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
- }
- ret = load_image(buf, phys_ram_base + vga_bios_offset);
-#endif /* !NOBIOS */
-
- /* setup basic memory access */
-#ifndef CONFIG_DM /* HVM domain owns memory */
- cpu_register_physical_memory(0xc0000, 0x10000,
- vga_bios_offset | IO_MEM_ROM);
-#endif
-
-#ifndef NOBIOS
- /* map the last 128KB of the BIOS in ISA space */
- isa_bios_size = bios_size;
- if (isa_bios_size > (128 * 1024))
- isa_bios_size = 128 * 1024;
- cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size,
- IO_MEM_UNASSIGNED);
- cpu_register_physical_memory(0x100000 - isa_bios_size,
- isa_bios_size,
- (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
-
- option_rom_offset = 0;
- for (i = 0; i < nb_option_roms; i++) {
- int offset = bios_offset + bios_size + option_rom_offset;
- int size;
-
- size = load_image(option_rom[i], phys_ram_base + offset);
- if ((size + option_rom_offset) > 0x10000) {
- fprintf(stderr, "Too many option ROMS\n");
- exit(1);
- }
- cpu_register_physical_memory(0xd0000 + option_rom_offset,
- size, offset | IO_MEM_ROM);
- option_rom_offset += size + 2047;
- option_rom_offset -= (option_rom_offset % 2048);
- }
-
- /* map all the bios at the top of memory */
- cpu_register_physical_memory((uint32_t)(-bios_size),
- bios_size, bios_offset | IO_MEM_ROM);
-#endif
-
- bochs_bios_init();
-
- if (linux_boot)
- load_linux(kernel_filename, initrd_filename, kernel_cmdline);
-
- if (pci_enabled) {
- pci_bus = i440fx_init(&i440fx_state);
- piix3_devfn = piix3_init(pci_bus, -1);
- } else {
- pci_bus = NULL;
- }
-
- /* init basic PC hardware */
- register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
-
- register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
-
- if (cirrus_vga_enabled) {
- if (pci_enabled) {
- pci_cirrus_vga_init(pci_bus,
- ds, NULL, ram_size,
- vga_ram_size);
- } else {
- isa_cirrus_vga_init(ds, NULL, ram_size,
- vga_ram_size);
- }
- } else {
- if (pci_enabled) {
- pci_vga_init(pci_bus, ds, NULL, ram_size,
- vga_ram_size, 0, 0);
- } else {
- isa_vga_init(ds, NULL, ram_size,
- vga_ram_size);
- }
- }
-
-#ifdef CONFIG_PASSTHROUGH
- /* Pass-through Initialization
- * init libpci even direct_pci is null, as can hotplug a dev runtime
- */
- if ( pci_enabled )
- {
- rc = pt_init(pci_bus, direct_pci);
- if ( rc < 0 )
- {
- fprintf(logfile, "Error: Initialization failed for pass-through devices\n");
- exit(1);
- }
- }
-#endif
-
- rtc_state = rtc_init(0x70, 8);
-
- register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
- register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
-
-#ifndef CONFIG_DM
- if (pci_enabled) {
- ioapic = ioapic_init();
- }
-#endif /* !CONFIG_DM */
- isa_pic = pic_init(pic_irq_request, first_cpu);
-#ifndef CONFIG_DM
- pit = pit_init(0x40, 0);
- pcspk_init(pit);
-#endif /* !CONFIG_DM */
-#ifndef CONFIG_DM
- if (pci_enabled) {
- pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
- }
-#endif /* !CONFIG_DM */
-
- if (pci_enabled)
- pci_xen_platform_init(pci_bus);
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_hds[i]) {
- serial_init(&pic_set_irq_new, isa_pic,
- serial_io[i], serial_irq[i], serial_hds[i]);
- }
- }
-
- for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
- if (parallel_hds[i]) {
- parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]);
- }
- }
-
- for(i = 0; i < nb_nics; i++) {
- nd = &nd_table[i];
- if (!nd->model) {
- if (pci_enabled) {
- nd->model = "ne2k_pci";
- } else {
- nd->model = "ne2k_isa";
- }
- }
- if (strcmp(nd->model, "ne2k_isa") == 0) {
- pc_init_ne2k_isa(nd);
- } else if (pci_enabled) {
- pci_nic_init(pci_bus, nd, -1);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
- exit(1);
- }
- }
-
- if (pci_enabled) {
- pci_piix3_ide_init(pci_bus, bs_table, piix3_devfn + 1);
- } else {
- for(i = 0; i < 2; i++) {
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
- bs_table[2 * i], bs_table[2 * i + 1]);
- }
- }
-
-#ifdef HAS_TPM
- if (has_tpm_device())
- tpm_tis_init(&pic_set_irq_new, isa_pic, 11);
-#endif
-
- kbd_init();
- DMA_init(0);
-#ifdef HAS_AUDIO
- audio_init(pci_enabled ? pci_bus : NULL);
-#endif
-
- floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
-
- cmos_init(ram_size, boot_device, bs_table);
-
- /* using PIIX4 acpi model */
- if (pci_enabled && acpi_enabled)
- pci_piix4_acpi_init(pci_bus, piix3_devfn + 2);
-
- if (pci_enabled && usb_enabled) {
- usb_uhci_init(pci_bus, piix3_devfn + (acpi_enabled ? 3 : 2));
- }
-
-#ifndef CONFIG_DM
- if (pci_enabled && acpi_enabled) {
- uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
- piix4_pm_init(pci_bus, piix3_devfn + 3);
- for (i = 0; i < 8; i++) {
- SMBusDevice *eeprom = smbus_eeprom_device_init(0x50 + i,
- eeprom_buf + (i * 256));
- piix4_smbus_register_device(eeprom, 0x50 + i);
- }
- }
-
- if (i440fx_state) {
- i440fx_init_memory_mappings(i440fx_state);
- }
-#if 0
- /* ??? Need to figure out some way for the user to
- specify SCSI devices. */
- if (pci_enabled) {
- void *scsi;
- BlockDriverState *bdrv;
-
- scsi = lsi_scsi_init(pci_bus, -1);
- bdrv = bdrv_new("scsidisk");
- bdrv_open(bdrv, "scsi_disk.img", 0);
- lsi_scsi_attach(scsi, bdrv, -1);
- bdrv = bdrv_new("scsicd");
- bdrv_open(bdrv, "scsi_cd.iso", 0);
- bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
- lsi_scsi_attach(scsi, bdrv, -1);
- }
-#endif
-#else
- if (pci_enabled) {
- void *scsi = NULL;
- for (i = 0; i < MAX_SCSI_DISKS ; i++) {
- if (!bs_table[i + MAX_DISKS])
- continue;
- if (!scsi)
- scsi = lsi_scsi_init(pci_bus, -1);
- lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1);
- }
- }
-#endif /* !CONFIG_DM */
-
- if (pci_enabled) {
- PCI_EMULATION_INFO *p;
- for (p = PciEmulationInfoHead; p != NULL; p = p->next) {
- pci_emulation_init(pci_bus, p);
- }
- }
-}
-
-static void pc_init_pci(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *direct_pci)
-{
- pc_init1(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline,
- initrd_filename, 1,
- direct_pci);
-}
-
-static void pc_init_isa(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *unused)
-{
- pc_init1(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline,
- initrd_filename, 0, NULL);
-}
-
-/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
- BIOS will read it and start S3 resume at POST Entry*/
-void cmos_set_s3_resume(void)
-{
- if (rtc_state)
- rtc_set_memory(rtc_state, 0xF, 0xFE);
-}
-
-QEMUMachine pc_machine = {
- "pc",
- "Standard PC",
- pc_init_pci,
-};
-
-QEMUMachine isapc_machine = {
- "isapc",
- "ISA-only PC",
- pc_init_isa,
-};
diff --git a/tools/ioemu/hw/pci.c b/tools/ioemu/hw/pci.c
deleted file mode 100644
index 255b849a9e..0000000000
--- a/tools/ioemu/hw/pci.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * QEMU PCI bus manager
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_PCI
-
-struct PCIBus {
- int bus_num;
- int devfn_min;
- pci_set_irq_fn set_irq;
- pci_map_irq_fn map_irq;
- uint32_t config_reg; /* XXX: suppress */
- /* low level pic */
- SetIRQFunc *low_set_irq;
- void *irq_opaque;
- PCIDevice *devices[256];
- PCIDevice *parent_dev;
- PCIBus *next;
- /* The bus IRQ state is the logical OR of the connected devices.
- Keep a count of the number of devices with raised IRQs. */
- int irq_count[];
-};
-
-static void pci_update_mappings(PCIDevice *d);
-
-target_phys_addr_t pci_mem_base;
-static PCIBus *first_bus;
-
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *pic, int devfn_min, int nirq)
-{
- PCIBus *bus;
- bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
- bus->set_irq = set_irq;
- bus->map_irq = map_irq;
- bus->irq_opaque = pic;
- bus->devfn_min = devfn_min;
- first_bus = bus;
- return bus;
-}
-
-PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
-{
- PCIBus *bus;
- bus = qemu_mallocz(sizeof(PCIBus));
- bus->map_irq = map_irq;
- bus->parent_dev = dev;
- bus->next = dev->bus->next;
- dev->bus->next = bus;
- return bus;
-}
-
-int pci_bus_num(PCIBus *s)
-{
- return s->bus_num;
-}
-
-void pci_device_save(PCIDevice *s, QEMUFile *f)
-{
- uint8_t irq_state = 0;
- int i;
- qemu_put_be32(f, 2); /* PCI device version */
- qemu_put_buffer(f, s->config, 256);
- for (i = 0; i < 4; i++)
- irq_state |= !!s->irq_state[i] << i;
- qemu_put_buffer(f, &irq_state, 1);
-}
-
-int pci_device_load(PCIDevice *s, QEMUFile *f)
-{
- uint32_t version_id;
- version_id = qemu_get_be32(f);
- if (version_id != 1 && version_id != 2)
- return -EINVAL;
- qemu_get_buffer(f, s->config, 256);
- pci_update_mappings(s);
- if (version_id == 2) {
- uint8_t irq_state;
- int i;
- qemu_get_buffer(f, &irq_state, 1);
- for (i = 0; i < 4; i++)
- pci_set_irq(s, i, (irq_state >> i) & 1);
- }
- return 0;
-}
-
-/* -1 for devfn means auto assign */
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write)
-{
- PCIDevice *pci_dev;
-
- if (devfn < 0) {
- for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
- if ( !bus->devices[devfn] &&
- !( devfn >= PHP_DEVFN_START && devfn < PHP_DEVFN_END ) )
- goto found;
- }
- return NULL;
- found: ;
- }
- pci_dev = qemu_mallocz(instance_size);
- if (!pci_dev)
- return NULL;
- pci_dev->bus = bus;
- pci_dev->devfn = devfn;
- pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
- memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
-
- if (!config_read)
- config_read = pci_default_read_config;
- if (!config_write)
- config_write = pci_default_write_config;
- pci_dev->config_read = config_read;
- pci_dev->config_write = config_write;
- bus->devices[devfn] = pci_dev;
- return pci_dev;
-}
-
-void pci_hide_device(PCIDevice *pci_dev)
-{
- PCIBus *bus = pci_dev->bus;
- bus->devices[pci_dev->devfn] = NULL;
-}
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func)
-{
- PCIIORegion *r;
- uint32_t addr;
-
- if ((unsigned int)region_num >= PCI_NUM_REGIONS)
- return;
- r = &pci_dev->io_regions[region_num];
- r->addr = -1;
- r->size = size;
- r->type = type;
- r->map_func = map_func;
- if (region_num == PCI_ROM_SLOT) {
- addr = 0x30;
- } else {
- addr = 0x10 + region_num * 4;
- }
- *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
-}
-
-target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
-{
- return addr + pci_mem_base;
-}
-
-static void pci_update_mappings(PCIDevice *d)
-{
- PCIIORegion *r;
- int cmd, i;
- uint32_t last_addr, new_addr, config_ofs;
-
- cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
- for(i = 0; i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (i == PCI_ROM_SLOT) {
- config_ofs = 0x30;
- } else {
- config_ofs = 0x10 + i * 4;
- }
- if (r->size != 0) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- if (cmd & PCI_COMMAND_IO) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we have only 64K ioports on PC */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr >= 0x10000) {
- new_addr = -1;
- }
- } else {
- new_addr = -1;
- }
- } else {
- if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- /* the ROM slot has a specific enable bit */
- if (i == PCI_ROM_SLOT && !(new_addr & 1))
- goto no_mem_map;
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we do not support wrapping */
- /* XXX: as we cannot support really dynamic
- mappings, we handle specific values as invalid
- mappings. */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr == -1) {
- new_addr = -1;
- }
- } else {
- no_mem_map:
- new_addr = -1;
- }
- }
- /* now do the real mapping */
- if (new_addr != r->addr) {
- if (r->addr != -1) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- int class;
- /* NOTE: specific hack for IDE in PC case:
- only one byte must be mapped. */
- class = d->config[0x0a] | (d->config[0x0b] << 8);
- if (class == 0x0101 && r->size == 4) {
- isa_unassign_ioport(r->addr + 2, 1);
- } else {
- isa_unassign_ioport(r->addr, r->size);
- }
- } else {
- cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
- r->size,
- IO_MEM_UNASSIGNED);
- }
- }
- r->addr = new_addr;
- if (r->addr != -1) {
- r->map_func(d, i, r->addr, r->size, r->type);
- }
- }
- }
- }
-}
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len)
-{
- uint32_t val;
-
- switch(len) {
- default:
- case 4:
- if (address <= 0xfc) {
- val = le32_to_cpu(*(uint32_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 2:
- if (address <= 0xfe) {
- val = le16_to_cpu(*(uint16_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 1:
- val = d->config[address];
- break;
- }
- return val;
-}
-
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- int can_write, i;
- uint32_t end, addr;
-
- if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
- (address >= 0x30 && address < 0x34))) {
- PCIIORegion *r;
- int reg;
-
- if ( address >= 0x30 ) {
- reg = PCI_ROM_SLOT;
- }else{
- reg = (address - 0x10) >> 2;
- }
- r = &d->io_regions[reg];
- if (r->size == 0)
- goto default_config;
- /* compute the stored value */
- if (reg == PCI_ROM_SLOT) {
- /* keep ROM enable bit */
- val &= (~(r->size - 1)) | 1;
- } else {
- val &= ~(r->size - 1);
- val |= r->type;
- }
- *(uint32_t *)(d->config + address) = cpu_to_le32(val);
- pci_update_mappings(d);
- return;
- }
- default_config:
- /* not efficient, but simple */
- addr = address;
- for(i = 0; i < len; i++) {
- /* default read/write accesses */
- switch(d->config[0x0e]) {
- case 0x00:
- case 0x80:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x10 ... 0x27: /* base */
- case 0x2c ... 0x2f: /* subsystem vendor id, subsystem id */
- case 0x30 ... 0x33: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- default:
- case 0x01:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x38 ... 0x3b: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- }
- if (can_write) {
- if( addr == 0x05 ) {
- /* In Command Register, bits 15:11 are reserved */
- val &= 0x07;
- } else if ( addr == 0x06 ) {
- /* In Status Register, bits 6, 2:0 are reserved, */
- /* and bits 7,5,4,3 are read only */
- val = d->config[addr];
- } else if ( addr == 0x07 ) {
- /* In Status Register, bits 10,9 are reserved, */
- val = (val & ~0x06) | (d->config[addr] & 0x06);
- }
-
- d->config[addr] = val;
- }
- if (++addr > 0xff)
- break;
- val >>= 8;
- }
-
- end = address + len;
- if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
- /* if the command register is modified, we must modify the mappings */
- pci_update_mappings(d);
- }
-}
-
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
-
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_write: addr=%08x val=%08x len=%d\n",
- addr, val, len);
-#endif
- bus_num = (addr >> 16) & 0xff;
- while (s && s->bus_num != bus_num)
- s = s->next;
- if (!s)
- return;
- pci_dev = s->devices[(addr >> 8) & 0xff];
- if (!pci_dev)
- return;
- config_addr = addr & 0xff;
-#if defined(DEBUG_PCI)
- printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- pci_dev->config_write(pci_dev, config_addr, val, len);
-}
-
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
- uint32_t val;
-
- bus_num = (addr >> 16) & 0xff;
- while (s && s->bus_num != bus_num)
- s= s->next;
- if (!s)
- goto fail;
- pci_dev = s->devices[(addr >> 8) & 0xff];
- if (!pci_dev) {
- fail:
- switch(len) {
- case 1:
- val = 0xff;
- break;
- case 2:
- val = 0xffff;
- break;
- default:
- case 4:
- val = 0xffffffff;
- break;
- }
- goto the_end;
- }
- config_addr = addr & 0xff;
- val = pci_dev->config_read(pci_dev, config_addr, len);
-#if defined(DEBUG_PCI)
- printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- the_end:
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_read: addr=%08x val=%08x len=%d\n",
- addr, val, len);
-#endif
- return val;
-}
-
-/***********************************************************/
-/* generic PCI irq support */
-
-/* 0 <= irq_num <= 3. level must be 0 or 1 */
-void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
-{
- PCIBus *bus;
- int change;
-
- change = level - pci_dev->irq_state[irq_num];
- if (!change)
- return;
-
- pci_dev->irq_state[irq_num] = level;
- for (;;) {
- bus = pci_dev->bus;
- irq_num = bus->map_irq(pci_dev, irq_num);
- if (bus->set_irq)
- break;
- pci_dev = bus->parent_dev;
- }
- bus->irq_count[irq_num] += change;
- bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
-}
-
-/***********************************************************/
-/* monitor info on PCI */
-
-typedef struct {
- uint16_t class;
- const char *desc;
-} pci_class_desc;
-
-static pci_class_desc pci_class_descriptions[] =
-{
- { 0x0100, "SCSI controller"},
- { 0x0101, "IDE controller"},
- { 0x0200, "Ethernet controller"},
- { 0x0300, "VGA controller"},
- { 0x0600, "Host bridge"},
- { 0x0601, "ISA bridge"},
- { 0x0604, "PCI bridge"},
- { 0x0c03, "USB controller"},
- { 0, NULL}
-};
-
-static void pci_info_device(PCIDevice *d)
-{
- int i, class;
- PCIIORegion *r;
- pci_class_desc *desc;
-
- term_printf(" Bus %2d, device %3d, function %d:\n",
- d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
- class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
- term_printf(" ");
- desc = pci_class_descriptions;
- while (desc->desc && class != desc->class)
- desc++;
- if (desc->desc) {
- term_printf("%s", desc->desc);
- } else {
- term_printf("Class %04x", class);
- }
- term_printf(": PCI device %04x:%04x\n",
- le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
- le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
-
- if (d->config[PCI_INTERRUPT_PIN] != 0) {
- term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
- }
- if (class == 0x0604) {
- term_printf(" BUS %d.\n", d->config[0x19]);
- }
- for(i = 0;i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (r->size != 0) {
- term_printf(" BAR%d: ", i);
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- term_printf("I/O at 0x%04x [0x%04x].\n",
- r->addr, r->addr + r->size - 1);
- } else {
- term_printf("32 bit memory at 0x%08x [0x%08x].\n",
- r->addr, r->addr + r->size - 1);
- }
- }
- }
- if (class == 0x0604 && d->config[0x19] != 0) {
- pci_for_each_device(d->config[0x19], pci_info_device);
- }
-}
-
-void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
-{
- PCIBus *bus = first_bus;
- PCIDevice *d;
- int devfn;
-
- while (bus && bus->bus_num != bus_num)
- bus = bus->next;
- if (bus) {
- for(devfn = 0; devfn < 256; devfn++) {
- d = bus->devices[devfn];
- if (d)
- fn(d);
- }
- }
-}
-
-void pci_info(void)
-{
- pci_for_each_device(0, pci_info_device);
-}
-
-/* Initialize a PCI NIC. */
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
-{
- if (strcmp(nd->model, "ne2k_pci") == 0) {
- pci_ne2000_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "rtl8139") == 0) {
- pci_rtl8139_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "pcnet") == 0) {
- pci_pcnet_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "e100") == 0) {
- pci_e100_init(bus, nd);
- } else if (strcmp(nd->model, "e1000") == 0) {
- pci_e1000_init(bus, nd, devfn);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
- exit (1);
- }
-}
-
-typedef struct {
- PCIDevice dev;
- PCIBus *bus;
-} PCIBridge;
-
-void pci_bridge_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- PCIBridge *s = (PCIBridge *)d;
-
- if (address == 0x19 || (address == 0x18 && len > 1)) {
- if (address == 0x19)
- s->bus->bus_num = val & 0xff;
- else
- s->bus->bus_num = (val >> 8) & 0xff;
-#if defined(DEBUG_PCI)
- printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
-#endif
- }
- pci_default_write_config(d, address, val, len);
-}
-
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
- pci_map_irq_fn map_irq, const char *name)
-{
- PCIBridge *s;
- s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
- devfn, NULL, pci_bridge_write_config);
- s->dev.config[0x00] = id >> 16;
- s->dev.config[0x01] = id > 24;
- s->dev.config[0x02] = id; // device_id
- s->dev.config[0x03] = id >> 8;
- s->dev.config[0x04] = 0x06; // command = bus master, pci mem
- s->dev.config[0x05] = 0x00;
- s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
- s->dev.config[0x07] = 0x00; // status = fast devsel
- s->dev.config[0x08] = 0x00; // revision
- s->dev.config[0x09] = 0x00; // programming i/f
- s->dev.config[0x0A] = 0x04; // class_sub = PCI to PCI bridge
- s->dev.config[0x0B] = 0x06; // class_base = PCI_bridge
- s->dev.config[0x0D] = 0x10; // latency_timer
- s->dev.config[0x0E] = 0x81; // header_type
- s->dev.config[0x1E] = 0xa0; // secondary status
-
- s->bus = pci_register_secondary_bus(&s->dev, map_irq);
- return s->bus;
-}
-
-int pt_chk_bar_overlap(PCIBus *bus, int devfn, uint32_t addr, uint32_t size)
-{
- PCIDevice *devices = NULL;
- PCIIORegion *r;
- int ret = 0;
- int i, j;
-
- /* check Overlapped to Base Address */
- for (i=0; i<256; i++)
- {
- if ( !(devices = bus->devices[i]) )
- continue;
-
- /* skip itself */
- if (devices->devfn == devfn)
- continue;
-
- for (j=0; j<PCI_NUM_REGIONS; j++)
- {
- r = &devices->io_regions[j];
- if ((addr < (r->addr + r->size)) && ((addr + size) > r->addr))
- {
- printf("Overlapped to device[%02x:%02x.%x][Region:%d]"
- "[Address:%08xh][Size:%08xh]\n", bus->bus_num,
- (devices->devfn >> 3) & 0x1F, (devices->devfn & 0x7),
- j, r->addr, r->size);
- ret = 1;
- goto out;
- }
- }
- }
-
-out:
- return ret;
-}
diff --git a/tools/ioemu/hw/pci_emulation.c b/tools/ioemu/hw/pci_emulation.c
deleted file mode 100644
index 0a4a7b452b..0000000000
--- a/tools/ioemu/hw/pci_emulation.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Changes to PCI emulation made by Marathon Technologies, June 2008
- */
-
-#include "vl.h"
-
-typedef struct {
- PCIDevice dev;
-} PCI_EMULATION_State;
-
-void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info)
-{
- char *p;
- int i;
- int ret;
- for (p = config_text, i = 0; *p != '\0'; p++) {
- if (*p == ':') {
- break;
- }
- if (i < sizeof(pci_emulation_info->name) - 1) {
- pci_emulation_info->name[i] = *p;
- i++;
- }
- }
- pci_emulation_info->name[i] = '\0';
- if (*p == '\0') return;
- p++;
- ret = sscanf(p, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
- &(pci_emulation_info->vendorid),
- &(pci_emulation_info->deviceid),
- &(pci_emulation_info->command),
- &(pci_emulation_info->status),
- &(pci_emulation_info->revision),
- &(pci_emulation_info->classcode),
- &(pci_emulation_info->headertype),
- &(pci_emulation_info->subvendorid),
- &(pci_emulation_info->subsystemid),
- &(pci_emulation_info->interruputline),
- &(pci_emulation_info->interruputpin));
-#ifdef DEBUG
- fprintf(logfile, "qemu: pciemulation %s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
- pci_emulation_info->name,
- pci_emulation_info->vendorid,
- pci_emulation_info->deviceid,
- pci_emulation_info->command,
- pci_emulation_info->status,
- pci_emulation_info->revision,
- pci_emulation_info->classcode,
- pci_emulation_info->headertype,
- pci_emulation_info->subvendorid,
- pci_emulation_info->subsystemid,
- pci_emulation_info->interruputline,
- pci_emulation_info->interruputpin);
-#endif
- return;
-}
-
-static void pci_emulation_save(QEMUFile *f, void *opaque)
-{
- PCIDevice *d = opaque;
-
- pci_device_save(d, f);
-}
-
-static int pci_emulation_load(QEMUFile *f, void *opaque, int version_id)
-{
- PCIDevice *d = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- return pci_device_load(d, f);
-}
-
-
-void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info)
-{
- int instance_id;
- PCI_EMULATION_State *d;
- uint8_t *pci_conf;
-
-#ifdef DEBUG
- fprintf(logfile, "qemu: pciinit\n");
-#endif
-
- d = (PCI_EMULATION_State *)pci_register_device(bus,
- pci_emulation_info->name,
- sizeof(PCI_EMULATION_State),
- -1,
- NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = pci_emulation_info->vendorid & 0xff;
- pci_conf[0x01] = (pci_emulation_info->vendorid & 0xff00) >> 8;
- pci_conf[0x02] = pci_emulation_info->deviceid & 0xff;
- pci_conf[0x03] = (pci_emulation_info->deviceid & 0xff00) >> 8;
- pci_conf[0x04] = pci_emulation_info->command & 0xff;
- pci_conf[0x05] = (pci_emulation_info->command & 0xff00) >> 8;
- pci_conf[0x06] = pci_emulation_info->status & 0xff;
- pci_conf[0x07] = (pci_emulation_info->status & 0xff00) >> 8;
- pci_conf[0x08] = pci_emulation_info->revision & 0xff;
- pci_conf[0x09] = pci_emulation_info->classcode & 0xff;
- pci_conf[0x0a] = (pci_emulation_info->classcode & 0xff00) >> 8;
- pci_conf[0x0b] = (pci_emulation_info->classcode & 0xff0000) >> 16;
- pci_conf[0x0e] = pci_emulation_info->headertype & 0xff;
- pci_conf[0x2c] = pci_emulation_info->subvendorid & 0xff;
- pci_conf[0x2d] = (pci_emulation_info->subvendorid & 0xff00) >> 8;
- pci_conf[0x2e] = pci_emulation_info->subsystemid & 0xff;
- pci_conf[0x2f] = (pci_emulation_info->subsystemid & 0xff00) >> 8;
- pci_conf[0x3c] = pci_emulation_info->interruputline & 0xff;
- pci_conf[0x3d] = pci_emulation_info->interruputpin & 0xff;
-
- instance_id = pci_bus_num(bus) << 8 | d->dev.devfn;
- register_savevm(pci_emulation_info->name, instance_id,
- 1, pci_emulation_save, pci_emulation_load, d);
-
-
- return;
-}
diff --git a/tools/ioemu/hw/pci_emulation.h b/tools/ioemu/hw/pci_emulation.h
deleted file mode 100644
index abb7572fce..0000000000
--- a/tools/ioemu/hw/pci_emulation.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Changes to PCI emulation made by Marathon Technologies, June 2008
- */
-
-typedef struct PCI_EMULATION_INFO_t {
- struct PCI_EMULATION_INFO_t *next;
- char name[32];
- unsigned int vendorid;
- unsigned int deviceid;
- unsigned int command;
- unsigned int status;
- unsigned int revision;
- unsigned int classcode;
- unsigned int headertype;
- unsigned int subvendorid;
- unsigned int subsystemid;
- unsigned int interruputline;
- unsigned int interruputpin;
-} PCI_EMULATION_INFO;
-
-void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info);
-void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info);
-
-extern PCI_EMULATION_INFO *PciEmulationInfoHead;
diff --git a/tools/ioemu/hw/pci_host.h b/tools/ioemu/hw/pci_host.h
deleted file mode 100644
index 708dae25e2..0000000000
--- a/tools/ioemu/hw/pci_host.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * QEMU Common PCI Host bridge configuration data space access routines.
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Worker routines for a PCI host controller that uses an {address,data}
- register pair to access PCI configuration space. */
-
-typedef struct {
- uint32_t config_reg;
- PCIBus *bus;
-} PCIHostState;
-
-static void pci_host_data_writeb(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1);
-}
-
-static void pci_host_data_writew(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2);
-}
-
-static void pci_host_data_writel(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg, val, 4);
-}
-
-static uint32_t pci_host_data_readb(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- if (!(s->config_reg & (1 << 31)))
- return 0xff;
- return pci_data_read(s->bus, s->config_reg | (addr & 3), 1);
-}
-
-static uint32_t pci_host_data_readw(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- uint32_t val;
- if (!(s->config_reg & (1 << 31)))
- return 0xffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t pci_host_data_readl(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- uint32_t val;
- if (!(s->config_reg & (1 << 31)))
- return 0xffffffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
diff --git a/tools/ioemu/hw/pckbd.c b/tools/ioemu/hw/pckbd.c
deleted file mode 100644
index 3c41e5f602..0000000000
--- a/tools/ioemu/hw/pckbd.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * QEMU PC keyboard emulation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug PC keyboard */
-//#define DEBUG_KBD
-
-/* debug PC keyboard : only mouse */
-//#define DEBUG_MOUSE
-
-/* Keyboard Controller Commands */
-#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
-#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
-#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
-#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
-#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
-#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
-#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
-#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
-#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
-#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
-#define KBD_CCMD_READ_INPORT 0xC0 /* read input port */
-#define KBD_CCMD_READ_OUTPORT 0xD0 /* read output port */
-#define KBD_CCMD_WRITE_OUTPORT 0xD1 /* write output port */
-#define KBD_CCMD_WRITE_OBUF 0xD2
-#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
- initiated by the auxiliary device */
-#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
-#define KBD_CCMD_DISABLE_A20 0xDD /* HP vectra only ? */
-#define KBD_CCMD_ENABLE_A20 0xDF /* HP vectra only ? */
-#define KBD_CCMD_RESET 0xFE
-
-/* Keyboard Commands */
-#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
-#define KBD_CMD_ECHO 0xEE
-#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
-#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
-#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
-#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
-#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
-#define KBD_CMD_RESET 0xFF /* Reset */
-
-/* Keyboard Replies */
-#define KBD_REPLY_POR 0xAA /* Power on reset */
-#define KBD_REPLY_ACK 0xFA /* Command ACK */
-#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
-
-/* Status Register Bits */
-#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
-#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
-#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
-#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
-#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
-#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
-#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
-#define KBD_STAT_PERR 0x80 /* Parity error */
-
-/* Controller Mode Register Bits */
-#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
-#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
-#define KBD_MODE_SYS 0x04 /* The system flag (?) */
-#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
-#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
-#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
-#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
-#define KBD_MODE_RFU 0x80
-
-/* Mouse Commands */
-#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
-#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
-#define AUX_SET_RES 0xE8 /* Set resolution */
-#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
-#define AUX_SET_STREAM 0xEA /* Set stream mode */
-#define AUX_POLL 0xEB /* Poll */
-#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
-#define AUX_SET_WRAP 0xEE /* Set wrap mode */
-#define AUX_SET_REMOTE 0xF0 /* Set remote mode */
-#define AUX_GET_TYPE 0xF2 /* Get type */
-#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
-#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
-#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
-#define AUX_SET_DEFAULT 0xF6
-#define AUX_RESET 0xFF /* Reset aux device */
-#define AUX_ACK 0xFA /* Command byte ACK. */
-
-#define MOUSE_STATUS_REMOTE 0x40
-#define MOUSE_STATUS_ENABLED 0x20
-#define MOUSE_STATUS_SCALE21 0x10
-
-#define KBD_QUEUE_SIZE 256
-
-#define KBD_PENDING_KBD 1
-#define KBD_PENDING_AUX 2
-
-typedef struct KBDState {
- uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
- uint8_t status;
- uint8_t mode;
- /* Bitmask of devices with data available. */
- uint8_t pending;
- void *kbd;
- void *mouse;
-} KBDState;
-
-KBDState kbd_state;
-
-/* update irq and KBD_STAT_[MOUSE_]OBF */
-/* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
- incorrect, but it avoids having to simulate exact delays */
-static void kbd_update_irq(KBDState *s)
-{
- int irq12_level, irq1_level;
-
- irq1_level = 0;
- irq12_level = 0;
- s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
- if (s->pending) {
- s->status |= KBD_STAT_OBF;
- /* kdb data takes priority over aux data. */
- if (s->pending == KBD_PENDING_AUX) {
- s->status |= KBD_STAT_MOUSE_OBF;
- if (s->mode & KBD_MODE_MOUSE_INT)
- irq12_level = 1;
- } else {
- if ((s->mode & KBD_MODE_KBD_INT) &&
- !(s->mode & KBD_MODE_DISABLE_KBD))
- irq1_level = 1;
- }
- }
- pic_set_irq(1, irq1_level);
- pic_set_irq(12, irq12_level);
-}
-
-static void kbd_update_kbd_irq(void *opaque, int level)
-{
- KBDState *s = (KBDState *)opaque;
-
- if (level)
- s->pending |= KBD_PENDING_KBD;
- else
- s->pending &= ~KBD_PENDING_KBD;
- kbd_update_irq(s);
-}
-
-static void kbd_update_aux_irq(void *opaque, int level)
-{
- KBDState *s = (KBDState *)opaque;
-
- if (level)
- s->pending |= KBD_PENDING_AUX;
- else
- s->pending &= ~KBD_PENDING_AUX;
- kbd_update_irq(s);
-}
-
-static uint32_t kbd_read_status(void *opaque, uint32_t addr)
-{
- KBDState *s = opaque;
- int val;
- val = s->status;
-#if defined(DEBUG_KBD)
- printf("kbd: read status=0x%02x\n", val);
-#endif
- return val;
-}
-
-static void kbd_queue(KBDState *s, int b, int aux)
-{
- if (aux)
- ps2_queue(s->mouse, b);
- else
- ps2_queue(s->kbd, b);
-}
-
-static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
-{
- KBDState *s = opaque;
-
-#ifdef DEBUG_KBD
- printf("kbd: write cmd=0x%02x\n", val);
-#endif
- switch(val) {
- case KBD_CCMD_READ_MODE:
- kbd_queue(s, s->mode, 0);
- break;
- case KBD_CCMD_WRITE_MODE:
- case KBD_CCMD_WRITE_OBUF:
- case KBD_CCMD_WRITE_AUX_OBUF:
- case KBD_CCMD_WRITE_MOUSE:
- case KBD_CCMD_WRITE_OUTPORT:
- s->write_cmd = val;
- break;
- case KBD_CCMD_MOUSE_DISABLE:
- s->mode |= KBD_MODE_DISABLE_MOUSE;
- break;
- case KBD_CCMD_MOUSE_ENABLE:
- s->mode &= ~KBD_MODE_DISABLE_MOUSE;
- break;
- case KBD_CCMD_TEST_MOUSE:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_SELF_TEST:
- s->status |= KBD_STAT_SELFTEST;
- kbd_queue(s, 0x55, 0);
- break;
- case KBD_CCMD_KBD_TEST:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_KBD_DISABLE:
- s->mode |= KBD_MODE_DISABLE_KBD;
- kbd_update_irq(s);
- break;
- case KBD_CCMD_KBD_ENABLE:
- s->mode &= ~KBD_MODE_DISABLE_KBD;
- kbd_update_irq(s);
- break;
- case KBD_CCMD_READ_INPORT:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_READ_OUTPORT:
- /* XXX: check that */
-#ifdef TARGET_I386
- val = 0x01 | (ioport_get_a20() << 1);
-#else
- val = 0x01;
-#endif
- if (s->status & KBD_STAT_OBF)
- val |= 0x10;
- if (s->status & KBD_STAT_MOUSE_OBF)
- val |= 0x20;
- kbd_queue(s, val, 0);
- break;
-#ifdef TARGET_I386
- case KBD_CCMD_ENABLE_A20:
- ioport_set_a20(1);
- break;
- case KBD_CCMD_DISABLE_A20:
- ioport_set_a20(0);
- break;
-#endif
- case KBD_CCMD_RESET:
- qemu_system_reset_request();
- break;
- case 0xff:
- /* ignore that - I don't know what is its use */
- break;
- default:
- fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
- break;
- }
-}
-
-static uint32_t kbd_read_data(void *opaque, uint32_t addr)
-{
- KBDState *s = opaque;
-
- if (s->pending == KBD_PENDING_AUX)
- return ps2_read_data(s->mouse);
-
- return ps2_read_data(s->kbd);
-}
-
-void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
-{
- KBDState *s = opaque;
-
-#ifdef DEBUG_KBD
- printf("kbd: write data=0x%02x\n", val);
-#endif
-
- switch(s->write_cmd) {
- case 0:
- ps2_write_keyboard(s->kbd, val);
- break;
- case KBD_CCMD_WRITE_MODE:
- s->mode = val;
- ps2_keyboard_set_translation(s->kbd, (s->mode & KBD_MODE_KCC) != 0);
- /* ??? */
- kbd_update_irq(s);
- break;
- case KBD_CCMD_WRITE_OBUF:
- kbd_queue(s, val, 0);
- break;
- case KBD_CCMD_WRITE_AUX_OBUF:
- kbd_queue(s, val, 1);
- break;
- case KBD_CCMD_WRITE_OUTPORT:
-#ifdef TARGET_I386
- ioport_set_a20((val >> 1) & 1);
-#endif
- if (!(val & 1)) {
- qemu_system_reset_request();
- }
- break;
- case KBD_CCMD_WRITE_MOUSE:
- ps2_write_mouse(s->mouse, val);
- break;
- default:
- break;
- }
- s->write_cmd = 0;
-}
-
-static void kbd_reset(void *opaque)
-{
- KBDState *s = opaque;
-
- s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
- s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
-}
-
-static void kbd_save(QEMUFile* f, void* opaque)
-{
- KBDState *s = (KBDState*)opaque;
-
- qemu_put_8s(f, &s->write_cmd);
- qemu_put_8s(f, &s->status);
- qemu_put_8s(f, &s->mode);
- qemu_put_8s(f, &s->pending);
-}
-
-static int kbd_load(QEMUFile* f, void* opaque, int version_id)
-{
- KBDState *s = (KBDState*)opaque;
-
- if (version_id != 3)
- return -EINVAL;
- qemu_get_8s(f, &s->write_cmd);
- qemu_get_8s(f, &s->status);
- qemu_get_8s(f, &s->mode);
- qemu_get_8s(f, &s->pending);
- return 0;
-}
-
-void kbd_init(void)
-{
- KBDState *s = &kbd_state;
-
- kbd_reset(s);
- register_savevm("pckbd", 0, 3, kbd_save, kbd_load, s);
- register_ioport_read(0x60, 1, 1, kbd_read_data, s);
- register_ioport_write(0x60, 1, 1, kbd_write_data, s);
- register_ioport_read(0x64, 1, 1, kbd_read_status, s);
- register_ioport_write(0x64, 1, 1, kbd_write_command, s);
-
- s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
- s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
- qemu_register_reset(kbd_reset, s);
-}
diff --git a/tools/ioemu/hw/pcnet.c b/tools/ioemu/hw/pcnet.c
deleted file mode 100644
index 6e68e23838..0000000000
--- a/tools/ioemu/hw/pcnet.c
+++ /dev/null
@@ -1,1992 +0,0 @@
-/*
- * QEMU AMD PC-Net II (Am79C970A) emulation
- *
- * Copyright (c) 2004 Antony T Curtis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* This software was written to be compatible with the specification:
- * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
- * AMD Publication# 19436 Rev:E Amendment/0 Issue Date: June 2000
- */
-
-/*
- * On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), also
- * produced as NCR89C100. See
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
- * and
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt
- */
-
-/* TODO: remove little endian host assumptions */
-
-#include "vl.h"
-
-//#define PCNET_DEBUG
-//#define PCNET_DEBUG_IO
-//#define PCNET_DEBUG_BCR
-//#define PCNET_DEBUG_CSR
-//#define PCNET_DEBUG_RMD
-//#define PCNET_DEBUG_TMD
-//#define PCNET_DEBUG_MATCH
-
-
-#define PCNET_IOPORT_SIZE 0x20
-#define PCNET_PNPMMIO_SIZE 0x20
-
-
-typedef struct PCNetState_st PCNetState;
-
-struct PCNetState_st {
- PCIDevice dev;
- PCIDevice *pci_dev;
- VLANClientState *vc;
- NICInfo *nd;
- QEMUTimer *poll_timer;
- int mmio_index, rap, isr, lnkst;
- uint32_t rdra, tdra;
- uint8_t prom[16];
- uint16_t csr[128];
- uint16_t bcr[32];
- uint64_t timer;
- int xmit_pos, recv_pos;
- uint8_t buffer[4096];
- int tx_busy;
- void (*set_irq_cb)(void *s, int isr);
- void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap);
- void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap);
- void *dma_opaque;
-};
-
-/* XXX: using bitfields for target memory structures is almost surely
- not portable, so it should be suppressed ASAP */
-#ifdef __GNUC__
-#define PACKED_FIELD(A) A __attribute__ ((packed))
-#else
-#error FixMe
-#endif
-
-struct qemu_ether_header {
- uint8_t ether_dhost[6];
- uint8_t ether_shost[6];
- uint16_t ether_type;
-};
-
-/* BUS CONFIGURATION REGISTERS */
-#define BCR_MSRDA 0
-#define BCR_MSWRA 1
-#define BCR_MC 2
-#define BCR_LNKST 4
-#define BCR_LED1 5
-#define BCR_LED2 6
-#define BCR_LED3 7
-#define BCR_FDC 9
-#define BCR_BSBC 18
-#define BCR_EECAS 19
-#define BCR_SWS 20
-#define BCR_PLAT 22
-
-#define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080)
-#define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100)
-#define BCR_SWSTYLE(S) ((S)->bcr[BCR_SWS ] & 0x00FF)
-
-#define CSR_INIT(S) !!(((S)->csr[0])&0x0001)
-#define CSR_STRT(S) !!(((S)->csr[0])&0x0002)
-#define CSR_STOP(S) !!(((S)->csr[0])&0x0004)
-#define CSR_TDMD(S) !!(((S)->csr[0])&0x0008)
-#define CSR_TXON(S) !!(((S)->csr[0])&0x0010)
-#define CSR_RXON(S) !!(((S)->csr[0])&0x0020)
-#define CSR_INEA(S) !!(((S)->csr[0])&0x0040)
-#define CSR_BSWP(S) !!(((S)->csr[3])&0x0004)
-#define CSR_LAPPEN(S) !!(((S)->csr[3])&0x0020)
-#define CSR_DXSUFLO(S) !!(((S)->csr[3])&0x0040)
-#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
-#define CSR_DPOLL(S) !!(((S)->csr[4])&0x1000)
-#define CSR_SPND(S) !!(((S)->csr[5])&0x0001)
-#define CSR_LTINTEN(S) !!(((S)->csr[5])&0x4000)
-#define CSR_TOKINTD(S) !!(((S)->csr[5])&0x8000)
-#define CSR_DRX(S) !!(((S)->csr[15])&0x0001)
-#define CSR_DTX(S) !!(((S)->csr[15])&0x0002)
-#define CSR_LOOP(S) !!(((S)->csr[15])&0x0004)
-#define CSR_DRCVPA(S) !!(((S)->csr[15])&0x2000)
-#define CSR_DRCVBC(S) !!(((S)->csr[15])&0x4000)
-#define CSR_PROM(S) !!(((S)->csr[15])&0x8000)
-
-#define CSR_CRBC(S) ((S)->csr[40])
-#define CSR_CRST(S) ((S)->csr[41])
-#define CSR_CXBC(S) ((S)->csr[42])
-#define CSR_CXST(S) ((S)->csr[43])
-#define CSR_NRBC(S) ((S)->csr[44])
-#define CSR_NRST(S) ((S)->csr[45])
-#define CSR_POLL(S) ((S)->csr[46])
-#define CSR_PINT(S) ((S)->csr[47])
-#define CSR_RCVRC(S) ((S)->csr[72])
-#define CSR_XMTRC(S) ((S)->csr[74])
-#define CSR_RCVRL(S) ((S)->csr[76])
-#define CSR_XMTRL(S) ((S)->csr[78])
-#define CSR_MISSC(S) ((S)->csr[112])
-
-#define CSR_IADR(S) ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
-#define CSR_CRBA(S) ((S)->csr[18] | ((S)->csr[19] << 16))
-#define CSR_CXBA(S) ((S)->csr[20] | ((S)->csr[21] << 16))
-#define CSR_NRBA(S) ((S)->csr[22] | ((S)->csr[23] << 16))
-#define CSR_BADR(S) ((S)->csr[24] | ((S)->csr[25] << 16))
-#define CSR_NRDA(S) ((S)->csr[26] | ((S)->csr[27] << 16))
-#define CSR_CRDA(S) ((S)->csr[28] | ((S)->csr[29] << 16))
-#define CSR_BADX(S) ((S)->csr[30] | ((S)->csr[31] << 16))
-#define CSR_NXDA(S) ((S)->csr[32] | ((S)->csr[33] << 16))
-#define CSR_CXDA(S) ((S)->csr[34] | ((S)->csr[35] << 16))
-#define CSR_NNRD(S) ((S)->csr[36] | ((S)->csr[37] << 16))
-#define CSR_NNXD(S) ((S)->csr[38] | ((S)->csr[39] << 16))
-#define CSR_PXDA(S) ((S)->csr[60] | ((S)->csr[61] << 16))
-#define CSR_NXBA(S) ((S)->csr[64] | ((S)->csr[65] << 16))
-
-#define PHYSADDR(S,A) \
- (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
-
-struct pcnet_initblk16 {
- uint16_t mode;
- uint16_t padr[3];
- uint16_t ladrf[4];
- uint32_t rdra;
- uint32_t tdra;
-};
-
-struct pcnet_initblk32 {
- uint16_t mode;
- uint8_t rlen;
- uint8_t tlen;
- uint16_t padr[3];
- uint16_t _res;
- uint16_t ladrf[4];
- uint32_t rdra;
- uint32_t tdra;
-};
-
-struct pcnet_TMD {
- struct {
- unsigned tbadr:32;
- } tmd0;
- struct {
- unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:7), PACKED_FIELD(bpe:1);
- unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(def:1), PACKED_FIELD(one:1);
- unsigned PACKED_FIELD(ltint:1), PACKED_FIELD(nofcs:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
- } tmd1;
- struct {
- unsigned PACKED_FIELD(trc:4), PACKED_FIELD(res:12);
- unsigned PACKED_FIELD(tdr:10), PACKED_FIELD(rtry:1), PACKED_FIELD(lcar:1);
- unsigned PACKED_FIELD(lcol:1), PACKED_FIELD(exdef:1), PACKED_FIELD(uflo:1), PACKED_FIELD(buff:1);
- } tmd2;
- struct {
- unsigned res:32;
- } tmd3;
-};
-
-struct pcnet_RMD {
- struct {
- unsigned rbadr:32;
- } rmd0;
- struct {
- unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:4);
- unsigned PACKED_FIELD(bam:1), PACKED_FIELD(lafm:1), PACKED_FIELD(pam:1), PACKED_FIELD(bpe:1);
- unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(buff:1), PACKED_FIELD(crc:1);
- unsigned PACKED_FIELD(oflo:1), PACKED_FIELD(fram:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
- } rmd1;
- struct {
- unsigned PACKED_FIELD(mcnt:12), PACKED_FIELD(zeros:4);
- unsigned PACKED_FIELD(rpc:8), PACKED_FIELD(rcc:8);
- } rmd2;
- struct {
- unsigned res:32;
- } rmd3;
-};
-
-
-#define PRINT_TMD(T) printf( \
- "TMD0 : TBADR=0x%08x\n" \
- "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, " \
- "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n" \
- " BPE=%d, BCNT=%d\n" \
- "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, " \
- "LCA=%d, RTR=%d,\n" \
- " TDR=%d, TRC=%d\n", \
- (T)->tmd0.tbadr, \
- (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs, \
- (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def, \
- (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe, \
- 4096-(T)->tmd1.bcnt, \
- (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\
- (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \
- (T)->tmd2.tdr, (T)->tmd2.trc)
-
-#define PRINT_RMD(R) printf( \
- "RMD0 : RBADR=0x%08x\n" \
- "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, " \
- "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n " \
- "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
- "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n", \
- (R)->rmd0.rbadr, \
- (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram, \
- (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff, \
- (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe, \
- (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam, \
- (R)->rmd1.ones, 4096-(R)->rmd1.bcnt, \
- (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt, \
- (R)->rmd2.zeros)
-
-static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1,
- target_phys_addr_t addr)
-{
- uint32_t *tmd = (uint32_t *)tmd1;
-
- if (!BCR_SWSTYLE(s)) {
- uint16_t xda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
- le16_to_cpus(&xda[0]);
- le16_to_cpus(&xda[1]);
- le16_to_cpus(&xda[2]);
- le16_to_cpus(&xda[3]);
- tmd[0] = (xda[0]&0xffff) |
- ((xda[1]&0x00ff) << 16);
- tmd[1] = (xda[2]&0xffff)|
- ((xda[1] & 0xff00) << 16);
- tmd[2] =
- (xda[3] & 0xffff) << 16;
- tmd[3] = 0;
- } else {
- uint32_t xda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
- le32_to_cpus(&xda[0]);
- le32_to_cpus(&xda[1]);
- le32_to_cpus(&xda[2]);
- le32_to_cpus(&xda[3]);
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(tmd, xda, sizeof(xda));
- } else {
- tmd[0] = xda[2];
- tmd[1] = xda[1];
- tmd[2] = xda[0];
- tmd[3] = xda[3];
- }
- }
-}
-
-static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd1,
- target_phys_addr_t addr)
-{
- const uint32_t *tmd = (const uint32_t *)tmd1;
- if (!BCR_SWSTYLE(s)) {
- uint16_t xda[4];
- xda[0] = tmd[0] & 0xffff;
- xda[1] = ((tmd[0]>>16)&0x00ff) |
- ((tmd[1]>>16)&0xff00);
- xda[2] = tmd[1] & 0xffff;
- xda[3] = tmd[2] >> 16;
- cpu_to_le16s(&xda[0]);
- cpu_to_le16s(&xda[1]);
- cpu_to_le16s(&xda[2]);
- cpu_to_le16s(&xda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
- } else {
- uint32_t xda[4];
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(xda, tmd, sizeof(xda));
- } else {
- xda[0] = tmd[2];
- xda[1] = tmd[1];
- xda[2] = tmd[0];
- xda[3] = tmd[3];
- }
- cpu_to_le32s(&xda[0]);
- cpu_to_le32s(&xda[1]);
- cpu_to_le32s(&xda[2]);
- cpu_to_le32s(&xda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
- }
-}
-
-static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd1,
- target_phys_addr_t addr)
-{
- uint32_t *rmd = (uint32_t *)rmd1;
-
- if (!BCR_SWSTYLE(s)) {
- uint16_t rda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
- le16_to_cpus(&rda[0]);
- le16_to_cpus(&rda[1]);
- le16_to_cpus(&rda[2]);
- le16_to_cpus(&rda[3]);
- rmd[0] = (rda[0]&0xffff)|
- ((rda[1] & 0x00ff) << 16);
- rmd[1] = (rda[2]&0xffff)|
- ((rda[1] & 0xff00) << 16);
- rmd[2] = rda[3] & 0xffff;
- rmd[3] = 0;
- } else {
- uint32_t rda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
- le32_to_cpus(&rda[0]);
- le32_to_cpus(&rda[1]);
- le32_to_cpus(&rda[2]);
- le32_to_cpus(&rda[3]);
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(rmd, rda, sizeof(rda));
- } else {
- rmd[0] = rda[2];
- rmd[1] = rda[1];
- rmd[2] = rda[0];
- rmd[3] = rda[3];
- }
- }
-}
-
-static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1,
- target_phys_addr_t addr)
-{
- const uint32_t *rmd = (const uint32_t *)rmd1;
-
- if (!BCR_SWSTYLE(s)) {
- uint16_t rda[4];
- rda[0] = rmd[0] & 0xffff;
- rda[1] = ((rmd[0]>>16)&0xff)|
- ((rmd[1]>>16)&0xff00);
- rda[2] = rmd[1] & 0xffff;
- rda[3] = rmd[2] & 0xffff;
- cpu_to_le16s(&rda[0]);
- cpu_to_le16s(&rda[1]);
- cpu_to_le16s(&rda[2]);
- cpu_to_le16s(&rda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
- } else {
- uint32_t rda[4];
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(rda, rmd, sizeof(rda));
- } else {
- rda[0] = rmd[2];
- rda[1] = rmd[1];
- rda[2] = rmd[0];
- rda[3] = rmd[3];
- }
- cpu_to_le32s(&rda[0]);
- cpu_to_le32s(&rda[1]);
- cpu_to_le32s(&rda[2]);
- cpu_to_le32s(&rda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
- }
-}
-
-
-#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
-
-#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
-
-#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
-
-#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
-
-#if 1
-
-#define CHECK_RMD(ADDR,RES) do { \
- struct pcnet_RMD rmd; \
- RMDLOAD(&rmd,(ADDR)); \
- (RES) |= (rmd.rmd1.ones != 15) \
- || (rmd.rmd2.zeros != 0); \
-} while (0)
-
-#define CHECK_TMD(ADDR,RES) do { \
- struct pcnet_TMD tmd; \
- TMDLOAD(&tmd,(ADDR)); \
- (RES) |= (tmd.tmd1.ones != 15); \
-} while (0)
-
-#else
-
-#define CHECK_RMD(ADDR,RES) do { \
- switch (BCR_SWSTYLE(s)) { \
- case 0x00: \
- do { \
- uint16_t rda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&rda[0], sizeof(rda), 0); \
- (RES) |= (rda[2] & 0xf000)!=0xf000; \
- (RES) |= (rda[3] & 0xf000)!=0x0000; \
- } while (0); \
- break; \
- case 0x01: \
- case 0x02: \
- do { \
- uint32_t rda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&rda[0], sizeof(rda), 0); \
- (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
- (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
- } while (0); \
- break; \
- case 0x03: \
- do { \
- uint32_t rda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&rda[0], sizeof(rda), 0); \
- (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
- (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
- break; \
- } \
-} while (0)
-
-#define CHECK_TMD(ADDR,RES) do { \
- switch (BCR_SWSTYLE(s)) { \
- case 0x00: \
- do { \
- uint16_t xda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&xda[0], sizeof(xda), 0); \
- (RES) |= (xda[2] & 0xf000)!=0xf000;\
- } while (0); \
- break; \
- case 0x01: \
- case 0x02: \
- case 0x03: \
- do { \
- uint32_t xda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&xda[0], sizeof(xda), 0); \
- (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
- break; \
- } \
-} while (0)
-
-#endif
-
-#define PRINT_PKTHDR(BUF) do { \
- struct qemu_ether_header *hdr = (void *)(BUF); \
- printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
- "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
- "type=0x%04x\n", \
- hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
- hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
- hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
- hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
- be16_to_cpu(hdr->ether_type)); \
-} while (0)
-
-#define MULTICAST_FILTER_LEN 8
-
-static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
-{
-#define LNC_POLYNOMIAL 0xEDB88320UL
- uint32_t crc = 0xFFFFFFFF;
- int idx, bit;
- uint8_t data;
-
- for (idx = 0; idx < 6; idx++) {
- for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
- crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
- data >>= 1;
- }
- }
- return crc;
-#undef LNC_POLYNOMIAL
-}
-
-#define CRC(crc, ch) (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
-
-/* generated using the AUTODIN II polynomial
- * x^32 + x^26 + x^23 + x^22 + x^16 +
- * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
- */
-static const uint32_t crctab[256] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
- 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
- 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
- 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
- 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
- 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
- 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
- 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
- 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
- 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
- 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
- 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
- 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
- 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
- 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
- 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
- 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
- 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
-{
- struct qemu_ether_header *hdr = (void *)buf;
- uint8_t padr[6] = {
- s->csr[12] & 0xff, s->csr[12] >> 8,
- s->csr[13] & 0xff, s->csr[13] >> 8,
- s->csr[14] & 0xff, s->csr[14] >> 8
- };
- int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
-#ifdef PCNET_DEBUG_MATCH
- printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
- "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
- hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
- hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
- padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
- printf("padr_match result=%d\n", result);
-#endif
- return result;
-}
-
-static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
-{
- static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- struct qemu_ether_header *hdr = (void *)buf;
- int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
-#ifdef PCNET_DEBUG_MATCH
- printf("padr_bcast result=%d\n", result);
-#endif
- return result;
-}
-
-static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
-{
- struct qemu_ether_header *hdr = (void *)buf;
- if ((*(hdr->ether_dhost)&0x01) &&
- ((uint64_t *)&s->csr[8])[0] != 0LL) {
- uint8_t ladr[8] = {
- s->csr[8] & 0xff, s->csr[8] >> 8,
- s->csr[9] & 0xff, s->csr[9] >> 8,
- s->csr[10] & 0xff, s->csr[10] >> 8,
- s->csr[11] & 0xff, s->csr[11] >> 8
- };
- int index = lnc_mchash(hdr->ether_dhost) >> 26;
- return !!(ladr[index >> 3] & (1 << (index & 7)));
- }
- return 0;
-}
-
-static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
-{
- while (idx < 1) idx += CSR_RCVRL(s);
- return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
-}
-
-static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
-{
- int64_t next_time = current_time +
- muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
- ticks_per_sec, 33000000L);
- if (next_time <= current_time)
- next_time = current_time + 1;
- return next_time;
-}
-
-static void pcnet_poll(PCNetState *s);
-static void pcnet_poll_timer(void *opaque);
-
-static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
-static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
-static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
-static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
-
-static void pcnet_s_reset(PCNetState *s)
-{
-#ifdef PCNET_DEBUG
- printf("pcnet_s_reset\n");
-#endif
-
- s->lnkst = 0x40;
- s->rdra = 0;
- s->tdra = 0;
- s->rap = 0;
-
- s->bcr[BCR_BSBC] &= ~0x0080;
-
- s->csr[0] = 0x0004;
- s->csr[3] = 0x0000;
- s->csr[4] = 0x0115;
- s->csr[5] = 0x0000;
- s->csr[6] = 0x0000;
- s->csr[8] = 0;
- s->csr[9] = 0;
- s->csr[10] = 0;
- s->csr[11] = 0;
- s->csr[12] = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
- s->csr[13] = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
- s->csr[14] = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
- s->csr[15] &= 0x21c4;
- s->csr[72] = 1;
- s->csr[74] = 1;
- s->csr[76] = 1;
- s->csr[78] = 1;
- s->csr[80] = 0x1410;
- s->csr[88] = 0x1003;
- s->csr[89] = 0x0262;
- s->csr[94] = 0x0000;
- s->csr[100] = 0x0200;
- s->csr[103] = 0x0105;
- s->csr[103] = 0x0105;
- s->csr[112] = 0x0000;
- s->csr[114] = 0x0000;
- s->csr[122] = 0x0000;
- s->csr[124] = 0x0000;
-
- s->tx_busy = 0;
-}
-
-static void pcnet_update_irq(PCNetState *s)
-{
- int isr = 0;
- s->csr[0] &= ~0x0080;
-
-#if 1
- if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
- (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
- (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
-#else
- if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
- (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
- (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
- (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
- (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
- (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
- (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
- (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
- (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
- (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
- (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
- (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
-#endif
- {
-
- isr = CSR_INEA(s);
- s->csr[0] |= 0x0080;
- }
-
- if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
- s->csr[4] &= ~0x0080;
- s->csr[4] |= 0x0040;
- s->csr[0] |= 0x0080;
- isr = 1;
-#ifdef PCNET_DEBUG
- printf("pcnet user int\n");
-#endif
- }
-
-#if 1
- if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
-#else
- if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
- (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
-#endif
- {
- isr = 1;
- s->csr[0] |= 0x0080;
- }
-
- if (isr != s->isr) {
-#ifdef PCNET_DEBUG
- printf("pcnet: INTA=%d\n", isr);
-#endif
- }
- s->set_irq_cb(s, isr);
- s->isr = isr;
-}
-
-static void pcnet_init(PCNetState *s)
-{
- int rlen, tlen;
- uint16_t *padr, *ladrf, mode;
- uint32_t rdra, tdra;
-
-#ifdef PCNET_DEBUG
- printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
-#endif
-
- if (BCR_SSIZE32(s)) {
- struct pcnet_initblk32 initblk;
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
- (uint8_t *)&initblk, sizeof(initblk), 0);
- mode = initblk.mode;
- rlen = initblk.rlen >> 4;
- tlen = initblk.tlen >> 4;
- ladrf = initblk.ladrf;
- padr = initblk.padr;
- rdra = le32_to_cpu(initblk.rdra);
- tdra = le32_to_cpu(initblk.tdra);
- s->rdra = PHYSADDR(s,initblk.rdra);
- s->tdra = PHYSADDR(s,initblk.tdra);
- } else {
- struct pcnet_initblk16 initblk;
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
- (uint8_t *)&initblk, sizeof(initblk), 0);
- mode = initblk.mode;
- ladrf = initblk.ladrf;
- padr = initblk.padr;
- rdra = le32_to_cpu(initblk.rdra);
- tdra = le32_to_cpu(initblk.tdra);
- rlen = rdra >> 29;
- tlen = tdra >> 29;
- rdra &= 0x00ffffff;
- tdra &= 0x00ffffff;
- }
-
-#if defined(PCNET_DEBUG)
- printf("rlen=%d tlen=%d\n",
- rlen, tlen);
-#endif
- CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
- CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
- s->csr[ 6] = (tlen << 12) | (rlen << 8);
- s->csr[15] = le16_to_cpu(mode);
- s->csr[ 8] = le16_to_cpu(ladrf[0]);
- s->csr[ 9] = le16_to_cpu(ladrf[1]);
- s->csr[10] = le16_to_cpu(ladrf[2]);
- s->csr[11] = le16_to_cpu(ladrf[3]);
- s->csr[12] = le16_to_cpu(padr[0]);
- s->csr[13] = le16_to_cpu(padr[1]);
- s->csr[14] = le16_to_cpu(padr[2]);
- s->rdra = PHYSADDR(s, rdra);
- s->tdra = PHYSADDR(s, tdra);
-
- CSR_RCVRC(s) = CSR_RCVRL(s);
- CSR_XMTRC(s) = CSR_XMTRL(s);
-
-#ifdef PCNET_DEBUG
- printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
- BCR_SSIZE32(s),
- s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
-#endif
-
- s->csr[0] |= 0x0101;
- s->csr[0] &= ~0x0004; /* clear STOP bit */
-}
-
-static void pcnet_start(PCNetState *s)
-{
-#ifdef PCNET_DEBUG
- printf("pcnet_start\n");
-#endif
-
- if (!CSR_DTX(s))
- s->csr[0] |= 0x0010; /* set TXON */
-
- if (!CSR_DRX(s))
- s->csr[0] |= 0x0020; /* set RXON */
-
- s->csr[0] &= ~0x0004; /* clear STOP bit */
- s->csr[0] |= 0x0002;
-}
-
-static void pcnet_stop(PCNetState *s)
-{
-#ifdef PCNET_DEBUG
- printf("pcnet_stop\n");
-#endif
- s->csr[0] &= ~0x7feb;
- s->csr[0] |= 0x0014;
- s->csr[4] &= ~0x02c2;
- s->csr[5] &= ~0x0011;
- pcnet_poll_timer(s);
-}
-
-static void pcnet_rdte_poll(PCNetState *s)
-{
- s->csr[28] = s->csr[29] = 0;
- if (s->rdra) {
- int bad = 0;
-#if 1
- target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
- target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
- target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
-#else
- target_phys_addr_t crda = s->rdra +
- (CSR_RCVRL(s) - CSR_RCVRC(s)) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
- target_phys_addr_t nrda = s->rdra +
- (CSR_RCVRL(s) - nrdc) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
- target_phys_addr_t nnrd = s->rdra +
- (CSR_RCVRL(s) - nnrc) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
-#endif
-
- CHECK_RMD(PHYSADDR(s,crda), bad);
- if (!bad) {
- CHECK_RMD(PHYSADDR(s,nrda), bad);
- if (bad || (nrda == crda)) nrda = 0;
- CHECK_RMD(PHYSADDR(s,nnrd), bad);
- if (bad || (nnrd == crda)) nnrd = 0;
-
- s->csr[28] = crda & 0xffff;
- s->csr[29] = crda >> 16;
- s->csr[26] = nrda & 0xffff;
- s->csr[27] = nrda >> 16;
- s->csr[36] = nnrd & 0xffff;
- s->csr[37] = nnrd >> 16;
-#ifdef PCNET_DEBUG
- if (bad) {
- printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
- PHYSADDR(s,crda));
- }
- } else {
- printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
-#endif
- }
- }
-
- if (CSR_CRDA(s)) {
- struct pcnet_RMD rmd;
- RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
- CSR_CRBC(s) = rmd.rmd1.bcnt;
- CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
-#ifdef PCNET_DEBUG_RMD_X
- printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
- PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
- ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
- PRINT_RMD(&rmd);
-#endif
- } else {
- CSR_CRBC(s) = CSR_CRST(s) = 0;
- }
-
- if (CSR_NRDA(s)) {
- struct pcnet_RMD rmd;
- RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
- CSR_NRBC(s) = rmd.rmd1.bcnt;
- CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
- } else {
- CSR_NRBC(s) = CSR_NRST(s) = 0;
- }
-
-}
-
-static int pcnet_tdte_poll(PCNetState *s)
-{
- s->csr[34] = s->csr[35] = 0;
- if (s->tdra) {
- target_phys_addr_t cxda = s->tdra +
- (CSR_XMTRL(s) - CSR_XMTRC(s)) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- int bad = 0;
- CHECK_TMD(PHYSADDR(s, cxda),bad);
- if (!bad) {
- if (CSR_CXDA(s) != cxda) {
- s->csr[60] = s->csr[34];
- s->csr[61] = s->csr[35];
- s->csr[62] = CSR_CXBC(s);
- s->csr[63] = CSR_CXST(s);
- }
- s->csr[34] = cxda & 0xffff;
- s->csr[35] = cxda >> 16;
-#ifdef PCNET_DEBUG
- } else {
- printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
-#endif
- }
- }
-
- if (CSR_CXDA(s)) {
- struct pcnet_TMD tmd;
-
- TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-
- CSR_CXBC(s) = tmd.tmd1.bcnt;
- CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
- } else {
- CSR_CXBC(s) = CSR_CXST(s) = 0;
- }
-
- return !!(CSR_CXST(s) & 0x8000);
-}
-
-static int pcnet_can_receive(void *opaque)
-{
- PCNetState *s = opaque;
- if (CSR_STOP(s) || CSR_SPND(s))
- return 0;
-
- if (s->recv_pos > 0)
- return 0;
-
- return sizeof(s->buffer)-16;
-}
-
-#define MIN_BUF_SIZE 60
-
-static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
-{
- PCNetState *s = opaque;
- int is_padr = 0, is_bcast = 0, is_ladr = 0;
- uint8_t buf1[60];
-
- if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
- return;
-
-#ifdef PCNET_DEBUG
- printf("pcnet_receive size=%d\n", size);
-#endif
-
- /* if too small buffer, then expand it */
- if (size < MIN_BUF_SIZE) {
- memcpy(buf1, buf, size);
- memset(buf1 + size, 0, MIN_BUF_SIZE - size);
- buf = buf1;
- size = MIN_BUF_SIZE;
- }
-
- if (CSR_PROM(s)
- || (is_padr=padr_match(s, buf, size))
- || (is_bcast=padr_bcast(s, buf, size))
- || (is_ladr=ladr_match(s, buf, size))) {
-
- pcnet_rdte_poll(s);
-
- if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
- struct pcnet_RMD rmd;
- int rcvrc = CSR_RCVRC(s)-1,i;
- target_phys_addr_t nrda;
- for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
- if (rcvrc <= 1)
- rcvrc = CSR_RCVRL(s);
- nrda = s->rdra +
- (CSR_RCVRL(s) - rcvrc) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
-#ifdef PCNET_DEBUG_RMD
- printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
- rcvrc, CSR_RCVRC(s));
-#endif
- CSR_RCVRC(s) = rcvrc;
- pcnet_rdte_poll(s);
- break;
- }
- }
- }
-
- if (!(CSR_CRST(s) & 0x8000)) {
-#ifdef PCNET_DEBUG_RMD
- printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
-#endif
- s->csr[0] |= 0x1000; /* Set MISS flag */
- CSR_MISSC(s)++;
- } else {
- uint8_t *src = &s->buffer[8];
- target_phys_addr_t crda = CSR_CRDA(s);
- struct pcnet_RMD rmd;
- int pktcount = 0;
-
- memcpy(src, buf, size);
-
-#if 1
- /* no need to compute the CRC */
- src[size] = 0;
- src[size + 1] = 0;
- src[size + 2] = 0;
- src[size + 3] = 0;
- size += 4;
-#else
- /* XXX: avoid CRC generation */
- if (!CSR_ASTRP_RCV(s)) {
- uint32_t fcs = ~0;
- uint8_t *p = src;
-
- while (size < 46) {
- src[size++] = 0;
- }
-
- while (p != &src[size]) {
- CRC(fcs, *p++);
- }
- ((uint32_t *)&src[size])[0] = htonl(fcs);
- size += 4; /* FCS at end of packet */
- } else size += 4;
-#endif
-
-#ifdef PCNET_DEBUG_MATCH
- PRINT_PKTHDR(buf);
-#endif
-
- RMDLOAD(&rmd, PHYSADDR(s,crda));
- /*if (!CSR_LAPPEN(s))*/
- rmd.rmd1.stp = 1;
-
-#define PCNET_RECV_STORE() do { \
- int count = MIN(4096 - rmd.rmd1.bcnt,size); \
- target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr); \
- s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
- src += count; size -= count; \
- rmd.rmd2.mcnt = count; rmd.rmd1.own = 0; \
- RMDSTORE(&rmd, PHYSADDR(s,crda)); \
- pktcount++; \
-} while (0)
-
- PCNET_RECV_STORE();
- if ((size > 0) && CSR_NRDA(s)) {
- target_phys_addr_t nrda = CSR_NRDA(s);
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
- crda = nrda;
- PCNET_RECV_STORE();
- if ((size > 0) && (nrda=CSR_NNRD(s))) {
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
- crda = nrda;
- PCNET_RECV_STORE();
- }
- }
- }
- }
-
-#undef PCNET_RECV_STORE
-
- RMDLOAD(&rmd, PHYSADDR(s,crda));
- if (size == 0) {
- rmd.rmd1.enp = 1;
- rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
- rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
- rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
- } else {
- rmd.rmd1.oflo = 1;
- rmd.rmd1.buff = 1;
- rmd.rmd1.err = 1;
- }
- RMDSTORE(&rmd, PHYSADDR(s,crda));
- s->csr[0] |= 0x0400;
-
-#ifdef PCNET_DEBUG
- printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
- CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
-#endif
-#ifdef PCNET_DEBUG_RMD
- PRINT_RMD(&rmd);
-#endif
-
- while (pktcount--) {
- if (CSR_RCVRC(s) <= 1)
- CSR_RCVRC(s) = CSR_RCVRL(s);
- else
- CSR_RCVRC(s)--;
- }
-
- pcnet_rdte_poll(s);
-
- }
- }
-
- pcnet_poll(s);
- pcnet_update_irq(s);
-}
-
-static void pcnet_transmit(PCNetState *s)
-{
- target_phys_addr_t xmit_cxda = 0;
- int count = CSR_XMTRL(s)-1;
- s->xmit_pos = -1;
-
- if (!CSR_TXON(s)) {
- s->csr[0] &= ~0x0008;
- return;
- }
-
- s->tx_busy = 1;
-
- txagain:
- if (pcnet_tdte_poll(s)) {
- struct pcnet_TMD tmd;
-
- TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-
-#ifdef PCNET_DEBUG_TMD
- printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
- PRINT_TMD(&tmd);
-#endif
- if (tmd.tmd1.stp) {
- s->xmit_pos = 0;
- if (!tmd.tmd1.enp) {
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer, 4096 - tmd.tmd1.bcnt,
- CSR_BSWP(s));
- s->xmit_pos += 4096 - tmd.tmd1.bcnt;
- }
- xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
- }
- if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt,
- CSR_BSWP(s));
- s->xmit_pos += 4096 - tmd.tmd1.bcnt;
-#ifdef PCNET_DEBUG
- printf("pcnet_transmit size=%d\n", s->xmit_pos);
-#endif
- if (CSR_LOOP(s))
- pcnet_receive(s, s->buffer, s->xmit_pos);
- else
- qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
-
- s->csr[0] &= ~0x0008; /* clear TDMD */
- s->csr[4] |= 0x0004; /* set TXSTRT */
- s->xmit_pos = -1;
- }
-
- tmd.tmd1.own = 0;
- TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
- if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
- s->csr[0] |= 0x0200; /* set TINT */
-
- if (CSR_XMTRC(s)<=1)
- CSR_XMTRC(s) = CSR_XMTRL(s);
- else
- CSR_XMTRC(s)--;
- if (count--)
- goto txagain;
-
- } else
- if (s->xmit_pos >= 0) {
- struct pcnet_TMD tmd;
- TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
- tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
- tmd.tmd1.own = 0;
- TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
- s->csr[0] |= 0x0200; /* set TINT */
- if (!CSR_DXSUFLO(s)) {
- s->csr[0] &= ~0x0010;
- } else
- if (count--)
- goto txagain;
- }
-
- s->tx_busy = 0;
-}
-
-static void pcnet_poll(PCNetState *s)
-{
- if (CSR_RXON(s)) {
- pcnet_rdte_poll(s);
- }
-
- if (CSR_TDMD(s) ||
- (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
- {
- /* prevent recursion */
- if (s->tx_busy)
- return;
-
- pcnet_transmit(s);
- }
-}
-
-static void pcnet_poll_timer(void *opaque)
-{
- PCNetState *s = opaque;
-
- qemu_del_timer(s->poll_timer);
-
- if (CSR_TDMD(s)) {
- pcnet_transmit(s);
- }
-
- pcnet_update_irq(s);
-
- if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
- uint64_t now = qemu_get_clock(vm_clock) * 33;
- if (!s->timer || !now)
- s->timer = now;
- else {
- uint64_t t = now - s->timer + CSR_POLL(s);
- if (t > 0xffffLL) {
- pcnet_poll(s);
- CSR_POLL(s) = CSR_PINT(s);
- } else
- CSR_POLL(s) = t;
- }
- qemu_mod_timer(s->poll_timer,
- pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
- }
-}
-
-
-static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
-{
- uint16_t val = new_value;
-#ifdef PCNET_DEBUG_CSR
- printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
-#endif
- switch (rap) {
- case 0:
- s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
-
- s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048);
-
- val = (val & 0x007f) | (s->csr[0] & 0x7f00);
-
- /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
- if ((val&7) == 7)
- val &= ~3;
-
- if (!CSR_STOP(s) && (val & 4))
- pcnet_stop(s);
-
- if (!CSR_INIT(s) && (val & 1))
- pcnet_init(s);
-
- if (!CSR_STRT(s) && (val & 2))
- pcnet_start(s);
-
- if (CSR_TDMD(s))
- pcnet_transmit(s);
-
- return;
- case 1:
- case 2:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 18: /* CRBAL */
- case 19: /* CRBAU */
- case 20: /* CXBAL */
- case 21: /* CXBAU */
- case 22: /* NRBAU */
- case 23: /* NRBAU */
- case 24:
- case 25:
- case 26:
- case 27:
- case 28:
- case 29:
- case 30:
- case 31:
- case 32:
- case 33:
- case 34:
- case 35:
- case 36:
- case 37:
- case 38:
- case 39:
- case 40: /* CRBC */
- case 41:
- case 42: /* CXBC */
- case 43:
- case 44:
- case 45:
- case 46: /* POLL */
- case 47: /* POLLINT */
- case 72:
- case 74:
- case 76: /* RCVRL */
- case 78: /* XMTRL */
- case 112:
- if (CSR_STOP(s) || CSR_SPND(s))
- break;
- return;
- case 3:
- break;
- case 4:
- s->csr[4] &= ~(val & 0x026a);
- val &= ~0x026a; val |= s->csr[4] & 0x026a;
- break;
- case 5:
- s->csr[5] &= ~(val & 0x0a90);
- val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
- break;
- case 16:
- pcnet_csr_writew(s,1,val);
- return;
- case 17:
- pcnet_csr_writew(s,2,val);
- return;
- case 58:
- pcnet_bcr_writew(s,BCR_SWS,val);
- break;
- default:
- return;
- }
- s->csr[rap] = val;
-}
-
-static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
-{
- uint32_t val;
- switch (rap) {
- case 0:
- pcnet_update_irq(s);
- val = s->csr[0];
- val |= (val & 0x7800) ? 0x8000 : 0;
- break;
- case 16:
- return pcnet_csr_readw(s,1);
- case 17:
- return pcnet_csr_readw(s,2);
- case 58:
- return pcnet_bcr_readw(s,BCR_SWS);
- case 88:
- val = s->csr[89];
- val <<= 16;
- val |= s->csr[88];
- break;
- default:
- val = s->csr[rap];
- }
-#ifdef PCNET_DEBUG_CSR
- printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
-#endif
- return val;
-}
-
-static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
-{
- rap &= 127;
-#ifdef PCNET_DEBUG_BCR
- printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
-#endif
- switch (rap) {
- case BCR_SWS:
- if (!(CSR_STOP(s) || CSR_SPND(s)))
- return;
- val &= ~0x0300;
- switch (val & 0x00ff) {
- case 0:
- val |= 0x0200;
- break;
- case 1:
- val |= 0x0100;
- break;
- case 2:
- case 3:
- val |= 0x0300;
- break;
- default:
- printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
- val = 0x0200;
- break;
- }
-#ifdef PCNET_DEBUG
- printf("BCR_SWS=0x%04x\n", val);
-#endif
- case BCR_LNKST:
- case BCR_LED1:
- case BCR_LED2:
- case BCR_LED3:
- case BCR_MC:
- case BCR_FDC:
- case BCR_BSBC:
- case BCR_EECAS:
- case BCR_PLAT:
- s->bcr[rap] = val;
- break;
- default:
- break;
- }
-}
-
-static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
-{
- uint32_t val;
- rap &= 127;
- switch (rap) {
- case BCR_LNKST:
- case BCR_LED1:
- case BCR_LED2:
- case BCR_LED3:
- val = s->bcr[rap] & ~0x8000;
- val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
- break;
- default:
- val = rap < 32 ? s->bcr[rap] : 0;
- break;
- }
-#ifdef PCNET_DEBUG_BCR
- printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
-#endif
- return val;
-}
-
-void pcnet_h_reset(void *opaque)
-{
- PCNetState *s = opaque;
- int i;
- uint16_t checksum;
-
- /* Initialize the PROM */
-
- memcpy(s->prom, s->nd->macaddr, 6);
- s->prom[12] = s->prom[13] = 0x00;
- s->prom[14] = s->prom[15] = 0x57;
-
- for (i = 0,checksum = 0; i < 16; i++)
- checksum += s->prom[i];
- *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
-
-
- s->bcr[BCR_MSRDA] = 0x0005;
- s->bcr[BCR_MSWRA] = 0x0005;
- s->bcr[BCR_MC ] = 0x0002;
- s->bcr[BCR_LNKST] = 0x00c0;
- s->bcr[BCR_LED1 ] = 0x0084;
- s->bcr[BCR_LED2 ] = 0x0088;
- s->bcr[BCR_LED3 ] = 0x0090;
- s->bcr[BCR_FDC ] = 0x0000;
- s->bcr[BCR_BSBC ] = 0x9001;
- s->bcr[BCR_EECAS] = 0x0002;
- s->bcr[BCR_SWS ] = 0x0200;
- s->bcr[BCR_PLAT ] = 0xff06;
-
- pcnet_s_reset(s);
-}
-
-static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCNetState *s = opaque;
-#ifdef PCNET_DEBUG
- printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
- /* Check APROMWE bit to enable write access */
- if (pcnet_bcr_readw(s,2) & 0x80)
- s->prom[addr & 15] = val;
-}
-
-static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
-{
- PCNetState *s = opaque;
- uint32_t val = s->prom[addr &= 15];
-#ifdef PCNET_DEBUG
- printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- PCNetState *s = opaque;
- pcnet_poll_timer(s);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
-#endif
- if (!BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- pcnet_csr_writew(s, s->rap, val);
- break;
- case 0x02:
- s->rap = val & 0x7f;
- break;
- case 0x06:
- pcnet_bcr_writew(s, s->rap, val);
- break;
- }
- }
- pcnet_update_irq(s);
-}
-
-static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
-{
- PCNetState *s = opaque;
- uint32_t val = -1;
- pcnet_poll_timer(s);
- if (!BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- val = pcnet_csr_readw(s, s->rap);
- break;
- case 0x02:
- val = s->rap;
- break;
- case 0x04:
- pcnet_s_reset(s);
- val = 0;
- break;
- case 0x06:
- val = pcnet_bcr_readw(s, s->rap);
- break;
- }
- }
- pcnet_update_irq(s);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
-#endif
- return val;
-}
-
-static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- PCNetState *s = opaque;
- pcnet_poll_timer(s);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- if (BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- pcnet_csr_writew(s, s->rap, val & 0xffff);
- break;
- case 0x04:
- s->rap = val & 0x7f;
- break;
- case 0x0c:
- pcnet_bcr_writew(s, s->rap, val & 0xffff);
- break;
- }
- } else
- if ((addr & 0x0f) == 0) {
- /* switch device to dword i/o mode */
- pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
-#ifdef PCNET_DEBUG_IO
- printf("device switched into dword i/o mode\n");
-#endif
- }
- pcnet_update_irq(s);
-}
-
-static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
-{
- PCNetState *s = opaque;
- uint32_t val = -1;
- pcnet_poll_timer(s);
- if (BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- val = pcnet_csr_readw(s, s->rap);
- break;
- case 0x04:
- val = s->rap;
- break;
- case 0x08:
- pcnet_s_reset(s);
- val = 0;
- break;
- case 0x0c:
- val = pcnet_bcr_readw(s, s->rap);
- break;
- }
- }
- pcnet_update_irq(s);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- return val;
-}
-
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCNetState *d = (PCNetState *)pci_dev;
-
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
-#endif
-
- register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
- register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
-
- register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
- register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
- register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
- register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
-}
-
-static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_writeb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
- if (!(addr & 0x10))
- pcnet_aprom_writeb(d, addr & 0x0f, val);
-}
-
-static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- PCNetState *d = opaque;
- uint32_t val = -1;
- if (!(addr & 0x10))
- val = pcnet_aprom_readb(d, addr & 0x0f);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_readb addr=0x%08x val=0x%02x\n", addr, val & 0xff);
-#endif
- return val;
-}
-
-static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_writew addr=0x%08x val=0x%04x\n", addr, val);
-#endif
- if (addr & 0x10)
- pcnet_ioport_writew(d, addr & 0x0f, val);
- else {
- addr &= 0x0f;
- pcnet_aprom_writeb(d, addr, val & 0xff);
- pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
- }
-}
-
-static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- PCNetState *d = opaque;
- uint32_t val = -1;
- if (addr & 0x10)
- val = pcnet_ioport_readw(d, addr & 0x0f);
- else {
- addr &= 0x0f;
- val = pcnet_aprom_readb(d, addr+1);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr);
- }
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_readw addr=0x%08x val = 0x%04x\n", addr, val & 0xffff);
-#endif
- return val;
-}
-
-static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_writel addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- if (addr & 0x10)
- pcnet_ioport_writel(d, addr & 0x0f, val);
- else {
- addr &= 0x0f;
- pcnet_aprom_writeb(d, addr, val & 0xff);
- pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
- pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
- pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
- }
-}
-
-static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- PCNetState *d = opaque;
- uint32_t val;
- if (addr & 0x10)
- val = pcnet_ioport_readl(d, addr & 0x0f);
- else {
- addr &= 0x0f;
- val = pcnet_aprom_readb(d, addr+3);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr+2);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr+1);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr);
- }
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_readl addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- return val;
-}
-
-
-static void pcnet_save(QEMUFile *f, void *opaque)
-{
- PCNetState *s = opaque;
- unsigned int i;
-
- if (s->pci_dev)
- pci_device_save(s->pci_dev, f);
-
- qemu_put_be32s(f, &s->rap);
- qemu_put_be32s(f, &s->isr);
- qemu_put_be32s(f, &s->lnkst);
- qemu_put_be32s(f, &s->rdra);
- qemu_put_be32s(f, &s->tdra);
- qemu_put_buffer(f, s->prom, 16);
- for (i = 0; i < 128; i++)
- qemu_put_be16s(f, &s->csr[i]);
- for (i = 0; i < 32; i++)
- qemu_put_be16s(f, &s->bcr[i]);
- qemu_put_be64s(f, &s->timer);
- qemu_put_be32s(f, &s->xmit_pos);
- qemu_put_be32s(f, &s->recv_pos);
- qemu_put_buffer(f, s->buffer, 4096);
- qemu_put_be32s(f, &s->tx_busy);
- qemu_put_timer(f, s->poll_timer);
-}
-
-static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
-{
- PCNetState *s = opaque;
- int i, ret;
-
- if (version_id != 2)
- return -EINVAL;
-
- if (s->pci_dev) {
- ret = pci_device_load(s->pci_dev, f);
- if (ret < 0)
- return ret;
- }
-
- qemu_get_be32s(f, &s->rap);
- qemu_get_be32s(f, &s->isr);
- qemu_get_be32s(f, &s->lnkst);
- qemu_get_be32s(f, &s->rdra);
- qemu_get_be32s(f, &s->tdra);
- qemu_get_buffer(f, s->prom, 16);
- for (i = 0; i < 128; i++)
- qemu_get_be16s(f, &s->csr[i]);
- for (i = 0; i < 32; i++)
- qemu_get_be16s(f, &s->bcr[i]);
- qemu_get_be64s(f, &s->timer);
- qemu_get_be32s(f, &s->xmit_pos);
- qemu_get_be32s(f, &s->recv_pos);
- qemu_get_buffer(f, s->buffer, 4096);
- qemu_get_be32s(f, &s->tx_busy);
- qemu_get_timer(f, s->poll_timer);
-
- return 0;
-}
-
-static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
-{
- int instance;
-
- d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
-
- d->nd = nd;
-
- d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
- pcnet_can_receive, d);
-
- snprintf(d->vc->info_str, sizeof(d->vc->info_str),
- "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- d->nd->macaddr[0],
- d->nd->macaddr[1],
- d->nd->macaddr[2],
- d->nd->macaddr[3],
- d->nd->macaddr[4],
- d->nd->macaddr[5]);
-
- pcnet_h_reset(d);
-
- instance = pci_bus_num(d->dev.bus) << 8 | d->dev.devfn;
- register_savevm("pcnet", instance, 2, pcnet_save, pcnet_load, d);
-}
-
-/* PCI interface */
-
-static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
- (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
- (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
- (CPUWriteMemoryFunc *)&pcnet_mmio_writel
-};
-
-static CPUReadMemoryFunc *pcnet_mmio_read[] = {
- (CPUReadMemoryFunc *)&pcnet_mmio_readb,
- (CPUReadMemoryFunc *)&pcnet_mmio_readw,
- (CPUReadMemoryFunc *)&pcnet_mmio_readl
-};
-
-static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCNetState *d = (PCNetState *)pci_dev;
-
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_map addr=0x%08x 0x%08x\n", addr, size);
-#endif
-
- cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
-}
-
-static void pcnet_pci_set_irq_cb(void *opaque, int isr)
-{
- PCNetState *s = opaque;
-
- pci_set_irq(&s->dev, 0, isr);
-}
-
-static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap)
-{
- cpu_physical_memory_write(addr, buf, len);
-}
-
-static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap)
-{
- cpu_physical_memory_read(addr, buf, len);
-}
-
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
-{
- PCNetState *d;
- uint8_t *pci_conf;
-
-#if 0
- printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
- sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
-#endif
-
- d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
- devfn, NULL, NULL);
-
- pci_conf = d->dev.config;
-
- *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
- *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
- *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
- *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
- pci_conf[0x08] = 0x10;
- pci_conf[0x09] = 0x00;
- pci_conf[0x0a] = 0x00; // ethernet network controller
- pci_conf[0x0b] = 0x02;
- pci_conf[0x0e] = 0x00; // header_type
-
- *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
- *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
-
- pci_conf[0x3d] = 1; // interrupt pin 0
- pci_conf[0x3e] = 0x06;
- pci_conf[0x3f] = 0xff;
-
- /* Handler for memory-mapped I/O */
- d->mmio_index =
- cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
-
- pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
- PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
-
- pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
- PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
-
- d->set_irq_cb = pcnet_pci_set_irq_cb;
- d->phys_mem_read = pci_physical_memory_read;
- d->phys_mem_write = pci_physical_memory_write;
- d->pci_dev = &d->dev;
-
- pcnet_common_init(d, nd, "pcnet");
-}
-
-/* SPARC32 interface */
-
-#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
-
-static CPUReadMemoryFunc *lance_mem_read[3] = {
- (CPUReadMemoryFunc *)&pcnet_ioport_readw,
- (CPUReadMemoryFunc *)&pcnet_ioport_readw,
- (CPUReadMemoryFunc *)&pcnet_ioport_readw,
-};
-
-static CPUWriteMemoryFunc *lance_mem_write[3] = {
- (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
- (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
- (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
-};
-
-static void pcnet_sparc_set_irq_cb(void *opaque, int isr)
-{
- PCNetState *s = opaque;
-
- ledma_set_irq(s->dma_opaque, isr);
-}
-
-void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque)
-{
- PCNetState *d;
- int lance_io_memory;
-
- d = qemu_mallocz(sizeof(PCNetState));
- if (!d)
- return NULL;
-
- lance_io_memory =
- cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
-
- d->dma_opaque = dma_opaque;
- cpu_register_physical_memory(leaddr, 4, lance_io_memory);
-
- d->set_irq_cb = pcnet_sparc_set_irq_cb;
- d->phys_mem_read = ledma_memory_read;
- d->phys_mem_write = ledma_memory_write;
-
- pcnet_common_init(d, nd, "lance");
-
- return d;
-}
-#endif /* TARGET_SPARC */
diff --git a/tools/ioemu/hw/pcspk.c b/tools/ioemu/hw/pcspk.c
deleted file mode 100644
index 0d52b31b45..0000000000
--- a/tools/ioemu/hw/pcspk.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * QEMU PC speaker emulation
- *
- * Copyright (c) 2006 Joachim Henke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-
-#define PCSPK_BUF_LEN 1792
-#define PCSPK_SAMPLE_RATE 32000
-#define PCSPK_MAX_FREQ (PCSPK_SAMPLE_RATE >> 1)
-#define PCSPK_MIN_COUNT ((PIT_FREQ + PCSPK_MAX_FREQ - 1) / PCSPK_MAX_FREQ)
-
-typedef struct {
- uint8_t sample_buf[PCSPK_BUF_LEN];
- QEMUSoundCard card;
- SWVoiceOut *voice;
- PITState *pit;
- unsigned int pit_count;
- unsigned int samples;
- unsigned int play_pos;
- int data_on;
- int dummy_refresh_clock;
-} PCSpkState;
-
-static const char *s_spk = "pcspk";
-static PCSpkState pcspk_state;
-
-static inline void generate_samples(PCSpkState *s)
-{
- unsigned int i;
-
- if (s->pit_count) {
- const uint32_t m = PCSPK_SAMPLE_RATE * s->pit_count;
- const uint32_t n = ((uint64_t)PIT_FREQ << 32) / m;
-
- /* multiple of wavelength for gapless looping */
- s->samples = (PCSPK_BUF_LEN * PIT_FREQ / m * m / (PIT_FREQ >> 1) + 1) >> 1;
- for (i = 0; i < s->samples; ++i)
- s->sample_buf[i] = (64 & (n * i >> 25)) - 32;
- } else {
- s->samples = PCSPK_BUF_LEN;
- for (i = 0; i < PCSPK_BUF_LEN; ++i)
- s->sample_buf[i] = 128; /* silence */
- }
-}
-
-static void pcspk_callback(void *opaque, int free)
-{
- PCSpkState *s = opaque;
- unsigned int n;
-
- if (pit_get_mode(s->pit, 2) != 3)
- return;
-
- n = pit_get_initial_count(s->pit, 2);
- /* avoid frequencies that are not reproducible with sample rate */
- if (n < PCSPK_MIN_COUNT)
- n = 0;
-
- if (s->pit_count != n) {
- s->pit_count = n;
- s->play_pos = 0;
- generate_samples(s);
- }
-
- while (free > 0) {
- n = audio_MIN(s->samples - s->play_pos, (unsigned int)free);
- n = AUD_write(s->voice, &s->sample_buf[s->play_pos], n);
- if (!n)
- break;
- s->play_pos = (s->play_pos + n) % s->samples;
- free -= n;
- }
-}
-
-int pcspk_audio_init(AudioState *audio)
-{
- PCSpkState *s = &pcspk_state;
- audsettings_t as = {PCSPK_SAMPLE_RATE, 1, AUD_FMT_U8, 0};
-
- if (!audio) {
- AUD_log(s_spk, "No audio state\n");
- return -1;
- }
- AUD_register_card(audio, s_spk, &s->card);
-
- s->voice = AUD_open_out(&s->card, s->voice, s_spk, s, pcspk_callback, &as);
- if (!s->voice) {
- AUD_log(s_spk, "Could not open voice\n");
- return -1;
- }
-
- return 0;
-}
-
-static uint32_t pcspk_ioport_read(void *opaque, uint32_t addr)
-{
- PCSpkState *s = opaque;
- int out;
-
- s->dummy_refresh_clock ^= (1 << 4);
- out = pit_get_out(s->pit, 2, qemu_get_clock(vm_clock)) << 5;
-
- return pit_get_gate(s->pit, 2) | (s->data_on << 1) | s->dummy_refresh_clock | out;
-}
-
-static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- PCSpkState *s = opaque;
- const int gate = val & 1;
-
- s->data_on = (val >> 1) & 1;
- pit_set_gate(s->pit, 2, gate);
- if (s->voice) {
- if (gate) /* restart */
- s->play_pos = 0;
- AUD_set_active_out(s->voice, gate & s->data_on);
- }
-}
-
-void pcspk_init(PITState *pit)
-{
- PCSpkState *s = &pcspk_state;
-
- s->pit = pit;
- register_ioport_read(0x61, 1, 1, pcspk_ioport_read, s);
- register_ioport_write(0x61, 1, 1, pcspk_ioport_write, s);
-}
diff --git a/tools/ioemu/hw/pflash_cfi02.c b/tools/ioemu/hw/pflash_cfi02.c
deleted file mode 100644
index 0db8b56454..0000000000
--- a/tools/ioemu/hw/pflash_cfi02.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * CFI parallel flash with AMD command set emulation
- *
- * Copyright (c) 2005 Jocelyn Mayer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * For now, this code can emulate flashes of 1, 2 or 4 bytes width.
- * Supported commands/modes are:
- * - flash read
- * - flash write
- * - flash ID read
- * - sector erase
- * - chip erase
- * - unlock bypass command
- * - CFI queries
- *
- * It does not support flash interleaving.
- * It does not implement boot blocs with reduced size
- * It does not implement software data protection as found in many real chips
- * It does not implement erase suspend/resume commands
- * It does not implement multiple sectors erase
- */
-
-#include "vl.h"
-
-//#define PFLASH_DEBUG
-#ifdef PFLASH_DEBUG
-#define DPRINTF(fmt, args...) \
-do { \
- printf("PFLASH: " fmt , ##args); \
-} while (0)
-#else
-#define DPRINTF(fmt, args...) do { } while (0)
-#endif
-
-struct pflash_t {
- BlockDriverState *bs;
- target_ulong base;
- target_ulong sector_len;
- target_ulong total_len;
- int width;
- int wcycle; /* if 0, the flash is read normally */
- int bypass;
- int ro;
- uint8_t cmd;
- uint8_t status;
- uint16_t ident[4];
- uint8_t cfi_len;
- uint8_t cfi_table[0x52];
- QEMUTimer *timer;
- ram_addr_t off;
- int fl_mem;
- void *storage;
-};
-
-static void pflash_timer (void *opaque)
-{
- pflash_t *pfl = opaque;
-
- DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
- /* Reset flash */
- pfl->status ^= 0x80;
- if (pfl->bypass) {
- pfl->wcycle = 2;
- } else {
- cpu_register_physical_memory(pfl->base, pfl->total_len,
- pfl->off | IO_MEM_ROMD | pfl->fl_mem);
- pfl->wcycle = 0;
- }
- pfl->cmd = 0;
-}
-
-static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width)
-{
- target_ulong boff;
- uint32_t ret;
- uint8_t *p;
-
- DPRINTF("%s: offset %08x\n", __func__, offset);
- ret = -1;
- offset -= pfl->base;
- boff = offset & 0xFF;
- if (pfl->width == 2)
- boff = boff >> 1;
- else if (pfl->width == 4)
- boff = boff >> 2;
- switch (pfl->cmd) {
- default:
- /* This should never happen : reset state & treat it as a read*/
- DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
- pfl->wcycle = 0;
- pfl->cmd = 0;
- case 0x80:
- /* We accept reads during second unlock sequence... */
- case 0x00:
- flash_read:
- /* Flash area read */
- p = pfl->storage;
- switch (width) {
- case 1:
- ret = p[offset];
-// DPRINTF("%s: data offset %08x %02x\n", __func__, offset, ret);
- break;
- case 2:
-#if defined(TARGET_WORDS_BIGENDIAN)
- ret = p[offset] << 8;
- ret |= p[offset + 1];
-#else
- ret = p[offset];
- ret |= p[offset + 1] << 8;
-#endif
-// DPRINTF("%s: data offset %08x %04x\n", __func__, offset, ret);
- break;
- case 4:
-#if defined(TARGET_WORDS_BIGENDIAN)
- ret = p[offset] << 24;
- ret |= p[offset + 1] << 16;
- ret |= p[offset + 2] << 8;
- ret |= p[offset + 3];
-#else
- ret = p[offset];
- ret |= p[offset + 1] << 8;
- ret |= p[offset + 2] << 16;
- ret |= p[offset + 3] << 24;
-#endif
-// DPRINTF("%s: data offset %08x %08x\n", __func__, offset, ret);
- break;
- }
- break;
- case 0x90:
- /* flash ID read */
- switch (boff) {
- case 0x00:
- case 0x01:
- ret = pfl->ident[boff & 0x01];
- break;
- case 0x02:
- ret = 0x00; /* Pretend all sectors are unprotected */
- break;
- case 0x0E:
- case 0x0F:
- if (pfl->ident[2 + (boff & 0x01)] == (uint8_t)-1)
- goto flash_read;
- ret = pfl->ident[2 + (boff & 0x01)];
- break;
- default:
- goto flash_read;
- }
- DPRINTF("%s: ID %d %x\n", __func__, boff, ret);
- break;
- case 0xA0:
- case 0x10:
- case 0x30:
- /* Status register read */
- ret = pfl->status;
- DPRINTF("%s: status %x\n", __func__, ret);
- /* Toggle bit 6 */
- pfl->status ^= 0x40;
- break;
- case 0x98:
- /* CFI query mode */
- if (boff > pfl->cfi_len)
- ret = 0;
- else
- ret = pfl->cfi_table[boff];
- break;
- }
-
- return ret;
-}
-
-/* update flash content on disk */
-static void pflash_update(pflash_t *pfl, int offset,
- int size)
-{
- int offset_end;
- if (pfl->bs) {
- offset_end = offset + size;
- /* round to sectors */
- offset = offset >> 9;
- offset_end = (offset_end + 511) >> 9;
- bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
- offset_end - offset);
- }
-}
-
-static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
- int width)
-{
- target_ulong boff;
- uint8_t *p;
- uint8_t cmd;
-
- /* WARNING: when the memory area is in ROMD mode, the offset is a
- ram offset, not a physical address */
- if (pfl->wcycle == 0)
- offset -= (target_ulong)(long)pfl->storage;
- else
- offset -= pfl->base;
-
- cmd = value;
- DPRINTF("%s: offset %08x %08x %d\n", __func__, offset, value, width);
- if (pfl->cmd != 0xA0 && cmd == 0xF0) {
- DPRINTF("%s: flash reset asked (%02x %02x)\n",
- __func__, pfl->cmd, cmd);
- goto reset_flash;
- }
- /* Set the device in I/O access mode */
- cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
- boff = offset & (pfl->sector_len - 1);
- if (pfl->width == 2)
- boff = boff >> 1;
- else if (pfl->width == 4)
- boff = boff >> 2;
- switch (pfl->wcycle) {
- case 0:
- /* We're in read mode */
- check_unlock0:
- if (boff == 0x55 && cmd == 0x98) {
- enter_CFI_mode:
- /* Enter CFI query mode */
- pfl->wcycle = 7;
- pfl->cmd = 0x98;
- return;
- }
- if (boff != 0x555 || cmd != 0xAA) {
- DPRINTF("%s: unlock0 failed %04x %02x %04x\n",
- __func__, boff, cmd, 0x555);
- goto reset_flash;
- }
- DPRINTF("%s: unlock sequence started\n", __func__);
- break;
- case 1:
- /* We started an unlock sequence */
- check_unlock1:
- if (boff != 0x2AA || cmd != 0x55) {
- DPRINTF("%s: unlock1 failed %04x %02x\n", __func__, boff, cmd);
- goto reset_flash;
- }
- DPRINTF("%s: unlock sequence done\n", __func__);
- break;
- case 2:
- /* We finished an unlock sequence */
- if (!pfl->bypass && boff != 0x555) {
- DPRINTF("%s: command failed %04x %02x\n", __func__, boff, cmd);
- goto reset_flash;
- }
- switch (cmd) {
- case 0x20:
- pfl->bypass = 1;
- goto do_bypass;
- case 0x80:
- case 0x90:
- case 0xA0:
- pfl->cmd = cmd;
- DPRINTF("%s: starting command %02x\n", __func__, cmd);
- break;
- default:
- DPRINTF("%s: unknown command %02x\n", __func__, cmd);
- goto reset_flash;
- }
- break;
- case 3:
- switch (pfl->cmd) {
- case 0x80:
- /* We need another unlock sequence */
- goto check_unlock0;
- case 0xA0:
- DPRINTF("%s: write data offset %08x %08x %d\n",
- __func__, offset, value, width);
- p = pfl->storage;
- switch (width) {
- case 1:
- p[offset] &= value;
- pflash_update(pfl, offset, 1);
- break;
- case 2:
-#if defined(TARGET_WORDS_BIGENDIAN)
- p[offset] &= value >> 8;
- p[offset + 1] &= value;
-#else
- p[offset] &= value;
- p[offset + 1] &= value >> 8;
-#endif
- pflash_update(pfl, offset, 2);
- break;
- case 4:
-#if defined(TARGET_WORDS_BIGENDIAN)
- p[offset] &= value >> 24;
- p[offset + 1] &= value >> 16;
- p[offset + 2] &= value >> 8;
- p[offset + 3] &= value;
-#else
- p[offset] &= value;
- p[offset + 1] &= value >> 8;
- p[offset + 2] &= value >> 16;
- p[offset + 3] &= value >> 24;
-#endif
- pflash_update(pfl, offset, 4);
- break;
- }
- pfl->status = 0x00 | ~(value & 0x80);
- /* Let's pretend write is immediate */
- if (pfl->bypass)
- goto do_bypass;
- goto reset_flash;
- case 0x90:
- if (pfl->bypass && cmd == 0x00) {
- /* Unlock bypass reset */
- goto reset_flash;
- }
- /* We can enter CFI query mode from autoselect mode */
- if (boff == 0x55 && cmd == 0x98)
- goto enter_CFI_mode;
- /* No break here */
- default:
- DPRINTF("%s: invalid write for command %02x\n",
- __func__, pfl->cmd);
- goto reset_flash;
- }
- case 4:
- switch (pfl->cmd) {
- case 0xA0:
- /* Ignore writes while flash data write is occuring */
- /* As we suppose write is immediate, this should never happen */
- return;
- case 0x80:
- goto check_unlock1;
- default:
- /* Should never happen */
- DPRINTF("%s: invalid command state %02x (wc 4)\n",
- __func__, pfl->cmd);
- goto reset_flash;
- }
- break;
- case 5:
- switch (cmd) {
- case 0x10:
- if (boff != 0x555) {
- DPRINTF("%s: chip erase: invalid address %04x\n",
- __func__, offset);
- goto reset_flash;
- }
- /* Chip erase */
- DPRINTF("%s: start chip erase\n", __func__);
- memset(pfl->storage, 0xFF, pfl->total_len);
- pfl->status = 0x00;
- pflash_update(pfl, 0, pfl->total_len);
- /* Let's wait 5 seconds before chip erase is done */
- qemu_mod_timer(pfl->timer,
- qemu_get_clock(vm_clock) + (ticks_per_sec * 5));
- break;
- case 0x30:
- /* Sector erase */
- p = pfl->storage;
- offset &= ~(pfl->sector_len - 1);
- DPRINTF("%s: start sector erase at %08x\n", __func__, offset);
- memset(p + offset, 0xFF, pfl->sector_len);
- pflash_update(pfl, offset, pfl->sector_len);
- pfl->status = 0x00;
- /* Let's wait 1/2 second before sector erase is done */
- qemu_mod_timer(pfl->timer,
- qemu_get_clock(vm_clock) + (ticks_per_sec / 2));
- break;
- default:
- DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
- goto reset_flash;
- }
- pfl->cmd = cmd;
- break;
- case 6:
- switch (pfl->cmd) {
- case 0x10:
- /* Ignore writes during chip erase */
- return;
- case 0x30:
- /* Ignore writes during sector erase */
- return;
- default:
- /* Should never happen */
- DPRINTF("%s: invalid command state %02x (wc 6)\n",
- __func__, pfl->cmd);
- goto reset_flash;
- }
- break;
- case 7: /* Special value for CFI queries */
- DPRINTF("%s: invalid write in CFI query mode\n", __func__);
- goto reset_flash;
- default:
- /* Should never happen */
- DPRINTF("%s: invalid write state (wc 7)\n", __func__);
- goto reset_flash;
- }
- pfl->wcycle++;
-
- return;
-
- /* Reset flash */
- reset_flash:
- if (pfl->wcycle != 0) {
- cpu_register_physical_memory(pfl->base, pfl->total_len,
- pfl->off | IO_MEM_ROMD | pfl->fl_mem);
- }
- pfl->bypass = 0;
- pfl->wcycle = 0;
- pfl->cmd = 0;
- return;
-
- do_bypass:
- pfl->wcycle = 2;
- pfl->cmd = 0;
- return;
-}
-
-
-static uint32_t pflash_readb (void *opaque, target_phys_addr_t addr)
-{
- return pflash_read(opaque, addr, 1);
-}
-
-static uint32_t pflash_readw (void *opaque, target_phys_addr_t addr)
-{
- pflash_t *pfl = opaque;
-
- return pflash_read(pfl, addr, 2);
-}
-
-static uint32_t pflash_readl (void *opaque, target_phys_addr_t addr)
-{
- pflash_t *pfl = opaque;
-
- return pflash_read(pfl, addr, 4);
-}
-
-static void pflash_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- pflash_write(opaque, addr, value, 1);
-}
-
-static void pflash_writew (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- pflash_t *pfl = opaque;
-
- pflash_write(pfl, addr, value, 2);
-}
-
-static void pflash_writel (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- pflash_t *pfl = opaque;
-
- pflash_write(pfl, addr, value, 4);
-}
-
-static CPUWriteMemoryFunc *pflash_write_ops[] = {
- &pflash_writeb,
- &pflash_writew,
- &pflash_writel,
-};
-
-static CPUReadMemoryFunc *pflash_read_ops[] = {
- &pflash_readb,
- &pflash_readw,
- &pflash_readl,
-};
-
-/* Count trailing zeroes of a 32 bits quantity */
-static int ctz32 (uint32_t n)
-{
- int ret;
-
- ret = 0;
- if (!(n & 0xFFFF)) {
- ret += 16;
- n = n >> 16;
- }
- if (!(n & 0xFF)) {
- ret += 8;
- n = n >> 8;
- }
- if (!(n & 0xF)) {
- ret += 4;
- n = n >> 4;
- }
- if (!(n & 0x3)) {
- ret += 2;
- n = n >> 2;
- }
- if (!(n & 0x1)) {
- ret++;
- n = n >> 1;
- }
-#if 0 /* This is not necessary as n is never 0 */
- if (!n)
- ret++;
-#endif
-
- return ret;
-}
-
-pflash_t *pflash_register (target_ulong base, ram_addr_t off,
- BlockDriverState *bs,
- target_ulong sector_len, int nb_blocs, int width,
- uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3)
-{
- pflash_t *pfl;
- target_long total_len;
-
- total_len = sector_len * nb_blocs;
- /* XXX: to be fixed */
- if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
- total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
- return NULL;
- pfl = qemu_mallocz(sizeof(pflash_t));
- if (pfl == NULL)
- return NULL;
- pfl->storage = phys_ram_base + off;
- pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops, pfl);
- pfl->off = off;
- cpu_register_physical_memory(base, total_len,
- off | pfl->fl_mem | IO_MEM_ROMD);
- pfl->bs = bs;
- if (pfl->bs) {
- /* read the initial flash content */
- bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
- }
-#if 0 /* XXX: there should be a bit to set up read-only,
- * the same way the hardware does (with WP pin).
- */
- pfl->ro = 1;
-#else
- pfl->ro = 0;
-#endif
- pfl->timer = qemu_new_timer(vm_clock, pflash_timer, pfl);
- pfl->base = base;
- pfl->sector_len = sector_len;
- pfl->total_len = total_len;
- pfl->width = width;
- pfl->wcycle = 0;
- pfl->cmd = 0;
- pfl->status = 0;
- pfl->ident[0] = id0;
- pfl->ident[1] = id1;
- pfl->ident[2] = id2;
- pfl->ident[3] = id3;
- /* Hardcoded CFI table (mostly from SG29 Spansion flash) */
- pfl->cfi_len = 0x52;
- /* Standard "QRY" string */
- pfl->cfi_table[0x10] = 'Q';
- pfl->cfi_table[0x11] = 'R';
- pfl->cfi_table[0x12] = 'Y';
- /* Command set (AMD/Fujitsu) */
- pfl->cfi_table[0x13] = 0x02;
- pfl->cfi_table[0x14] = 0x00;
- /* Primary extended table address (none) */
- pfl->cfi_table[0x15] = 0x00;
- pfl->cfi_table[0x16] = 0x00;
- /* Alternate command set (none) */
- pfl->cfi_table[0x17] = 0x00;
- pfl->cfi_table[0x18] = 0x00;
- /* Alternate extended table (none) */
- pfl->cfi_table[0x19] = 0x00;
- pfl->cfi_table[0x1A] = 0x00;
- /* Vcc min */
- pfl->cfi_table[0x1B] = 0x27;
- /* Vcc max */
- pfl->cfi_table[0x1C] = 0x36;
- /* Vpp min (no Vpp pin) */
- pfl->cfi_table[0x1D] = 0x00;
- /* Vpp max (no Vpp pin) */
- pfl->cfi_table[0x1E] = 0x00;
- /* Reserved */
- pfl->cfi_table[0x1F] = 0x07;
- /* Timeout for min size buffer write (16 µs) */
- pfl->cfi_table[0x20] = 0x04;
- /* Typical timeout for block erase (512 ms) */
- pfl->cfi_table[0x21] = 0x09;
- /* Typical timeout for full chip erase (4096 ms) */
- pfl->cfi_table[0x22] = 0x0C;
- /* Reserved */
- pfl->cfi_table[0x23] = 0x01;
- /* Max timeout for buffer write */
- pfl->cfi_table[0x24] = 0x04;
- /* Max timeout for block erase */
- pfl->cfi_table[0x25] = 0x0A;
- /* Max timeout for chip erase */
- pfl->cfi_table[0x26] = 0x0D;
- /* Device size */
- pfl->cfi_table[0x27] = ctz32(total_len) + 1;
- /* Flash device interface (8 & 16 bits) */
- pfl->cfi_table[0x28] = 0x02;
- pfl->cfi_table[0x29] = 0x00;
- /* Max number of bytes in multi-bytes write */
- pfl->cfi_table[0x2A] = 0x05;
- pfl->cfi_table[0x2B] = 0x00;
- /* Number of erase block regions (uniform) */
- pfl->cfi_table[0x2C] = 0x01;
- /* Erase block region 1 */
- pfl->cfi_table[0x2D] = nb_blocs - 1;
- pfl->cfi_table[0x2E] = (nb_blocs - 1) >> 8;
- pfl->cfi_table[0x2F] = sector_len >> 8;
- pfl->cfi_table[0x30] = sector_len >> 16;
-
- return pfl;
-}
diff --git a/tools/ioemu/hw/piix4acpi.c b/tools/ioemu/hw/piix4acpi.c
deleted file mode 100644
index f084c8ec65..0000000000
--- a/tools/ioemu/hw/piix4acpi.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * PIIX4 ACPI controller emulation
- *
- * Winston liwen Wang, winston.l.wang@intel.com
- * Copyright (c) 2006 , Intel Corporation.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-#include <xen/hvm/ioreq.h>
-#include <xen/hvm/params.h>
-
-/* PM1a_CNT bits, as defined in the ACPI specification. */
-#define SCI_EN (1 << 0)
-#define GBL_RLS (1 << 2)
-#define SLP_TYP_Sx (7 << 10)
-#define SLP_EN (1 << 13)
-
-/* Sleep state type codes as defined by the \_Sx objects in the DSDT. */
-/* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */
-#define SLP_TYP_S4 (6 << 10)
-#define SLP_TYP_S3 (5 << 10)
-#define SLP_TYP_S5 (7 << 10)
-
-#define ACPI_DBG_IO_ADDR 0xb044
-#define ACPI_PHP_IO_ADDR 0x10c0
-
-#define PHP_EVT_ADD 0x0
-#define PHP_EVT_REMOVE 0x3
-
-#define ACPI_SCI_IRQ 9
-
-/* The bit in GPE0_STS/EN to notify the pci hotplug event */
-#define ACPI_PHP_GPE_BIT 3
-
-#define ACPI_PHP_SLOT_NUM PHP_SLOT_LEN
-
-typedef struct AcpiDeviceState AcpiDeviceState;
-AcpiDeviceState *acpi_device_table;
-
-typedef struct PCIAcpiState {
- PCIDevice dev;
- uint16_t pm1_control; /* pm1a_ECNT_BLK */
-} PCIAcpiState;
-
-typedef struct GPEState {
- /* GPE0 block */
- uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN / 2];
- uint8_t gpe0_en[ACPI_GPE0_BLK_LEN / 2];
-
- /* SCI IRQ level */
- uint8_t sci_asserted;
-
-} GPEState;
-
-GPEState gpe_state;
-
-typedef struct PHPSlots {
- struct {
- uint8_t status; /* Apaptor stats */
- } slot[ACPI_PHP_SLOT_NUM];
- uint8_t plug_evt; /* slot|event slot:0-no event;1-1st. event:0-remove;1-add */
-} PHPSlots;
-
-PHPSlots php_slots;
-
-int s3_shutdown_flag;
-
-static void piix4acpi_save(QEMUFile *f, void *opaque)
-{
- PCIAcpiState *s = opaque;
- pci_device_save(&s->dev, f);
- qemu_put_be16s(f, &s->pm1_control);
-}
-
-static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
-{
- PCIAcpiState *s = opaque;
- int ret;
- if (version_id > 1)
- return -EINVAL;
- ret = pci_device_load(&s->dev, f);
- if (ret < 0)
- return ret;
- qemu_get_be16s(f, &s->pm1_control);
- return 0;
-}
-
-static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
- s->pm1_control = (s->pm1_control & 0xff00) | (val & 0xff);
-}
-
-static uint32_t acpiPm1Control_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- /* Mask out the write-only bits */
- return (uint8_t)(s->pm1_control & ~(GBL_RLS|SLP_EN));
-}
-
-static void acpi_shutdown(uint32_t val)
-{
- if (!(val & SLP_EN))
- return;
-
- switch (val & SLP_TYP_Sx) {
- case SLP_TYP_S3:
- s3_shutdown_flag = 1;
- qemu_system_reset();
- s3_shutdown_flag = 0;
- cmos_set_s3_resume();
- xc_set_hvm_param(xc_handle, domid, HVM_PARAM_ACPI_S_STATE, 3);
- break;
- case SLP_TYP_S4:
- case SLP_TYP_S5:
- qemu_system_shutdown_request();
- break;
- default:
- break;
- }
-}
-
-static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- val <<= 8;
- s->pm1_control = ((s->pm1_control & 0xff) | val) & ~SLP_EN;
-
- acpi_shutdown(val);
-}
-
-static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- /* Mask out the write-only bits */
- return (uint8_t)((s->pm1_control & ~(GBL_RLS|SLP_EN)) >> 8);
-}
-
-static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_control = val & ~SLP_EN;
-
- acpi_shutdown(val);
-}
-
-static uint32_t acpiPm1Control_readw(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- /* Mask out the write-only bits */
- return (s->pm1_control & ~(GBL_RLS|SLP_EN));
-}
-
-static void acpi_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIAcpiState *d = (PCIAcpiState *)pci_dev;
-
- /* Byte access */
- register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
- register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
- register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
- register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
-
- /* Word access */
- register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
- register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
-}
-
-#ifdef CONFIG_PASSTHROUGH
-
-static inline int test_bit(uint8_t *map, int bit)
-{
- return ( map[bit / 8] & (1 << (bit % 8)) );
-}
-
-static inline void set_bit(uint8_t *map, int bit)
-{
- map[bit / 8] |= (1 << (bit % 8));
-}
-
-static inline void clear_bit(uint8_t *map, int bit)
-{
- map[bit / 8] &= ~(1 << (bit % 8));
-}
-
-extern FILE *logfile;
-static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-#if defined(DEBUG)
- printf("ACPI: DBG: 0x%08x\n", val);
-#endif
- fprintf(logfile, "ACPI:debug: write addr=0x%x, val=0x%x.\n", addr, val);
-}
-
-/*
- * simple PCI hotplug controller IO
- * ACPI_PHP_IO_ADDR + :
- * 0 - the hotplug description: slot(|event(remove/add);
- * 1 - 1st php slot ctr/sts reg
- * 2 - 2nd php slot ctr/sts reg
- * ......
- */
-static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
-{
- PHPSlots *hotplug_slots = opaque;
- int num;
- uint32_t val;
-
- switch (addr)
- {
- case ACPI_PHP_IO_ADDR:
- val = hotplug_slots->plug_evt;
- break;
- default:
- num = addr - ACPI_PHP_IO_ADDR - 1;
- val = hotplug_slots->slot[num].status;
- }
-
- fprintf(logfile, "ACPI PCI hotplug: read addr=0x%x, val=0x%x.\n",
- addr, val);
-
- return val;
-}
-
-static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PHPSlots *hotplug_slots = opaque;
- int php_slot;
-
- fprintf(logfile, "ACPI PCI hotplug: write addr=0x%x, val=0x%x.\n",
- addr, val);
-
- switch (addr)
- {
- case ACPI_PHP_IO_ADDR:
- break;
- default:
- php_slot = addr - ACPI_PHP_IO_ADDR - 1;
- if ( val == 0x1 ) { /* Eject command */
- /* make _STA of the slot 0 */
- hotplug_slots->slot[php_slot].status = 0;
-
- /* clear the hotplug event */
- hotplug_slots->plug_evt = 0;
-
- /* power off the slot */
- power_off_php_slot(php_slot);
-
- /* signal the CP ACPI hot remove done. */
- xenstore_record_dm_state("pci-removed");
- }
- }
-}
-
-static void pcislots_save(QEMUFile* f, void* opaque)
-{
- PHPSlots *s = (PHPSlots*)opaque;
- int i;
- for ( i = 0; i < ACPI_PHP_SLOT_NUM; i++ ) {
- qemu_put_8s( f, &s->slot[i].status);
- }
- qemu_put_8s(f, &s->plug_evt);
-}
-
-static int pcislots_load(QEMUFile* f, void* opaque, int version_id)
-{
- PHPSlots *s = (PHPSlots*)opaque;
- int i;
- if (version_id != 1)
- return -EINVAL;
- for ( i = 0; i < ACPI_PHP_SLOT_NUM; i++ ) {
- qemu_get_8s( f, &s->slot[i].status);
- }
- qemu_get_8s(f, &s->plug_evt);
- return 0;
-}
-
-static void php_slots_init(void)
-{
- PHPSlots *slots = &php_slots;
- int i;
- memset(slots, 0, sizeof(PHPSlots));
-
- /* update the pci slot status */
- for ( i = 0; i < PHP_SLOT_LEN; i++ ) {
- if ( test_pci_slot( PHP_TO_PCI_SLOT(i) ) == 1 )
- slots->slot[i].status = 0xf;
- }
-
-
- /* ACPI PCI hotplug controller */
- register_ioport_read(ACPI_PHP_IO_ADDR, ACPI_PHP_SLOT_NUM + 1, 1, acpi_php_readb, slots);
- register_ioport_write(ACPI_PHP_IO_ADDR, ACPI_PHP_SLOT_NUM + 1, 1, acpi_php_writeb, slots);
- register_savevm("pcislots", 0, 1, pcislots_save, pcislots_load, slots);
-}
-
-/* GPEx_STS occupy 1st half of the block, while GPEx_EN 2nd half */
-static uint32_t gpe_sts_read(void *opaque, uint32_t addr)
-{
- GPEState *s = opaque;
-
- return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS];
-}
-
-/* write 1 to clear specific GPE bits */
-static void gpe_sts_write(void *opaque, uint32_t addr, uint32_t val)
-{
- GPEState *s = opaque;
- int hotplugged = 0;
-
- fprintf(logfile, "gpe_sts_write: addr=0x%x, val=0x%x.\n", addr, val);
-
- hotplugged = test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT);
- s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val;
- if ( s->sci_asserted &&
- hotplugged &&
- !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT)) {
- fprintf(logfile, "Clear the GPE0_STS bit for ACPI hotplug & deassert the IRQ.\n");
- pic_set_irq(ACPI_SCI_IRQ, 0);
- }
-
-}
-
-static uint32_t gpe_en_read(void *opaque, uint32_t addr)
-{
- GPEState *s = opaque;
-
- return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)];
-}
-
-/* write 0 to clear en bit */
-static void gpe_en_write(void *opaque, uint32_t addr, uint32_t val)
-{
- GPEState *s = opaque;
- int reg_count;
-
- fprintf(logfile, "gpe_en_write: addr=0x%x, val=0x%x.\n", addr, val);
- reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2);
- s->gpe0_en[reg_count] = val;
- /* If disable GPE bit right after generating SCI on it,
- * need deassert the intr to avoid redundant intrs
- */
- if ( s->sci_asserted &&
- reg_count == (ACPI_PHP_GPE_BIT / 8) &&
- !(val & (1 << (ACPI_PHP_GPE_BIT % 8))) ) {
- fprintf(logfile, "deassert due to disable GPE bit.\n");
- s->sci_asserted = 0;
- pic_set_irq(ACPI_SCI_IRQ, 0);
- }
-
-}
-
-static void gpe_save(QEMUFile* f, void* opaque)
-{
- GPEState *s = (GPEState*)opaque;
- int i;
-
- for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) {
- qemu_put_8s(f, &s->gpe0_sts[i]);
- qemu_put_8s(f, &s->gpe0_en[i]);
- }
-
- qemu_put_8s(f, &s->sci_asserted);
- if ( s->sci_asserted ) {
- fprintf(logfile, "gpe_save with sci asserted!\n");
- }
-}
-
-static int gpe_load(QEMUFile* f, void* opaque, int version_id)
-{
- GPEState *s = (GPEState*)opaque;
- int i;
- if (version_id != 1)
- return -EINVAL;
-
- for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) {
- qemu_get_8s(f, &s->gpe0_sts[i]);
- qemu_get_8s(f, &s->gpe0_en[i]);
- }
-
- qemu_get_8s(f, &s->sci_asserted);
- return 0;
-}
-
-static void gpe_acpi_init(void)
-{
- GPEState *s = &gpe_state;
- memset(s, 0, sizeof(GPEState));
-
- register_ioport_read(ACPI_GPE0_BLK_ADDRESS,
- ACPI_GPE0_BLK_LEN / 2,
- 1,
- gpe_sts_read,
- s);
- register_ioport_read(ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2,
- ACPI_GPE0_BLK_LEN / 2,
- 1,
- gpe_en_read,
- s);
-
- register_ioport_write(ACPI_GPE0_BLK_ADDRESS,
- ACPI_GPE0_BLK_LEN / 2,
- 1,
- gpe_sts_write,
- s);
- register_ioport_write(ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2,
- ACPI_GPE0_BLK_LEN / 2,
- 1,
- gpe_en_write,
- s);
-
- register_savevm("gpe", 0, 1, gpe_save, gpe_load, s);
-}
-
-static void acpi_sci_intr(GPEState *s)
-{
- if ( !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT) &&
- test_bit(&s->gpe0_en[0], ACPI_PHP_GPE_BIT) ) {
-
- set_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT);
- s->sci_asserted = 1;
- pic_set_irq(ACPI_SCI_IRQ, 1);
- fprintf(logfile, "generate a sci for PHP.\n");
- }
-}
-
-void acpi_php_del(int pci_slot)
-{
- GPEState *s = &gpe_state;
- PHPSlots *hotplug_slots = &php_slots;
- int php_slot = PCI_TO_PHP_SLOT(pci_slot);
-
- if ( pci_slot < PHP_SLOT_START || pci_slot >= PHP_SLOT_END ) {
- fprintf(logfile, "not find the pci slot %d when hot remove.\n", pci_slot);
-
- return;
- }
-
- /* update the php controller status */
- hotplug_slots->plug_evt = (((php_slot+1) << 4) | PHP_EVT_REMOVE);
-
- /* generate a SCI interrupt */
- acpi_sci_intr(s);
-}
-
-void acpi_php_add(int pci_slot)
-{
- GPEState *s = &gpe_state;
- PHPSlots *hotplug_slots = &php_slots;
- int php_slot = PCI_TO_PHP_SLOT(pci_slot);
- char ret_str[30];
-
- if ( pci_slot < PHP_SLOT_START || pci_slot >= PHP_SLOT_END ) {
- fprintf(logfile, "hot add pci slot %d exceed.\n", pci_slot);
-
- if ( pci_slot == 0 )
- sprintf(ret_str, "no free hotplug slots");
- else if ( pci_slot == -1 )
- sprintf(ret_str, "wrong bdf or vslot");
-
- if ( strlen(ret_str) > 0 )
- xenstore_record_dm("parameter", ret_str);
-
- return;
- }
-
- /* update the php controller status */
- hotplug_slots->plug_evt = (((php_slot+1) << 4) | PHP_EVT_ADD);
-
- /* update the slot status as present */
- hotplug_slots->slot[php_slot].status = 0xf;
-
- /* power on the slot */
- power_on_php_slot(php_slot);
-
- /* tell Control panel which slot for the new pass-throgh dev */
- sprintf(ret_str, "0x%x", pci_slot);
- xenstore_record_dm("parameter", ret_str);
-
- /* signal the CP ACPI hot insert done */
- xenstore_record_dm_state("pci-inserted");
-
- /* generate a SCI interrupt */
- acpi_sci_intr(s);
-}
-
-#endif /* CONFIG_PASSTHROUGH */
-
-/* PIIX4 acpi pci configuration space, func 2 */
-void pci_piix4_acpi_init(PCIBus *bus, int devfn)
-{
- PCIAcpiState *d;
- uint8_t *pci_conf;
-
- /* register a function 2 of PIIX4 */
- d = (PCIAcpiState *)pci_register_device(
- bus, "PIIX4 ACPI", sizeof(PCIAcpiState),
- devfn, NULL, NULL);
-
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x86; /* Intel */
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x13;
- pci_conf[0x03] = 0x71;
- pci_conf[0x08] = 0x01; /* B0 stepping */
- pci_conf[0x09] = 0x00; /* base class */
- pci_conf[0x0a] = 0x80; /* Sub class */
- pci_conf[0x0b] = 0x06;
- pci_conf[0x0e] = 0x00;
- pci_conf[0x3d] = 0x01; /* Hardwired to PIRQA is used */
-
-
- /* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40
- * to make shutdown work for IPF, due to IPF Guest Firmware
- * will enumerate pci devices.
- *
- * TODO: if Guest Firmware or Guest OS will change this PMBA,
- * More logic will be added.
- */
- pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
- pci_conf[0x41] = 0x1f;
- pci_conf[0x42] = 0x00;
- pci_conf[0x43] = 0x00;
- d->pm1_control = SCI_EN;
-
- acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
-
-#ifdef CONFIG_PASSTHROUGH
- gpe_acpi_init();
- php_slots_init();
- register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d);
-#endif
-
- register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);
-}
diff --git a/tools/ioemu/hw/piix_pci.c b/tools/ioemu/hw/piix_pci.c
deleted file mode 100644
index 1b16652bc0..0000000000
--- a/tools/ioemu/hw/piix_pci.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * QEMU i440FX/PIIX3 PCI Bridge Emulation
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-typedef uint32_t pci_addr_t;
-#include "pci_host.h"
-
-typedef PCIHostState I440FXState;
-
-static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
-{
- I440FXState *s = opaque;
- s->config_reg = val;
-}
-
-static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
-{
- I440FXState *s = opaque;
- return s->config_reg;
-}
-
-static void piix3_set_irq(void *pic, int irq_num, int level);
-
-/* return the global irq number corresponding to a given device irq
- pin. We could also use the bus number to have a more precise
- mapping. */
-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
-{
- int slot_addend;
- slot_addend = (pci_dev->devfn >> 3) - 1;
- return (irq_num + slot_addend) & 3;
-}
-
-static uint32_t isa_page_descs[384 / 4];
-static uint8_t smm_enabled;
-
-static void update_pam(PCIDevice *d, uint32_t start, uint32_t end, int r)
-{
- uint32_t addr;
-
- // printf("ISA mapping %08x-0x%08x: %d\n", start, end, r);
- switch(r) {
- case 3:
- /* RAM */
- cpu_register_physical_memory(start, end - start,
- start);
- break;
- case 1:
- /* ROM (XXX: not quite correct) */
- cpu_register_physical_memory(start, end - start,
- start | IO_MEM_ROM);
- break;
- case 2:
- case 0:
- /* XXX: should distinguish read/write cases */
- for(addr = start; addr < end; addr += 4096) {
- cpu_register_physical_memory(addr, 4096,
- isa_page_descs[(addr - 0xa0000) >> 12]);
- }
- break;
- }
-}
-
-static void i440fx_update_memory_mappings(PCIDevice *d)
-{
- int i, r;
- uint32_t smram, addr;
-
- update_pam(d, 0xf0000, 0x100000, (d->config[0x59] >> 4) & 3);
- for(i = 0; i < 12; i++) {
- r = (d->config[(i >> 1) + 0x5a] >> ((i & 1) * 4)) & 3;
- update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r);
- }
- smram = d->config[0x72];
- if ((smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
- cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
- } else {
- for(addr = 0xa0000; addr < 0xc0000; addr += 4096) {
- cpu_register_physical_memory(addr, 4096,
- isa_page_descs[(addr - 0xa0000) >> 12]);
- }
- }
-}
-
-void i440fx_set_smm(PCIDevice *d, int val)
-{
- val = (val != 0);
- if (smm_enabled != val) {
- smm_enabled = val;
- i440fx_update_memory_mappings(d);
- }
-}
-
-
-/* XXX: suppress when better memory API. We make the assumption that
- no device (in particular the VGA) changes the memory mappings in
- the 0xa0000-0x100000 range */
-void i440fx_init_memory_mappings(PCIDevice *d)
-{
- int i;
- for(i = 0; i < 96; i++) {
- isa_page_descs[i] = cpu_get_physical_page_desc(0xa0000 + i * 0x1000);
- }
-}
-
-static void i440fx_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- /* XXX: implement SMRAM.D_LOCK */
- pci_default_write_config(d, address, val, len);
- if ((address >= 0x59 && address <= 0x5f) || address == 0x72)
- i440fx_update_memory_mappings(d);
-}
-
-static void i440fx_save(QEMUFile* f, void *opaque)
-{
- PCIDevice *d = opaque;
- pci_device_save(d, f);
- qemu_put_8s(f, &smm_enabled);
-}
-
-static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
-{
- PCIDevice *d = opaque;
- int ret;
-
- if (version_id != 1)
- return -EINVAL;
- ret = pci_device_load(d, f);
- if (ret < 0)
- return ret;
- i440fx_update_memory_mappings(d);
- qemu_get_8s(f, &smm_enabled);
- return 0;
-}
-
-PCIBus *i440fx_init(PCIDevice **pi440fx_state)
-{
- PCIBus *b;
- PCIDevice *d;
- I440FXState *s;
-
- s = qemu_mallocz(sizeof(I440FXState));
- b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, NULL, 0, 4);
- s->bus = b;
-
- register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
- register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
-
- register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
- register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
- register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
- register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
- register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
- register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
-
- d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
- NULL, i440fx_write_config);
-
- d->config[0x00] = 0x86; // vendor_id
- d->config[0x01] = 0x80;
- d->config[0x02] = 0x37; // device_id
- d->config[0x03] = 0x12;
- d->config[0x08] = 0x02; // revision
- d->config[0x0a] = 0x00; // class_sub = host2pci
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x00; // header_type
-
- d->config[0x72] = 0x02; /* SMRAM */
-
- register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d);
- *pi440fx_state = d;
- return b;
-}
-
-/* PIIX3 PCI to ISA bridge */
-
-PCIDevice *piix3_dev;
-PCIDevice *piix4_dev;
-
-/* just used for simpler irq handling. */
-#define PCI_IRQ_WORDS ((PCI_DEVICES_MAX + 31) / 32)
-
-static int pci_irq_levels[4];
-
-static void piix3_set_irq(void *pic, int irq_num, int level)
-{
- int i, pic_irq, pic_level;
-
- pci_irq_levels[irq_num] = level;
-
- /* now we change the pic irq level according to the piix irq mappings */
- /* XXX: optimize */
- pic_irq = piix3_dev->config[0x60 + irq_num];
- if (pic_irq < 16) {
- /* The pic level is the logical OR of all the PCI irqs mapped
- to it */
- pic_level = 0;
- for (i = 0; i < 4; i++) {
- if (pic_irq == piix3_dev->config[0x60 + i])
- pic_level |= pci_irq_levels[i];
- }
- pic_set_irq(pic_irq, pic_level);
- }
-}
-
-static void piix3_reset(PCIDevice *d)
-{
- uint8_t *pci_conf = d->config;
-
- pci_conf[0x04] = 0x07; // master, memory and I/O
- pci_conf[0x05] = 0x00;
- pci_conf[0x06] = 0x00;
- pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
- pci_conf[0x4c] = 0x4d;
- pci_conf[0x4e] = 0x03;
- pci_conf[0x4f] = 0x00;
- pci_conf[0x60] = 0x80;
- pci_conf[0x69] = 0x02;
- pci_conf[0x70] = 0x80;
- pci_conf[0x76] = 0x0c;
- pci_conf[0x77] = 0x0c;
- pci_conf[0x78] = 0x02;
- pci_conf[0x79] = 0x00;
- pci_conf[0x80] = 0x00;
- pci_conf[0x82] = 0x00;
- pci_conf[0xa0] = 0x08;
- pci_conf[0xa2] = 0x00;
- pci_conf[0xa3] = 0x00;
- pci_conf[0xa4] = 0x00;
- pci_conf[0xa5] = 0x00;
- pci_conf[0xa6] = 0x00;
- pci_conf[0xa7] = 0x00;
- pci_conf[0xa8] = 0x0f;
- pci_conf[0xaa] = 0x00;
- pci_conf[0xab] = 0x00;
- pci_conf[0xac] = 0x00;
- pci_conf[0xae] = 0x00;
-}
-
-static void piix4_reset(PCIDevice *d)
-{
- uint8_t *pci_conf = d->config;
-
- pci_conf[0x04] = 0x07; // master, memory and I/O
- pci_conf[0x05] = 0x00;
- pci_conf[0x06] = 0x00;
- pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
- pci_conf[0x4c] = 0x4d;
- pci_conf[0x4e] = 0x03;
- pci_conf[0x4f] = 0x00;
- pci_conf[0x60] = 0x0a; // PCI A -> IRQ 10
- pci_conf[0x61] = 0x0a; // PCI B -> IRQ 10
- pci_conf[0x62] = 0x0b; // PCI C -> IRQ 11
- pci_conf[0x63] = 0x0b; // PCI D -> IRQ 11
- pci_conf[0x69] = 0x02;
- pci_conf[0x70] = 0x80;
- pci_conf[0x76] = 0x0c;
- pci_conf[0x77] = 0x0c;
- pci_conf[0x78] = 0x02;
- pci_conf[0x79] = 0x00;
- pci_conf[0x80] = 0x00;
- pci_conf[0x82] = 0x00;
- pci_conf[0xa0] = 0x08;
- pci_conf[0xa2] = 0x00;
- pci_conf[0xa3] = 0x00;
- pci_conf[0xa4] = 0x00;
- pci_conf[0xa5] = 0x00;
- pci_conf[0xa6] = 0x00;
- pci_conf[0xa7] = 0x00;
- pci_conf[0xa8] = 0x0f;
- pci_conf[0xaa] = 0x00;
- pci_conf[0xab] = 0x00;
- pci_conf[0xac] = 0x00;
- pci_conf[0xae] = 0x00;
-}
-
-static void piix_save(QEMUFile* f, void *opaque)
-{
- PCIDevice *d = opaque;
- pci_device_save(d, f);
-}
-
-static int piix_load(QEMUFile* f, void *opaque, int version_id)
-{
- PCIDevice *d = opaque;
- if (version_id != 2)
- return -EINVAL;
- return pci_device_load(d, f);
-}
-
-int piix_init(PCIBus *bus, int devfn)
-{
- PCIDevice *d;
- uint8_t *pci_conf;
-
- d = pci_register_device(bus, "PIIX", sizeof(PCIDevice),
- devfn, NULL, NULL);
- register_savevm("PIIX", 0, 2, piix_save, piix_load, d);
-
- piix3_dev = d;
- pci_conf = d->config;
-
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x2E; // 82371FB PIIX PCI-to-ISA bridge
- pci_conf[0x03] = 0x12;
- pci_conf[0x08] = 0x02; // Step A1
- pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
- pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
- pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
-
- piix3_reset(d);
- return d->devfn;
-}
-
-int piix3_init(PCIBus *bus, int devfn)
-{
- PCIDevice *d;
- uint8_t *pci_conf;
-
- d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),
- devfn, NULL, NULL);
- register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);
-
- piix3_dev = d;
- pci_conf = d->config;
-
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
- pci_conf[0x03] = 0x70;
- pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
- pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
- pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
-
- piix3_reset(d);
- return d->devfn;
-}
-
-int piix4_init(PCIBus *bus, int devfn)
-{
- PCIDevice *d;
- uint8_t *pci_conf;
-
- d = pci_register_device(bus, "PIIX4", sizeof(PCIDevice),
- devfn, NULL, NULL);
- register_savevm("PIIX4", 0, 2, piix_save, piix_load, d);
-
- piix4_dev = d;
- pci_conf = d->config;
-
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x10; // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
- pci_conf[0x03] = 0x71;
- pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
- pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
- pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
-
- piix4_reset(d);
- return d->devfn;
-}
diff --git a/tools/ioemu/hw/pl011.c b/tools/ioemu/hw/pl011.c
deleted file mode 100644
index fb7ab7b53d..0000000000
--- a/tools/ioemu/hw/pl011.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Arm PrimeCell PL011 UART
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-
-typedef struct {
- uint32_t base;
- uint32_t readbuff;
- uint32_t flags;
- uint32_t lcr;
- uint32_t cr;
- uint32_t dmacr;
- uint32_t int_enabled;
- uint32_t int_level;
- uint32_t read_fifo[16];
- uint32_t ilpr;
- uint32_t ibrd;
- uint32_t fbrd;
- uint32_t ifl;
- int read_pos;
- int read_count;
- int read_trigger;
- CharDriverState *chr;
- void *pic;
- int irq;
-} pl011_state;
-
-#define PL011_INT_TX 0x20
-#define PL011_INT_RX 0x10
-
-#define PL011_FLAG_TXFE 0x80
-#define PL011_FLAG_RXFF 0x40
-#define PL011_FLAG_TXFF 0x20
-#define PL011_FLAG_RXFE 0x10
-
-static const unsigned char pl011_id[] =
-{ 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-
-static void pl011_update(pl011_state *s)
-{
- uint32_t flags;
-
- flags = s->int_level & s->int_enabled;
- pic_set_irq_new(s->pic, s->irq, flags != 0);
-}
-
-static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
-{
- pl011_state *s = (pl011_state *)opaque;
- uint32_t c;
-
- offset -= s->base;
- if (offset >= 0xfe0 && offset < 0x1000) {
- return pl011_id[(offset - 0xfe0) >> 2];
- }
- switch (offset >> 2) {
- case 0: /* UARTDR */
- s->flags &= ~PL011_FLAG_RXFF;
- c = s->read_fifo[s->read_pos];
- if (s->read_count > 0) {
- s->read_count--;
- if (++s->read_pos == 16)
- s->read_pos = 0;
- }
- if (s->read_count == 0) {
- s->flags |= PL011_FLAG_RXFE;
- }
- if (s->read_count == s->read_trigger - 1)
- s->int_level &= ~ PL011_INT_RX;
- pl011_update(s);
- return c;
- case 1: /* UARTCR */
- return 0;
- case 6: /* UARTFR */
- return s->flags;
- case 8: /* UARTILPR */
- return s->ilpr;
- case 9: /* UARTIBRD */
- return s->ibrd;
- case 10: /* UARTFBRD */
- return s->fbrd;
- case 11: /* UARTLCR_H */
- return s->lcr;
- case 12: /* UARTCR */
- return s->cr;
- case 13: /* UARTIFLS */
- return s->ifl;
- case 14: /* UARTIMSC */
- return s->int_enabled;
- case 15: /* UARTRIS */
- return s->int_level;
- case 16: /* UARTMIS */
- return s->int_level & s->int_enabled;
- case 18: /* UARTDMACR */
- return s->dmacr;
- default:
- cpu_abort (cpu_single_env, "pl011_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void pl011_set_read_trigger(pl011_state *s)
-{
-#if 0
- /* The docs say the RX interrupt is triggered when the FIFO exceeds
- the threshold. However linux only reads the FIFO in response to an
- interrupt. Triggering the interrupt when the FIFO is non-empty seems
- to make things work. */
- if (s->lcr & 0x10)
- s->read_trigger = (s->ifl >> 1) & 0x1c;
- else
-#endif
- s->read_trigger = 1;
-}
-
-static void pl011_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- pl011_state *s = (pl011_state *)opaque;
- unsigned char ch;
-
- offset -= s->base;
- switch (offset >> 2) {
- case 0: /* UARTDR */
- /* ??? Check if transmitter is enabled. */
- ch = value;
- if (s->chr)
- qemu_chr_write(s->chr, &ch, 1);
- s->int_level |= PL011_INT_TX;
- pl011_update(s);
- break;
- case 1: /* UARTCR */
- s->cr = value;
- break;
- case 8: /* UARTUARTILPR */
- s->ilpr = value;
- break;
- case 9: /* UARTIBRD */
- s->ibrd = value;
- break;
- case 10: /* UARTFBRD */
- s->fbrd = value;
- break;
- case 11: /* UARTLCR_H */
- s->lcr = value;
- pl011_set_read_trigger(s);
- break;
- case 12: /* UARTCR */
- /* ??? Need to implement the enable and loopback bits. */
- s->cr = value;
- break;
- case 13: /* UARTIFS */
- s->ifl = value;
- pl011_set_read_trigger(s);
- break;
- case 14: /* UARTIMSC */
- s->int_enabled = value;
- pl011_update(s);
- break;
- case 17: /* UARTICR */
- s->int_level &= ~value;
- pl011_update(s);
- break;
- case 18: /* UARTDMACR */
- s->dmacr = value;
- if (value & 3)
- cpu_abort(cpu_single_env, "PL011: DMA not implemented\n");
- break;
- default:
- cpu_abort (cpu_single_env, "pl011_write: Bad offset %x\n", offset);
- }
-}
-
-static int pl011_can_recieve(void *opaque)
-{
- pl011_state *s = (pl011_state *)opaque;
-
- if (s->lcr & 0x10)
- return s->read_count < 16;
- else
- return s->read_count < 1;
-}
-
-static void pl011_recieve(void *opaque, const uint8_t *buf, int size)
-{
- pl011_state *s = (pl011_state *)opaque;
- int slot;
-
- slot = s->read_pos + s->read_count;
- if (slot >= 16)
- slot -= 16;
- s->read_fifo[slot] = *buf;
- s->read_count++;
- s->flags &= ~PL011_FLAG_RXFE;
- if (s->cr & 0x10 || s->read_count == 16) {
- s->flags |= PL011_FLAG_RXFF;
- }
- if (s->read_count == s->read_trigger) {
- s->int_level |= PL011_INT_RX;
- pl011_update(s);
- }
-}
-
-static void pl011_event(void *opaque, int event)
-{
- /* ??? Should probably implement break. */
-}
-
-static CPUReadMemoryFunc *pl011_readfn[] = {
- pl011_read,
- pl011_read,
- pl011_read
-};
-
-static CPUWriteMemoryFunc *pl011_writefn[] = {
- pl011_write,
- pl011_write,
- pl011_write
-};
-
-void pl011_init(uint32_t base, void *pic, int irq,
- CharDriverState *chr)
-{
- int iomemtype;
- pl011_state *s;
-
- s = (pl011_state *)qemu_mallocz(sizeof(pl011_state));
- iomemtype = cpu_register_io_memory(0, pl011_readfn,
- pl011_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
- s->pic = pic;
- s->irq = irq;
- s->chr = chr;
- s->read_trigger = 1;
- s->ifl = 0x12;
- s->cr = 0x300;
- s->flags = 0x90;
- if (chr){
- qemu_chr_add_handlers(chr, pl011_can_recieve, pl011_recieve,
- pl011_event, s);
- }
- /* ??? Save/restore. */
-}
-
diff --git a/tools/ioemu/hw/pl050.c b/tools/ioemu/hw/pl050.c
deleted file mode 100644
index 20451e532e..0000000000
--- a/tools/ioemu/hw/pl050.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Arm PrimeCell PL050 Keyboard / Mouse Interface
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-
-typedef struct {
- void *dev;
- uint32_t base;
- uint32_t cr;
- uint32_t clk;
- uint32_t last;
- void *pic;
- int pending;
- int irq;
- int is_mouse;
-} pl050_state;
-
-static const unsigned char pl050_id[] =
-{ 0x50, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-
-static void pl050_update(void *opaque, int level)
-{
- pl050_state *s = (pl050_state *)opaque;
- int raise;
-
- s->pending = level;
- raise = (s->pending && (s->cr & 0x10) != 0)
- || (s->cr & 0x08) != 0;
- pic_set_irq_new(s->pic, s->irq, raise);
-}
-
-static uint32_t pl050_read(void *opaque, target_phys_addr_t offset)
-{
- pl050_state *s = (pl050_state *)opaque;
- offset -= s->base;
- if (offset >= 0xfe0 && offset < 0x1000)
- return pl050_id[(offset - 0xfe0) >> 2];
-
- switch (offset >> 2) {
- case 0: /* KMICR */
- return s->cr;
- case 1: /* KMISTAT */
- /* KMIC and KMID bits not implemented. */
- if (s->pending) {
- return 0x10;
- } else {
- return 0;
- }
- case 2: /* KMIDATA */
- if (s->pending)
- s->last = ps2_read_data(s->dev);
- return s->last;
- case 3: /* KMICLKDIV */
- return s->clk;
- case 4: /* KMIIR */
- return s->pending | 2;
- default:
- cpu_abort (cpu_single_env, "pl050_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void pl050_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- pl050_state *s = (pl050_state *)opaque;
- offset -= s->base;
- switch (offset >> 2) {
- case 0: /* KMICR */
- s->cr = value;
- pl050_update(s, s->pending);
- /* ??? Need to implement the enable/disable bit. */
- break;
- case 2: /* KMIDATA */
- /* ??? This should toggle the TX interrupt line. */
- /* ??? This means kbd/mouse can block each other. */
- if (s->is_mouse) {
- ps2_write_mouse(s->dev, value);
- } else {
- ps2_write_keyboard(s->dev, value);
- }
- break;
- case 3: /* KMICLKDIV */
- s->clk = value;
- return;
- default:
- cpu_abort (cpu_single_env, "pl050_write: Bad offset %x\n", offset);
- }
-}
-static CPUReadMemoryFunc *pl050_readfn[] = {
- pl050_read,
- pl050_read,
- pl050_read
-};
-
-static CPUWriteMemoryFunc *pl050_writefn[] = {
- pl050_write,
- pl050_write,
- pl050_write
-};
-
-void pl050_init(uint32_t base, void *pic, int irq, int is_mouse)
-{
- int iomemtype;
- pl050_state *s;
-
- s = (pl050_state *)qemu_mallocz(sizeof(pl050_state));
- iomemtype = cpu_register_io_memory(0, pl050_readfn,
- pl050_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
- s->pic = pic;
- s->irq = irq;
- s->is_mouse = is_mouse;
- if (is_mouse)
- s->dev = ps2_mouse_init(pl050_update, s);
- else
- s->dev = ps2_kbd_init(pl050_update, s);
- /* ??? Save/restore. */
-}
-
diff --git a/tools/ioemu/hw/pl080.c b/tools/ioemu/hw/pl080.c
deleted file mode 100644
index 549b3bfd10..0000000000
--- a/tools/ioemu/hw/pl080.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Arm PrimeCell PL080/PL081 DMA controller
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-
-#define PL080_MAX_CHANNELS 8
-#define PL080_CONF_E 0x1
-#define PL080_CONF_M1 0x2
-#define PL080_CONF_M2 0x4
-
-#define PL080_CCONF_H 0x40000
-#define PL080_CCONF_A 0x20000
-#define PL080_CCONF_L 0x10000
-#define PL080_CCONF_ITC 0x08000
-#define PL080_CCONF_IE 0x04000
-#define PL080_CCONF_E 0x00001
-
-#define PL080_CCTRL_I 0x80000000
-#define PL080_CCTRL_DI 0x08000000
-#define PL080_CCTRL_SI 0x04000000
-#define PL080_CCTRL_D 0x02000000
-#define PL080_CCTRL_S 0x01000000
-
-typedef struct {
- uint32_t src;
- uint32_t dest;
- uint32_t lli;
- uint32_t ctrl;
- uint32_t conf;
-} pl080_channel;
-
-typedef struct {
- uint32_t base;
- uint8_t tc_int;
- uint8_t tc_mask;
- uint8_t err_int;
- uint8_t err_mask;
- uint32_t conf;
- uint32_t sync;
- uint32_t req_single;
- uint32_t req_burst;
- pl080_channel chan[PL080_MAX_CHANNELS];
- int nchannels;
- /* Flag to avoid recursive DMA invocations. */
- int running;
- void *pic;
- int irq;
-} pl080_state;
-
-static const unsigned char pl080_id[] =
-{ 0x80, 0x10, 0x04, 0x0a, 0x0d, 0xf0, 0x05, 0xb1 };
-
-static const unsigned char pl081_id[] =
-{ 0x81, 0x10, 0x04, 0x0a, 0x0d, 0xf0, 0x05, 0xb1 };
-
-static void pl080_update(pl080_state *s)
-{
- if ((s->tc_int & s->tc_mask)
- || (s->err_int & s->err_mask))
- pic_set_irq_new(s->pic, s->irq, 1);
- else
- pic_set_irq_new(s->pic, s->irq, 1);
-}
-
-static void pl080_run(pl080_state *s)
-{
- int c;
- int flow;
- pl080_channel *ch;
- int swidth;
- int dwidth;
- int xsize;
- int n;
- int src_id;
- int dest_id;
- int size;
- char buff[4];
- uint32_t req;
-
- s->tc_mask = 0;
- for (c = 0; c < s->nchannels; c++) {
- if (s->chan[c].conf & PL080_CCONF_ITC)
- s->tc_mask |= 1 << c;
- if (s->chan[c].conf & PL080_CCONF_IE)
- s->err_mask |= 1 << c;
- }
-
- if ((s->conf & PL080_CONF_E) == 0)
- return;
-
-cpu_abort(cpu_single_env, "DMA active\n");
- /* If we are already in the middle of a DMA operation then indicate that
- there may be new DMA requests and return immediately. */
- if (s->running) {
- s->running++;
- return;
- }
- s->running = 1;
- while (s->running) {
- for (c = 0; c < s->nchannels; c++) {
- ch = &s->chan[c];
-again:
- /* Test if thiws channel has any pending DMA requests. */
- if ((ch->conf & (PL080_CCONF_H | PL080_CCONF_E))
- != PL080_CCONF_E)
- continue;
- flow = (ch->conf >> 11) & 7;
- if (flow >= 4) {
- cpu_abort(cpu_single_env,
- "pl080_run: Peripheral flow control not implemented\n");
- }
- src_id = (ch->conf >> 1) & 0x1f;
- dest_id = (ch->conf >> 6) & 0x1f;
- size = ch->ctrl & 0xfff;
- req = s->req_single | s->req_burst;
- switch (flow) {
- case 0:
- break;
- case 1:
- if ((req & (1u << dest_id)) == 0)
- size = 0;
- break;
- case 2:
- if ((req & (1u << src_id)) == 0)
- size = 0;
- break;
- case 3:
- if ((req & (1u << src_id)) == 0
- || (req & (1u << dest_id)) == 0)
- size = 0;
- break;
- }
- if (!size)
- continue;
-
- /* Transfer one element. */
- /* ??? Should transfer multiple elements for a burst request. */
- /* ??? Unclear what the proper behavior is when source and
- destination widths are different. */
- swidth = 1 << ((ch->ctrl >> 18) & 7);
- dwidth = 1 << ((ch->ctrl >> 21) & 7);
- for (n = 0; n < dwidth; n+= swidth) {
- cpu_physical_memory_read(ch->src, buff + n, swidth);
- if (ch->ctrl & PL080_CCTRL_SI)
- ch->src += swidth;
- }
- xsize = (dwidth < swidth) ? swidth : dwidth;
- /* ??? This may pad the value incorrectly for dwidth < 32. */
- for (n = 0; n < xsize; n += dwidth) {
- cpu_physical_memory_write(ch->dest + n, buff + n, dwidth);
- if (ch->ctrl & PL080_CCTRL_DI)
- ch->dest += swidth;
- }
-
- size--;
- ch->ctrl = (ch->ctrl & 0xfffff000) | size;
- if (size == 0) {
- /* Transfer complete. */
- if (ch->lli) {
- ch->src = ldl_phys(ch->lli);
- ch->dest = ldl_phys(ch->lli + 4);
- ch->ctrl = ldl_phys(ch->lli + 12);
- ch->lli = ldl_phys(ch->lli + 8);
- } else {
- ch->conf &= ~PL080_CCONF_E;
- }
- if (ch->ctrl & PL080_CCTRL_I) {
- s->tc_int |= 1 << c;
- }
- }
- goto again;
- }
- if (--s->running)
- s->running = 1;
- }
-}
-
-static uint32_t pl080_read(void *opaque, target_phys_addr_t offset)
-{
- pl080_state *s = (pl080_state *)opaque;
- uint32_t i;
- uint32_t mask;
-
- offset -= s->base;
- if (offset >= 0xfe0 && offset < 0x1000) {
- if (s->nchannels == 8) {
- return pl080_id[(offset - 0xfe0) >> 2];
- } else {
- return pl081_id[(offset - 0xfe0) >> 2];
- }
- }
- if (offset >= 0x100 && offset < 0x200) {
- i = (offset & 0xe0) >> 5;
- if (i >= s->nchannels)
- goto bad_offset;
- switch (offset >> 2) {
- case 0: /* SrcAddr */
- return s->chan[i].src;
- case 1: /* DestAddr */
- return s->chan[i].dest;
- case 2: /* LLI */
- return s->chan[i].lli;
- case 3: /* Control */
- return s->chan[i].ctrl;
- case 4: /* Configuration */
- return s->chan[i].conf;
- default:
- goto bad_offset;
- }
- }
- switch (offset >> 2) {
- case 0: /* IntStatus */
- return (s->tc_int & s->tc_mask) | (s->err_int & s->err_mask);
- case 1: /* IntTCStatus */
- return (s->tc_int & s->tc_mask);
- case 3: /* IntErrorStatus */
- return (s->err_int & s->err_mask);
- case 5: /* RawIntTCStatus */
- return s->tc_int;
- case 6: /* RawIntErrorStatus */
- return s->err_int;
- case 7: /* EnbldChns */
- mask = 0;
- for (i = 0; i < s->nchannels; i++) {
- if (s->chan[i].conf & PL080_CCONF_E)
- mask |= 1 << i;
- }
- return mask;
- case 8: /* SoftBReq */
- case 9: /* SoftSReq */
- case 10: /* SoftLBReq */
- case 11: /* SoftLSReq */
- /* ??? Implement these. */
- return 0;
- case 12: /* Configuration */
- return s->conf;
- case 13: /* Sync */
- return s->sync;
- default:
- bad_offset:
- cpu_abort(cpu_single_env, "pl080_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void pl080_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- pl080_state *s = (pl080_state *)opaque;
- int i;
-
- offset -= s->base;
- if (offset >= 0x100 && offset < 0x200) {
- i = (offset & 0xe0) >> 5;
- if (i >= s->nchannels)
- goto bad_offset;
- switch (offset >> 2) {
- case 0: /* SrcAddr */
- s->chan[i].src = value;
- break;
- case 1: /* DestAddr */
- s->chan[i].dest = value;
- break;
- case 2: /* LLI */
- s->chan[i].lli = value;
- break;
- case 3: /* Control */
- s->chan[i].ctrl = value;
- break;
- case 4: /* Configuration */
- s->chan[i].conf = value;
- pl080_run(s);
- break;
- }
- }
- switch (offset >> 2) {
- case 2: /* IntTCClear */
- s->tc_int &= ~value;
- break;
- case 4: /* IntErrorClear */
- s->err_int &= ~value;
- break;
- case 8: /* SoftBReq */
- case 9: /* SoftSReq */
- case 10: /* SoftLBReq */
- case 11: /* SoftLSReq */
- /* ??? Implement these. */
- cpu_abort(cpu_single_env, "pl080_write: Soft DMA not implemented\n");
- break;
- case 12: /* Configuration */
- s->conf = value;
- if (s->conf & (PL080_CONF_M1 | PL080_CONF_M1)) {
- cpu_abort(cpu_single_env,
- "pl080_write: Big-endian DMA not implemented\n");
- }
- pl080_run(s);
- break;
- case 13: /* Sync */
- s->sync = value;
- break;
- default:
- bad_offset:
- cpu_abort(cpu_single_env, "pl080_write: Bad offset %x\n", offset);
- }
- pl080_update(s);
-}
-
-static CPUReadMemoryFunc *pl080_readfn[] = {
- pl080_read,
- pl080_read,
- pl080_read
-};
-
-static CPUWriteMemoryFunc *pl080_writefn[] = {
- pl080_write,
- pl080_write,
- pl080_write
-};
-
-/* The PL080 and PL081 are the same except for the number of channels
- they implement (8 and 2 respectively). */
-void *pl080_init(uint32_t base, void *pic, int irq, int nchannels)
-{
- int iomemtype;
- pl080_state *s;
-
- s = (pl080_state *)qemu_mallocz(sizeof(pl080_state));
- iomemtype = cpu_register_io_memory(0, pl080_readfn,
- pl080_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
- s->pic = pic;
- s->irq = irq;
- s->nchannels = nchannels;
- /* ??? Save/restore. */
- return s;
-}
-
diff --git a/tools/ioemu/hw/pl110.c b/tools/ioemu/hw/pl110.c
deleted file mode 100644
index 16de16c0dd..0000000000
--- a/tools/ioemu/hw/pl110.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Arm PrimeCell PL110 Color LCD Controller
- *
- * Copyright (c) 2005-2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GNU LGPL
- */
-
-#include "vl.h"
-
-#define PL110_CR_EN 0x001
-#define PL110_CR_BEBO 0x200
-#define PL110_CR_BEPO 0x400
-#define PL110_CR_PWR 0x800
-
-enum pl110_bppmode
-{
- BPP_1,
- BPP_2,
- BPP_4,
- BPP_8,
- BPP_16,
- BPP_32
-};
-
-typedef struct {
- uint32_t base;
- DisplayState *ds;
- /* The Versatile/PB uses a slightly modified PL110 controller. */
- int versatile;
- void *pic;
- uint32_t timing[4];
- uint32_t cr;
- uint32_t upbase;
- uint32_t lpbase;
- uint32_t int_status;
- uint32_t int_mask;
- int cols;
- int rows;
- enum pl110_bppmode bpp;
- int invalidate;
- uint32_t pallette[256];
- uint32_t raw_pallette[128];
- int irq;
-} pl110_state;
-
-static const unsigned char pl110_id[] =
-{ 0x10, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-
-/* The Arm documentation (DDI0224C) says the CLDC on the Versatile board
- has a different ID. However Linux only looks for the normal ID. */
-#if 0
-static const unsigned char pl110_versatile_id[] =
-{ 0x93, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-#else
-#define pl110_versatile_id pl110_id
-#endif
-
-static inline uint32_t rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-}
-
-static inline uint32_t rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
-}
-
-static inline uint32_t rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-}
-
-static inline uint32_t rgb_to_pixel24(unsigned int r, unsigned int g, unsigned b)
-{
- return (r << 16) | (g << 8) | b;
-}
-
-static inline uint32_t rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
-{
- return (r << 16) | (g << 8) | b;
-}
-
-typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int);
-
-#define BITS 8
-#include "pl110_template.h"
-#define BITS 15
-#include "pl110_template.h"
-#define BITS 16
-#include "pl110_template.h"
-#define BITS 24
-#include "pl110_template.h"
-#define BITS 32
-#include "pl110_template.h"
-
-static int pl110_enabled(pl110_state *s)
-{
- return (s->cr & PL110_CR_EN) && (s->cr & PL110_CR_PWR);
-}
-
-static void pl110_update_display(void *opaque)
-{
- pl110_state *s = (pl110_state *)opaque;
- drawfn* fntable;
- drawfn fn;
- uint32_t *pallette;
- uint32_t addr;
- uint32_t base;
- int dest_width;
- int src_width;
- uint8_t *dest;
- uint8_t *src;
- int first, last = 0;
- int dirty, new_dirty;
- int i;
-
- if (!pl110_enabled(s))
- return;
-
- switch (s->ds->depth) {
- case 0:
- return;
- case 8:
- fntable = pl110_draw_fn_8;
- dest_width = 1;
- break;
- case 15:
- fntable = pl110_draw_fn_15;
- dest_width = 2;
- break;
- case 16:
- fntable = pl110_draw_fn_16;
- dest_width = 2;
- break;
- case 24:
- fntable = pl110_draw_fn_24;
- dest_width = 3;
- break;
- case 32:
- fntable = pl110_draw_fn_32;
- dest_width = 4;
- break;
- default:
- fprintf(stderr, "pl110: Bad color depth\n");
- exit(1);
- }
- if (s->cr & PL110_CR_BEBO)
- fn = fntable[s->bpp + 6];
- else if (s->cr & PL110_CR_BEPO)
- fn = fntable[s->bpp + 12];
- else
- fn = fntable[s->bpp];
-
- src_width = s->cols;
- switch (s->bpp) {
- case BPP_1:
- src_width >>= 3;
- break;
- case BPP_2:
- src_width >>= 2;
- break;
- case BPP_4:
- src_width >>= 1;
- break;
- case BPP_8:
- break;
- case BPP_16:
- src_width <<= 1;
- break;
- case BPP_32:
- src_width <<= 2;
- break;
- }
- dest_width *= s->cols;
- pallette = s->pallette;
- base = s->upbase;
- /* HACK: Arm aliases physical memory at 0x80000000. */
- if (base > 0x80000000)
- base -= 0x80000000;
- src = phys_ram_base + base;
- dest = s->ds->data;
- first = -1;
- addr = base;
-
- dirty = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
- new_dirty = dirty;
- for (i = 0; i < s->rows; i++) {
- if ((addr & ~TARGET_PAGE_MASK) + src_width >= TARGET_PAGE_SIZE) {
- uint32_t tmp;
- new_dirty = 0;
- for (tmp = 0; tmp < src_width; tmp += TARGET_PAGE_SIZE) {
- new_dirty |= cpu_physical_memory_get_dirty(addr + tmp,
- VGA_DIRTY_FLAG);
- }
- }
-
- if (dirty || new_dirty || s->invalidate) {
- fn(pallette, dest, src, s->cols);
- if (first == -1)
- first = i;
- last = i;
- }
- dirty = new_dirty;
- addr += src_width;
- dest += dest_width;
- src += src_width;
- }
- if (first < 0)
- return;
-
- s->invalidate = 0;
- cpu_physical_memory_reset_dirty(base + first * src_width,
- base + (last + 1) * src_width,
- VGA_DIRTY_FLAG);
- dpy_update(s->ds, 0, first, s->cols, last - first + 1);
-}
-
-static void pl110_invalidate_display(void * opaque)
-{
- pl110_state *s = (pl110_state *)opaque;
- s->invalidate = 1;
-}
-
-static void pl110_update_pallette(pl110_state *s, int n)
-{
- int i;
- uint32_t raw;
- unsigned int r, g, b;
-
- raw = s->raw_pallette[n];
- n <<= 1;
- for (i = 0; i < 2; i++) {
- r = (raw & 0x1f) << 3;
- raw >>= 5;
- g = (raw & 0x1f) << 3;
- raw >>= 5;
- b = (raw & 0x1f) << 3;
- /* The I bit is ignored. */
- raw >>= 6;
- switch (s->ds->depth) {
- case 8:
- s->pallette[n] = rgb_to_pixel8(r, g, b);
- break;
- case 15:
- s->pallette[n] = rgb_to_pixel15(r, g, b);
- break;
- case 16:
- s->pallette[n] = rgb_to_pixel16(r, g, b);
- break;
- case 24:
- case 32:
- s->pallette[n] = rgb_to_pixel32(r, g, b);
- break;
- }
- n++;
- }
-}
-
-static void pl110_resize(pl110_state *s, int width, int height)
-{
- if (width != s->cols || height != s->rows) {
- if (pl110_enabled(s)) {
- dpy_resize(s->ds, width, height);
- }
- }
- s->cols = width;
- s->rows = height;
-}
-
-/* Update interrupts. */
-static void pl110_update(pl110_state *s)
-{
- /* TODO: Implement interrupts. */
-}
-
-static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
-{
- pl110_state *s = (pl110_state *)opaque;
-
- offset -= s->base;
- if (offset >= 0xfe0 && offset < 0x1000) {
- if (s->versatile)
- return pl110_versatile_id[(offset - 0xfe0) >> 2];
- else
- return pl110_id[(offset - 0xfe0) >> 2];
- }
- if (offset >= 0x200 && offset < 0x400) {
- return s->raw_pallette[(offset - 0x200) >> 2];
- }
- switch (offset >> 2) {
- case 0: /* LCDTiming0 */
- return s->timing[0];
- case 1: /* LCDTiming1 */
- return s->timing[1];
- case 2: /* LCDTiming2 */
- return s->timing[2];
- case 3: /* LCDTiming3 */
- return s->timing[3];
- case 4: /* LCDUPBASE */
- return s->upbase;
- case 5: /* LCDLPBASE */
- return s->lpbase;
- case 6: /* LCDIMSC */
- return s->int_mask;
- case 7: /* LCDControl */
- return s->cr;
- case 8: /* LCDRIS */
- return s->int_status;
- case 9: /* LCDMIS */
- return s->int_status & s->int_mask;
- case 11: /* LCDUPCURR */
- /* TODO: Implement vertical refresh. */
- return s->upbase;
- case 12: /* LCDLPCURR */
- return s->lpbase;
- default:
- cpu_abort (cpu_single_env, "pl110_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void pl110_write(void *opaque, target_phys_addr_t offset,
- uint32_t val)
-{
- pl110_state *s = (pl110_state *)opaque;
- int n;
-
- /* For simplicity invalidate the display whenever a control register
- is writen to. */
- s->invalidate = 1;
- offset -= s->base;
- if (offset >= 0x200 && offset < 0x400) {
- /* Pallette. */
- n = (offset - 0x200) >> 2;
- s->raw_pallette[(offset - 0x200) >> 2] = val;
- pl110_update_pallette(s, n);
- return;
- }
- switch (offset >> 2) {
- case 0: /* LCDTiming0 */
- s->timing[0] = val;
- n = ((val & 0xfc) + 4) * 4;
- pl110_resize(s, n, s->rows);
- break;
- case 1: /* LCDTiming1 */
- s->timing[1] = val;
- n = (val & 0x3ff) + 1;
- pl110_resize(s, s->cols, n);
- break;
- case 2: /* LCDTiming2 */
- s->timing[2] = val;
- break;
- case 3: /* LCDTiming3 */
- s->timing[3] = val;
- break;
- case 4: /* LCDUPBASE */
- s->upbase = val;
- break;
- case 5: /* LCDLPBASE */
- s->lpbase = val;
- break;
- case 6: /* LCDIMSC */
- if (s->versatile)
- goto control;
- imsc:
- s->int_mask = val;
- pl110_update(s);
- break;
- case 7: /* LCDControl */
- if (s->versatile)
- goto imsc;
- control:
- s->cr = val;
- s->bpp = (val >> 1) & 7;
- if (pl110_enabled(s)) {
- dpy_resize(s->ds, s->cols, s->rows);
- }
- break;
- case 10: /* LCDICR */
- s->int_status &= ~val;
- pl110_update(s);
- break;
- default:
- cpu_abort (cpu_single_env, "pl110_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *pl110_readfn[] = {
- pl110_read,
- pl110_read,
- pl110_read
-};
-
-static CPUWriteMemoryFunc *pl110_writefn[] = {
- pl110_write,
- pl110_write,
- pl110_write
-};
-
-void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq,
- int versatile)
-{
- pl110_state *s;
- int iomemtype;
-
- s = (pl110_state *)qemu_mallocz(sizeof(pl110_state));
- iomemtype = cpu_register_io_memory(0, pl110_readfn,
- pl110_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
- s->ds = ds;
- s->versatile = versatile;
- s->pic = pic;
- s->irq = irq;
- graphic_console_init(ds, pl110_update_display, pl110_invalidate_display,
- NULL, s);
- /* ??? Save/restore. */
- return s;
-}
diff --git a/tools/ioemu/hw/pl110_template.h b/tools/ioemu/hw/pl110_template.h
deleted file mode 100644
index ed533aca19..0000000000
--- a/tools/ioemu/hw/pl110_template.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Arm PrimeCell PL110 Color LCD Controller
- *
- * Copyright (c) 2005 CodeSourcery, LLC.
- * Written by Paul Brook
- *
- * This code is licenced under the GNU LGPL
- *
- * Framebuffer format conversion routines.
- */
-
-#ifndef ORDER
-
-#if BITS == 8
-#define COPY_PIXEL(to, from) *(to++) = from
-#elif BITS == 15 || BITS == 16
-#define COPY_PIXEL(to, from) *(uint16_t *)to = from; to += 2;
-#elif BITS == 24
-#define COPY_PIXEL(to, from) \
- *(to++) = from; *(to++) = (from) >> 8; *(to++) = (from) >> 16
-#elif BITS == 32
-#define COPY_PIXEL(to, from) *(uint32_t *)to = from; to += 4;
-#else
-#error unknown bit depth
-#endif
-
-#define ORDER 0
-#include "pl110_template.h"
-#define ORDER 1
-#include "pl110_template.h"
-#define ORDER 2
-#include "pl110_template.h"
-
-static drawfn glue(pl110_draw_fn_,BITS)[18] =
-{
- glue(pl110_draw_line1_lblp,BITS),
- glue(pl110_draw_line2_lblp,BITS),
- glue(pl110_draw_line4_lblp,BITS),
- glue(pl110_draw_line8_lblp,BITS),
- glue(pl110_draw_line16_lblp,BITS),
- glue(pl110_draw_line32_lblp,BITS),
-
- glue(pl110_draw_line1_bbbp,BITS),
- glue(pl110_draw_line2_bbbp,BITS),
- glue(pl110_draw_line4_bbbp,BITS),
- glue(pl110_draw_line8_bbbp,BITS),
- glue(pl110_draw_line16_bbbp,BITS),
- glue(pl110_draw_line32_bbbp,BITS),
-
- glue(pl110_draw_line1_lbbp,BITS),
- glue(pl110_draw_line2_lbbp,BITS),
- glue(pl110_draw_line4_lbbp,BITS),
- glue(pl110_draw_line8_lbbp,BITS),
- glue(pl110_draw_line16_lbbp,BITS),
- glue(pl110_draw_line32_lbbp,BITS)
-};
-
-#undef BITS
-#undef COPY_PIXEL
-
-#else
-
-#if ORDER == 0
-#define NAME glue(lblp, BITS)
-#ifdef WORDS_BIGENDIAN
-#define SWAP_WORDS 1
-#endif
-#elif ORDER == 1
-#define NAME glue(bbbp, BITS)
-#ifndef WORDS_BIGENDIAN
-#define SWAP_WORDS 1
-#endif
-#else
-#define SWAP_PIXELS 1
-#define NAME glue(lbbp, BITS)
-#ifdef WORDS_BIGENDIAN
-#define SWAP_WORDS 1
-#endif
-#endif
-
-#define FN_2(x, y) FN(x, y) FN(x+1, y)
-#define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
-#define FN_8(y) FN_4(0, y) FN_4(4, y)
-
-static void glue(pl110_draw_line1_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
-{
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_PIXELS
-#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 7 - (x))) & 1]);
-#else
-#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x) + y)) & 1]);
-#endif
-#ifdef SWAP_WORDS
- FN_8(24)
- FN_8(16)
- FN_8(8)
- FN_8(0)
-#else
- FN_8(0)
- FN_8(8)
- FN_8(16)
- FN_8(24)
-#endif
-#undef FN
- width -= 32;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line2_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
-{
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_PIXELS
-#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 6 - (x)*2)) & 3]);
-#else
-#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x)*2 + y)) & 3]);
-#endif
-#ifdef SWAP_WORDS
- FN_4(0, 24)
- FN_4(0, 16)
- FN_4(0, 8)
- FN_4(0, 0)
-#else
- FN_4(0, 0)
- FN_4(0, 8)
- FN_4(0, 16)
- FN_4(0, 24)
-#endif
-#undef FN
- width -= 16;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line4_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
-{
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_PIXELS
-#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 4 - (x)*4)) & 0xf]);
-#else
-#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x)*4 + y)) & 0xf]);
-#endif
-#ifdef SWAP_WORDS
- FN_2(0, 24)
- FN_2(0, 16)
- FN_2(0, 8)
- FN_2(0, 0)
-#else
- FN_2(0, 0)
- FN_2(0, 8)
- FN_2(0, 16)
- FN_2(0, 24)
-#endif
-#undef FN
- width -= 8;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line8_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
-{
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#define FN(x) COPY_PIXEL(d, pallette[(data >> (x)) & 0xff]);
-#ifdef SWAP_WORDS
- FN(24)
- FN(16)
- FN(8)
- FN(0)
-#else
- FN(0)
- FN(8)
- FN(16)
- FN(24)
-#endif
-#undef FN
- width -= 4;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line16_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
-#if 0
- r = data & 0x1f;
- data >>= 5;
- g = data & 0x3f;
- data >>= 6;
- b = data & 0x1f;
- data >>= 5;
-#else
- r = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x3f) << 2;
- data >>= 6;
- b = (data & 0x1f) << 3;
- data >>= 5;
-#endif
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
- r = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x3f) << 2;
- data >>= 6;
- b = (data & 0x1f) << 3;
- data >>= 5;
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
- width -= 2;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line32_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_WORDS
- r = data & 0xff;
- g = (data >> 8) & 0xff;
- b = (data >> 16) & 0xff;
-#else
- r = (data >> 24) & 0xff;
- g = (data >> 16) & 0xff;
- b = (data >> 8) & 0xff;
-#endif
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
- width--;
- src += 4;
- }
-}
-
-#undef SWAP_PIXELS
-#undef NAME
-#undef SWAP_WORDS
-#undef ORDER
-
-#endif
diff --git a/tools/ioemu/hw/pl190.c b/tools/ioemu/hw/pl190.c
deleted file mode 100644
index 55c7180f5a..0000000000
--- a/tools/ioemu/hw/pl190.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Arm PrimeCell PL190 Vector Interrupt Controller
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-/* The number of virtual priority levels. 16 user vectors plus the
- unvectored IRQ. Chained interrupts would require an additional level
- if implemented. */
-
-#define PL190_NUM_PRIO 17
-
-typedef struct {
- arm_pic_handler handler;
- uint32_t base;
- DisplayState *ds;
- uint32_t level;
- uint32_t soft_level;
- uint32_t irq_enable;
- uint32_t fiq_select;
- uint32_t default_addr;
- uint8_t vect_control[16];
- uint32_t vect_addr[PL190_NUM_PRIO];
- /* Mask containing interrupts with higher priority than this one. */
- uint32_t prio_mask[PL190_NUM_PRIO + 1];
- int protected;
- /* Current priority level. */
- int priority;
- int prev_prio[PL190_NUM_PRIO];
- void *parent;
- int irq;
- int fiq;
-} pl190_state;
-
-static const unsigned char pl190_id[] =
-{ 0x90, 0x11, 0x04, 0x00, 0x0D, 0xf0, 0x05, 0xb1 };
-
-static inline uint32_t pl190_irq_level(pl190_state *s)
-{
- return (s->level | s->soft_level) & s->irq_enable & ~s->fiq_select;
-}
-
-/* Update interrupts. */
-static void pl190_update(pl190_state *s)
-{
- uint32_t level = pl190_irq_level(s);
- int set;
-
- set = (level & s->prio_mask[s->priority]) != 0;
- pic_set_irq_new(s->parent, s->irq, set);
- set = ((s->level | s->soft_level) & s->fiq_select) != 0;
- pic_set_irq_new(s->parent, s->fiq, set);
-}
-
-static void pl190_set_irq(void *opaque, int irq, int level)
-{
- pl190_state *s = (pl190_state *)opaque;
-
- if (level)
- s->level |= 1u << irq;
- else
- s->level &= ~(1u << irq);
- pl190_update(s);
-}
-
-static void pl190_update_vectors(pl190_state *s)
-{
- uint32_t mask;
- int i;
- int n;
-
- mask = 0;
- for (i = 0; i < 16; i++)
- {
- s->prio_mask[i] = mask;
- if (s->vect_control[i] & 0x20)
- {
- n = s->vect_control[i] & 0x1f;
- mask |= 1 << n;
- }
- }
- s->prio_mask[16] = mask;
- pl190_update(s);
-}
-
-static uint32_t pl190_read(void *opaque, target_phys_addr_t offset)
-{
- pl190_state *s = (pl190_state *)opaque;
- int i;
-
- offset -= s->base;
- if (offset >= 0xfe0 && offset < 0x1000) {
- return pl190_id[(offset - 0xfe0) >> 2];
- }
- if (offset >= 0x100 && offset < 0x140) {
- return s->vect_addr[(offset - 0x100) >> 2];
- }
- if (offset >= 0x200 && offset < 0x240) {
- return s->vect_control[(offset - 0x200) >> 2];
- }
- switch (offset >> 2) {
- case 0: /* IRQSTATUS */
- return pl190_irq_level(s);
- case 1: /* FIQSATUS */
- return (s->level | s->soft_level) & s->fiq_select;
- case 2: /* RAWINTR */
- return s->level | s->soft_level;
- case 3: /* INTSELECT */
- return s->fiq_select;
- case 4: /* INTENABLE */
- return s->irq_enable;
- case 6: /* SOFTINT */
- return s->soft_level;
- case 8: /* PROTECTION */
- return s->protected;
- case 12: /* VECTADDR */
- /* Read vector address at the start of an ISR. Increases the
- current priority level to that of the current interrupt. */
- for (i = 0; i < s->priority; i++)
- {
- if ((s->level | s->soft_level) & s->prio_mask[i])
- break;
- }
- /* Reading this value with no pending interrupts is undefined.
- We return the default address. */
- if (i == PL190_NUM_PRIO)
- return s->vect_addr[16];
- if (i < s->priority)
- {
- s->prev_prio[i] = s->priority;
- s->priority = i;
- pl190_update(s);
- }
- return s->vect_addr[s->priority];
- case 13: /* DEFVECTADDR */
- return s->vect_addr[16];
- default:
- cpu_abort (cpu_single_env, "pl190_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void pl190_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- pl190_state *s = (pl190_state *)opaque;
-
- offset -= s->base;
- if (offset >= 0x100 && offset < 0x140) {
- s->vect_addr[(offset - 0x100) >> 2] = val;
- pl190_update_vectors(s);
- return;
- }
- if (offset >= 0x200 && offset < 0x240) {
- s->vect_control[(offset - 0x200) >> 2] = val;
- pl190_update_vectors(s);
- return;
- }
- switch (offset >> 2) {
- case 0: /* SELECT */
- /* This is a readonly register, but linux tries to write to it
- anyway. Ignore the write. */
- break;
- case 3: /* INTSELECT */
- s->fiq_select = val;
- break;
- case 4: /* INTENABLE */
- s->irq_enable |= val;
- break;
- case 5: /* INTENCLEAR */
- s->irq_enable &= ~val;
- break;
- case 6: /* SOFTINT */
- s->soft_level |= val;
- break;
- case 7: /* SOFTINTCLEAR */
- s->soft_level &= ~val;
- break;
- case 8: /* PROTECTION */
- /* TODO: Protection (supervisor only access) is not implemented. */
- s->protected = val & 1;
- break;
- case 12: /* VECTADDR */
- /* Restore the previous priority level. The value written is
- ignored. */
- if (s->priority < PL190_NUM_PRIO)
- s->priority = s->prev_prio[s->priority];
- break;
- case 13: /* DEFVECTADDR */
- s->default_addr = val;
- break;
- case 0xc0: /* ITCR */
- if (val)
- cpu_abort(cpu_single_env, "pl190: Test mode not implemented\n");
- break;
- default:
- cpu_abort(cpu_single_env, "pl190_write: Bad offset %x\n", offset);
- return;
- }
- pl190_update(s);
-}
-
-static CPUReadMemoryFunc *pl190_readfn[] = {
- pl190_read,
- pl190_read,
- pl190_read
-};
-
-static CPUWriteMemoryFunc *pl190_writefn[] = {
- pl190_write,
- pl190_write,
- pl190_write
-};
-
-void pl190_reset(pl190_state *s)
-{
- int i;
-
- for (i = 0; i < 16; i++)
- {
- s->vect_addr[i] = 0;
- s->vect_control[i] = 0;
- }
- s->vect_addr[16] = 0;
- s->prio_mask[17] = 0xffffffff;
- s->priority = PL190_NUM_PRIO;
- pl190_update_vectors(s);
-}
-
-void *pl190_init(uint32_t base, void *parent, int irq, int fiq)
-{
- pl190_state *s;
- int iomemtype;
-
- s = (pl190_state *)qemu_mallocz(sizeof(pl190_state));
- iomemtype = cpu_register_io_memory(0, pl190_readfn,
- pl190_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->handler = pl190_set_irq;
- s->base = base;
- s->parent = parent;
- s->irq = irq;
- s->fiq = fiq;
- pl190_reset(s);
- /* ??? Save/restore. */
- return s;
-}
diff --git a/tools/ioemu/hw/ppc.c b/tools/ioemu/hw/ppc.c
deleted file mode 100644
index b0865c1646..0000000000
--- a/tools/ioemu/hw/ppc.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * QEMU generic PPC hardware System Emulator
- *
- * Copyright (c) 2003-2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "m48t59.h"
-
-/*****************************************************************************/
-/* PPC time base and decrementer emulation */
-//#define DEBUG_TB
-
-struct ppc_tb_t {
- /* Time base management */
- int64_t tb_offset; /* Compensation */
- uint32_t tb_freq; /* TB frequency */
- /* Decrementer management */
- uint64_t decr_next; /* Tick for next decr interrupt */
- struct QEMUTimer *decr_timer;
-};
-
-static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
-{
- /* TB time in tb periods */
- return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
- tb_env->tb_freq, ticks_per_sec);
-}
-
-uint32_t cpu_ppc_load_tbl (CPUState *env)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint64_t tb;
-
- tb = cpu_ppc_get_tb(tb_env);
-#ifdef DEBUG_TB
- {
- static int last_time;
- int now;
- now = time(NULL);
- if (last_time != now) {
- last_time = now;
- printf("%s: tb=0x%016lx %d %08lx\n",
- __func__, tb, now, tb_env->tb_offset);
- }
- }
-#endif
-
- return tb & 0xFFFFFFFF;
-}
-
-uint32_t cpu_ppc_load_tbu (CPUState *env)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint64_t tb;
-
- tb = cpu_ppc_get_tb(tb_env);
-#ifdef DEBUG_TB
- printf("%s: tb=0x%016lx\n", __func__, tb);
-#endif
- return tb >> 32;
-}
-
-static void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t value)
-{
- tb_env->tb_offset = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
- - qemu_get_clock(vm_clock);
-#ifdef DEBUG_TB
- printf("%s: tb=0x%016lx offset=%08x\n", __func__, value);
-#endif
-}
-
-void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
-{
- ppc_tb_t *tb_env = env->tb_env;
-
- cpu_ppc_store_tb(tb_env,
- ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
-}
-
-void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
-{
- ppc_tb_t *tb_env = env->tb_env;
-
- cpu_ppc_store_tb(tb_env,
- ((uint64_t)cpu_ppc_load_tbu(env) << 32) | value);
-}
-
-uint32_t cpu_ppc_load_decr (CPUState *env)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint32_t decr;
- int64_t diff;
-
- diff = tb_env->decr_next - qemu_get_clock(vm_clock);
- if (diff >= 0)
- decr = muldiv64(diff, tb_env->tb_freq, ticks_per_sec);
- else
- decr = -muldiv64(-diff, tb_env->tb_freq, ticks_per_sec);
-#if defined(DEBUG_TB)
- printf("%s: 0x%08x\n", __func__, decr);
-#endif
- return decr;
-}
-
-/* When decrementer expires,
- * all we need to do is generate or queue a CPU exception
- */
-static inline void cpu_ppc_decr_excp (CPUState *env)
-{
- /* Raise it */
-#ifdef DEBUG_TB
- printf("raise decrementer exception\n");
-#endif
- cpu_interrupt(env, CPU_INTERRUPT_TIMER);
-}
-
-static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
- uint32_t value, int is_excp)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint64_t now, next;
-
-#ifdef DEBUG_TB
- printf("%s: 0x%08x => 0x%08x\n", __func__, decr, value);
-#endif
- now = qemu_get_clock(vm_clock);
- next = now + muldiv64(value, ticks_per_sec, tb_env->tb_freq);
- if (is_excp)
- next += tb_env->decr_next - now;
- if (next == now)
- next++;
- tb_env->decr_next = next;
- /* Adjust timer */
- qemu_mod_timer(tb_env->decr_timer, next);
- /* If we set a negative value and the decrementer was positive,
- * raise an exception.
- */
- if ((value & 0x80000000) && !(decr & 0x80000000))
- cpu_ppc_decr_excp(env);
-}
-
-void cpu_ppc_store_decr (CPUState *env, uint32_t value)
-{
- _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
-}
-
-static void cpu_ppc_decr_cb (void *opaque)
-{
- _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
-}
-
-/* Set up (once) timebase frequency (in Hz) */
-ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq)
-{
- ppc_tb_t *tb_env;
-
- tb_env = qemu_mallocz(sizeof(ppc_tb_t));
- if (tb_env == NULL)
- return NULL;
- env->tb_env = tb_env;
- if (tb_env->tb_freq == 0 || 1) {
- tb_env->tb_freq = freq;
- /* Create new timer */
- tb_env->decr_timer =
- qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
- /* There is a bug in 2.4 kernels:
- * if a decrementer exception is pending when it enables msr_ee,
- * it's not ready to handle it...
- */
- _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
- }
-
- return tb_env;
-}
-
-#if 0
-/*****************************************************************************/
-/* Handle system reset (for now, just stop emulation) */
-void cpu_ppc_reset (CPUState *env)
-{
- printf("Reset asked... Stop emulation\n");
- abort();
-}
-#endif
-
-/*****************************************************************************/
-/* Debug port */
-void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
-{
- addr &= 0xF;
- switch (addr) {
- case 0:
- printf("%c", val);
- break;
- case 1:
- printf("\n");
- fflush(stdout);
- break;
- case 2:
- printf("Set loglevel to %04x\n", val);
- cpu_set_log(val | 0x100);
- break;
- }
-}
-
-/*****************************************************************************/
-/* NVRAM helpers */
-void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
-{
- m48t59_write(nvram, addr, value);
-}
-
-uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
-{
- return m48t59_read(nvram, addr);
-}
-
-void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
-{
- m48t59_write(nvram, addr, value >> 8);
- m48t59_write(nvram, addr + 1, value & 0xFF);
-}
-
-uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
-{
- uint16_t tmp;
-
- tmp = m48t59_read(nvram, addr) << 8;
- tmp |= m48t59_read(nvram, addr + 1);
- return tmp;
-}
-
-void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
-{
- m48t59_write(nvram, addr, value >> 24);
- m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);
- m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);
- m48t59_write(nvram, addr + 3, value & 0xFF);
-}
-
-uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
-{
- uint32_t tmp;
-
- tmp = m48t59_read(nvram, addr) << 24;
- tmp |= m48t59_read(nvram, addr + 1) << 16;
- tmp |= m48t59_read(nvram, addr + 2) << 8;
- tmp |= m48t59_read(nvram, addr + 3);
- return tmp;
-}
-
-void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
- const unsigned char *str, uint32_t max)
-{
- int i;
-
- for (i = 0; i < max && str[i] != '\0'; i++) {
- m48t59_write(nvram, addr + i, str[i]);
- }
- m48t59_write(nvram, addr + max - 1, '\0');
-}
-
-int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
-{
- int i;
-
- memset(dst, 0, max);
- for (i = 0; i < max; i++) {
- dst[i] = NVRAM_get_byte(nvram, addr + i);
- if (dst[i] == '\0')
- break;
- }
-
- return i;
-}
-
-static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
-{
- uint16_t tmp;
- uint16_t pd, pd1, pd2;
-
- tmp = prev >> 8;
- pd = prev ^ value;
- pd1 = pd & 0x000F;
- pd2 = ((pd >> 4) & 0x000F) ^ pd1;
- tmp ^= (pd1 << 3) | (pd1 << 8);
- tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
-
- return tmp;
-}
-
-uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
-{
- uint32_t i;
- uint16_t crc = 0xFFFF;
- int odd;
-
- odd = count & 1;
- count &= ~1;
- for (i = 0; i != count; i++) {
- crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
- }
- if (odd) {
- crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
- }
-
- return crc;
-}
-
-#define CMDLINE_ADDR 0x017ff000
-
-int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
- const unsigned char *arch,
- uint32_t RAM_size, int boot_device,
- uint32_t kernel_image, uint32_t kernel_size,
- const char *cmdline,
- uint32_t initrd_image, uint32_t initrd_size,
- uint32_t NVRAM_image,
- int width, int height, int depth)
-{
- uint16_t crc;
-
- /* Set parameters for Open Hack'Ware BIOS */
- NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
- NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */
- NVRAM_set_word(nvram, 0x14, NVRAM_size);
- NVRAM_set_string(nvram, 0x20, arch, 16);
- NVRAM_set_lword(nvram, 0x30, RAM_size);
- NVRAM_set_byte(nvram, 0x34, boot_device);
- NVRAM_set_lword(nvram, 0x38, kernel_image);
- NVRAM_set_lword(nvram, 0x3C, kernel_size);
- if (cmdline) {
- /* XXX: put the cmdline in NVRAM too ? */
- strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
- NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR);
- NVRAM_set_lword(nvram, 0x44, strlen(cmdline));
- } else {
- NVRAM_set_lword(nvram, 0x40, 0);
- NVRAM_set_lword(nvram, 0x44, 0);
- }
- NVRAM_set_lword(nvram, 0x48, initrd_image);
- NVRAM_set_lword(nvram, 0x4C, initrd_size);
- NVRAM_set_lword(nvram, 0x50, NVRAM_image);
-
- NVRAM_set_word(nvram, 0x54, width);
- NVRAM_set_word(nvram, 0x56, height);
- NVRAM_set_word(nvram, 0x58, depth);
- crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
- NVRAM_set_word(nvram, 0xFC, crc);
-
- return 0;
-}
diff --git a/tools/ioemu/hw/ppc_chrp.c b/tools/ioemu/hw/ppc_chrp.c
deleted file mode 100644
index 1e0fd2e9da..0000000000
--- a/tools/ioemu/hw/ppc_chrp.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * QEMU PPC CHRP/PMAC hardware System Emulator
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define BIOS_FILENAME "ppc_rom.bin"
-#define VGABIOS_FILENAME "video.x"
-#define NVRAM_SIZE 0x2000
-
-#define KERNEL_LOAD_ADDR 0x01000000
-#define INITRD_LOAD_ADDR 0x01800000
-
-/* MacIO devices (mapped inside the MacIO address space): CUDA, DBDMA,
- NVRAM */
-
-static int dbdma_mem_index;
-static int cuda_mem_index;
-static int ide0_mem_index = -1;
-static int ide1_mem_index = -1;
-static int openpic_mem_index = -1;
-static int heathrow_pic_mem_index = -1;
-static int macio_nvram_mem_index = -1;
-
-/* DBDMA: currently no op - should suffice right now */
-
-static void dbdma_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- printf("%s: 0x%08x <= 0x%08x\n", __func__, addr, value);
-}
-
-static void dbdma_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static void dbdma_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)
-{
- printf("%s: 0x%08x => 0x00000000\n", __func__, addr);
- return 0;
-}
-
-static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static CPUWriteMemoryFunc *dbdma_write[] = {
- &dbdma_writeb,
- &dbdma_writew,
- &dbdma_writel,
-};
-
-static CPUReadMemoryFunc *dbdma_read[] = {
- &dbdma_readb,
- &dbdma_readw,
- &dbdma_readl,
-};
-
-/* macio style NVRAM device */
-typedef struct MacIONVRAMState {
- uint8_t data[0x2000];
-} MacIONVRAMState;
-
-static void macio_nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- MacIONVRAMState *s = opaque;
- addr = (addr >> 4) & 0x1fff;
- s->data[addr] = value;
- // printf("macio_nvram_writeb %04x = %02x\n", addr, value);
-}
-
-static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
-{
- MacIONVRAMState *s = opaque;
- uint32_t value;
-
- addr = (addr >> 4) & 0x1fff;
- value = s->data[addr];
- // printf("macio_nvram_readb %04x = %02x\n", addr, value);
- return value;
-}
-
-static CPUWriteMemoryFunc *macio_nvram_write[] = {
- &macio_nvram_writeb,
- &macio_nvram_writeb,
- &macio_nvram_writeb,
-};
-
-static CPUReadMemoryFunc *macio_nvram_read[] = {
- &macio_nvram_readb,
- &macio_nvram_readb,
- &macio_nvram_readb,
-};
-
-static MacIONVRAMState *macio_nvram_init(void)
-{
- MacIONVRAMState *s;
- s = qemu_mallocz(sizeof(MacIONVRAMState));
- if (!s)
- return NULL;
- macio_nvram_mem_index = cpu_register_io_memory(0, macio_nvram_read,
- macio_nvram_write, s);
- return s;
-}
-
-static void macio_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- if (heathrow_pic_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x00000, 0x1000,
- heathrow_pic_mem_index);
- }
- cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index);
- cpu_register_physical_memory(addr + 0x16000, 0x2000, cuda_mem_index);
- if (ide0_mem_index >= 0)
- cpu_register_physical_memory(addr + 0x1f000, 0x1000, ide0_mem_index);
- if (ide1_mem_index >= 0)
- cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index);
- if (openpic_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x40000, 0x40000,
- openpic_mem_index);
- }
- if (macio_nvram_mem_index >= 0)
- cpu_register_physical_memory(addr + 0x60000, 0x20000, macio_nvram_mem_index);
-}
-
-static void macio_init(PCIBus *bus, int device_id)
-{
- PCIDevice *d;
-
- d = pci_register_device(bus, "macio", sizeof(PCIDevice),
- -1, NULL, NULL);
- /* Note: this code is strongly inspirated from the corresponding code
- in PearPC */
- d->config[0x00] = 0x6b; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = device_id;
- d->config[0x03] = device_id >> 8;
-
- d->config[0x0a] = 0x00; // class_sub = pci2pci
- d->config[0x0b] = 0xff; // class_base = bridge
- d->config[0x0e] = 0x00; // header_type
-
- d->config[0x3d] = 0x01; // interrupt on pin 1
-
- dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
-
- pci_register_io_region(d, 0, 0x80000,
- PCI_ADDRESS_SPACE_MEM, macio_map);
-}
-
-/* UniN device */
-static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static uint32_t unin_readl (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static CPUWriteMemoryFunc *unin_write[] = {
- &unin_writel,
- &unin_writel,
- &unin_writel,
-};
-
-static CPUReadMemoryFunc *unin_read[] = {
- &unin_readl,
- &unin_readl,
- &unin_readl,
-};
-
-/* temporary frame buffer OSI calls for the video.x driver. The right
- solution is to modify the driver to use VGA PCI I/Os */
-static int vga_osi_call(CPUState *env)
-{
- static int vga_vbl_enabled;
- int linesize;
-
- // printf("osi_call R5=%d\n", env->gpr[5]);
-
- /* same handler as PearPC, coming from the original MOL video
- driver. */
- switch(env->gpr[5]) {
- case 4:
- break;
- case 28: /* set_vmode */
- if (env->gpr[6] != 1 || env->gpr[7] != 0)
- env->gpr[3] = 1;
- else
- env->gpr[3] = 0;
- break;
- case 29: /* get_vmode_info */
- if (env->gpr[6] != 0) {
- if (env->gpr[6] != 1 || env->gpr[7] != 0) {
- env->gpr[3] = 1;
- break;
- }
- }
- env->gpr[3] = 0;
- env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */
- env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */
- env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */
- env->gpr[7] = 85 << 16; /* refresh rate */
- env->gpr[8] = (graphic_depth + 7) & ~7; /* depth (round to byte) */
- linesize = ((graphic_depth + 7) >> 3) * graphic_width;
- linesize = (linesize + 3) & ~3;
- env->gpr[9] = (linesize << 16) | 0; /* row_bytes, offset */
- break;
- case 31: /* set_video power */
- env->gpr[3] = 0;
- break;
- case 39: /* video_ctrl */
- if (env->gpr[6] == 0 || env->gpr[6] == 1)
- vga_vbl_enabled = env->gpr[6];
- env->gpr[3] = 0;
- break;
- case 47:
- break;
- case 59: /* set_color */
- /* R6 = index, R7 = RGB */
- env->gpr[3] = 0;
- break;
- case 64: /* get color */
- /* R6 = index */
- env->gpr[3] = 0;
- break;
- case 116: /* set hwcursor */
- /* R6 = x, R7 = y, R8 = visible, R9 = data */
- break;
- default:
- fprintf(stderr, "unsupported OSI call R5=%08x\n", env->gpr[5]);
- break;
- }
- return 1; /* osi_call handled */
-}
-
-/* XXX: suppress that */
-static void pic_irq_request(void *opaque, int level)
-{
-}
-
-static uint8_t nvram_chksum(const uint8_t *buf, int n)
-{
- int sum, i;
- sum = 0;
- for(i = 0; i < n; i++)
- sum += buf[i];
- return (sum & 0xff) + (sum >> 8);
-}
-
-/* set a free Mac OS NVRAM partition */
-void pmac_format_nvram_partition(uint8_t *buf, int len)
-{
- char partition_name[12] = "wwwwwwwwwwww";
-
- buf[0] = 0x7f; /* free partition magic */
- buf[1] = 0; /* checksum */
- buf[2] = len >> 8;
- buf[3] = len;
- memcpy(buf + 4, partition_name, 12);
- buf[1] = nvram_chksum(buf, 16);
-}
-
-/* PowerPC CHRP hardware initialisation */
-static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- int is_heathrow)
-{
- CPUState *env;
- char buf[1024];
- SetIRQFunc *set_irq;
- void *pic;
- m48t59_t *nvram;
- int unin_memory;
- int linux_boot, i;
- unsigned long bios_offset, vga_bios_offset;
- uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
- ppc_def_t *def;
- PCIBus *pci_bus;
- const char *arch_name;
- int vga_bios_size, bios_size;
-
- linux_boot = (kernel_filename != NULL);
-
- /* init CPUs */
- env = cpu_init();
- register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
-
- /* Register CPU as a 74x/75x */
- /* XXX: CPU model (or PVR) should be provided on command line */
- // ppc_find_by_name("750gx", &def); // Linux boot OK
- // ppc_find_by_name("750fx", &def); // Linux boot OK
- /* Linux does not boot on 750cxe (and probably other 750cx based)
- * because it assumes it has 8 IBAT & DBAT pairs as it only have 4.
- */
- // ppc_find_by_name("750cxe", &def);
- // ppc_find_by_name("750p", &def);
- // ppc_find_by_name("740p", &def);
- ppc_find_by_name("750", &def);
- // ppc_find_by_name("740", &def);
- // ppc_find_by_name("G3", &def);
- // ppc_find_by_name("604r", &def);
- // ppc_find_by_name("604e", &def);
- // ppc_find_by_name("604", &def);
- if (def == NULL) {
- cpu_abort(env, "Unable to find PowerPC CPU definition\n");
- }
- cpu_ppc_register(env, def);
-
- /* Set time-base frequency to 100 Mhz */
- cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
-
- env->osi_call = vga_osi_call;
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- /* allocate and load BIOS */
- bios_offset = ram_size + vga_ram_size;
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- bios_size = load_image(buf, phys_ram_base + bios_offset);
- if (bios_size < 0 || bios_size > BIOS_SIZE) {
- fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", buf);
- exit(1);
- }
- bios_size = (bios_size + 0xfff) & ~0xfff;
- cpu_register_physical_memory((uint32_t)(-bios_size),
- bios_size, bios_offset | IO_MEM_ROM);
-
- /* allocate and load VGA BIOS */
- vga_bios_offset = bios_offset + bios_size;
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
- vga_bios_size = load_image(buf, phys_ram_base + vga_bios_offset + 8);
- if (vga_bios_size < 0) {
- /* if no bios is present, we can still work */
- fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", buf);
- vga_bios_size = 0;
- } else {
- /* set a specific header (XXX: find real Apple format for NDRV
- drivers) */
- phys_ram_base[vga_bios_offset] = 'N';
- phys_ram_base[vga_bios_offset + 1] = 'D';
- phys_ram_base[vga_bios_offset + 2] = 'R';
- phys_ram_base[vga_bios_offset + 3] = 'V';
- cpu_to_be32w((uint32_t *)(phys_ram_base + vga_bios_offset + 4),
- vga_bios_size);
- vga_bios_size += 8;
- }
- vga_bios_size = (vga_bios_size + 0xfff) & ~0xfff;
-
- if (linux_boot) {
- kernel_base = KERNEL_LOAD_ADDR;
- /* now we can load the kernel */
- kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
- /* load initrd */
- if (initrd_filename) {
- initrd_base = INITRD_LOAD_ADDR;
- initrd_size = load_image(initrd_filename,
- phys_ram_base + initrd_base);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- } else {
- initrd_base = 0;
- initrd_size = 0;
- }
- boot_device = 'm';
- } else {
- kernel_base = 0;
- kernel_size = 0;
- initrd_base = 0;
- initrd_size = 0;
- }
-
- if (is_heathrow) {
- isa_mem_base = 0x80000000;
-
- /* Register 2 MB of ISA IO space */
- isa_mmio_init(0xfe000000, 0x00200000);
-
- /* init basic PC hardware */
- pic = heathrow_pic_init(&heathrow_pic_mem_index);
- set_irq = heathrow_pic_set_irq;
- pci_bus = pci_grackle_init(0xfec00000, pic);
- pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
- ram_size, vga_ram_size,
- vga_bios_offset, vga_bios_size);
-
- /* XXX: suppress that */
- isa_pic = pic_init(pic_irq_request, NULL);
-
- /* XXX: use Mac Serial port */
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
-
- for(i = 0; i < nb_nics; i++) {
- if (!nd_table[i].model)
- nd_table[i].model = "ne2k_pci";
- pci_nic_init(pci_bus, &nd_table[i], -1);
- }
-
- pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
-
- /* cuda also initialize ADB */
- cuda_mem_index = cuda_init(set_irq, pic, 0x12);
-
- adb_kbd_init(&adb_bus);
- adb_mouse_init(&adb_bus);
-
- {
- MacIONVRAMState *nvr;
- nvr = macio_nvram_init();
- pmac_format_nvram_partition(nvr->data, 0x2000);
- }
-
- macio_init(pci_bus, 0x0017);
-
- nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
-
- arch_name = "HEATHROW";
- } else {
- isa_mem_base = 0x80000000;
-
- /* Register 8 MB of ISA IO space */
- isa_mmio_init(0xf2000000, 0x00800000);
-
- /* UniN init */
- unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
- cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
-
- pic = openpic_init(NULL, &openpic_mem_index, 1, &env);
- set_irq = openpic_set_irq;
- pci_bus = pci_pmac_init(pic);
- /* init basic PC hardware */
- pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
- ram_size, vga_ram_size,
- vga_bios_offset, vga_bios_size);
-
- /* XXX: suppress that */
- isa_pic = pic_init(pic_irq_request, NULL);
-
- /* XXX: use Mac Serial port */
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
-
- for(i = 0; i < nb_nics; i++) {
- pci_ne2000_init(pci_bus, &nd_table[i], -1);
- }
-
-#if 1
- ide0_mem_index = pmac_ide_init(&bs_table[0], set_irq, pic, 0x13);
- ide1_mem_index = pmac_ide_init(&bs_table[2], set_irq, pic, 0x14);
-#else
- pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
-#endif
- /* cuda also initialize ADB */
- cuda_mem_index = cuda_init(set_irq, pic, 0x19);
-
- adb_kbd_init(&adb_bus);
- adb_mouse_init(&adb_bus);
-
- macio_init(pci_bus, 0x0022);
-
- nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
-
- arch_name = "MAC99";
- }
-
- if (usb_enabled) {
- usb_ohci_init(pci_bus, 3, -1);
- }
-
- if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
- graphic_depth = 15;
-
- PPC_NVRAM_set_params(nvram, NVRAM_SIZE, arch_name, ram_size, boot_device,
- kernel_base, kernel_size,
- kernel_cmdline,
- initrd_base, initrd_size,
- /* XXX: need an option to load a NVRAM image */
- 0,
- graphic_width, graphic_height, graphic_depth);
- /* No PCI init: the BIOS will do it */
-
- /* Special port to get debug messages from Open-Firmware */
- register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
-}
-
-static void ppc_core99_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename)
-{
- ppc_chrp_init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline,
- initrd_filename, 0);
-}
-
-static void ppc_heathrow_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename)
-{
- ppc_chrp_init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline,
- initrd_filename, 1);
-}
-
-QEMUMachine core99_machine = {
- "mac99",
- "Mac99 based PowerMAC",
- ppc_core99_init,
-};
-
-QEMUMachine heathrow_machine = {
- "g3bw",
- "Heathrow based PowerMAC",
- ppc_heathrow_init,
-};
diff --git a/tools/ioemu/hw/ppc_prep.c b/tools/ioemu/hw/ppc_prep.c
deleted file mode 100644
index c4b7ff5baa..0000000000
--- a/tools/ioemu/hw/ppc_prep.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * QEMU PPC PREP hardware System Emulator
- *
- * Copyright (c) 2003-2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define HARD_DEBUG_PPC_IO
-//#define DEBUG_PPC_IO
-
-#define BIOS_FILENAME "ppc_rom.bin"
-#define KERNEL_LOAD_ADDR 0x01000000
-#define INITRD_LOAD_ADDR 0x01800000
-
-extern int loglevel;
-extern FILE *logfile;
-
-#if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
-#define DEBUG_PPC_IO
-#endif
-
-#if defined (HARD_DEBUG_PPC_IO)
-#define PPC_IO_DPRINTF(fmt, args...) \
-do { \
- if (loglevel & CPU_LOG_IOPORT) { \
- fprintf(logfile, "%s: " fmt, __func__ , ##args); \
- } else { \
- printf("%s : " fmt, __func__ , ##args); \
- } \
-} while (0)
-#elif defined (DEBUG_PPC_IO)
-#define PPC_IO_DPRINTF(fmt, args...) \
-do { \
- if (loglevel & CPU_LOG_IOPORT) { \
- fprintf(logfile, "%s: " fmt, __func__ , ##args); \
- } \
-} while (0)
-#else
-#define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
-#endif
-
-/* Constants for devices init */
-static const int ide_iobase[2] = { 0x1f0, 0x170 };
-static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 13, 13 };
-
-#define NE2000_NB_MAX 6
-
-static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
-static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
-
-//static PITState *pit;
-
-/* ISA IO ports bridge */
-#define PPC_IO_BASE 0x80000000
-
-/* Speaker port 0x61 */
-int speaker_data_on;
-int dummy_refresh_clock;
-
-static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-#if 0
- speaker_data_on = (val >> 1) & 1;
- pit_set_gate(pit, 2, val & 1);
-#endif
-}
-
-static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
-{
-#if 0
- int out;
- out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
- dummy_refresh_clock ^= 1;
- return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
- (dummy_refresh_clock << 4);
-#endif
- return 0;
-}
-
-static void pic_irq_request(void *opaque, int level)
-{
- if (level)
- cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
- else
- cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
-}
-
-/* PCI intack register */
-/* Read-only register (?) */
-static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- // printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
-}
-
-static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- if (addr == 0xBFFFFFF0)
- retval = pic_intack_read(isa_pic);
- // printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
-
- return retval;
-}
-
-static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
-{
- return _PPC_intack_read(addr);
-}
-
-static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- return bswap16(_PPC_intack_read(addr));
-#else
- return _PPC_intack_read(addr);
-#endif
-}
-
-static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- return bswap32(_PPC_intack_read(addr));
-#else
- return _PPC_intack_read(addr);
-#endif
-}
-
-static CPUWriteMemoryFunc *PPC_intack_write[] = {
- &_PPC_intack_write,
- &_PPC_intack_write,
- &_PPC_intack_write,
-};
-
-static CPUReadMemoryFunc *PPC_intack_read[] = {
- &PPC_intack_readb,
- &PPC_intack_readw,
- &PPC_intack_readl,
-};
-
-/* PowerPC control and status registers */
-#if 0 // Not used
-static struct {
- /* IDs */
- uint32_t veni_devi;
- uint32_t revi;
- /* Control and status */
- uint32_t gcsr;
- uint32_t xcfr;
- uint32_t ct32;
- uint32_t mcsr;
- /* General purpose registers */
- uint32_t gprg[6];
- /* Exceptions */
- uint32_t feen;
- uint32_t fest;
- uint32_t fema;
- uint32_t fecl;
- uint32_t eeen;
- uint32_t eest;
- uint32_t eecl;
- uint32_t eeint;
- uint32_t eemck0;
- uint32_t eemck1;
- /* Error diagnostic */
-} XCSR;
-
-static void PPC_XCSR_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
-}
-
-static void PPC_XCSR_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap16(value);
-#endif
- printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
-}
-
-static void PPC_XCSR_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap32(value);
-#endif
- printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
-}
-
-static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
-
- return retval;
-}
-
-static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap16(retval);
-#endif
-
- return retval;
-}
-
-static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap32(retval);
-#endif
-
- return retval;
-}
-
-static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
- &PPC_XCSR_writeb,
- &PPC_XCSR_writew,
- &PPC_XCSR_writel,
-};
-
-static CPUReadMemoryFunc *PPC_XCSR_read[] = {
- &PPC_XCSR_readb,
- &PPC_XCSR_readw,
- &PPC_XCSR_readl,
-};
-#endif
-
-/* Fake super-io ports for PREP platform (Intel 82378ZB) */
-typedef struct sysctrl_t {
- m48t59_t *nvram;
- uint8_t state;
- uint8_t syscontrol;
- uint8_t fake_io[2];
- int contiguous_map;
- int endian;
-} sysctrl_t;
-
-enum {
- STATE_HARDFILE = 0x01,
-};
-
-static sysctrl_t *sysctrl;
-
-static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
- sysctrl->fake_io[addr - 0x0398] = val;
-}
-
-static uint32_t PREP_io_read (void *opaque, uint32_t addr)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE,
- sysctrl->fake_io[addr - 0x0398]);
- return sysctrl->fake_io[addr - 0x0398];
-}
-
-static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
- switch (addr) {
- case 0x0092:
- /* Special port 92 */
- /* Check soft reset asked */
- if (val & 0x01) {
- // cpu_interrupt(first_cpu, CPU_INTERRUPT_RESET);
- }
- /* Check LE mode */
- if (val & 0x02) {
- sysctrl->endian = 1;
- } else {
- sysctrl->endian = 0;
- }
- break;
- case 0x0800:
- /* Motorola CPU configuration register : read-only */
- break;
- case 0x0802:
- /* Motorola base module feature register : read-only */
- break;
- case 0x0803:
- /* Motorola base module status register : read-only */
- break;
- case 0x0808:
- /* Hardfile light register */
- if (val & 1)
- sysctrl->state |= STATE_HARDFILE;
- else
- sysctrl->state &= ~STATE_HARDFILE;
- break;
- case 0x0810:
- /* Password protect 1 register */
- if (sysctrl->nvram != NULL)
- m48t59_toggle_lock(sysctrl->nvram, 1);
- break;
- case 0x0812:
- /* Password protect 2 register */
- if (sysctrl->nvram != NULL)
- m48t59_toggle_lock(sysctrl->nvram, 2);
- break;
- case 0x0814:
- /* L2 invalidate register */
- // tlb_flush(first_cpu, 1);
- break;
- case 0x081C:
- /* system control register */
- sysctrl->syscontrol = val & 0x0F;
- break;
- case 0x0850:
- /* I/O map type register */
- sysctrl->contiguous_map = val & 0x01;
- break;
- default:
- printf("ERROR: unaffected IO port write: %04lx => %02x\n",
- (long)addr, val);
- break;
- }
-}
-
-static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
-{
- sysctrl_t *sysctrl = opaque;
- uint32_t retval = 0xFF;
-
- switch (addr) {
- case 0x0092:
- /* Special port 92 */
- retval = 0x00;
- break;
- case 0x0800:
- /* Motorola CPU configuration register */
- retval = 0xEF; /* MPC750 */
- break;
- case 0x0802:
- /* Motorola Base module feature register */
- retval = 0xAD; /* No ESCC, PMC slot neither ethernet */
- break;
- case 0x0803:
- /* Motorola base module status register */
- retval = 0xE0; /* Standard MPC750 */
- break;
- case 0x080C:
- /* Equipment present register:
- * no L2 cache
- * no upgrade processor
- * no cards in PCI slots
- * SCSI fuse is bad
- */
- retval = 0x3C;
- break;
- case 0x0810:
- /* Motorola base module extended feature register */
- retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
- break;
- case 0x0814:
- /* L2 invalidate: don't care */
- break;
- case 0x0818:
- /* Keylock */
- retval = 0x00;
- break;
- case 0x081C:
- /* system control register
- * 7 - 6 / 1 - 0: L2 cache enable
- */
- retval = sysctrl->syscontrol;
- break;
- case 0x0823:
- /* */
- retval = 0x03; /* no L2 cache */
- break;
- case 0x0850:
- /* I/O map type register */
- retval = sysctrl->contiguous_map;
- break;
- default:
- printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
- break;
- }
- PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE, retval);
-
- return retval;
-}
-
-static inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
- target_phys_addr_t addr)
-{
- if (sysctrl->contiguous_map == 0) {
- /* 64 KB contiguous space for IOs */
- addr &= 0xFFFF;
- } else {
- /* 8 MB non-contiguous space for IOs */
- addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7);
- }
-
- return addr;
-}
-
-static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- sysctrl_t *sysctrl = opaque;
-
- addr = prep_IO_address(sysctrl, addr);
- cpu_outb(NULL, addr, value);
-}
-
-static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
-{
- sysctrl_t *sysctrl = opaque;
- uint32_t ret;
-
- addr = prep_IO_address(sysctrl, addr);
- ret = cpu_inb(NULL, addr);
-
- return ret;
-}
-
-static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- sysctrl_t *sysctrl = opaque;
-
- addr = prep_IO_address(sysctrl, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap16(value);
-#endif
- PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
- cpu_outw(NULL, addr, value);
-}
-
-static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
-{
- sysctrl_t *sysctrl = opaque;
- uint32_t ret;
-
- addr = prep_IO_address(sysctrl, addr);
- ret = cpu_inw(NULL, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = bswap16(ret);
-#endif
- PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
-
- return ret;
-}
-
-static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- sysctrl_t *sysctrl = opaque;
-
- addr = prep_IO_address(sysctrl, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap32(value);
-#endif
- PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
- cpu_outl(NULL, addr, value);
-}
-
-static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
-{
- sysctrl_t *sysctrl = opaque;
- uint32_t ret;
-
- addr = prep_IO_address(sysctrl, addr);
- ret = cpu_inl(NULL, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = bswap32(ret);
-#endif
- PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
-
- return ret;
-}
-
-CPUWriteMemoryFunc *PPC_prep_io_write[] = {
- &PPC_prep_io_writeb,
- &PPC_prep_io_writew,
- &PPC_prep_io_writel,
-};
-
-CPUReadMemoryFunc *PPC_prep_io_read[] = {
- &PPC_prep_io_readb,
- &PPC_prep_io_readw,
- &PPC_prep_io_readl,
-};
-
-#define NVRAM_SIZE 0x2000
-
-/* PowerPC PREP hardware initialisation */
-static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- CPUState *env;
- char buf[1024];
- m48t59_t *nvram;
- int PPC_io_memory;
- int linux_boot, i, nb_nics1, bios_size;
- unsigned long bios_offset;
- uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
- ppc_def_t *def;
- PCIBus *pci_bus;
-
- sysctrl = qemu_mallocz(sizeof(sysctrl_t));
- if (sysctrl == NULL)
- return;
-
- linux_boot = (kernel_filename != NULL);
-
- /* init CPUs */
-
- env = cpu_init();
- register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
-
- /* Register CPU as a 604 */
- /* XXX: CPU model (or PVR) should be provided on command line */
- // ppc_find_by_name("604r", &def);
- // ppc_find_by_name("604e", &def);
- ppc_find_by_name("604", &def);
- if (def == NULL) {
- cpu_abort(env, "Unable to find PowerPC CPU definition\n");
- }
- cpu_ppc_register(env, def);
- /* Set time-base frequency to 100 Mhz */
- cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- /* allocate and load BIOS */
- bios_offset = ram_size + vga_ram_size;
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- bios_size = load_image(buf, phys_ram_base + bios_offset);
- if (bios_size < 0 || bios_size > BIOS_SIZE) {
- fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
- exit(1);
- }
- bios_size = (bios_size + 0xfff) & ~0xfff;
- cpu_register_physical_memory((uint32_t)(-bios_size),
- bios_size, bios_offset | IO_MEM_ROM);
-
- if (linux_boot) {
- kernel_base = KERNEL_LOAD_ADDR;
- /* now we can load the kernel */
- kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
- /* load initrd */
- if (initrd_filename) {
- initrd_base = INITRD_LOAD_ADDR;
- initrd_size = load_image(initrd_filename,
- phys_ram_base + initrd_base);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- } else {
- initrd_base = 0;
- initrd_size = 0;
- }
- boot_device = 'm';
- } else {
- kernel_base = 0;
- kernel_size = 0;
- initrd_base = 0;
- initrd_size = 0;
- }
-
- isa_mem_base = 0xc0000000;
- pci_bus = pci_prep_init();
- // pci_bus = i440fx_init();
- /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
- PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,
- PPC_prep_io_write, sysctrl);
- cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
-
- /* init basic PC hardware */
- pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
- vga_ram_size, 0, 0);
- rtc_init(0x70, 8);
- // openpic = openpic_init(0x00000000, 0xF0000000, 1);
- isa_pic = pic_init(pic_irq_request, first_cpu);
- // pit = pit_init(0x40, 0);
-
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
- nb_nics1 = nb_nics;
- if (nb_nics1 > NE2000_NB_MAX)
- nb_nics1 = NE2000_NB_MAX;
- for(i = 0; i < nb_nics1; i++) {
- if (nd_table[0].model == NULL
- || strcmp(nd_table[0].model, "ne2k_isa") == 0) {
- isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
- exit (1);
- }
- }
-
- for(i = 0; i < 2; i++) {
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
- bs_table[2 * i], bs_table[2 * i + 1]);
- }
- kbd_init();
- DMA_init(1);
- // AUD_init();
- // SB16_init();
-
- fdctrl_init(6, 2, 0, 0x3f0, fd_table);
-
- /* Register speaker port */
- register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
- register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
- /* Register fake IO ports for PREP */
- register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
- register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
- /* System control ports */
- register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
- register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
- register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
- register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
- /* PCI intack location */
- PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
- PPC_intack_write, NULL);
- cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
- /* PowerPC control and status register group */
-#if 0
- PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write, NULL);
- cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
-#endif
-
- if (usb_enabled) {
- usb_ohci_init(pci_bus, 3, -1);
- }
-
- nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE, 59);
- if (nvram == NULL)
- return;
- sysctrl->nvram = nvram;
-
- /* Initialise NVRAM */
- PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
- kernel_base, kernel_size,
- kernel_cmdline,
- initrd_base, initrd_size,
- /* XXX: need an option to load a NVRAM image */
- 0,
- graphic_width, graphic_height, graphic_depth);
-
- /* Special port to get debug messages from Open-Firmware */
- register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
-}
-
-QEMUMachine prep_machine = {
- "prep",
- "PowerPC PREP platform",
- ppc_prep_init,
-};
diff --git a/tools/ioemu/hw/prep_pci.c b/tools/ioemu/hw/prep_pci.c
deleted file mode 100644
index 3d93c065ff..0000000000
--- a/tools/ioemu/hw/prep_pci.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * QEMU PREP PCI host
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-typedef uint32_t pci_addr_t;
-#include "pci_host.h"
-
-typedef PCIHostState PREPPCIState;
-
-static void pci_prep_addr_writel(void* opaque, uint32_t addr, uint32_t val)
-{
- PREPPCIState *s = opaque;
- s->config_reg = val;
-}
-
-static uint32_t pci_prep_addr_readl(void* opaque, uint32_t addr)
-{
- PREPPCIState *s = opaque;
- return s->config_reg;
-}
-
-static inline uint32_t PPC_PCIIO_config(target_phys_addr_t addr)
-{
- int i;
-
- for(i = 0; i < 11; i++) {
- if ((addr & (1 << (11 + i))) != 0)
- break;
- }
- return (addr & 0x7ff) | (i << 11);
-}
-
-static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PREPPCIState *s = opaque;
- pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 1);
-}
-
-static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PREPPCIState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 2);
-}
-
-static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PREPPCIState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 4);
-}
-
-static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
-{
- PREPPCIState *s = opaque;
- uint32_t val;
- val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 1);
- return val;
-}
-
-static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
-{
- PREPPCIState *s = opaque;
- uint32_t val;
- val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
-{
- PREPPCIState *s = opaque;
- uint32_t val;
- val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
-static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
- &PPC_PCIIO_writeb,
- &PPC_PCIIO_writew,
- &PPC_PCIIO_writel,
-};
-
-static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
- &PPC_PCIIO_readb,
- &PPC_PCIIO_readw,
- &PPC_PCIIO_readl,
-};
-
-/* Don't know if this matches real hardware, but it agrees with OHW. */
-static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
-{
- return (irq_num + (pci_dev->devfn >> 3)) & 1;
-}
-
-static void prep_set_irq(void *pic, int irq_num, int level)
-{
- pic_set_irq(irq_num ? 11 : 9, level);
-}
-
-PCIBus *pci_prep_init(void)
-{
- PREPPCIState *s;
- PCIDevice *d;
- int PPC_io_memory;
-
- s = qemu_mallocz(sizeof(PREPPCIState));
- s->bus = pci_register_bus(prep_set_irq, prep_map_irq, NULL, 0, 2);
-
- register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
- register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);
-
- register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
- register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
- register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
- register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
- register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
- register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
-
- PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,
- PPC_PCIIO_write, s);
- cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
-
- /* PCI host bridge */
- d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",
- sizeof(PCIDevice), 0, NULL, NULL);
- d->config[0x00] = 0x57; // vendor_id : Motorola
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x01; // device_id : Raven
- d->config[0x03] = 0x48;
- d->config[0x08] = 0x00; // revision
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
- d->config[0x34] = 0x00; // capabilities_pointer
-
- return s->bus;
-}
-
diff --git a/tools/ioemu/hw/ps2.c b/tools/ioemu/hw/ps2.c
deleted file mode 100644
index 3794c60366..0000000000
--- a/tools/ioemu/hw/ps2.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * QEMU PS/2 keyboard/mouse emulation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug PC keyboard */
-//#define DEBUG_KBD
-
-/* debug PC keyboard : only mouse */
-//#define DEBUG_MOUSE
-
-/* Keyboard Commands */
-#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
-#define KBD_CMD_ECHO 0xEE
-#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
-#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
-#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
-#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
-#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
-#define KBD_CMD_RESET 0xFF /* Reset */
-
-/* Keyboard Replies */
-#define KBD_REPLY_POR 0xAA /* Power on reset */
-#define KBD_REPLY_ACK 0xFA /* Command ACK */
-#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
-
-/* Mouse Commands */
-#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
-#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
-#define AUX_SET_RES 0xE8 /* Set resolution */
-#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
-#define AUX_SET_STREAM 0xEA /* Set stream mode */
-#define AUX_POLL 0xEB /* Poll */
-#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
-#define AUX_SET_WRAP 0xEE /* Set wrap mode */
-#define AUX_SET_REMOTE 0xF0 /* Set remote mode */
-#define AUX_GET_TYPE 0xF2 /* Get type */
-#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
-#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
-#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
-#define AUX_SET_DEFAULT 0xF6
-#define AUX_RESET 0xFF /* Reset aux device */
-#define AUX_ACK 0xFA /* Command byte ACK. */
-
-#define MOUSE_STATUS_REMOTE 0x40
-#define MOUSE_STATUS_ENABLED 0x20
-#define MOUSE_STATUS_SCALE21 0x10
-
-#define PS2_QUEUE_SIZE 256
-
-typedef struct {
- uint8_t data[PS2_QUEUE_SIZE];
- int rptr, wptr, count;
-} PS2Queue;
-
-typedef struct {
- PS2Queue queue;
- int32_t write_cmd;
- void (*update_irq)(void *, int);
- void *update_arg;
-} PS2State;
-
-typedef struct {
- PS2State common;
- int scan_enabled;
- /* Qemu uses translated PC scancodes internally. To avoid multiple
- conversions we do the translation (if any) in the PS/2 emulation
- not the keyboard controller. */
- int translate;
-} PS2KbdState;
-
-typedef struct {
- PS2State common;
- uint8_t mouse_status;
- uint8_t mouse_resolution;
- uint8_t mouse_sample_rate;
- uint8_t mouse_wrap;
- uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
- uint8_t mouse_detect_state;
- int mouse_dx; /* current values, needed for 'poll' mode */
- int mouse_dy;
- int mouse_dz;
- uint8_t mouse_buttons;
-} PS2MouseState;
-
-/* Table to convert from PC scancodes to raw scancodes. */
-static const unsigned char ps2_raw_keycode[128] = {
- 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
- 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
- 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
- 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
- 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
- 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
- 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
- 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
-};
-
-void ps2_queue(void *opaque, int b)
-{
- PS2State *s = (PS2State *)opaque;
- PS2Queue *q = &s->queue;
-
- if (q->count >= PS2_QUEUE_SIZE)
- return;
- q->data[q->wptr] = b;
- if (++q->wptr == PS2_QUEUE_SIZE)
- q->wptr = 0;
- q->count++;
- s->update_irq(s->update_arg, 1);
-}
-
-static void ps2_put_keycode(void *opaque, int keycode)
-{
- PS2KbdState *s = opaque;
- if (!s->translate && keycode < 0xe0)
- {
- if (keycode & 0x80)
- ps2_queue(&s->common, 0xf0);
- keycode = ps2_raw_keycode[keycode & 0x7f];
- }
- ps2_queue(&s->common, keycode);
-}
-
-uint32_t ps2_read_data(void *opaque)
-{
- PS2State *s = (PS2State *)opaque;
- PS2Queue *q;
- int val, index;
-
- q = &s->queue;
- if (q->count == 0) {
- /* NOTE: if no data left, we return the last keyboard one
- (needed for EMM386) */
- /* XXX: need a timer to do things correctly */
- index = q->rptr - 1;
- if (index < 0)
- index = PS2_QUEUE_SIZE - 1;
- val = q->data[index];
- } else {
- val = q->data[q->rptr];
- if (++q->rptr == PS2_QUEUE_SIZE)
- q->rptr = 0;
- q->count--;
- /* reading deasserts IRQ */
- s->update_irq(s->update_arg, 0);
- /* reassert IRQs if data left */
- s->update_irq(s->update_arg, q->count != 0);
- }
- return val;
-}
-
-static void ps2_reset_keyboard(PS2KbdState *s)
-{
- s->scan_enabled = 1;
-}
-
-void ps2_write_keyboard(void *opaque, int val)
-{
- PS2KbdState *s = (PS2KbdState *)opaque;
-
- switch(s->common.write_cmd) {
- default:
- case -1:
- switch(val) {
- case 0x00:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case 0x05:
- ps2_queue(&s->common, KBD_REPLY_RESEND);
- break;
- case KBD_CMD_GET_ID:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- ps2_queue(&s->common, 0xab);
- ps2_queue(&s->common, 0x83);
- break;
- case KBD_CMD_ECHO:
- ps2_queue(&s->common, KBD_CMD_ECHO);
- break;
- case KBD_CMD_ENABLE:
- s->scan_enabled = 1;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_SET_LEDS:
- case KBD_CMD_SET_RATE:
- s->common.write_cmd = val;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_RESET_DISABLE:
- ps2_reset_keyboard(s);
- s->scan_enabled = 0;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_RESET_ENABLE:
- ps2_reset_keyboard(s);
- s->scan_enabled = 1;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_RESET:
- ps2_reset_keyboard(s);
- ps2_queue(&s->common, KBD_REPLY_ACK);
- ps2_queue(&s->common, KBD_REPLY_POR);
- break;
- default:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- }
- break;
- case KBD_CMD_SET_LEDS:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- s->common.write_cmd = -1;
- break;
- case KBD_CMD_SET_RATE:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- s->common.write_cmd = -1;
- break;
- }
-}
-
-/* Set the scancode translation mode.
- 0 = raw scancodes.
- 1 = translated scancodes (used by qemu internally). */
-
-void ps2_keyboard_set_translation(void *opaque, int mode)
-{
- PS2KbdState *s = (PS2KbdState *)opaque;
- s->translate = mode;
-}
-
-static void ps2_mouse_send_packet(PS2MouseState *s)
-{
- unsigned int b;
- int dx1, dy1, dz1;
-
- dx1 = s->mouse_dx;
- dy1 = s->mouse_dy;
- dz1 = s->mouse_dz;
- /* XXX: increase range to 8 bits ? */
- if (dx1 > 127)
- dx1 = 127;
- else if (dx1 < -127)
- dx1 = -127;
- if (dy1 > 127)
- dy1 = 127;
- else if (dy1 < -127)
- dy1 = -127;
- b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
- ps2_queue(&s->common, b);
- ps2_queue(&s->common, dx1 & 0xff);
- ps2_queue(&s->common, dy1 & 0xff);
- /* extra byte for IMPS/2 or IMEX */
- switch(s->mouse_type) {
- default:
- break;
- case 3:
- if (dz1 > 127)
- dz1 = 127;
- else if (dz1 < -127)
- dz1 = -127;
- ps2_queue(&s->common, dz1 & 0xff);
- break;
- case 4:
- if (dz1 > 7)
- dz1 = 7;
- else if (dz1 < -7)
- dz1 = -7;
- b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
- ps2_queue(&s->common, b);
- break;
- }
-
- /* update deltas */
- s->mouse_dx -= dx1;
- s->mouse_dy -= dy1;
- s->mouse_dz -= dz1;
-}
-
-static void ps2_mouse_event(void *opaque,
- int dx, int dy, int dz, int buttons_state)
-{
- PS2MouseState *s = opaque;
-
- /* check if deltas are recorded when disabled */
- if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
- return;
-
- s->mouse_dx += dx;
- s->mouse_dy -= dy;
- s->mouse_dz += dz;
- /* XXX: SDL sometimes generates nul events: we delete them */
- if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
- s->mouse_buttons == buttons_state)
- return;
- s->mouse_buttons = buttons_state;
-
- if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
- (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
- for(;;) {
- /* if not remote, send event. Multiple events are sent if
- too big deltas */
- ps2_mouse_send_packet(s);
- if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
- break;
- }
- }
-}
-
-void ps2_write_mouse(void *opaque, int val)
-{
- PS2MouseState *s = (PS2MouseState *)opaque;
-#ifdef DEBUG_MOUSE
- printf("kbd: write mouse 0x%02x\n", val);
-#endif
- switch(s->common.write_cmd) {
- default:
- case -1:
- /* mouse command */
- if (s->mouse_wrap) {
- if (val == AUX_RESET_WRAP) {
- s->mouse_wrap = 0;
- ps2_queue(&s->common, AUX_ACK);
- return;
- } else if (val != AUX_RESET) {
- ps2_queue(&s->common, val);
- return;
- }
- }
- switch(val) {
- case AUX_SET_SCALE11:
- s->mouse_status &= ~MOUSE_STATUS_SCALE21;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_SCALE21:
- s->mouse_status |= MOUSE_STATUS_SCALE21;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_STREAM:
- s->mouse_status &= ~MOUSE_STATUS_REMOTE;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_WRAP:
- s->mouse_wrap = 1;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_REMOTE:
- s->mouse_status |= MOUSE_STATUS_REMOTE;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_GET_TYPE:
- ps2_queue(&s->common, AUX_ACK);
- ps2_queue(&s->common, s->mouse_type);
- break;
- case AUX_SET_RES:
- case AUX_SET_SAMPLE:
- s->common.write_cmd = val;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_GET_SCALE:
- ps2_queue(&s->common, AUX_ACK);
- ps2_queue(&s->common, s->mouse_status);
- ps2_queue(&s->common, s->mouse_resolution);
- ps2_queue(&s->common, s->mouse_sample_rate);
- break;
- case AUX_POLL:
- ps2_queue(&s->common, AUX_ACK);
- ps2_mouse_send_packet(s);
- break;
- case AUX_ENABLE_DEV:
- s->mouse_status |= MOUSE_STATUS_ENABLED;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_DISABLE_DEV:
- s->mouse_status &= ~MOUSE_STATUS_ENABLED;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_DEFAULT:
- s->mouse_sample_rate = 100;
- s->mouse_resolution = 2;
- s->mouse_status = 0;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_RESET:
- s->mouse_sample_rate = 100;
- s->mouse_resolution = 2;
- s->mouse_status = 0;
- s->mouse_type = 0;
- ps2_queue(&s->common, AUX_ACK);
- ps2_queue(&s->common, 0xaa);
- ps2_queue(&s->common, s->mouse_type);
- break;
- default:
- break;
- }
- break;
- case AUX_SET_SAMPLE:
- s->mouse_sample_rate = val;
- /* detect IMPS/2 or IMEX */
- switch(s->mouse_detect_state) {
- default:
- case 0:
- if (val == 200)
- s->mouse_detect_state = 1;
- break;
- case 1:
- if (val == 100)
- s->mouse_detect_state = 2;
- else if (val == 200)
- s->mouse_detect_state = 3;
- else
- s->mouse_detect_state = 0;
- break;
- case 2:
- if (val == 80)
- s->mouse_type = 3; /* IMPS/2 */
- s->mouse_detect_state = 0;
- break;
- case 3:
- if (val == 80)
- s->mouse_type = 4; /* IMEX */
- s->mouse_detect_state = 0;
- break;
- }
- ps2_queue(&s->common, AUX_ACK);
- s->common.write_cmd = -1;
- break;
- case AUX_SET_RES:
- s->mouse_resolution = val;
- ps2_queue(&s->common, AUX_ACK);
- s->common.write_cmd = -1;
- break;
- }
-}
-
-static void ps2_reset(void *opaque)
-{
- PS2State *s = (PS2State *)opaque;
- PS2Queue *q;
- s->write_cmd = -1;
- q = &s->queue;
- q->rptr = 0;
- q->wptr = 0;
- q->count = 0;
-}
-
-static void ps2_common_save (QEMUFile *f, PS2State *s)
-{
- qemu_put_be32s (f, &s->write_cmd);
- qemu_put_be32s (f, &s->queue.rptr);
- qemu_put_be32s (f, &s->queue.wptr);
- qemu_put_be32s (f, &s->queue.count);
- qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
-}
-
-static void ps2_common_load (QEMUFile *f, PS2State *s)
-{
- qemu_get_be32s (f, &s->write_cmd);
- qemu_get_be32s (f, &s->queue.rptr);
- qemu_get_be32s (f, &s->queue.wptr);
- qemu_get_be32s (f, &s->queue.count);
- qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
-}
-
-static void ps2_kbd_save(QEMUFile* f, void* opaque)
-{
- PS2KbdState *s = (PS2KbdState*)opaque;
-
- ps2_common_save (f, &s->common);
- qemu_put_be32s(f, &s->scan_enabled);
- qemu_put_be32s(f, &s->translate);
-}
-
-static void ps2_mouse_save(QEMUFile* f, void* opaque)
-{
- PS2MouseState *s = (PS2MouseState*)opaque;
-
- ps2_common_save (f, &s->common);
- qemu_put_8s(f, &s->mouse_status);
- qemu_put_8s(f, &s->mouse_resolution);
- qemu_put_8s(f, &s->mouse_sample_rate);
- qemu_put_8s(f, &s->mouse_wrap);
- qemu_put_8s(f, &s->mouse_type);
- qemu_put_8s(f, &s->mouse_detect_state);
- qemu_put_be32s(f, &s->mouse_dx);
- qemu_put_be32s(f, &s->mouse_dy);
- qemu_put_be32s(f, &s->mouse_dz);
- qemu_put_8s(f, &s->mouse_buttons);
-}
-
-static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
-{
- PS2KbdState *s = (PS2KbdState*)opaque;
-
- if (version_id != 2)
- return -EINVAL;
-
- ps2_common_load (f, &s->common);
- qemu_get_be32s(f, &s->scan_enabled);
- qemu_get_be32s(f, &s->translate);
- return 0;
-}
-
-static int ps2_mouse_load(QEMUFile* f, void* opaque, int version_id)
-{
- PS2MouseState *s = (PS2MouseState*)opaque;
-
- if (version_id != 2)
- return -EINVAL;
-
- ps2_common_load (f, &s->common);
- qemu_get_8s(f, &s->mouse_status);
- qemu_get_8s(f, &s->mouse_resolution);
- qemu_get_8s(f, &s->mouse_sample_rate);
- qemu_get_8s(f, &s->mouse_wrap);
- qemu_get_8s(f, &s->mouse_type);
- qemu_get_8s(f, &s->mouse_detect_state);
- qemu_get_be32s(f, &s->mouse_dx);
- qemu_get_be32s(f, &s->mouse_dy);
- qemu_get_be32s(f, &s->mouse_dz);
- qemu_get_8s(f, &s->mouse_buttons);
- return 0;
-}
-
-void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
-{
- PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
-
- s->common.update_irq = update_irq;
- s->common.update_arg = update_arg;
- ps2_reset(&s->common);
- register_savevm("ps2kbd", 0, 2, ps2_kbd_save, ps2_kbd_load, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
- qemu_register_reset(ps2_reset, &s->common);
- return s;
-}
-
-void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
-{
- PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
-
- s->common.update_irq = update_irq;
- s->common.update_arg = update_arg;
- ps2_reset(&s->common);
- register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
- qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
- qemu_register_reset(ps2_reset, &s->common);
- return s;
-}
diff --git a/tools/ioemu/hw/pt-msi.c b/tools/ioemu/hw/pt-msi.c
deleted file mode 100644
index 9ac0614915..0000000000
--- a/tools/ioemu/hw/pt-msi.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Jiang Yunhong <yunhong.jiang@intel.com>
- *
- * This file implements direct PCI assignment to a HVM guest
- */
-
-#include "pt-msi.h"
-#include <sys/mman.h>
-
-/* MSI virtuailization functions */
-
-/*
- * setup physical msi, but didn't enable it
- */
-int pt_msi_setup(struct pt_dev *dev)
-{
- int pirq = -1;
-
- if ( !(dev->msi->flags & MSI_FLAG_UNINIT) )
- {
- PT_LOG("setup physical after initialized?? \n");
- return -1;
- }
-
- if ( xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq,
- dev->pci_dev->dev << 3 | dev->pci_dev->func,
- dev->pci_dev->bus, 0, 0) )
- {
- PT_LOG("error map msi\n");
- return -1;
- }
-
- if ( pirq < 0 )
- {
- PT_LOG("invalid pirq number\n");
- return -1;
- }
-
- dev->msi->pirq = pirq;
- PT_LOG("msi mapped with pirq %x\n", pirq);
-
- return 0;
-}
-
-uint32_t __get_msi_gflags(uint32_t data, uint64_t addr)
-{
- uint32_t result = 0;
- int rh, dm, dest_id, deliv_mode, trig_mode;
-
- rh = (addr >> MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
- dm = (addr >> MSI_ADDR_DESTMODE_SHIFT) & 0x1;
- dest_id = (addr >> MSI_TARGET_CPU_SHIFT) & 0xff;
- deliv_mode = (data >> MSI_DATA_DELIVERY_SHIFT) & 0x7;
- trig_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
-
- result |= dest_id | (rh << GFLAGS_SHIFT_RH) | (dm << GFLAGS_SHIFT_DM) | \
- (deliv_mode << GLFAGS_SHIFT_DELIV_MODE) |
- (trig_mode << GLFAGS_SHIFT_TRG_MODE);
-
- return result;
-}
-
-/*
- * Update msi mapping, usually called when MSI enabled,
- * except the first time
- */
-int pt_msi_update(struct pt_dev *d)
-{
- uint8_t gvec = 0;
- uint32_t gflags = 0;
- uint64_t addr = 0;
-
- /* get vector, address, flags info, etc. */
- gvec = d->msi->data & 0xFF;
- addr = (uint64_t)d->msi->addr_hi << 32 | d->msi->addr_lo;
- gflags = __get_msi_gflags(d->msi->data, addr);
-
- PT_LOG("now update msi with pirq %x gvec %x\n", d->msi->pirq, gvec);
- return xc_domain_update_msi_irq(xc_handle, domid, gvec,
- d->msi->pirq, gflags);
-}
-
-/* MSI-X virtulization functions */
-static void mask_physical_msix_entry(struct pt_dev *dev, int entry_nr, int mask)
-{
- void *phys_off;
-
- phys_off = dev->msix->phys_iomem_base + 16 * entry_nr + 12;
- *(uint32_t *)phys_off = mask;
-}
-
-static int pt_msix_update_one(struct pt_dev *dev, int entry_nr)
-{
- struct msix_entry_info *entry = &dev->msix->msix_entry[entry_nr];
- int pirq = entry->pirq;
- int gvec = entry->io_mem[2] & 0xff;
- uint64_t gaddr = *(uint64_t *)&entry->io_mem[0];
- uint32_t gflags = __get_msi_gflags(entry->io_mem[2], gaddr);
- int ret;
-
- if ( !entry->flags )
- return 0;
-
- /* Check if this entry is already mapped */
- if ( entry->pirq == -1 )
- {
- ret = xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq,
- dev->pci_dev->dev << 3 | dev->pci_dev->func,
- dev->pci_dev->bus, entry_nr,
- dev->msix->table_base);
- if ( ret )
- {
- PT_LOG("error map msix entry %x\n", entry_nr);
- return ret;
- }
- entry->pirq = pirq;
- }
-
- PT_LOG("now update msix entry %x with pirq %x gvec %x\n",
- entry_nr, pirq, gvec);
-
- ret = xc_domain_update_msi_irq(xc_handle, domid, gvec, pirq, gflags);
- if ( ret )
- {
- PT_LOG("error update msix irq info for entry %d\n", entry_nr);
- return ret;
- }
-
- entry->flags = 0;
-
- return 0;
-}
-
-int pt_msix_update(struct pt_dev *dev)
-{
- struct pt_msix_info *msix = dev->msix;
- int i;
-
- for ( i = 0; i < msix->total_entries; i++ )
- {
- pt_msix_update_one(dev, i);
- }
-
- return 0;
-}
-
-static void pci_msix_invalid_write(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PT_LOG("invalid write to MSI-X table, \
- only dword access is allowed.\n");
-}
-
-static void pci_msix_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- struct pt_dev *dev = (struct pt_dev *)opaque;
- struct pt_msix_info *msix = dev->msix;
- struct msix_entry_info *entry;
- int entry_nr, offset;
-
- if ( addr % 4 )
- {
- PT_LOG("unaligned dword access to MSI-X table, addr %016lx\n",
- addr);
- return;
- }
-
- entry_nr = (addr - msix->mmio_base_addr) / 16;
- entry = &msix->msix_entry[entry_nr];
- offset = ((addr - msix->mmio_base_addr) % 16) / 4;
-
- if ( offset != 3 && msix->enabled && !(entry->io_mem[3] & 0x1) )
- {
- PT_LOG("can not update msix entry %d since MSI-X is already \
- function now.\n", entry_nr);
- return;
- }
-
- if ( offset != 3 && entry->io_mem[offset] != val )
- entry->flags = 1;
- entry->io_mem[offset] = val;
-
- if ( offset == 3 )
- {
- if ( msix->enabled && !(val & 0x1) )
- pt_msix_update_one(dev, entry_nr);
- mask_physical_msix_entry(dev, entry_nr, entry->io_mem[3] & 0x1);
- }
-}
-
-static CPUWriteMemoryFunc *pci_msix_write[] = {
- pci_msix_invalid_write,
- pci_msix_invalid_write,
- pci_msix_writel
-};
-
-static uint32_t pci_msix_invalid_read(void *opaque, target_phys_addr_t addr)
-{
- PT_LOG("invalid read to MSI-X table, \
- only dword access is allowed.\n");
- return 0;
-}
-
-static uint32_t pci_msix_readl(void *opaque, target_phys_addr_t addr)
-{
- struct pt_dev *dev = (struct pt_dev *)opaque;
- struct pt_msix_info *msix = dev->msix;
- int entry_nr, offset;
-
- if ( addr % 4 )
- {
- PT_LOG("unaligned dword access to MSI-X table, addr %016lx\n",
- addr);
- return 0;
- }
-
- entry_nr = (addr - msix->mmio_base_addr) / 16;
- offset = ((addr - msix->mmio_base_addr) % 16) / 4;
-
- return msix->msix_entry[entry_nr].io_mem[offset];
-}
-
-static CPUReadMemoryFunc *pci_msix_read[] = {
- pci_msix_invalid_read,
- pci_msix_invalid_read,
- pci_msix_readl
-};
-
-int add_msix_mapping(struct pt_dev *dev, int bar_index)
-{
- if ( !(dev->msix && dev->msix->bar_index == bar_index) )
- return 0;
-
- return xc_domain_memory_mapping(xc_handle, domid,
- dev->msix->mmio_base_addr >> XC_PAGE_SHIFT,
- (dev->bases[bar_index].access.maddr
- + dev->msix->table_off) >> XC_PAGE_SHIFT,
- (dev->msix->total_entries * 16
- + XC_PAGE_SIZE -1) >> XC_PAGE_SHIFT,
- DPCI_ADD_MAPPING);
-}
-
-int remove_msix_mapping(struct pt_dev *dev, int bar_index)
-{
- if ( !(dev->msix && dev->msix->bar_index == bar_index) )
- return 0;
-
- dev->msix->mmio_base_addr = dev->bases[bar_index].e_physbase
- + dev->msix->table_off;
-
- cpu_register_physical_memory(dev->msix->mmio_base_addr,
- dev->msix->total_entries * 16,
- dev->msix->mmio_index);
-
- return xc_domain_memory_mapping(xc_handle, domid,
- dev->msix->mmio_base_addr >> XC_PAGE_SHIFT,
- (dev->bases[bar_index].access.maddr
- + dev->msix->table_off) >> XC_PAGE_SHIFT,
- (dev->msix->total_entries * 16
- + XC_PAGE_SIZE -1) >> XC_PAGE_SHIFT,
- DPCI_REMOVE_MAPPING);
-}
-
-int pt_msix_init(struct pt_dev *dev, int pos)
-{
- uint8_t id;
- uint16_t control;
- int i, total_entries, table_off, bar_index;
- struct pci_dev *pd = dev->pci_dev;
-
- id = pci_read_byte(pd, pos + PCI_CAP_LIST_ID);
-
- if ( id != PCI_CAP_ID_MSIX )
- {
- PT_LOG("error id %x pos %x\n", id, pos);
- return -1;
- }
-
- control = pci_read_word(pd, pos + 2);
- total_entries = control & 0x7ff;
- total_entries += 1;
-
- dev->msix = malloc(sizeof(struct pt_msix_info)
- + total_entries*sizeof(struct msix_entry_info));
- if ( !dev->msix )
- {
- PT_LOG("error allocation pt_msix_info\n");
- return -1;
- }
- memset(dev->msix, 0, sizeof(struct pt_msix_info)
- + total_entries*sizeof(struct msix_entry_info));
- dev->msix->total_entries = total_entries;
- for ( i = 0; i < total_entries; i++ )
- dev->msix->msix_entry[i].pirq = -1;
-
- dev->msix->mmio_index =
- cpu_register_io_memory(0, pci_msix_read, pci_msix_write, dev);
-
- table_off = pci_read_long(pd, pos + PCI_MSIX_TABLE);
- bar_index = dev->msix->bar_index = table_off & PCI_MSIX_BIR;
- table_off = dev->msix->table_off = table_off & ~PCI_MSIX_BIR;
- dev->msix->table_base = dev->pci_dev->base_addr[bar_index];
- PT_LOG("get MSI-X table bar base %llx\n",
- (unsigned long long)dev->msix->table_base);
-
- dev->msix->fd = open("/dev/mem", O_RDWR);
- dev->msix->phys_iomem_base = mmap(0, total_entries * 16,
- PROT_WRITE | PROT_READ, MAP_SHARED | MAP_LOCKED,
- dev->msix->fd, dev->msix->table_base + table_off);
- PT_LOG("mapping physical MSI-X table to %lx\n",
- (unsigned long)dev->msix->phys_iomem_base);
- return 0;
-}
-
-void pt_msix_delete(struct pt_dev *dev)
-{
- /* unmap the MSI-X memory mapped register area */
- if (dev->msix->phys_iomem_base)
- {
- PT_LOG("unmapping physical MSI-X table from %lx\n",
- (unsigned long)dev->msix->phys_iomem_base);
- munmap(dev->msix->phys_iomem_base, dev->msix->total_entries * 16);
- }
-
- free(dev->msix);
-}
diff --git a/tools/ioemu/hw/pt-msi.h b/tools/ioemu/hw/pt-msi.h
deleted file mode 100644
index d2f3e11269..0000000000
--- a/tools/ioemu/hw/pt-msi.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef _PT_MSI_H
-#define _PT_MSI_H
-
-#include "vl.h"
-#include "pci/pci.h"
-#include "pass-through.h"
-
-#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
-#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
-
-/* Message Signalled Interrupts registers */
-#define PCI_MSI_FLAGS 2 /* Various flags */
-#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
-#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
-#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
-#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
-#define PCI_MSI_RFU 3 /* Rest of capability flags */
-#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
-#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
-#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
-#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
-
-/* MSI-X */
-#define PCI_MSIX_ENABLE 0x8000
-#define PCI_MSIX_MASK 0x4000
-#define PCI_MSIX_TABSIZE 0x03ff
-#define PCI_MSIX_TABLE 4
-#define PCI_MSIX_PBA 8
-#define PCI_MSIX_BIR 0x7
-
-#define MSI_FLAG_UNINIT 0x1000
-#define PT_MSI_MAPPED 0x2000
-
-#define MSI_DATA_VECTOR_SHIFT 0
-#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
-
-#define MSI_DATA_DELIVERY_SHIFT 8
-#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
-#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
-
-#define MSI_DATA_LEVEL_SHIFT 14
-#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
-#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
-
-#define MSI_DATA_TRIGGER_SHIFT 15
-#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
-#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
-
-/*
- + * Shift/mask fields for APIC-based bus address
- + */
-
-#define MSI_ADDR_HEADER 0xfee00000
-#define MSI_TARGET_CPU_SHIFT 12
-
-#define MSI_ADDR_DESTID_MASK 0xfff0000f
-#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
-
-#define MSI_ADDR_DESTMODE_SHIFT 2
-#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
-#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
-
-#define MSI_ADDR_REDIRECTION_SHIFT 3
-#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
-#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
-
-#define AUTO_ASSIGN -1
-
-/* shift count for gflags */
-#define GFLAGS_SHIFT_DEST_ID 0
-#define GFLAGS_SHIFT_RH 8
-#define GFLAGS_SHIFT_DM 9
-#define GLFAGS_SHIFT_DELIV_MODE 12
-#define GLFAGS_SHIFT_TRG_MODE 15
-
-int
-pt_msi_setup(struct pt_dev *dev);
-
-uint32_t
-__get_msi_gflags(uint32_t data, uint64_t addr);
-
-int
-pt_msi_update(struct pt_dev *d);
-
-int
-pt_msix_update(struct pt_dev *dev);
-
-int
-remove_msix_mapping(struct pt_dev *dev, int bar_index);
-
-int
-add_msix_mapping(struct pt_dev *dev, int bar_index);
-
-int
-pt_msix_init(struct pt_dev *dev, int pos);
-
-void
-pt_msix_delete(struct pt_dev *dev);
-
-#endif
diff --git a/tools/ioemu/hw/realview.c b/tools/ioemu/hw/realview.c
deleted file mode 100644
index ea42705adb..0000000000
--- a/tools/ioemu/hw/realview.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * ARM RealView Baseboard System emulation.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-/* Board init. */
-
-static void realview_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- CPUState *env;
- void *pic;
- void *scsi_hba;
- PCIBus *pci_bus;
- NICInfo *nd;
- int n;
- int done_smc = 0;
-
- env = cpu_init();
- cpu_arm_set_model(env, ARM_CPUID_ARM926);
- //cpu_arm_set_model(env, ARM_CPUID_ARM11MPCORE);
- /* ??? RAM shoud repeat to fill physical memory space. */
- /* SDRAM at address zero. */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- arm_sysctl_init(0x10000000, 0xc1400400);
- pic = arm_pic_init_cpu(env);
- /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
- is nIRQ (there are inconsistencies). However Linux 2.6.17 expects
- GIC1 to be nIRQ and ignores all the others, so do that for now. */
- pic = arm_gic_init(0x10040000, pic, ARM_PIC_CPU_IRQ);
- pl050_init(0x10006000, pic, 20, 0);
- pl050_init(0x10007000, pic, 21, 1);
-
- pl011_init(0x10009000, pic, 12, serial_hds[0]);
- pl011_init(0x1000a000, pic, 13, serial_hds[1]);
- pl011_init(0x1000b000, pic, 14, serial_hds[2]);
- pl011_init(0x1000c000, pic, 15, serial_hds[3]);
-
- /* DMA controller is optional, apparently. */
- pl080_init(0x10030000, pic, 24, 2);
-
- sp804_init(0x10011000, pic, 4);
- sp804_init(0x10012000, pic, 5);
-
- pl110_init(ds, 0x10020000, pic, 23, 1);
-
- pci_bus = pci_vpb_init(pic, 48, 1);
- if (usb_enabled) {
- usb_ohci_init(pci_bus, 3, -1);
- }
- scsi_hba = lsi_scsi_init(pci_bus, -1);
- for (n = 0; n < MAX_DISKS; n++) {
- if (bs_table[n]) {
- lsi_scsi_attach(scsi_hba, bs_table[n], n);
- }
- }
- for(n = 0; n < nb_nics; n++) {
- nd = &nd_table[n];
- if (!nd->model)
- nd->model = done_smc ? "rtl8139" : "smc91c111";
- if (strcmp(nd->model, "smc91c111") == 0) {
- smc91c111_init(nd, 0x4e000000, pic, 28);
- } else {
- pci_nic_init(pci_bus, nd, -1);
- }
- }
-
- /* Memory map for RealView Emulation Baseboard: */
- /* 0x10000000 System registers. */
- /* 0x10001000 System controller. */
- /* 0x10002000 Two-Wire Serial Bus. */
- /* 0x10003000 Reserved. */
- /* 0x10004000 AACI. */
- /* 0x10005000 MCI. */
- /* 0x10006000 KMI0. */
- /* 0x10007000 KMI1. */
- /* 0x10008000 Character LCD. */
- /* 0x10009000 UART0. */
- /* 0x1000a000 UART1. */
- /* 0x1000b000 UART2. */
- /* 0x1000c000 UART3. */
- /* 0x1000d000 SSPI. */
- /* 0x1000e000 SCI. */
- /* 0x1000f000 Reserved. */
- /* 0x10010000 Watchdog. */
- /* 0x10011000 Timer 0+1. */
- /* 0x10012000 Timer 2+3. */
- /* 0x10013000 GPIO 0. */
- /* 0x10014000 GPIO 1. */
- /* 0x10015000 GPIO 2. */
- /* 0x10016000 Reserved. */
- /* 0x10017000 RTC. */
- /* 0x10018000 DMC. */
- /* 0x10019000 PCI controller config. */
- /* 0x10020000 CLCD. */
- /* 0x10030000 DMA Controller. */
- /* 0x10040000 GIC1 (FIQ1). */
- /* 0x10050000 GIC2 (IRQ1). */
- /* 0x10060000 GIC3 (FIQ2). */
- /* 0x10070000 GIC4 (IRQ2). */
- /* 0x10080000 SMC. */
- /* 0x40000000 NOR flash. */
- /* 0x44000000 DoC flash. */
- /* 0x48000000 SRAM. */
- /* 0x4c000000 Configuration flash. */
- /* 0x4e000000 Ethernet. */
- /* 0x4f000000 USB. */
- /* 0x50000000 PISMO. */
- /* 0x54000000 PISMO. */
- /* 0x58000000 PISMO. */
- /* 0x5c000000 PISMO. */
- /* 0x60000000 PCI. */
- /* 0x61000000 PCI Self Config. */
- /* 0x62000000 PCI Config. */
- /* 0x63000000 PCI IO. */
- /* 0x64000000 PCI mem 0. */
- /* 0x68000000 PCI mem 1. */
- /* 0x6c000000 PCI mem 2. */
-
- arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
- initrd_filename, 0x33b);
-}
-
-QEMUMachine realview_machine = {
- "realview",
- "ARM RealView Emulation Baseboard (ARM926EJ-S)",
- realview_init
-};
diff --git a/tools/ioemu/hw/rtl8139.c b/tools/ioemu/hw/rtl8139.c
deleted file mode 100644
index f0414edc91..0000000000
--- a/tools/ioemu/hw/rtl8139.c
+++ /dev/null
@@ -1,3499 +0,0 @@
-/**
- * QEMU RTL8139 emulation
- *
- * Copyright (c) 2006 Igor Kovalenko
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
-
- * Modifications:
- * 2006-Jan-28 Mark Malakanov : TSAD and CSCR implementation (for Windows driver)
- *
- * 2006-Apr-28 Juergen Lock : EEPROM emulation changes for FreeBSD driver
- * HW revision ID changes for FreeBSD driver
- *
- * 2006-Jul-01 Igor Kovalenko : Implemented loopback mode for FreeBSD driver
- * Corrected packet transfer reassembly routine for 8139C+ mode
- * Rearranged debugging print statements
- * Implemented PCI timer interrupt (disabled by default)
- * Implemented Tally Counters, increased VM load/save version
- * Implemented IP/TCP/UDP checksum task offloading
- *
- * 2006-Jul-04 Igor Kovalenko : Implemented TCP segmentation offloading
- * Fixed MTU=1500 for produced ethernet frames
- *
- * 2006-Jul-09 Igor Kovalenko : Fixed TCP header length calculation while processing
- * segmentation offloading
- * Removed slirp.h dependency
- * Added rx/tx buffer reset when enabling rx/tx operation
- */
-
-#include "vl.h"
-
-/* debug RTL8139 card */
-//#define DEBUG_RTL8139 1
-
-#define PCI_FREQUENCY 33000000L
-
-/* debug RTL8139 card C+ mode only */
-//#define DEBUG_RTL8139CP 1
-
-/* Calculate CRCs propoerly on Rx packets */
-#define RTL8139_CALCULATE_RXCRC 1
-
-/* Uncomment to enable on-board timer interrupts */
-//#define RTL8139_ONBOARD_TIMER 1
-
-#if defined(RTL8139_CALCULATE_RXCRC)
-/* For crc32 */
-#include <zlib.h>
-#endif
-
-#define SET_MASKED(input, mask, curr) \
- ( ( (input) & ~(mask) ) | ( (curr) & (mask) ) )
-
-/* arg % size for size which is a power of 2 */
-#define MOD2(input, size) \
- ( ( input ) & ( size - 1 ) )
-
-#if defined (DEBUG_RTL8139)
-# define DEBUG_PRINT(x) do { printf x ; } while (0)
-#else
-# define DEBUG_PRINT(x)
-#endif
-
-/* Symbolic offsets to registers. */
-enum RTL8139_registers {
- MAC0 = 0, /* Ethernet hardware address. */
- MAR0 = 8, /* Multicast filter. */
- TxStatus0 = 0x10,/* Transmit status (Four 32bit registers). C mode only */
- /* Dump Tally Conter control register(64bit). C+ mode only */
- TxAddr0 = 0x20, /* Tx descriptors (also four 32bit). */
- RxBuf = 0x30,
- ChipCmd = 0x37,
- RxBufPtr = 0x38,
- RxBufAddr = 0x3A,
- IntrMask = 0x3C,
- IntrStatus = 0x3E,
- TxConfig = 0x40,
- RxConfig = 0x44,
- Timer = 0x48, /* A general-purpose counter. */
- RxMissed = 0x4C, /* 24 bits valid, write clears. */
- Cfg9346 = 0x50,
- Config0 = 0x51,
- Config1 = 0x52,
- FlashReg = 0x54,
- MediaStatus = 0x58,
- Config3 = 0x59,
- Config4 = 0x5A, /* absent on RTL-8139A */
- HltClk = 0x5B,
- MultiIntr = 0x5C,
- PCIRevisionID = 0x5E,
- TxSummary = 0x60, /* TSAD register. Transmit Status of All Descriptors*/
- BasicModeCtrl = 0x62,
- BasicModeStatus = 0x64,
- NWayAdvert = 0x66,
- NWayLPAR = 0x68,
- NWayExpansion = 0x6A,
- /* Undocumented registers, but required for proper operation. */
- FIFOTMS = 0x70, /* FIFO Control and test. */
- CSCR = 0x74, /* Chip Status and Configuration Register. */
- PARA78 = 0x78,
- PARA7c = 0x7c, /* Magic transceiver parameter register. */
- Config5 = 0xD8, /* absent on RTL-8139A */
- /* C+ mode */
- TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */
- RxMaxSize = 0xDA, /* Max size of an Rx packet (8169 only) */
- CpCmd = 0xE0, /* C+ Command register (C+ mode only) */
- IntrMitigate = 0xE2, /* rx/tx interrupt mitigation control */
- RxRingAddrLO = 0xE4, /* 64-bit start addr of Rx ring */
- RxRingAddrHI = 0xE8, /* 64-bit start addr of Rx ring */
- TxThresh = 0xEC, /* Early Tx threshold */
-};
-
-enum ClearBitMasks {
- MultiIntrClear = 0xF000,
- ChipCmdClear = 0xE2,
- Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
-};
-
-enum ChipCmdBits {
- CmdReset = 0x10,
- CmdRxEnb = 0x08,
- CmdTxEnb = 0x04,
- RxBufEmpty = 0x01,
-};
-
-/* C+ mode */
-enum CplusCmdBits {
- CPlusRxVLAN = 0x0040, /* enable receive VLAN detagging */
- CPlusRxChkSum = 0x0020, /* enable receive checksum offloading */
- CPlusRxEnb = 0x0002,
- CPlusTxEnb = 0x0001,
-};
-
-/* Interrupt register bits, using my own meaningful names. */
-enum IntrStatusBits {
- PCIErr = 0x8000,
- PCSTimeout = 0x4000,
- RxFIFOOver = 0x40,
- RxUnderrun = 0x20,
- RxOverflow = 0x10,
- TxErr = 0x08,
- TxOK = 0x04,
- RxErr = 0x02,
- RxOK = 0x01,
-
- RxAckBits = RxFIFOOver | RxOverflow | RxOK,
-};
-
-enum TxStatusBits {
- TxHostOwns = 0x2000,
- TxUnderrun = 0x4000,
- TxStatOK = 0x8000,
- TxOutOfWindow = 0x20000000,
- TxAborted = 0x40000000,
- TxCarrierLost = 0x80000000,
-};
-enum RxStatusBits {
- RxMulticast = 0x8000,
- RxPhysical = 0x4000,
- RxBroadcast = 0x2000,
- RxBadSymbol = 0x0020,
- RxRunt = 0x0010,
- RxTooLong = 0x0008,
- RxCRCErr = 0x0004,
- RxBadAlign = 0x0002,
- RxStatusOK = 0x0001,
-};
-
-/* Bits in RxConfig. */
-enum rx_mode_bits {
- AcceptErr = 0x20,
- AcceptRunt = 0x10,
- AcceptBroadcast = 0x08,
- AcceptMulticast = 0x04,
- AcceptMyPhys = 0x02,
- AcceptAllPhys = 0x01,
-};
-
-/* Bits in TxConfig. */
-enum tx_config_bits {
-
- /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
- TxIFGShift = 24,
- TxIFG84 = (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */
- TxIFG88 = (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */
- TxIFG92 = (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */
- TxIFG96 = (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */
-
- TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
- TxCRC = (1 << 16), /* DISABLE appending CRC to end of Tx packets */
- TxClearAbt = (1 << 0), /* Clear abort (WO) */
- TxDMAShift = 8, /* DMA burst value (0-7) is shifted this many bits */
- TxRetryShift = 4, /* TXRR value (0-15) is shifted this many bits */
-
- TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
-};
-
-
-/* Transmit Status of All Descriptors (TSAD) Register */
-enum TSAD_bits {
- TSAD_TOK3 = 1<<15, // TOK bit of Descriptor 3
- TSAD_TOK2 = 1<<14, // TOK bit of Descriptor 2
- TSAD_TOK1 = 1<<13, // TOK bit of Descriptor 1
- TSAD_TOK0 = 1<<12, // TOK bit of Descriptor 0
- TSAD_TUN3 = 1<<11, // TUN bit of Descriptor 3
- TSAD_TUN2 = 1<<10, // TUN bit of Descriptor 2
- TSAD_TUN1 = 1<<9, // TUN bit of Descriptor 1
- TSAD_TUN0 = 1<<8, // TUN bit of Descriptor 0
- TSAD_TABT3 = 1<<07, // TABT bit of Descriptor 3
- TSAD_TABT2 = 1<<06, // TABT bit of Descriptor 2
- TSAD_TABT1 = 1<<05, // TABT bit of Descriptor 1
- TSAD_TABT0 = 1<<04, // TABT bit of Descriptor 0
- TSAD_OWN3 = 1<<03, // OWN bit of Descriptor 3
- TSAD_OWN2 = 1<<02, // OWN bit of Descriptor 2
- TSAD_OWN1 = 1<<01, // OWN bit of Descriptor 1
- TSAD_OWN0 = 1<<00, // OWN bit of Descriptor 0
-};
-
-
-/* Bits in Config1 */
-enum Config1Bits {
- Cfg1_PM_Enable = 0x01,
- Cfg1_VPD_Enable = 0x02,
- Cfg1_PIO = 0x04,
- Cfg1_MMIO = 0x08,
- LWAKE = 0x10, /* not on 8139, 8139A */
- Cfg1_Driver_Load = 0x20,
- Cfg1_LED0 = 0x40,
- Cfg1_LED1 = 0x80,
- SLEEP = (1 << 1), /* only on 8139, 8139A */
- PWRDN = (1 << 0), /* only on 8139, 8139A */
-};
-
-/* Bits in Config3 */
-enum Config3Bits {
- Cfg3_FBtBEn = (1 << 0), /* 1 = Fast Back to Back */
- Cfg3_FuncRegEn = (1 << 1), /* 1 = enable CardBus Function registers */
- Cfg3_CLKRUN_En = (1 << 2), /* 1 = enable CLKRUN */
- Cfg3_CardB_En = (1 << 3), /* 1 = enable CardBus registers */
- Cfg3_LinkUp = (1 << 4), /* 1 = wake up on link up */
- Cfg3_Magic = (1 << 5), /* 1 = wake up on Magic Packet (tm) */
- Cfg3_PARM_En = (1 << 6), /* 0 = software can set twister parameters */
- Cfg3_GNTSel = (1 << 7), /* 1 = delay 1 clock from PCI GNT signal */
-};
-
-/* Bits in Config4 */
-enum Config4Bits {
- LWPTN = (1 << 2), /* not on 8139, 8139A */
-};
-
-/* Bits in Config5 */
-enum Config5Bits {
- Cfg5_PME_STS = (1 << 0), /* 1 = PCI reset resets PME_Status */
- Cfg5_LANWake = (1 << 1), /* 1 = enable LANWake signal */
- Cfg5_LDPS = (1 << 2), /* 0 = save power when link is down */
- Cfg5_FIFOAddrPtr = (1 << 3), /* Realtek internal SRAM testing */
- Cfg5_UWF = (1 << 4), /* 1 = accept unicast wakeup frame */
- Cfg5_MWF = (1 << 5), /* 1 = accept multicast wakeup frame */
- Cfg5_BWF = (1 << 6), /* 1 = accept broadcast wakeup frame */
-};
-
-enum RxConfigBits {
- /* rx fifo threshold */
- RxCfgFIFOShift = 13,
- RxCfgFIFONone = (7 << RxCfgFIFOShift),
-
- /* Max DMA burst */
- RxCfgDMAShift = 8,
- RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
-
- /* rx ring buffer length */
- RxCfgRcv8K = 0,
- RxCfgRcv16K = (1 << 11),
- RxCfgRcv32K = (1 << 12),
- RxCfgRcv64K = (1 << 11) | (1 << 12),
-
- /* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
- RxNoWrap = (1 << 7),
-};
-
-/* Twister tuning parameters from RealTek.
- Completely undocumented, but required to tune bad links on some boards. */
-/*
-enum CSCRBits {
- CSCR_LinkOKBit = 0x0400,
- CSCR_LinkChangeBit = 0x0800,
- CSCR_LinkStatusBits = 0x0f000,
- CSCR_LinkDownOffCmd = 0x003c0,
- CSCR_LinkDownCmd = 0x0f3c0,
-*/
-enum CSCRBits {
- CSCR_Testfun = 1<<15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */
- CSCR_LD = 1<<9, /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/
- CSCR_HEART_BIT = 1<<8, /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/
- CSCR_JBEN = 1<<7, /* 1 = enable jabber function. 0 = disable jabber function, def 1*/
- CSCR_F_LINK_100 = 1<<6, /* Used to login force good link in 100Mbps for diagnostic purposes. 1 = DISABLE, 0 = ENABLE. def 1*/
- CSCR_F_Connect = 1<<5, /* Assertion of this bit forces the disconnect function to be bypassed. def 0*/
- CSCR_Con_status = 1<<3, /* This bit indicates the status of the connection. 1 = valid connected link detected; 0 = disconnected link detected. RO def 0*/
- CSCR_Con_status_En = 1<<2, /* Assertion of this bit configures LED1 pin to indicate connection status. def 0*/
- CSCR_PASS_SCR = 1<<0, /* Bypass Scramble, def 0*/
-};
-
-enum Cfg9346Bits {
- Cfg9346_Lock = 0x00,
- Cfg9346_Unlock = 0xC0,
-};
-
-typedef enum {
- CH_8139 = 0,
- CH_8139_K,
- CH_8139A,
- CH_8139A_G,
- CH_8139B,
- CH_8130,
- CH_8139C,
- CH_8100,
- CH_8100B_8139D,
- CH_8101,
-} chip_t;
-
-enum chip_flags {
- HasHltClk = (1 << 0),
- HasLWake = (1 << 1),
-};
-
-#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
- (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
-#define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1)
-
-#define RTL8139_PCI_REVID_8139 0x10
-#define RTL8139_PCI_REVID_8139CPLUS 0x20
-
-#define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139CPLUS
-
-/* Size is 64 * 16bit words */
-#define EEPROM_9346_ADDR_BITS 6
-#define EEPROM_9346_SIZE (1 << EEPROM_9346_ADDR_BITS)
-#define EEPROM_9346_ADDR_MASK (EEPROM_9346_SIZE - 1)
-
-enum Chip9346Operation
-{
- Chip9346_op_mask = 0xc0, /* 10 zzzzzz */
- Chip9346_op_read = 0x80, /* 10 AAAAAA */
- Chip9346_op_write = 0x40, /* 01 AAAAAA D(15)..D(0) */
- Chip9346_op_ext_mask = 0xf0, /* 11 zzzzzz */
- Chip9346_op_write_enable = 0x30, /* 00 11zzzz */
- Chip9346_op_write_all = 0x10, /* 00 01zzzz */
- Chip9346_op_write_disable = 0x00, /* 00 00zzzz */
-};
-
-enum Chip9346Mode
-{
- Chip9346_none = 0,
- Chip9346_enter_command_mode,
- Chip9346_read_command,
- Chip9346_data_read, /* from output register */
- Chip9346_data_write, /* to input register, then to contents at specified address */
- Chip9346_data_write_all, /* to input register, then filling contents */
-};
-
-typedef struct EEprom9346
-{
- uint16_t contents[EEPROM_9346_SIZE];
- int mode;
- uint32_t tick;
- uint8_t address;
- uint16_t input;
- uint16_t output;
-
- uint8_t eecs;
- uint8_t eesk;
- uint8_t eedi;
- uint8_t eedo;
-} EEprom9346;
-
-typedef struct RTL8139TallyCounters
-{
- /* Tally counters */
- uint64_t TxOk;
- uint64_t RxOk;
- uint64_t TxERR;
- uint32_t RxERR;
- uint16_t MissPkt;
- uint16_t FAE;
- uint32_t Tx1Col;
- uint32_t TxMCol;
- uint64_t RxOkPhy;
- uint64_t RxOkBrd;
- uint32_t RxOkMul;
- uint16_t TxAbt;
- uint16_t TxUndrn;
-} RTL8139TallyCounters;
-
-/* Clears all tally counters */
-static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters);
-
-/* Writes tally counters to specified physical memory address */
-static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters);
-
-/* Loads values of tally counters from VM state file */
-static void RTL8139TallyCounters_load(QEMUFile* f, RTL8139TallyCounters *tally_counters);
-
-/* Saves values of tally counters to VM state file */
-static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters);
-
-typedef struct RTL8139State {
- uint8_t phys[8]; /* mac address */
- uint8_t mult[8]; /* multicast mask array */
-
- uint32_t TxStatus[4]; /* TxStatus0 in C mode*/ /* also DTCCR[0] and DTCCR[1] in C+ mode */
- uint32_t TxAddr[4]; /* TxAddr0 */
- uint32_t RxBuf; /* Receive buffer */
- uint32_t RxBufferSize;/* internal variable, receive ring buffer size in C mode */
- uint32_t RxBufPtr;
- uint32_t RxBufAddr;
-
- uint16_t IntrStatus;
- uint16_t IntrMask;
-
- uint32_t TxConfig;
- uint32_t RxConfig;
- uint32_t RxMissed;
-
- uint16_t CSCR;
-
- uint8_t Cfg9346;
- uint8_t Config0;
- uint8_t Config1;
- uint8_t Config3;
- uint8_t Config4;
- uint8_t Config5;
-
- uint8_t clock_enabled;
- uint8_t bChipCmdState;
-
- uint16_t MultiIntr;
-
- uint16_t BasicModeCtrl;
- uint16_t BasicModeStatus;
- uint16_t NWayAdvert;
- uint16_t NWayLPAR;
- uint16_t NWayExpansion;
-
- uint16_t CpCmd;
- uint8_t TxThresh;
-
- int irq;
- PCIDevice *pci_dev;
- VLANClientState *vc;
- uint8_t macaddr[6];
- int rtl8139_mmio_io_addr;
-
- /* C ring mode */
- uint32_t currTxDesc;
-
- /* C+ mode */
- uint32_t currCPlusRxDesc;
- uint32_t currCPlusTxDesc;
-
- uint32_t RxRingAddrLO;
- uint32_t RxRingAddrHI;
-
- EEprom9346 eeprom;
-
- uint32_t TCTR;
- uint32_t TimerInt;
- int64_t TCTR_base;
-
- /* Tally counters */
- RTL8139TallyCounters tally_counters;
-
- /* Non-persistent data */
- uint8_t *cplus_txbuffer;
- int cplus_txbuffer_len;
- int cplus_txbuffer_offset;
-
- /* PCI interrupt timer */
- QEMUTimer *timer;
-
-} RTL8139State;
-
-void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
-{
- DEBUG_PRINT(("RTL8139: eeprom command 0x%02x\n", command));
-
- switch (command & Chip9346_op_mask)
- {
- case Chip9346_op_read:
- {
- eeprom->address = command & EEPROM_9346_ADDR_MASK;
- eeprom->output = eeprom->contents[eeprom->address];
- eeprom->eedo = 0;
- eeprom->tick = 0;
- eeprom->mode = Chip9346_data_read;
- DEBUG_PRINT(("RTL8139: eeprom read from address 0x%02x data=0x%04x\n",
- eeprom->address, eeprom->output));
- }
- break;
-
- case Chip9346_op_write:
- {
- eeprom->address = command & EEPROM_9346_ADDR_MASK;
- eeprom->input = 0;
- eeprom->tick = 0;
- eeprom->mode = Chip9346_none; /* Chip9346_data_write */
- DEBUG_PRINT(("RTL8139: eeprom begin write to address 0x%02x\n",
- eeprom->address));
- }
- break;
- default:
- eeprom->mode = Chip9346_none;
- switch (command & Chip9346_op_ext_mask)
- {
- case Chip9346_op_write_enable:
- DEBUG_PRINT(("RTL8139: eeprom write enabled\n"));
- break;
- case Chip9346_op_write_all:
- DEBUG_PRINT(("RTL8139: eeprom begin write all\n"));
- break;
- case Chip9346_op_write_disable:
- DEBUG_PRINT(("RTL8139: eeprom write disabled\n"));
- break;
- }
- break;
- }
-}
-
-void prom9346_shift_clock(EEprom9346 *eeprom)
-{
- int bit = eeprom->eedi?1:0;
-
- ++ eeprom->tick;
-
- DEBUG_PRINT(("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, eeprom->eedo));
-
- switch (eeprom->mode)
- {
- case Chip9346_enter_command_mode:
- if (bit)
- {
- eeprom->mode = Chip9346_read_command;
- eeprom->tick = 0;
- eeprom->input = 0;
- DEBUG_PRINT(("eeprom: +++ synchronized, begin command read\n"));
- }
- break;
-
- case Chip9346_read_command:
- eeprom->input = (eeprom->input << 1) | (bit & 1);
- if (eeprom->tick == 8)
- {
- prom9346_decode_command(eeprom, eeprom->input & 0xff);
- }
- break;
-
- case Chip9346_data_read:
- eeprom->eedo = (eeprom->output & 0x8000)?1:0;
- eeprom->output <<= 1;
- if (eeprom->tick == 16)
- {
-#if 1
- // the FreeBSD drivers (rl and re) don't explicitly toggle
- // CS between reads (or does setting Cfg9346 to 0 count too?),
- // so we need to enter wait-for-command state here
- eeprom->mode = Chip9346_enter_command_mode;
- eeprom->input = 0;
- eeprom->tick = 0;
-
- DEBUG_PRINT(("eeprom: +++ end of read, awaiting next command\n"));
-#else
- // original behaviour
- ++eeprom->address;
- eeprom->address &= EEPROM_9346_ADDR_MASK;
- eeprom->output = eeprom->contents[eeprom->address];
- eeprom->tick = 0;
-
- DEBUG_PRINT(("eeprom: +++ read next address 0x%02x data=0x%04x\n",
- eeprom->address, eeprom->output));
-#endif
- }
- break;
-
- case Chip9346_data_write:
- eeprom->input = (eeprom->input << 1) | (bit & 1);
- if (eeprom->tick == 16)
- {
- DEBUG_PRINT(("RTL8139: eeprom write to address 0x%02x data=0x%04x\n",
- eeprom->address, eeprom->input));
-
- eeprom->contents[eeprom->address] = eeprom->input;
- eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */
- eeprom->tick = 0;
- eeprom->input = 0;
- }
- break;
-
- case Chip9346_data_write_all:
- eeprom->input = (eeprom->input << 1) | (bit & 1);
- if (eeprom->tick == 16)
- {
- int i;
- for (i = 0; i < EEPROM_9346_SIZE; i++)
- {
- eeprom->contents[i] = eeprom->input;
- }
- DEBUG_PRINT(("RTL8139: eeprom filled with data=0x%04x\n",
- eeprom->input));
-
- eeprom->mode = Chip9346_enter_command_mode;
- eeprom->tick = 0;
- eeprom->input = 0;
- }
- break;
-
- default:
- break;
- }
-}
-
-int prom9346_get_wire(RTL8139State *s)
-{
- EEprom9346 *eeprom = &s->eeprom;
- if (!eeprom->eecs)
- return 0;
-
- return eeprom->eedo;
-}
-
-void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi)
-{
- EEprom9346 *eeprom = &s->eeprom;
- uint8_t old_eecs = eeprom->eecs;
- uint8_t old_eesk = eeprom->eesk;
-
- eeprom->eecs = eecs;
- eeprom->eesk = eesk;
- eeprom->eedi = eedi;
-
- DEBUG_PRINT(("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n",
- eeprom->eecs, eeprom->eesk, eeprom->eedi, eeprom->eedo));
-
- if (!old_eecs && eecs)
- {
- /* Synchronize start */
- eeprom->tick = 0;
- eeprom->input = 0;
- eeprom->output = 0;
- eeprom->mode = Chip9346_enter_command_mode;
-
- DEBUG_PRINT(("=== eeprom: begin access, enter command mode\n"));
- }
-
- if (!eecs)
- {
- DEBUG_PRINT(("=== eeprom: end access\n"));
- return;
- }
-
- if (!old_eesk && eesk)
- {
- /* SK front rules */
- prom9346_shift_clock(eeprom);
- }
-}
-
-static void rtl8139_update_irq(RTL8139State *s)
-{
- int isr;
- isr = (s->IntrStatus & s->IntrMask) & 0xffff;
-
- DEBUG_PRINT(("RTL8139: Set IRQ line %d to %d (%04x %04x)\n",
- s->irq, isr ? 1 : 0, s->IntrStatus, s->IntrMask));
-
- if (s->irq == 16) {
- /* PCI irq */
- pci_set_irq(s->pci_dev, 0, (isr != 0));
- } else {
- /* ISA irq */
- pic_set_irq(s->irq, (isr != 0));
- }
-}
-
-#define POLYNOMIAL 0x04c11db6
-
-/* From FreeBSD */
-/* XXX: optimize */
-static int compute_mcast_idx(const uint8_t *ep)
-{
- uint32_t crc;
- int carry, i, j;
- uint8_t b;
-
- crc = 0xffffffff;
- for (i = 0; i < 6; i++) {
- b = *ep++;
- for (j = 0; j < 8; j++) {
- carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
- crc <<= 1;
- b >>= 1;
- if (carry)
- crc = ((crc ^ POLYNOMIAL) | carry);
- }
- }
- return (crc >> 26);
-}
-
-static int rtl8139_RxWrap(RTL8139State *s)
-{
- /* wrapping enabled; assume 1.5k more buffer space if size < 65536 */
- return (s->RxConfig & (1 << 7));
-}
-
-static int rtl8139_receiver_enabled(RTL8139State *s)
-{
- return s->bChipCmdState & CmdRxEnb;
-}
-
-static int rtl8139_transmitter_enabled(RTL8139State *s)
-{
- return s->bChipCmdState & CmdTxEnb;
-}
-
-static int rtl8139_cp_receiver_enabled(RTL8139State *s)
-{
- return s->CpCmd & CPlusRxEnb;
-}
-
-static int rtl8139_cp_transmitter_enabled(RTL8139State *s)
-{
- return s->CpCmd & CPlusTxEnb;
-}
-
-static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
-{
- if (s->RxBufAddr + size > s->RxBufferSize)
- {
- int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize);
-
- /* write packet data */
- if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s)))
- {
- DEBUG_PRINT((">>> RTL8139: rx packet wrapped in buffer at %d\n", size-wrapped));
-
- if (size > wrapped)
- {
- cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
- buf, size-wrapped );
- }
-
- /* reset buffer pointer */
- s->RxBufAddr = 0;
-
- cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
- buf + (size-wrapped), wrapped );
-
- s->RxBufAddr = wrapped;
-
- return;
- }
- }
-
- /* non-wrapping path or overwrapping enabled */
- cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size );
-
- s->RxBufAddr += size;
-}
-
-#define MIN_BUF_SIZE 60
-static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
-{
-#if TARGET_PHYS_ADDR_BITS > 32
- return low | ((target_phys_addr_t)high << 32);
-#else
- return low;
-#endif
-}
-
-static int rtl8139_can_receive(void *opaque)
-{
- RTL8139State *s = opaque;
- int avail;
-
- /* Recieve (drop) packets if card is disabled. */
- if (!s->clock_enabled)
- return 1;
- if (!rtl8139_receiver_enabled(s))
- return 1;
-
- if (rtl8139_cp_receiver_enabled(s)) {
- /* ??? Flow control not implemented in c+ mode.
- This is a hack to work around slirp deficiencies anyway. */
- return 1;
- } else {
- avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
- s->RxBufferSize);
- return (avail == 0 || avail >= 1514);
- }
-}
-
-static void rtl8139_do_receive(void *opaque, const uint8_t *buf, int size, int do_interrupt)
-{
- RTL8139State *s = opaque;
-
- uint32_t packet_header = 0;
-
- uint8_t buf1[60];
- static const uint8_t broadcast_macaddr[6] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- DEBUG_PRINT((">>> RTL8139: received len=%d\n", size));
-
- /* test if board clock is stopped */
- if (!s->clock_enabled)
- {
- DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
- return;
- }
-
- /* first check if receiver is enabled */
-
- if (!rtl8139_receiver_enabled(s))
- {
- DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
- return;
- }
-
- /* XXX: check this */
- if (s->RxConfig & AcceptAllPhys) {
- /* promiscuous: receive all */
- DEBUG_PRINT((">>> RTL8139: packet received in promiscuous mode\n"));
-
- } else {
- if (!memcmp(buf, broadcast_macaddr, 6)) {
- /* broadcast address */
- if (!(s->RxConfig & AcceptBroadcast))
- {
- DEBUG_PRINT((">>> RTL8139: broadcast packet rejected\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxERR;
-
- return;
- }
-
- packet_header |= RxBroadcast;
-
- DEBUG_PRINT((">>> RTL8139: broadcast packet received\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxOkBrd;
-
- } else if (buf[0] & 0x01) {
- /* multicast */
- if (!(s->RxConfig & AcceptMulticast))
- {
- DEBUG_PRINT((">>> RTL8139: multicast packet rejected\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxERR;
-
- return;
- }
-
- int mcast_idx = compute_mcast_idx(buf);
-
- if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
- {
- DEBUG_PRINT((">>> RTL8139: multicast address mismatch\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxERR;
-
- return;
- }
-
- packet_header |= RxMulticast;
-
- DEBUG_PRINT((">>> RTL8139: multicast packet received\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxOkMul;
-
- } else if (s->phys[0] == buf[0] &&
- s->phys[1] == buf[1] &&
- s->phys[2] == buf[2] &&
- s->phys[3] == buf[3] &&
- s->phys[4] == buf[4] &&
- s->phys[5] == buf[5]) {
- /* match */
- if (!(s->RxConfig & AcceptMyPhys))
- {
- DEBUG_PRINT((">>> RTL8139: rejecting physical address matching packet\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxERR;
-
- return;
- }
-
- packet_header |= RxPhysical;
-
- DEBUG_PRINT((">>> RTL8139: physical address matching packet received\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxOkPhy;
-
- } else {
-
- DEBUG_PRINT((">>> RTL8139: unknown packet\n"));
-
- /* update tally counter */
- ++s->tally_counters.RxERR;
-
- return;
- }
- }
-
- /* if too small buffer, then expand it */
- if (size < MIN_BUF_SIZE) {
- memcpy(buf1, buf, size);
- memset(buf1 + size, 0, MIN_BUF_SIZE - size);
- buf = buf1;
- size = MIN_BUF_SIZE;
- }
-
- if (rtl8139_cp_receiver_enabled(s))
- {
- DEBUG_PRINT(("RTL8139: in C+ Rx mode ================\n"));
-
- /* begin C+ receiver mode */
-
-/* w0 ownership flag */
-#define CP_RX_OWN (1<<31)
-/* w0 end of ring flag */
-#define CP_RX_EOR (1<<30)
-/* w0 bits 0...12 : buffer size */
-#define CP_RX_BUFFER_SIZE_MASK ((1<<13) - 1)
-/* w1 tag available flag */
-#define CP_RX_TAVA (1<<16)
-/* w1 bits 0...15 : VLAN tag */
-#define CP_RX_VLAN_TAG_MASK ((1<<16) - 1)
-/* w2 low 32bit of Rx buffer ptr */
-/* w3 high 32bit of Rx buffer ptr */
-
- int descriptor = s->currCPlusRxDesc;
- target_phys_addr_t cplus_rx_ring_desc;
-
- cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);
- cplus_rx_ring_desc += 16 * descriptor;
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from host memory at %08x %08x = %016" PRIx64 "\n",
- descriptor, s->RxRingAddrHI, s->RxRingAddrLO, (uint64_t)cplus_rx_ring_desc));
-
- uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;
-
- cpu_physical_memory_read(cplus_rx_ring_desc, (uint8_t *)&val, 4);
- rxdw0 = le32_to_cpu(val);
- cpu_physical_memory_read(cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
- rxdw1 = le32_to_cpu(val);
- cpu_physical_memory_read(cplus_rx_ring_desc+8, (uint8_t *)&val, 4);
- rxbufLO = le32_to_cpu(val);
- cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
- rxbufHI = le32_to_cpu(val);
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",
- descriptor,
- rxdw0, rxdw1, rxbufLO, rxbufHI));
-
- if (!(rxdw0 & CP_RX_OWN))
- {
- DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d is owned by host\n", descriptor));
-
- s->IntrStatus |= RxOverflow;
- ++s->RxMissed;
-
- /* update tally counter */
- ++s->tally_counters.RxERR;
- ++s->tally_counters.MissPkt;
-
- rtl8139_update_irq(s);
- return;
- }
-
- uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;
-
- /* TODO: scatter the packet over available receive ring descriptors space */
-
- if (size+4 > rx_space)
- {
- DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d size %d received %d + 4\n",
- descriptor, rx_space, size));
-
- s->IntrStatus |= RxOverflow;
- ++s->RxMissed;
-
- /* update tally counter */
- ++s->tally_counters.RxERR;
- ++s->tally_counters.MissPkt;
-
- rtl8139_update_irq(s);
- return;
- }
-
- target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
-
- /* receive/copy to target memory */
- cpu_physical_memory_write( rx_addr, buf, size );
-
- if (s->CpCmd & CPlusRxChkSum)
- {
- /* do some packet checksumming */
- }
-
- /* write checksum */
-#if defined (RTL8139_CALCULATE_RXCRC)
- val = cpu_to_le32(crc32(0, buf, size));
-#else
- val = 0;
-#endif
- cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4);
-
-/* first segment of received packet flag */
-#define CP_RX_STATUS_FS (1<<29)
-/* last segment of received packet flag */
-#define CP_RX_STATUS_LS (1<<28)
-/* multicast packet flag */
-#define CP_RX_STATUS_MAR (1<<26)
-/* physical-matching packet flag */
-#define CP_RX_STATUS_PAM (1<<25)
-/* broadcast packet flag */
-#define CP_RX_STATUS_BAR (1<<24)
-/* runt packet flag */
-#define CP_RX_STATUS_RUNT (1<<19)
-/* crc error flag */
-#define CP_RX_STATUS_CRC (1<<18)
-/* IP checksum error flag */
-#define CP_RX_STATUS_IPF (1<<15)
-/* UDP checksum error flag */
-#define CP_RX_STATUS_UDPF (1<<14)
-/* TCP checksum error flag */
-#define CP_RX_STATUS_TCPF (1<<13)
-
- /* transfer ownership to target */
- rxdw0 &= ~CP_RX_OWN;
-
- /* set first segment bit */
- rxdw0 |= CP_RX_STATUS_FS;
-
- /* set last segment bit */
- rxdw0 |= CP_RX_STATUS_LS;
-
- /* set received packet type flags */
- if (packet_header & RxBroadcast)
- rxdw0 |= CP_RX_STATUS_BAR;
- if (packet_header & RxMulticast)
- rxdw0 |= CP_RX_STATUS_MAR;
- if (packet_header & RxPhysical)
- rxdw0 |= CP_RX_STATUS_PAM;
-
- /* set received size */
- rxdw0 &= ~CP_RX_BUFFER_SIZE_MASK;
- rxdw0 |= (size+4);
-
- /* reset VLAN tag flag */
- rxdw1 &= ~CP_RX_TAVA;
-
- /* update ring data */
- val = cpu_to_le32(rxdw0);
- cpu_physical_memory_write(cplus_rx_ring_desc, (uint8_t *)&val, 4);
- val = cpu_to_le32(rxdw1);
- cpu_physical_memory_write(cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
-
- /* update tally counter */
- ++s->tally_counters.RxOk;
-
- /* seek to next Rx descriptor */
- if (rxdw0 & CP_RX_EOR)
- {
- s->currCPlusRxDesc = 0;
- }
- else
- {
- ++s->currCPlusRxDesc;
- }
-
- DEBUG_PRINT(("RTL8139: done C+ Rx mode ----------------\n"));
-
- }
- else
- {
- DEBUG_PRINT(("RTL8139: in ring Rx mode ================\n"));
-
- /* begin ring receiver mode */
- int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize);
-
- /* if receiver buffer is empty then avail == 0 */
-
- if (avail != 0 && size + 8 >= avail)
- {
- DEBUG_PRINT(("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n",
- s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8));
-
- s->IntrStatus |= RxOverflow;
- ++s->RxMissed;
- rtl8139_update_irq(s);
- return;
- }
-
- packet_header |= RxStatusOK;
-
- packet_header |= (((size+4) << 16) & 0xffff0000);
-
- /* write header */
- uint32_t val = cpu_to_le32(packet_header);
-
- rtl8139_write_buffer(s, (uint8_t *)&val, 4);
-
- rtl8139_write_buffer(s, buf, size);
-
- /* write checksum */
-#if defined (RTL8139_CALCULATE_RXCRC)
- val = cpu_to_le32(crc32(0, buf, size));
-#else
- val = 0;
-#endif
-
- rtl8139_write_buffer(s, (uint8_t *)&val, 4);
-
- /* correct buffer write pointer */
- s->RxBufAddr = MOD2((s->RxBufAddr + 3) & ~0x3, s->RxBufferSize);
-
- /* now we can signal we have received something */
-
- DEBUG_PRINT((" received: rx buffer length %d head 0x%04x read 0x%04x\n",
- s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
- }
-
- s->IntrStatus |= RxOK;
-
- if (do_interrupt)
- {
- rtl8139_update_irq(s);
- }
-}
-
-static void rtl8139_receive(void *opaque, const uint8_t *buf, int size)
-{
- rtl8139_do_receive(opaque, buf, size, 1);
-}
-
-static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
-{
- s->RxBufferSize = bufferSize;
- s->RxBufPtr = 0;
- s->RxBufAddr = 0;
-}
-
-static void rtl8139_reset(RTL8139State *s)
-{
- int i;
-
- /* restore MAC address */
- memcpy(s->phys, s->macaddr, 6);
-
- /* reset interrupt mask */
- s->IntrStatus = 0;
- s->IntrMask = 0;
-
- rtl8139_update_irq(s);
-
- /* prepare eeprom */
- s->eeprom.contents[0] = 0x8129;
-#if 1
- // PCI vendor and device ID should be mirrored here
- s->eeprom.contents[1] = 0x10ec;
- s->eeprom.contents[2] = 0x8139;
-#endif
- memcpy(&s->eeprom.contents[7], s->macaddr, 6);
-
- /* mark all status registers as owned by host */
- for (i = 0; i < 4; ++i)
- {
- s->TxStatus[i] = TxHostOwns;
- }
-
- s->currTxDesc = 0;
- s->currCPlusRxDesc = 0;
- s->currCPlusTxDesc = 0;
-
- s->RxRingAddrLO = 0;
- s->RxRingAddrHI = 0;
-
- s->RxBuf = 0;
-
- rtl8139_reset_rxring(s, 8192);
-
- /* ACK the reset */
- s->TxConfig = 0;
-
-#if 0
-// s->TxConfig |= HW_REVID(1, 0, 0, 0, 0, 0, 0); // RTL-8139 HasHltClk
- s->clock_enabled = 0;
-#else
- s->TxConfig |= HW_REVID(1, 1, 1, 0, 1, 1, 0); // RTL-8139C+ HasLWake
- s->clock_enabled = 1;
-#endif
-
- s->bChipCmdState = CmdReset; /* RxBufEmpty bit is calculated on read from ChipCmd */;
-
- /* set initial state data */
- s->Config0 = 0x0; /* No boot ROM */
- s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */
- s->Config3 = 0x1; /* fast back-to-back compatible */
- s->Config5 = 0x0;
-
- s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD;
-
- s->CpCmd = 0x0; /* reset C+ mode */
-
-// s->BasicModeCtrl = 0x3100; // 100Mbps, full duplex, autonegotiation
-// s->BasicModeCtrl = 0x2100; // 100Mbps, full duplex
- s->BasicModeCtrl = 0x1000; // autonegotiation
-
- s->BasicModeStatus = 0x7809;
- //s->BasicModeStatus |= 0x0040; /* UTP medium */
- s->BasicModeStatus |= 0x0020; /* autonegotiation completed */
- s->BasicModeStatus |= 0x0004; /* link is up */
-
- s->NWayAdvert = 0x05e1; /* all modes, full duplex */
- s->NWayLPAR = 0x05e1; /* all modes, full duplex */
- s->NWayExpansion = 0x0001; /* autonegotiation supported */
-
- /* also reset timer and disable timer interrupt */
- s->TCTR = 0;
- s->TimerInt = 0;
- s->TCTR_base = 0;
-
- /* reset tally counters */
- RTL8139TallyCounters_clear(&s->tally_counters);
-}
-
-void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters)
-{
- counters->TxOk = 0;
- counters->RxOk = 0;
- counters->TxERR = 0;
- counters->RxERR = 0;
- counters->MissPkt = 0;
- counters->FAE = 0;
- counters->Tx1Col = 0;
- counters->TxMCol = 0;
- counters->RxOkPhy = 0;
- counters->RxOkBrd = 0;
- counters->RxOkMul = 0;
- counters->TxAbt = 0;
- counters->TxUndrn = 0;
-}
-
-static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters)
-{
- uint16_t val16;
- uint32_t val32;
- uint64_t val64;
-
- val64 = cpu_to_le64(tally_counters->TxOk);
- cpu_physical_memory_write(tc_addr + 0, (uint8_t *)&val64, 8);
-
- val64 = cpu_to_le64(tally_counters->RxOk);
- cpu_physical_memory_write(tc_addr + 8, (uint8_t *)&val64, 8);
-
- val64 = cpu_to_le64(tally_counters->TxERR);
- cpu_physical_memory_write(tc_addr + 16, (uint8_t *)&val64, 8);
-
- val32 = cpu_to_le32(tally_counters->RxERR);
- cpu_physical_memory_write(tc_addr + 24, (uint8_t *)&val32, 4);
-
- val16 = cpu_to_le16(tally_counters->MissPkt);
- cpu_physical_memory_write(tc_addr + 28, (uint8_t *)&val16, 2);
-
- val16 = cpu_to_le16(tally_counters->FAE);
- cpu_physical_memory_write(tc_addr + 30, (uint8_t *)&val16, 2);
-
- val32 = cpu_to_le32(tally_counters->Tx1Col);
- cpu_physical_memory_write(tc_addr + 32, (uint8_t *)&val32, 4);
-
- val32 = cpu_to_le32(tally_counters->TxMCol);
- cpu_physical_memory_write(tc_addr + 36, (uint8_t *)&val32, 4);
-
- val64 = cpu_to_le64(tally_counters->RxOkPhy);
- cpu_physical_memory_write(tc_addr + 40, (uint8_t *)&val64, 8);
-
- val64 = cpu_to_le64(tally_counters->RxOkBrd);
- cpu_physical_memory_write(tc_addr + 48, (uint8_t *)&val64, 8);
-
- val32 = cpu_to_le32(tally_counters->RxOkMul);
- cpu_physical_memory_write(tc_addr + 56, (uint8_t *)&val32, 4);
-
- val16 = cpu_to_le16(tally_counters->TxAbt);
- cpu_physical_memory_write(tc_addr + 60, (uint8_t *)&val16, 2);
-
- val16 = cpu_to_le16(tally_counters->TxUndrn);
- cpu_physical_memory_write(tc_addr + 62, (uint8_t *)&val16, 2);
-}
-
-/* Loads values of tally counters from VM state file */
-static void RTL8139TallyCounters_load(QEMUFile* f, RTL8139TallyCounters *tally_counters)
-{
- qemu_get_be64s(f, &tally_counters->TxOk);
- qemu_get_be64s(f, &tally_counters->RxOk);
- qemu_get_be64s(f, &tally_counters->TxERR);
- qemu_get_be32s(f, &tally_counters->RxERR);
- qemu_get_be16s(f, &tally_counters->MissPkt);
- qemu_get_be16s(f, &tally_counters->FAE);
- qemu_get_be32s(f, &tally_counters->Tx1Col);
- qemu_get_be32s(f, &tally_counters->TxMCol);
- qemu_get_be64s(f, &tally_counters->RxOkPhy);
- qemu_get_be64s(f, &tally_counters->RxOkBrd);
- qemu_get_be32s(f, &tally_counters->RxOkMul);
- qemu_get_be16s(f, &tally_counters->TxAbt);
- qemu_get_be16s(f, &tally_counters->TxUndrn);
-}
-
-/* Saves values of tally counters to VM state file */
-static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters)
-{
- qemu_put_be64s(f, &tally_counters->TxOk);
- qemu_put_be64s(f, &tally_counters->RxOk);
- qemu_put_be64s(f, &tally_counters->TxERR);
- qemu_put_be32s(f, &tally_counters->RxERR);
- qemu_put_be16s(f, &tally_counters->MissPkt);
- qemu_put_be16s(f, &tally_counters->FAE);
- qemu_put_be32s(f, &tally_counters->Tx1Col);
- qemu_put_be32s(f, &tally_counters->TxMCol);
- qemu_put_be64s(f, &tally_counters->RxOkPhy);
- qemu_put_be64s(f, &tally_counters->RxOkBrd);
- qemu_put_be32s(f, &tally_counters->RxOkMul);
- qemu_put_be16s(f, &tally_counters->TxAbt);
- qemu_put_be16s(f, &tally_counters->TxUndrn);
-}
-
-static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xff;
-
- DEBUG_PRINT(("RTL8139: ChipCmd write val=0x%08x\n", val));
-
- if (val & CmdReset)
- {
- DEBUG_PRINT(("RTL8139: ChipCmd reset\n"));
- rtl8139_reset(s);
- }
- if (val & CmdRxEnb)
- {
- DEBUG_PRINT(("RTL8139: ChipCmd enable receiver\n"));
-
- s->currCPlusRxDesc = 0;
- }
- if (val & CmdTxEnb)
- {
- DEBUG_PRINT(("RTL8139: ChipCmd enable transmitter\n"));
-
- s->currCPlusTxDesc = 0;
- }
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0xe3, s->bChipCmdState);
-
- /* Deassert reset pin before next read */
- val &= ~CmdReset;
-
- s->bChipCmdState = val;
-}
-
-static int rtl8139_RxBufferEmpty(RTL8139State *s)
-{
- int unread = MOD2(s->RxBufferSize + s->RxBufAddr - s->RxBufPtr, s->RxBufferSize);
-
- if (unread != 0)
- {
- DEBUG_PRINT(("RTL8139: receiver buffer data available 0x%04x\n", unread));
- return 0;
- }
-
- DEBUG_PRINT(("RTL8139: receiver buffer is empty\n"));
-
- return 1;
-}
-
-static uint32_t rtl8139_ChipCmd_read(RTL8139State *s)
-{
- uint32_t ret = s->bChipCmdState;
-
- if (rtl8139_RxBufferEmpty(s))
- ret |= RxBufEmpty;
-
- DEBUG_PRINT(("RTL8139: ChipCmd read val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_CpCmd_write(RTL8139State *s, uint32_t val)
-{
- int i;
-
- val &= 0xffff;
-
- DEBUG_PRINT(("RTL8139C+ command register write(w) val=0x%04x\n", val));
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0xff84, s->CpCmd);
-
- if ( (s->CpCmd & CPlusTxEnb) &&
- !(val & CPlusTxEnb) )
- {
- /* Reset TX status when the transmitter drops from C+ to
- non-C+ mode. Windows has a habit of turning off C+ and
- then waiting for the TX requests to clear as part of shut
- down, and you get stuck forever if there are old DTCRs in
- the registers. */
- for (i = 0; i < 4; i++)
- {
- s->TxStatus[i] = TxHostOwns;
- }
- }
-
- s->CpCmd = val;
-}
-
-static uint32_t rtl8139_CpCmd_read(RTL8139State *s)
-{
- uint32_t ret = s->CpCmd;
-
- DEBUG_PRINT(("RTL8139C+ command register read(w) val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_IntrMitigate_write(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139C+ IntrMitigate register write(w) val=0x%04x\n", val));
-}
-
-static uint32_t rtl8139_IntrMitigate_read(RTL8139State *s)
-{
- uint32_t ret = 0;
-
- DEBUG_PRINT(("RTL8139C+ IntrMitigate register read(w) val=0x%04x\n", ret));
-
- return ret;
-}
-
-int rtl8139_config_writeable(RTL8139State *s)
-{
- if (s->Cfg9346 & Cfg9346_Unlock)
- {
- return 1;
- }
-
- DEBUG_PRINT(("RTL8139: Configuration registers are write-protected\n"));
-
- return 0;
-}
-
-static void rtl8139_BasicModeCtrl_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xffff;
-
- DEBUG_PRINT(("RTL8139: BasicModeCtrl register write(w) val=0x%04x\n", val));
-
- /* mask unwriteable bits */
- uint32_t mask = 0x4cff;
-
- if (1 || !rtl8139_config_writeable(s))
- {
- /* Speed setting and autonegotiation enable bits are read-only */
- mask |= 0x3000;
- /* Duplex mode setting is read-only */
- mask |= 0x0100;
- }
-
- val = SET_MASKED(val, mask, s->BasicModeCtrl);
-
- s->BasicModeCtrl = val;
-}
-
-static uint32_t rtl8139_BasicModeCtrl_read(RTL8139State *s)
-{
- uint32_t ret = s->BasicModeCtrl;
-
- DEBUG_PRINT(("RTL8139: BasicModeCtrl register read(w) val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_BasicModeStatus_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xffff;
-
- DEBUG_PRINT(("RTL8139: BasicModeStatus register write(w) val=0x%04x\n", val));
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0xff3f, s->BasicModeStatus);
-
- s->BasicModeStatus = val;
-}
-
-static uint32_t rtl8139_BasicModeStatus_read(RTL8139State *s)
-{
- uint32_t ret = s->BasicModeStatus;
-
- DEBUG_PRINT(("RTL8139: BasicModeStatus register read(w) val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xff;
-
- DEBUG_PRINT(("RTL8139: Cfg9346 write val=0x%02x\n", val));
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0x31, s->Cfg9346);
-
- uint32_t opmode = val & 0xc0;
- uint32_t eeprom_val = val & 0xf;
-
- if (opmode == 0x80) {
- /* eeprom access */
- int eecs = (eeprom_val & 0x08)?1:0;
- int eesk = (eeprom_val & 0x04)?1:0;
- int eedi = (eeprom_val & 0x02)?1:0;
- prom9346_set_wire(s, eecs, eesk, eedi);
- } else if (opmode == 0x40) {
- /* Reset. */
- val = 0;
- rtl8139_reset(s);
- }
-
- s->Cfg9346 = val;
-}
-
-static uint32_t rtl8139_Cfg9346_read(RTL8139State *s)
-{
- uint32_t ret = s->Cfg9346;
-
- uint32_t opmode = ret & 0xc0;
-
- if (opmode == 0x80)
- {
- /* eeprom access */
- int eedo = prom9346_get_wire(s);
- if (eedo)
- {
- ret |= 0x01;
- }
- else
- {
- ret &= ~0x01;
- }
- }
-
- DEBUG_PRINT(("RTL8139: Cfg9346 read val=0x%02x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_Config0_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xff;
-
- DEBUG_PRINT(("RTL8139: Config0 write val=0x%02x\n", val));
-
- if (!rtl8139_config_writeable(s))
- return;
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0xf8, s->Config0);
-
- s->Config0 = val;
-}
-
-static uint32_t rtl8139_Config0_read(RTL8139State *s)
-{
- uint32_t ret = s->Config0;
-
- DEBUG_PRINT(("RTL8139: Config0 read val=0x%02x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_Config1_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xff;
-
- DEBUG_PRINT(("RTL8139: Config1 write val=0x%02x\n", val));
-
- if (!rtl8139_config_writeable(s))
- return;
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0xC, s->Config1);
-
- s->Config1 = val;
-}
-
-static uint32_t rtl8139_Config1_read(RTL8139State *s)
-{
- uint32_t ret = s->Config1;
-
- DEBUG_PRINT(("RTL8139: Config1 read val=0x%02x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_Config3_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xff;
-
- DEBUG_PRINT(("RTL8139: Config3 write val=0x%02x\n", val));
-
- if (!rtl8139_config_writeable(s))
- return;
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0x8F, s->Config3);
-
- s->Config3 = val;
-}
-
-static uint32_t rtl8139_Config3_read(RTL8139State *s)
-{
- uint32_t ret = s->Config3;
-
- DEBUG_PRINT(("RTL8139: Config3 read val=0x%02x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_Config4_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xff;
-
- DEBUG_PRINT(("RTL8139: Config4 write val=0x%02x\n", val));
-
- if (!rtl8139_config_writeable(s))
- return;
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0x0a, s->Config4);
-
- s->Config4 = val;
-}
-
-static uint32_t rtl8139_Config4_read(RTL8139State *s)
-{
- uint32_t ret = s->Config4;
-
- DEBUG_PRINT(("RTL8139: Config4 read val=0x%02x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_Config5_write(RTL8139State *s, uint32_t val)
-{
- val &= 0xff;
-
- DEBUG_PRINT(("RTL8139: Config5 write val=0x%02x\n", val));
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0x80, s->Config5);
-
- s->Config5 = val;
-}
-
-static uint32_t rtl8139_Config5_read(RTL8139State *s)
-{
- uint32_t ret = s->Config5;
-
- DEBUG_PRINT(("RTL8139: Config5 read val=0x%02x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val)
-{
- if (!rtl8139_transmitter_enabled(s))
- {
- DEBUG_PRINT(("RTL8139: transmitter disabled; no TxConfig write val=0x%08x\n", val));
- return;
- }
-
- DEBUG_PRINT(("RTL8139: TxConfig write val=0x%08x\n", val));
-
- val = SET_MASKED(val, TxVersionMask | 0x8070f80f, s->TxConfig);
-
- s->TxConfig = val;
-}
-
-static void rtl8139_TxConfig_writeb(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139C TxConfig via write(b) val=0x%02x\n", val));
-
- uint32_t tc = s->TxConfig;
- tc &= 0xFFFFFF00;
- tc |= (val & 0x000000FF);
- rtl8139_TxConfig_write(s, tc);
-}
-
-static uint32_t rtl8139_TxConfig_read(RTL8139State *s)
-{
- uint32_t ret = s->TxConfig;
-
- DEBUG_PRINT(("RTL8139: TxConfig read val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139: RxConfig write val=0x%08x\n", val));
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0xf0fc0040, s->RxConfig);
-
- s->RxConfig = val;
-
- /* reset buffer size and read/write pointers */
- rtl8139_reset_rxring(s, 8192 << ((s->RxConfig >> 11) & 0x3));
-
- DEBUG_PRINT(("RTL8139: RxConfig write reset buffer size to %d\n", s->RxBufferSize));
-}
-
-static uint32_t rtl8139_RxConfig_read(RTL8139State *s)
-{
- uint32_t ret = s->RxConfig;
-
- DEBUG_PRINT(("RTL8139: RxConfig read val=0x%08x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_transfer_frame(RTL8139State *s, const uint8_t *buf, int size, int do_interrupt)
-{
- if (!size)
- {
- DEBUG_PRINT(("RTL8139: +++ empty ethernet frame\n"));
- return;
- }
-
- if (TxLoopBack == (s->TxConfig & TxLoopBack))
- {
- DEBUG_PRINT(("RTL8139: +++ transmit loopback mode\n"));
- rtl8139_do_receive(s, buf, size, do_interrupt);
- }
- else
- {
- qemu_send_packet(s->vc, buf, size);
- }
-}
-
-static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
-{
- if (!rtl8139_transmitter_enabled(s))
- {
- DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: transmitter disabled\n",
- descriptor));
- s->TxStatus[descriptor] = TxAborted | TxHostOwns;
- return 0;
- }
-
- if (s->TxStatus[descriptor] & TxHostOwns)
- {
- DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: owned by host (%08x)\n",
- descriptor, s->TxStatus[descriptor]));
- s->TxStatus[descriptor] = TxAborted | TxHostOwns;
- return 0;
- }
-
- DEBUG_PRINT(("RTL8139: +++ transmitting from descriptor %d\n", descriptor));
-
- int txsize = s->TxStatus[descriptor] & 0x1fff;
- uint8_t txbuffer[0x2000];
-
- DEBUG_PRINT(("RTL8139: +++ transmit reading %d bytes from host memory at 0x%08x\n",
- txsize, s->TxAddr[descriptor]));
-
- cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
-
- /* Mark descriptor as transferred */
- s->TxStatus[descriptor] |= TxHostOwns;
- s->TxStatus[descriptor] |= TxStatOK;
-
- rtl8139_transfer_frame(s, txbuffer, txsize, 0);
-
- DEBUG_PRINT(("RTL8139: +++ transmitted %d bytes from descriptor %d\n", txsize, descriptor));
-
- /* update interrupt */
- s->IntrStatus |= TxOK;
- rtl8139_update_irq(s);
-
- return 1;
-}
-
-/* structures and macros for task offloading */
-typedef struct ip_header
-{
- uint8_t ip_ver_len; /* version and header length */
- uint8_t ip_tos; /* type of service */
- uint16_t ip_len; /* total length */
- uint16_t ip_id; /* identification */
- uint16_t ip_off; /* fragment offset field */
- uint8_t ip_ttl; /* time to live */
- uint8_t ip_p; /* protocol */
- uint16_t ip_sum; /* checksum */
- uint32_t ip_src,ip_dst; /* source and dest address */
-} ip_header;
-
-#define IP_HEADER_VERSION_4 4
-#define IP_HEADER_VERSION(ip) ((ip->ip_ver_len >> 4)&0xf)
-#define IP_HEADER_LENGTH(ip) (((ip->ip_ver_len)&0xf) << 2)
-
-typedef struct tcp_header
-{
- uint16_t th_sport; /* source port */
- uint16_t th_dport; /* destination port */
- uint32_t th_seq; /* sequence number */
- uint32_t th_ack; /* acknowledgement number */
- uint16_t th_offset_flags; /* data offset, reserved 6 bits, TCP protocol flags */
- uint16_t th_win; /* window */
- uint16_t th_sum; /* checksum */
- uint16_t th_urp; /* urgent pointer */
-} tcp_header;
-
-typedef struct udp_header
-{
- uint16_t uh_sport; /* source port */
- uint16_t uh_dport; /* destination port */
- uint16_t uh_ulen; /* udp length */
- uint16_t uh_sum; /* udp checksum */
-} udp_header;
-
-typedef struct ip_pseudo_header
-{
- uint32_t ip_src;
- uint32_t ip_dst;
- uint8_t zeros;
- uint8_t ip_proto;
- uint16_t ip_payload;
-} ip_pseudo_header;
-
-#define IP_PROTO_TCP 6
-#define IP_PROTO_UDP 17
-
-#define TCP_HEADER_DATA_OFFSET(tcp) (((be16_to_cpu(tcp->th_offset_flags) >> 12)&0xf) << 2)
-#define TCP_FLAGS_ONLY(flags) ((flags)&0x3f)
-#define TCP_HEADER_FLAGS(tcp) TCP_FLAGS_ONLY(be16_to_cpu(tcp->th_offset_flags))
-
-#define TCP_HEADER_CLEAR_FLAGS(tcp, off) ((tcp)->th_offset_flags &= cpu_to_be16(~TCP_FLAGS_ONLY(off)))
-
-#define TCP_FLAG_FIN 0x01
-#define TCP_FLAG_PUSH 0x08
-
-/* produces ones' complement sum of data */
-static uint16_t ones_complement_sum(uint8_t *data, size_t len)
-{
- uint32_t result = 0;
-
- for (; len > 1; data+=2, len-=2)
- {
- result += *(uint16_t*)data;
- }
-
- /* add the remainder byte */
- if (len)
- {
- uint8_t odd[2] = {*data, 0};
- result += *(uint16_t*)odd;
- }
-
- while (result>>16)
- result = (result & 0xffff) + (result >> 16);
-
- return result;
-}
-
-static uint16_t ip_checksum(void *data, size_t len)
-{
- return ~ones_complement_sum((uint8_t*)data, len);
-}
-
-static int rtl8139_cplus_transmit_one(RTL8139State *s)
-{
- if (!rtl8139_transmitter_enabled(s))
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode: transmitter disabled\n"));
- return 0;
- }
-
- if (!rtl8139_cp_transmitter_enabled(s))
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode: C+ transmitter disabled\n"));
- return 0 ;
- }
-
- int descriptor = s->currCPlusTxDesc;
-
- target_phys_addr_t cplus_tx_ring_desc =
- rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]);
-
- /* Normal priority ring */
- cplus_tx_ring_desc += 16 * descriptor;
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode reading TX descriptor %d from host memory at %08x0x%08x = 0x%8lx\n",
- descriptor, s->TxAddr[1], s->TxAddr[0], cplus_tx_ring_desc));
-
- uint32_t val, txdw0,txdw1,txbufLO,txbufHI;
-
- cpu_physical_memory_read(cplus_tx_ring_desc, (uint8_t *)&val, 4);
- txdw0 = le32_to_cpu(val);
- cpu_physical_memory_read(cplus_tx_ring_desc+4, (uint8_t *)&val, 4);
- txdw1 = le32_to_cpu(val);
- cpu_physical_memory_read(cplus_tx_ring_desc+8, (uint8_t *)&val, 4);
- txbufLO = le32_to_cpu(val);
- cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
- txbufHI = le32_to_cpu(val);
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode TX descriptor %d %08x %08x %08x %08x\n",
- descriptor,
- txdw0, txdw1, txbufLO, txbufHI));
-
-/* w0 ownership flag */
-#define CP_TX_OWN (1<<31)
-/* w0 end of ring flag */
-#define CP_TX_EOR (1<<30)
-/* first segment of received packet flag */
-#define CP_TX_FS (1<<29)
-/* last segment of received packet flag */
-#define CP_TX_LS (1<<28)
-/* large send packet flag */
-#define CP_TX_LGSEN (1<<27)
-/* large send MSS mask, bits 16...25 */
-#define CP_TC_LGSEN_MSS_MASK ((1 << 12) - 1)
-
-/* IP checksum offload flag */
-#define CP_TX_IPCS (1<<18)
-/* UDP checksum offload flag */
-#define CP_TX_UDPCS (1<<17)
-/* TCP checksum offload flag */
-#define CP_TX_TCPCS (1<<16)
-
-/* w0 bits 0...15 : buffer size */
-#define CP_TX_BUFFER_SIZE (1<<16)
-#define CP_TX_BUFFER_SIZE_MASK (CP_TX_BUFFER_SIZE - 1)
-/* w1 tag available flag */
-#define CP_RX_TAGC (1<<17)
-/* w1 bits 0...15 : VLAN tag */
-#define CP_TX_VLAN_TAG_MASK ((1<<16) - 1)
-/* w2 low 32bit of Rx buffer ptr */
-/* w3 high 32bit of Rx buffer ptr */
-
-/* set after transmission */
-/* FIFO underrun flag */
-#define CP_TX_STATUS_UNF (1<<25)
-/* transmit error summary flag, valid if set any of three below */
-#define CP_TX_STATUS_TES (1<<23)
-/* out-of-window collision flag */
-#define CP_TX_STATUS_OWC (1<<22)
-/* link failure flag */
-#define CP_TX_STATUS_LNKF (1<<21)
-/* excessive collisions flag */
-#define CP_TX_STATUS_EXC (1<<20)
-
- if (!(txdw0 & CP_TX_OWN))
- {
- DEBUG_PRINT(("RTL8139: C+ Tx mode : descriptor %d is owned by host\n", descriptor));
- return 0 ;
- }
-
- DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : transmitting from descriptor %d\n", descriptor));
-
- if (txdw0 & CP_TX_FS)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is first segment descriptor\n", descriptor));
-
- /* reset internal buffer offset */
- s->cplus_txbuffer_offset = 0;
- }
-
- int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK;
- target_phys_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);
-
- /* make sure we have enough space to assemble the packet */
- if (!s->cplus_txbuffer)
- {
- s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE;
- s->cplus_txbuffer = malloc(s->cplus_txbuffer_len);
- s->cplus_txbuffer_offset = 0;
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len));
- }
-
- if (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
- {
- free(s->cplus_txbuffer);
- s->cplus_txbuffer = NULL;
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space exceeded: %d\n", s->cplus_txbuffer_offset + txsize));
- }
-
- if (!s->cplus_txbuffer)
- {
- /* out of memory */
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmiter failed to reallocate %d bytes\n", s->cplus_txbuffer_len));
-
- /* update tally counter */
- ++s->tally_counters.TxERR;
- ++s->tally_counters.TxAbt;
-
- return 0;
- }
-
- /* append more data to the packet */
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host memory at %016" PRIx64 " to offset %d\n",
- txsize, (uint64_t)tx_addr, s->cplus_txbuffer_offset));
-
- cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
- s->cplus_txbuffer_offset += txsize;
-
- /* seek to next Rx descriptor */
- if (txdw0 & CP_TX_EOR)
- {
- s->currCPlusTxDesc = 0;
- }
- else
- {
- ++s->currCPlusTxDesc;
- if (s->currCPlusTxDesc >= 64)
- s->currCPlusTxDesc = 0;
- }
-
- /* transfer ownership to target */
- txdw0 &= ~CP_RX_OWN;
-
- /* reset error indicator bits */
- txdw0 &= ~CP_TX_STATUS_UNF;
- txdw0 &= ~CP_TX_STATUS_TES;
- txdw0 &= ~CP_TX_STATUS_OWC;
- txdw0 &= ~CP_TX_STATUS_LNKF;
- txdw0 &= ~CP_TX_STATUS_EXC;
-
- /* update ring data */
- val = cpu_to_le32(txdw0);
- cpu_physical_memory_write(cplus_tx_ring_desc, (uint8_t *)&val, 4);
-// val = cpu_to_le32(txdw1);
-// cpu_physical_memory_write(cplus_tx_ring_desc+4, &val, 4);
-
- /* Now decide if descriptor being processed is holding the last segment of packet */
- if (txdw0 & CP_TX_LS)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is last segment descriptor\n", descriptor));
-
- /* can transfer fully assembled packet */
-
- uint8_t *saved_buffer = s->cplus_txbuffer;
- int saved_size = s->cplus_txbuffer_offset;
- int saved_buffer_len = s->cplus_txbuffer_len;
-
- /* reset the card space to protect from recursive call */
- s->cplus_txbuffer = NULL;
- s->cplus_txbuffer_offset = 0;
- s->cplus_txbuffer_len = 0;
-
- if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN))
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task checksum\n"));
-
- #define ETH_P_IP 0x0800 /* Internet Protocol packet */
- #define ETH_HLEN 14
- #define ETH_MTU 1500
-
- /* ip packet header */
- ip_header *ip = 0;
- int hlen = 0;
- uint8_t ip_protocol = 0;
- uint16_t ip_data_len = 0;
-
- uint8_t *eth_payload_data = 0;
- size_t eth_payload_len = 0;
-
- int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
- if (proto == ETH_P_IP)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode has IP packet\n"));
-
- /* not aligned */
- eth_payload_data = saved_buffer + ETH_HLEN;
- eth_payload_len = saved_size - ETH_HLEN;
-
- ip = (ip_header*)eth_payload_data;
-
- if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
- DEBUG_PRINT(("RTL8139: +++ C+ mode packet has bad IP version %d expected %d\n", IP_HEADER_VERSION(ip), IP_HEADER_VERSION_4));
- ip = NULL;
- } else {
- hlen = IP_HEADER_LENGTH(ip);
- ip_protocol = ip->ip_p;
- ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
- }
- }
-
- if (ip)
- {
- if (txdw0 & CP_TX_IPCS)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n"));
-
- if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */
- /* bad packet header len */
- /* or packet too short */
- }
- else
- {
- ip->ip_sum = 0;
- ip->ip_sum = ip_checksum(ip, hlen);
- DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
- }
- }
-
- if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
- {
-#if defined (DEBUG_RTL8139)
- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
-#endif
- DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n",
- ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss));
-
- int tcp_send_offset = 0;
- int send_count = 0;
-
- /* maximum IP header length is 60 bytes */
- uint8_t saved_ip_header[60];
-
- /* save IP header template; data area is used in tcp checksum calculation */
- memcpy(saved_ip_header, eth_payload_data, hlen);
-
- /* a placeholder for checksum calculation routine in tcp case */
- uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
- // size_t data_to_checksum_len = eth_payload_len - hlen + 12;
-
- /* pointer to TCP header */
- tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
-
- int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
-
- /* ETH_MTU = ip header len + tcp header len + payload */
- int tcp_data_len = ip_data_len - tcp_hlen;
- int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n",
- ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size));
-
- /* note the cycle below overwrites IP header data,
- but restores it from saved_ip_header before sending packet */
-
- int is_last_frame = 0;
-
- for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
- {
- uint16_t chunk_size = tcp_chunk_size;
-
- /* check if this is the last frame */
- if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
- {
- is_last_frame = 1;
- chunk_size = tcp_data_len - tcp_send_offset;
- }
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq)));
-
- /* add 4 TCP pseudoheader fields */
- /* copy IP source and destination fields */
- memcpy(data_to_checksum, saved_ip_header + 12, 8);
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size));
-
- if (tcp_send_offset)
- {
- memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
- }
-
- /* keep PUSH and FIN flags only for the last frame */
- if (!is_last_frame)
- {
- TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
- }
-
- /* recalculate TCP checksum */
- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
- p_tcpip_hdr->zeros = 0;
- p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
- p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
-
- p_tcp_hdr->th_sum = 0;
-
- int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum));
-
- p_tcp_hdr->th_sum = tcp_checksum;
-
- /* restore IP header */
- memcpy(eth_payload_data, saved_ip_header, hlen);
-
- /* set IP data length and recalculate IP checksum */
- ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
-
- /* increment IP id for subsequent frames */
- ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
-
- ip->ip_sum = 0;
- ip->ip_sum = ip_checksum(eth_payload_data, hlen);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
-
- int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size));
- rtl8139_transfer_frame(s, saved_buffer, tso_send_size, 0);
-
- /* add transferred count to TCP sequence number */
- p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
- ++send_count;
- }
-
- /* Stop sending this frame */
- saved_size = 0;
- }
- else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n"));
-
- /* maximum IP header length is 60 bytes */
- uint8_t saved_ip_header[60];
- memcpy(saved_ip_header, eth_payload_data, hlen);
-
- uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
- // size_t data_to_checksum_len = eth_payload_len - hlen + 12;
-
- /* add 4 TCP pseudoheader fields */
- /* copy IP source and destination fields */
- memcpy(data_to_checksum, saved_ip_header + 12, 8);
-
- if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len));
-
- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
- p_tcpip_hdr->zeros = 0;
- p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
- p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
-
- tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
-
- p_tcp_hdr->th_sum = 0;
-
- int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum));
-
- p_tcp_hdr->th_sum = tcp_checksum;
- }
- else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len));
-
- ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
- p_udpip_hdr->zeros = 0;
- p_udpip_hdr->ip_proto = IP_PROTO_UDP;
- p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
-
- udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
-
- p_udp_hdr->uh_sum = 0;
-
- int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum));
-
- p_udp_hdr->uh_sum = udp_checksum;
- }
-
- /* restore IP header */
- memcpy(eth_payload_data, saved_ip_header, hlen);
- }
- }
- }
-
- /* update tally counter */
- ++s->tally_counters.TxOk;
-
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmitting %d bytes packet\n", saved_size));
-
- rtl8139_transfer_frame(s, saved_buffer, saved_size, 1);
-
- /* restore card space if there was no recursion and reset offset */
- if (!s->cplus_txbuffer)
- {
- s->cplus_txbuffer = saved_buffer;
- s->cplus_txbuffer_len = saved_buffer_len;
- s->cplus_txbuffer_offset = 0;
- }
- else
- {
- free(saved_buffer);
- }
- }
- else
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission continue to next descriptor\n"));
- }
-
- return 1;
-}
-
-static void rtl8139_cplus_transmit(RTL8139State *s)
-{
- int txcount = 0;
-
- while (rtl8139_cplus_transmit_one(s))
- {
- ++txcount;
- }
-
- /* Mark transfer completed */
- if (!txcount)
- {
- DEBUG_PRINT(("RTL8139: C+ mode : transmitter queue stalled, current TxDesc = %d\n",
- s->currCPlusTxDesc));
- }
- else
- {
- /* update interrupt status */
- s->IntrStatus |= TxOK;
- rtl8139_update_irq(s);
- }
-}
-
-static void rtl8139_transmit(RTL8139State *s)
-{
- int descriptor = s->currTxDesc, txcount = 0;
-
- /*while*/
- if (rtl8139_transmit_one(s, descriptor))
- {
- ++s->currTxDesc;
- s->currTxDesc %= 4;
- ++txcount;
- }
-
- /* Mark transfer completed */
- if (!txcount)
- {
- DEBUG_PRINT(("RTL8139: transmitter queue stalled, current TxDesc = %d\n", s->currTxDesc));
- }
-}
-
-static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32_t val)
-{
-
- int descriptor = txRegOffset/4;
-
- /* handle C+ transmit mode register configuration */
-
- if (rtl8139_cp_transmitter_enabled(s))
- {
- DEBUG_PRINT(("RTL8139C+ DTCCR write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
-
- /* handle Dump Tally Counters command */
- s->TxStatus[descriptor] = val;
-
- if (descriptor == 0 && (val & 0x8))
- {
- target_phys_addr_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]);
-
- /* dump tally counters to specified memory location */
- RTL8139TallyCounters_physical_memory_write( tc_addr, &s->tally_counters);
-
- /* mark dump completed */
- s->TxStatus[0] &= ~0x8;
- }
-
- return;
- }
-
- DEBUG_PRINT(("RTL8139: TxStatus write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
-
- /* mask only reserved bits */
- val &= ~0xff00c000; /* these bits are reset on write */
- val = SET_MASKED(val, 0x00c00000, s->TxStatus[descriptor]);
-
- s->TxStatus[descriptor] = val;
-
- /* attempt to start transmission */
- rtl8139_transmit(s);
-}
-
-static uint32_t rtl8139_TxStatus_read(RTL8139State *s, uint32_t txRegOffset)
-{
- uint32_t ret = s->TxStatus[txRegOffset/4];
-
- DEBUG_PRINT(("RTL8139: TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret));
-
- return ret;
-}
-
-static uint16_t rtl8139_TSAD_read(RTL8139State *s)
-{
- uint16_t ret = 0;
-
- /* Simulate TSAD, it is read only anyway */
-
- ret = ((s->TxStatus[3] & TxStatOK )?TSAD_TOK3:0)
- |((s->TxStatus[2] & TxStatOK )?TSAD_TOK2:0)
- |((s->TxStatus[1] & TxStatOK )?TSAD_TOK1:0)
- |((s->TxStatus[0] & TxStatOK )?TSAD_TOK0:0)
-
- |((s->TxStatus[3] & TxUnderrun)?TSAD_TUN3:0)
- |((s->TxStatus[2] & TxUnderrun)?TSAD_TUN2:0)
- |((s->TxStatus[1] & TxUnderrun)?TSAD_TUN1:0)
- |((s->TxStatus[0] & TxUnderrun)?TSAD_TUN0:0)
-
- |((s->TxStatus[3] & TxAborted )?TSAD_TABT3:0)
- |((s->TxStatus[2] & TxAborted )?TSAD_TABT2:0)
- |((s->TxStatus[1] & TxAborted )?TSAD_TABT1:0)
- |((s->TxStatus[0] & TxAborted )?TSAD_TABT0:0)
-
- |((s->TxStatus[3] & TxHostOwns )?TSAD_OWN3:0)
- |((s->TxStatus[2] & TxHostOwns )?TSAD_OWN2:0)
- |((s->TxStatus[1] & TxHostOwns )?TSAD_OWN1:0)
- |((s->TxStatus[0] & TxHostOwns )?TSAD_OWN0:0) ;
-
-
- DEBUG_PRINT(("RTL8139: TSAD read val=0x%04x\n", ret));
-
- return ret;
-}
-
-static uint16_t rtl8139_CSCR_read(RTL8139State *s)
-{
- uint16_t ret = s->CSCR;
-
- DEBUG_PRINT(("RTL8139: CSCR read val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_TxAddr_write(RTL8139State *s, uint32_t txAddrOffset, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139: TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val));
-
- s->TxAddr[txAddrOffset/4] = le32_to_cpu(val);
-}
-
-static uint32_t rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset)
-{
- uint32_t ret = cpu_to_le32(s->TxAddr[txAddrOffset/4]);
-
- DEBUG_PRINT(("RTL8139: TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret));
-
- return ret;
-}
-
-static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139: RxBufPtr write val=0x%04x\n", val));
-
- /* this value is off by 16 */
- s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize);
-
- DEBUG_PRINT((" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
- s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
-}
-
-static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s)
-{
- /* this value is off by 16 */
- uint32_t ret = s->RxBufPtr - 0x10;
-
- DEBUG_PRINT(("RTL8139: RxBufPtr read val=0x%04x\n", ret));
-
- return ret;
-}
-
-static uint32_t rtl8139_RxBufAddr_read(RTL8139State *s)
-{
- /* this value is NOT off by 16 */
- uint32_t ret = s->RxBufAddr;
-
- DEBUG_PRINT(("RTL8139: RxBufAddr read val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_RxBuf_write(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139: RxBuf write val=0x%08x\n", val));
-
- s->RxBuf = val;
-
- /* may need to reset rxring here */
-}
-
-static uint32_t rtl8139_RxBuf_read(RTL8139State *s)
-{
- uint32_t ret = s->RxBuf;
-
- DEBUG_PRINT(("RTL8139: RxBuf read val=0x%08x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_IntrMask_write(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139: IntrMask write(w) val=0x%04x\n", val));
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0x1e00, s->IntrMask);
-
- s->IntrMask = val;
-
- rtl8139_update_irq(s);
-}
-
-static uint32_t rtl8139_IntrMask_read(RTL8139State *s)
-{
- uint32_t ret = s->IntrMask;
-
- DEBUG_PRINT(("RTL8139: IntrMask read(w) val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139: IntrStatus write(w) val=0x%04x\n", val));
-
-#if 0
-
- /* writing to ISR has no effect */
-
- return;
-
-#else
- uint16_t newStatus = s->IntrStatus & ~val;
-
- /* mask unwriteable bits */
- newStatus = SET_MASKED(newStatus, 0x1e00, s->IntrStatus);
-
- /* writing 1 to interrupt status register bit clears it */
- s->IntrStatus = 0;
- rtl8139_update_irq(s);
-
- s->IntrStatus = newStatus;
- rtl8139_update_irq(s);
-#endif
-}
-
-static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
-{
- uint32_t ret = s->IntrStatus;
-
- DEBUG_PRINT(("RTL8139: IntrStatus read(w) val=0x%04x\n", ret));
-
-#if 0
-
- /* reading ISR clears all interrupts */
- s->IntrStatus = 0;
-
- rtl8139_update_irq(s);
-
-#endif
-
- return ret;
-}
-
-static void rtl8139_MultiIntr_write(RTL8139State *s, uint32_t val)
-{
- DEBUG_PRINT(("RTL8139: MultiIntr write(w) val=0x%04x\n", val));
-
- /* mask unwriteable bits */
- val = SET_MASKED(val, 0xf000, s->MultiIntr);
-
- s->MultiIntr = val;
-}
-
-static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
-{
- uint32_t ret = s->MultiIntr;
-
- DEBUG_PRINT(("RTL8139: MultiIntr read(w) val=0x%04x\n", ret));
-
- return ret;
-}
-
-static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
-{
- RTL8139State *s = opaque;
-
- addr &= 0xff;
-
- switch (addr)
- {
- case MAC0 ... MAC0+5:
- s->phys[addr - MAC0] = val;
- break;
- case MAC0+6 ... MAC0+7:
- /* reserved */
- break;
- case MAR0 ... MAR0+7:
- s->mult[addr - MAR0] = val;
- break;
- case ChipCmd:
- rtl8139_ChipCmd_write(s, val);
- break;
- case Cfg9346:
- rtl8139_Cfg9346_write(s, val);
- break;
- case TxConfig: /* windows driver sometimes writes using byte-lenth call */
- rtl8139_TxConfig_writeb(s, val);
- break;
- case Config0:
- rtl8139_Config0_write(s, val);
- break;
- case Config1:
- rtl8139_Config1_write(s, val);
- break;
- case Config3:
- rtl8139_Config3_write(s, val);
- break;
- case Config4:
- rtl8139_Config4_write(s, val);
- break;
- case Config5:
- rtl8139_Config5_write(s, val);
- break;
- case MediaStatus:
- /* ignore */
- DEBUG_PRINT(("RTL8139: not implemented write(b) to MediaStatus val=0x%02x\n", val));
- break;
-
- case HltClk:
- DEBUG_PRINT(("RTL8139: HltClk write val=0x%08x\n", val));
- if (val == 'R')
- {
- s->clock_enabled = 1;
- }
- else if (val == 'H')
- {
- s->clock_enabled = 0;
- }
- break;
-
- case TxThresh:
- DEBUG_PRINT(("RTL8139C+ TxThresh write(b) val=0x%02x\n", val));
- s->TxThresh = val;
- break;
-
- case TxPoll:
- DEBUG_PRINT(("RTL8139C+ TxPoll write(b) val=0x%02x\n", val));
- if (val & (1 << 7))
- {
- DEBUG_PRINT(("RTL8139C+ TxPoll high priority transmission (not implemented)\n"));
- //rtl8139_cplus_transmit(s);
- }
- if (val & (1 << 6))
- {
- DEBUG_PRINT(("RTL8139C+ TxPoll normal priority transmission\n"));
- rtl8139_cplus_transmit(s);
- }
-
- break;
-
- default:
- DEBUG_PRINT(("RTL8139: not implemented write(b) addr=0x%x val=0x%02x\n", addr, val));
- break;
- }
-}
-
-static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
-{
- RTL8139State *s = opaque;
-
- addr &= 0xfe;
-
- switch (addr)
- {
- case IntrMask:
- rtl8139_IntrMask_write(s, val);
- break;
-
- case IntrStatus:
- rtl8139_IntrStatus_write(s, val);
- break;
-
- case MultiIntr:
- rtl8139_MultiIntr_write(s, val);
- break;
-
- case RxBufPtr:
- rtl8139_RxBufPtr_write(s, val);
- break;
-
- case BasicModeCtrl:
- rtl8139_BasicModeCtrl_write(s, val);
- break;
- case BasicModeStatus:
- rtl8139_BasicModeStatus_write(s, val);
- break;
- case NWayAdvert:
- DEBUG_PRINT(("RTL8139: NWayAdvert write(w) val=0x%04x\n", val));
- s->NWayAdvert = val;
- break;
- case NWayLPAR:
- DEBUG_PRINT(("RTL8139: forbidden NWayLPAR write(w) val=0x%04x\n", val));
- break;
- case NWayExpansion:
- DEBUG_PRINT(("RTL8139: NWayExpansion write(w) val=0x%04x\n", val));
- s->NWayExpansion = val;
- break;
-
- case CpCmd:
- rtl8139_CpCmd_write(s, val);
- break;
-
- case IntrMitigate:
- rtl8139_IntrMitigate_write(s, val);
- break;
-
- default:
- DEBUG_PRINT(("RTL8139: ioport write(w) addr=0x%x val=0x%04x via write(b)\n", addr, val));
-
-#ifdef TARGET_WORDS_BIGENDIAN
- rtl8139_io_writeb(opaque, addr, (val >> 8) & 0xff);
- rtl8139_io_writeb(opaque, addr + 1, val & 0xff);
-#else
- rtl8139_io_writeb(opaque, addr, val & 0xff);
- rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
- break;
- }
-}
-
-static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
-{
- RTL8139State *s = opaque;
-
- addr &= 0xfc;
-
- switch (addr)
- {
- case RxMissed:
- DEBUG_PRINT(("RTL8139: RxMissed clearing on write\n"));
- s->RxMissed = 0;
- break;
-
- case TxConfig:
- rtl8139_TxConfig_write(s, val);
- break;
-
- case RxConfig:
- rtl8139_RxConfig_write(s, val);
- break;
-
- case TxStatus0 ... TxStatus0+4*4-1:
- rtl8139_TxStatus_write(s, addr-TxStatus0, val);
- break;
-
- case TxAddr0 ... TxAddr0+4*4-1:
- rtl8139_TxAddr_write(s, addr-TxAddr0, val);
- break;
-
- case RxBuf:
- rtl8139_RxBuf_write(s, val);
- break;
-
- case RxRingAddrLO:
- DEBUG_PRINT(("RTL8139: C+ RxRing low bits write val=0x%08x\n", val));
- s->RxRingAddrLO = val;
- break;
-
- case RxRingAddrHI:
- DEBUG_PRINT(("RTL8139: C+ RxRing high bits write val=0x%08x\n", val));
- s->RxRingAddrHI = val;
- break;
-
- case Timer:
- DEBUG_PRINT(("RTL8139: TCTR Timer reset on write\n"));
- s->TCTR = 0;
- s->TCTR_base = qemu_get_clock(vm_clock);
- break;
-
- case FlashReg:
- DEBUG_PRINT(("RTL8139: FlashReg TimerInt write val=0x%08x\n", val));
- s->TimerInt = val;
- break;
-
- default:
- DEBUG_PRINT(("RTL8139: ioport write(l) addr=0x%x val=0x%08x via write(b)\n", addr, val));
-#ifdef TARGET_WORDS_BIGENDIAN
- rtl8139_io_writeb(opaque, addr, (val >> 24) & 0xff);
- rtl8139_io_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- rtl8139_io_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- rtl8139_io_writeb(opaque, addr + 3, val & 0xff);
-#else
- rtl8139_io_writeb(opaque, addr, val & 0xff);
- rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- rtl8139_io_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
- break;
- }
-}
-
-static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
-{
- RTL8139State *s = opaque;
- int ret;
-
- addr &= 0xff;
-
- switch (addr)
- {
- case MAC0 ... MAC0+5:
- ret = s->phys[addr - MAC0];
- break;
- case MAC0+6 ... MAC0+7:
- ret = 0;
- break;
- case MAR0 ... MAR0+7:
- ret = s->mult[addr - MAR0];
- break;
- case ChipCmd:
- ret = rtl8139_ChipCmd_read(s);
- break;
- case Cfg9346:
- ret = rtl8139_Cfg9346_read(s);
- break;
- case Config0:
- ret = rtl8139_Config0_read(s);
- break;
- case Config1:
- ret = rtl8139_Config1_read(s);
- break;
- case Config3:
- ret = rtl8139_Config3_read(s);
- break;
- case Config4:
- ret = rtl8139_Config4_read(s);
- break;
- case Config5:
- ret = rtl8139_Config5_read(s);
- break;
-
- case MediaStatus:
- ret = 0xd0;
- DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret));
- break;
-
- case HltClk:
- ret = s->clock_enabled;
- DEBUG_PRINT(("RTL8139: HltClk read 0x%x\n", ret));
- break;
-
- case PCIRevisionID:
- ret = RTL8139_PCI_REVID;
- DEBUG_PRINT(("RTL8139: PCI Revision ID read 0x%x\n", ret));
- break;
-
- case TxThresh:
- ret = s->TxThresh;
- DEBUG_PRINT(("RTL8139C+ TxThresh read(b) val=0x%02x\n", ret));
- break;
-
- case 0x43: /* Part of TxConfig register. Windows driver tries to read it */
- ret = s->TxConfig >> 24;
- DEBUG_PRINT(("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret));
- break;
-
- default:
- DEBUG_PRINT(("RTL8139: not implemented read(b) addr=0x%x\n", addr));
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
-{
- RTL8139State *s = opaque;
- uint32_t ret;
-
- addr &= 0xfe; /* mask lower bit */
-
- switch (addr)
- {
- case IntrMask:
- ret = rtl8139_IntrMask_read(s);
- break;
-
- case IntrStatus:
- ret = rtl8139_IntrStatus_read(s);
- break;
-
- case MultiIntr:
- ret = rtl8139_MultiIntr_read(s);
- break;
-
- case RxBufPtr:
- ret = rtl8139_RxBufPtr_read(s);
- break;
-
- case RxBufAddr:
- ret = rtl8139_RxBufAddr_read(s);
- break;
-
- case BasicModeCtrl:
- ret = rtl8139_BasicModeCtrl_read(s);
- break;
- case BasicModeStatus:
- ret = rtl8139_BasicModeStatus_read(s);
- break;
- case NWayAdvert:
- ret = s->NWayAdvert;
- DEBUG_PRINT(("RTL8139: NWayAdvert read(w) val=0x%04x\n", ret));
- break;
- case NWayLPAR:
- ret = s->NWayLPAR;
- DEBUG_PRINT(("RTL8139: NWayLPAR read(w) val=0x%04x\n", ret));
- break;
- case NWayExpansion:
- ret = s->NWayExpansion;
- DEBUG_PRINT(("RTL8139: NWayExpansion read(w) val=0x%04x\n", ret));
- break;
-
- case CpCmd:
- ret = rtl8139_CpCmd_read(s);
- break;
-
- case IntrMitigate:
- ret = rtl8139_IntrMitigate_read(s);
- break;
-
- case TxSummary:
- ret = rtl8139_TSAD_read(s);
- break;
-
- case CSCR:
- ret = rtl8139_CSCR_read(s);
- break;
-
- default:
- DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x via read(b)\n", addr));
-
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = rtl8139_io_readb(opaque, addr) << 8;
- ret |= rtl8139_io_readb(opaque, addr + 1);
-#else
- ret = rtl8139_io_readb(opaque, addr);
- ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
-#endif
-
- DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x val=0x%04x\n", addr, ret));
- break;
- }
-
- return ret;
-}
-
-static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
-{
- RTL8139State *s = opaque;
- uint32_t ret;
-
- addr &= 0xfc; /* also mask low 2 bits */
-
- switch (addr)
- {
- case RxMissed:
- ret = s->RxMissed;
-
- DEBUG_PRINT(("RTL8139: RxMissed read val=0x%08x\n", ret));
- break;
-
- case TxConfig:
- ret = rtl8139_TxConfig_read(s);
- break;
-
- case RxConfig:
- ret = rtl8139_RxConfig_read(s);
- break;
-
- case TxStatus0 ... TxStatus0+4*4-1:
- ret = rtl8139_TxStatus_read(s, addr-TxStatus0);
- break;
-
- case TxAddr0 ... TxAddr0+4*4-1:
- ret = rtl8139_TxAddr_read(s, addr-TxAddr0);
- break;
-
- case RxBuf:
- ret = rtl8139_RxBuf_read(s);
- break;
-
- case RxRingAddrLO:
- ret = s->RxRingAddrLO;
- DEBUG_PRINT(("RTL8139: C+ RxRing low bits read val=0x%08x\n", ret));
- break;
-
- case RxRingAddrHI:
- ret = s->RxRingAddrHI;
- DEBUG_PRINT(("RTL8139: C+ RxRing high bits read val=0x%08x\n", ret));
- break;
-
- case Timer:
- ret = s->TCTR;
- DEBUG_PRINT(("RTL8139: TCTR Timer read val=0x%08x\n", ret));
- break;
-
- case FlashReg:
- ret = s->TimerInt;
- DEBUG_PRINT(("RTL8139: FlashReg TimerInt read val=0x%08x\n", ret));
- break;
-
- default:
- DEBUG_PRINT(("RTL8139: ioport read(l) addr=0x%x via read(b)\n", addr));
-
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = rtl8139_io_readb(opaque, addr) << 24;
- ret |= rtl8139_io_readb(opaque, addr + 1) << 16;
- ret |= rtl8139_io_readb(opaque, addr + 2) << 8;
- ret |= rtl8139_io_readb(opaque, addr + 3);
-#else
- ret = rtl8139_io_readb(opaque, addr);
- ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
- ret |= rtl8139_io_readb(opaque, addr + 2) << 16;
- ret |= rtl8139_io_readb(opaque, addr + 3) << 24;
-#endif
-
- DEBUG_PRINT(("RTL8139: read(l) addr=0x%x val=%08x\n", addr, ret));
- break;
- }
-
- return ret;
-}
-
-/* */
-
-static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- rtl8139_io_writeb(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- rtl8139_io_writew(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- rtl8139_io_writel(opaque, addr & 0xFF, val);
-}
-
-static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
-{
- return rtl8139_io_readb(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
-{
- return rtl8139_io_readw(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
-{
- return rtl8139_io_readl(opaque, addr & 0xFF);
-}
-
-/* */
-
-static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- rtl8139_io_writeb(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- rtl8139_io_writew(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- rtl8139_io_writel(opaque, addr & 0xFF, val);
-}
-
-static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- return rtl8139_io_readb(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- return rtl8139_io_readw(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- return rtl8139_io_readl(opaque, addr & 0xFF);
-}
-
-/* */
-
-static void rtl8139_save(QEMUFile* f,void* opaque)
-{
- RTL8139State* s=(RTL8139State*)opaque;
- int i;
-
- pci_device_save(s->pci_dev, f);
-
- qemu_put_buffer(f, s->phys, 6);
- qemu_put_buffer(f, s->mult, 8);
-
- for (i=0; i<4; ++i)
- {
- qemu_put_be32s(f, &s->TxStatus[i]); /* TxStatus0 */
- }
- for (i=0; i<4; ++i)
- {
- qemu_put_be32s(f, &s->TxAddr[i]); /* TxAddr0 */
- }
-
- qemu_put_be32s(f, &s->RxBuf); /* Receive buffer */
- qemu_put_be32s(f, &s->RxBufferSize);/* internal variable, receive ring buffer size in C mode */
- qemu_put_be32s(f, &s->RxBufPtr);
- qemu_put_be32s(f, &s->RxBufAddr);
-
- qemu_put_be16s(f, &s->IntrStatus);
- qemu_put_be16s(f, &s->IntrMask);
-
- qemu_put_be32s(f, &s->TxConfig);
- qemu_put_be32s(f, &s->RxConfig);
- qemu_put_be32s(f, &s->RxMissed);
- qemu_put_be16s(f, &s->CSCR);
-
- qemu_put_8s(f, &s->Cfg9346);
- qemu_put_8s(f, &s->Config0);
- qemu_put_8s(f, &s->Config1);
- qemu_put_8s(f, &s->Config3);
- qemu_put_8s(f, &s->Config4);
- qemu_put_8s(f, &s->Config5);
-
- qemu_put_8s(f, &s->clock_enabled);
- qemu_put_8s(f, &s->bChipCmdState);
-
- qemu_put_be16s(f, &s->MultiIntr);
-
- qemu_put_be16s(f, &s->BasicModeCtrl);
- qemu_put_be16s(f, &s->BasicModeStatus);
- qemu_put_be16s(f, &s->NWayAdvert);
- qemu_put_be16s(f, &s->NWayLPAR);
- qemu_put_be16s(f, &s->NWayExpansion);
-
- qemu_put_be16s(f, &s->CpCmd);
- qemu_put_8s(f, &s->TxThresh);
-
- qemu_put_be32s(f, &s->irq);
- qemu_put_buffer(f, s->macaddr, 6);
- qemu_put_be32s(f, &s->rtl8139_mmio_io_addr);
-
- qemu_put_be32s(f, &s->currTxDesc);
- qemu_put_be32s(f, &s->currCPlusRxDesc);
- qemu_put_be32s(f, &s->currCPlusTxDesc);
- qemu_put_be32s(f, &s->RxRingAddrLO);
- qemu_put_be32s(f, &s->RxRingAddrHI);
-
- for (i=0; i<EEPROM_9346_SIZE; ++i)
- {
- qemu_put_be16s(f, &s->eeprom.contents[i]);
- }
- qemu_put_be32s(f, &s->eeprom.mode);
- qemu_put_be32s(f, &s->eeprom.tick);
- qemu_put_8s(f, &s->eeprom.address);
- qemu_put_be16s(f, &s->eeprom.input);
- qemu_put_be16s(f, &s->eeprom.output);
-
- qemu_put_8s(f, &s->eeprom.eecs);
- qemu_put_8s(f, &s->eeprom.eesk);
- qemu_put_8s(f, &s->eeprom.eedi);
- qemu_put_8s(f, &s->eeprom.eedo);
-
- qemu_put_be32s(f, &s->TCTR);
- qemu_put_be32s(f, &s->TimerInt);
- qemu_put_be64s(f, &s->TCTR_base);
-
- RTL8139TallyCounters_save(f, &s->tally_counters);
-}
-
-static int rtl8139_load(QEMUFile* f,void* opaque,int version_id)
-{
- RTL8139State* s=(RTL8139State*)opaque;
- int i, ret;
-
- /* just 2 versions for now */
- if (version_id > 3)
- return -EINVAL;
-
- if (version_id >= 3) {
- ret = pci_device_load(s->pci_dev, f);
- if (ret < 0)
- return ret;
- }
-
- /* saved since version 1 */
- qemu_get_buffer(f, s->phys, 6);
- qemu_get_buffer(f, s->mult, 8);
-
- for (i=0; i<4; ++i)
- {
- qemu_get_be32s(f, &s->TxStatus[i]); /* TxStatus0 */
- }
- for (i=0; i<4; ++i)
- {
- qemu_get_be32s(f, &s->TxAddr[i]); /* TxAddr0 */
- }
-
- qemu_get_be32s(f, &s->RxBuf); /* Receive buffer */
- qemu_get_be32s(f, &s->RxBufferSize);/* internal variable, receive ring buffer size in C mode */
- qemu_get_be32s(f, &s->RxBufPtr);
- qemu_get_be32s(f, &s->RxBufAddr);
-
- qemu_get_be16s(f, &s->IntrStatus);
- qemu_get_be16s(f, &s->IntrMask);
-
- qemu_get_be32s(f, &s->TxConfig);
- qemu_get_be32s(f, &s->RxConfig);
- qemu_get_be32s(f, &s->RxMissed);
- qemu_get_be16s(f, &s->CSCR);
-
- qemu_get_8s(f, &s->Cfg9346);
- qemu_get_8s(f, &s->Config0);
- qemu_get_8s(f, &s->Config1);
- qemu_get_8s(f, &s->Config3);
- qemu_get_8s(f, &s->Config4);
- qemu_get_8s(f, &s->Config5);
-
- qemu_get_8s(f, &s->clock_enabled);
- qemu_get_8s(f, &s->bChipCmdState);
-
- qemu_get_be16s(f, &s->MultiIntr);
-
- qemu_get_be16s(f, &s->BasicModeCtrl);
- qemu_get_be16s(f, &s->BasicModeStatus);
- qemu_get_be16s(f, &s->NWayAdvert);
- qemu_get_be16s(f, &s->NWayLPAR);
- qemu_get_be16s(f, &s->NWayExpansion);
-
- qemu_get_be16s(f, &s->CpCmd);
- qemu_get_8s(f, &s->TxThresh);
-
- qemu_get_be32s(f, &s->irq);
- qemu_get_buffer(f, s->macaddr, 6);
- qemu_get_be32s(f, &s->rtl8139_mmio_io_addr);
-
- qemu_get_be32s(f, &s->currTxDesc);
- qemu_get_be32s(f, &s->currCPlusRxDesc);
- qemu_get_be32s(f, &s->currCPlusTxDesc);
- qemu_get_be32s(f, &s->RxRingAddrLO);
- qemu_get_be32s(f, &s->RxRingAddrHI);
-
- for (i=0; i<EEPROM_9346_SIZE; ++i)
- {
- qemu_get_be16s(f, &s->eeprom.contents[i]);
- }
- qemu_get_be32s(f, &s->eeprom.mode);
- qemu_get_be32s(f, &s->eeprom.tick);
- qemu_get_8s(f, &s->eeprom.address);
- qemu_get_be16s(f, &s->eeprom.input);
- qemu_get_be16s(f, &s->eeprom.output);
-
- qemu_get_8s(f, &s->eeprom.eecs);
- qemu_get_8s(f, &s->eeprom.eesk);
- qemu_get_8s(f, &s->eeprom.eedi);
- qemu_get_8s(f, &s->eeprom.eedo);
-
- /* saved since version 2 */
- if (version_id >= 2)
- {
- qemu_get_be32s(f, &s->TCTR);
- qemu_get_be32s(f, &s->TimerInt);
- qemu_get_be64s(f, &s->TCTR_base);
-
- RTL8139TallyCounters_load(f, &s->tally_counters);
- }
- else
- {
- /* not saved, use default */
- s->TCTR = 0;
- s->TimerInt = 0;
- s->TCTR_base = 0;
-
- RTL8139TallyCounters_clear(&s->tally_counters);
- }
-
- return 0;
-}
-
-/***********************************************************/
-/* PCI RTL8139 definitions */
-
-typedef struct PCIRTL8139State {
- PCIDevice dev;
- RTL8139State rtl8139;
-} PCIRTL8139State;
-
-static void rtl8139_mmio_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIRTL8139State *d = (PCIRTL8139State *)pci_dev;
- RTL8139State *s = &d->rtl8139;
-
- cpu_register_physical_memory(addr + 0, 0x100, s->rtl8139_mmio_io_addr);
-}
-
-static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIRTL8139State *d = (PCIRTL8139State *)pci_dev;
- RTL8139State *s = &d->rtl8139;
-
- register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
- register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb, s);
-
- register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
- register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw, s);
-
- register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
- register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl, s);
-}
-
-static CPUReadMemoryFunc *rtl8139_mmio_read[3] = {
- rtl8139_mmio_readb,
- rtl8139_mmio_readw,
- rtl8139_mmio_readl,
-};
-
-static CPUWriteMemoryFunc *rtl8139_mmio_write[3] = {
- rtl8139_mmio_writeb,
- rtl8139_mmio_writew,
- rtl8139_mmio_writel,
-};
-
-static inline int64_t rtl8139_get_next_tctr_time(RTL8139State *s, int64_t current_time)
-{
- int64_t next_time = current_time +
- muldiv64(1, ticks_per_sec, PCI_FREQUENCY);
- if (next_time <= current_time)
- next_time = current_time + 1;
- return next_time;
-}
-
-#if RTL8139_ONBOARD_TIMER
-static void rtl8139_timer(void *opaque)
-{
- RTL8139State *s = opaque;
-
- int is_timeout = 0;
-
- int64_t curr_time;
- uint32_t curr_tick;
-
- if (!s->clock_enabled)
- {
- DEBUG_PRINT(("RTL8139: >>> timer: clock is not running\n"));
- return;
- }
-
- curr_time = qemu_get_clock(vm_clock);
-
- curr_tick = muldiv64(curr_time - s->TCTR_base, PCI_FREQUENCY, ticks_per_sec);
-
- if (s->TimerInt && curr_tick >= s->TimerInt)
- {
- if (s->TCTR < s->TimerInt || curr_tick < s->TCTR)
- {
- is_timeout = 1;
- }
- }
-
- s->TCTR = curr_tick;
-
-// DEBUG_PRINT(("RTL8139: >>> timer: tick=%08u\n", s->TCTR));
-
- if (is_timeout)
- {
- DEBUG_PRINT(("RTL8139: >>> timer: timeout tick=%08u\n", s->TCTR));
- s->IntrStatus |= PCSTimeout;
- rtl8139_update_irq(s);
- }
-
- qemu_mod_timer(s->timer,
- rtl8139_get_next_tctr_time(s,curr_time));
-}
-#endif /* RTL8139_ONBOARD_TIMER */
-
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
-{
- PCIRTL8139State *d;
- RTL8139State *s;
- uint8_t *pci_conf;
- int instance;
-
- d = (PCIRTL8139State *)pci_register_device(bus,
- "RTL8139", sizeof(PCIRTL8139State),
- devfn,
- NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0xec; /* Realtek 8139 */
- pci_conf[0x01] = 0x10;
- pci_conf[0x02] = 0x39;
- pci_conf[0x03] = 0x81;
- pci_conf[0x04] = 0x05; /* command = I/O space, Bus Master */
- pci_conf[0x08] = RTL8139_PCI_REVID; /* PCI revision ID; >=0x20 is for 8139C+ */
- pci_conf[0x0a] = 0x00; /* ethernet network controller */
- pci_conf[0x0b] = 0x02;
- pci_conf[0x0e] = 0x00; /* header_type */
- pci_conf[0x3d] = 1; /* interrupt pin 0 */
- pci_conf[0x34] = 0xdc;
- pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
- pci_conf[0x2d] = 0x58;
- pci_conf[0x2e] = 0x01; /* subsystem device */
- pci_conf[0x2f] = 0x00;
-
- s = &d->rtl8139;
-
- /* I/O handler for memory-mapped I/O */
- s->rtl8139_mmio_io_addr =
- cpu_register_io_memory(0, rtl8139_mmio_read, rtl8139_mmio_write, s);
-
- pci_register_io_region(&d->dev, 0, 0x100,
- PCI_ADDRESS_SPACE_IO, rtl8139_ioport_map);
-
- pci_register_io_region(&d->dev, 1, 0x100,
- PCI_ADDRESS_SPACE_MEM, rtl8139_mmio_map);
-
- s->irq = 16; /* PCI interrupt */
- s->pci_dev = (PCIDevice *)d;
- memcpy(s->macaddr, nd->macaddr, 6);
- rtl8139_reset(s);
- s->vc = qemu_new_vlan_client(nd->vlan, rtl8139_receive,
- rtl8139_can_receive, s);
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "rtl8139 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- s->macaddr[0],
- s->macaddr[1],
- s->macaddr[2],
- s->macaddr[3],
- s->macaddr[4],
- s->macaddr[5]);
-
- s->cplus_txbuffer = NULL;
- s->cplus_txbuffer_len = 0;
- s->cplus_txbuffer_offset = 0;
-
- instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
- register_savevm("rtl8139", instance, 3, rtl8139_save, rtl8139_load, s);
-
-#if RTL8139_ONBOARD_TIMER
- s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
-
- qemu_mod_timer(s->timer,
- rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
-#endif /* RTL8139_ONBOARD_TIMER */
-}
-
diff --git a/tools/ioemu/hw/sb16.c b/tools/ioemu/hw/sb16.c
deleted file mode 100644
index b34afab40b..0000000000
--- a/tools/ioemu/hw/sb16.c
+++ /dev/null
@@ -1,1457 +0,0 @@
-/*
- * QEMU Soundblaster 16 emulation
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
-
-/* #define DEBUG */
-/* #define DEBUG_SB16_MOST */
-
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#define IO_READ_PROTO(name) \
- uint32_t name (void *opaque, uint32_t nport)
-#define IO_WRITE_PROTO(name) \
- void name (void *opaque, uint32_t nport, uint32_t val)
-
-static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
-
-static struct {
- int ver_lo;
- int ver_hi;
- int irq;
- int dma;
- int hdma;
- int port;
-} conf = {5, 4, 5, 1, 5, 0x220};
-
-typedef struct SB16State {
- QEMUSoundCard card;
- int irq;
- int dma;
- int hdma;
- int port;
- int ver;
-
- int in_index;
- int out_data_len;
- int fmt_stereo;
- int fmt_signed;
- int fmt_bits;
- audfmt_e fmt;
- int dma_auto;
- int block_size;
- int fifo;
- int freq;
- int time_const;
- int speaker;
- int needed_bytes;
- int cmd;
- int use_hdma;
- int highspeed;
- int can_write;
-
- int v2x6;
-
- uint8_t csp_param;
- uint8_t csp_value;
- uint8_t csp_mode;
- uint8_t csp_regs[256];
- uint8_t csp_index;
- uint8_t csp_reg83[4];
- int csp_reg83r;
- int csp_reg83w;
-
- uint8_t in2_data[10];
- uint8_t out_data[50];
- uint8_t test_reg;
- uint8_t last_read_byte;
- int nzero;
-
- int left_till_irq;
-
- int dma_running;
- int bytes_per_second;
- int align;
- int audio_free;
- SWVoiceOut *voice;
-
- QEMUTimer *aux_ts;
- /* mixer state */
- int mixer_nreg;
- uint8_t mixer_regs[256];
-} SB16State;
-
-static void SB_audio_callback (void *opaque, int free);
-
-static int magic_of_irq (int irq)
-{
- switch (irq) {
- case 5:
- return 2;
- case 7:
- return 4;
- case 9:
- return 1;
- case 10:
- return 8;
- default:
- dolog ("bad irq %d\n", irq);
- return 2;
- }
-}
-
-static int irq_of_magic (int magic)
-{
- switch (magic) {
- case 1:
- return 9;
- case 2:
- return 5;
- case 4:
- return 7;
- case 8:
- return 10;
- default:
- dolog ("bad irq magic %d\n", magic);
- return -1;
- }
-}
-
-#if 0
-static void log_dsp (SB16State *dsp)
-{
- ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
- dsp->fmt_stereo ? "Stereo" : "Mono",
- dsp->fmt_signed ? "Signed" : "Unsigned",
- dsp->fmt_bits,
- dsp->dma_auto ? "Auto" : "Single",
- dsp->block_size,
- dsp->freq,
- dsp->time_const,
- dsp->speaker);
-}
-#endif
-
-static void speaker (SB16State *s, int on)
-{
- s->speaker = on;
- /* AUD_enable (s->voice, on); */
-}
-
-static void control (SB16State *s, int hold)
-{
- int dma = s->use_hdma ? s->hdma : s->dma;
- s->dma_running = hold;
-
- ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
-
- if (hold) {
- DMA_hold_DREQ (dma);
- AUD_set_active_out (s->voice, 1);
- }
- else {
- DMA_release_DREQ (dma);
- AUD_set_active_out (s->voice, 0);
- }
-}
-
-static void aux_timer (void *opaque)
-{
- SB16State *s = opaque;
- s->can_write = 1;
- pic_set_irq (s->irq, 1);
-}
-
-#define DMA8_AUTO 1
-#define DMA8_HIGH 2
-
-static void continue_dma8 (SB16State *s)
-{
- if (s->freq > 0) {
- audsettings_t as;
-
- s->audio_free = 0;
-
- as.freq = s->freq;
- as.nchannels = 1 << s->fmt_stereo;
- as.fmt = s->fmt;
- as.endianness = 0;
-
- s->voice = AUD_open_out (
- &s->card,
- s->voice,
- "sb16",
- s,
- SB_audio_callback,
- &as
- );
- }
-
- control (s, 1);
-}
-
-static void dma_cmd8 (SB16State *s, int mask, int dma_len)
-{
- s->fmt = AUD_FMT_U8;
- s->use_hdma = 0;
- s->fmt_bits = 8;
- s->fmt_signed = 0;
- s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
- if (-1 == s->time_const) {
- if (s->freq <= 0)
- s->freq = 11025;
- }
- else {
- int tmp = (256 - s->time_const);
- s->freq = (1000000 + (tmp / 2)) / tmp;
- }
-
- if (dma_len != -1) {
- s->block_size = dma_len << s->fmt_stereo;
- }
- else {
- /* This is apparently the only way to make both Act1/PL
- and SecondReality/FC work
-
- Act1 sets block size via command 0x48 and it's an odd number
- SR does the same with even number
- Both use stereo, and Creatives own documentation states that
- 0x48 sets block size in bytes less one.. go figure */
- s->block_size &= ~s->fmt_stereo;
- }
-
- s->freq >>= s->fmt_stereo;
- s->left_till_irq = s->block_size;
- s->bytes_per_second = (s->freq << s->fmt_stereo);
- /* s->highspeed = (mask & DMA8_HIGH) != 0; */
- s->dma_auto = (mask & DMA8_AUTO) != 0;
- s->align = (1 << s->fmt_stereo) - 1;
-
- if (s->block_size & s->align) {
- dolog ("warning: misaligned block size %d, alignment %d\n",
- s->block_size, s->align + 1);
- }
-
- ldebug ("freq %d, stereo %d, sign %d, bits %d, "
- "dma %d, auto %d, fifo %d, high %d\n",
- s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
- s->block_size, s->dma_auto, s->fifo, s->highspeed);
-
- continue_dma8 (s);
- speaker (s, 1);
-}
-
-static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
-{
- s->use_hdma = cmd < 0xc0;
- s->fifo = (cmd >> 1) & 1;
- s->dma_auto = (cmd >> 2) & 1;
- s->fmt_signed = (d0 >> 4) & 1;
- s->fmt_stereo = (d0 >> 5) & 1;
-
- switch (cmd >> 4) {
- case 11:
- s->fmt_bits = 16;
- break;
-
- case 12:
- s->fmt_bits = 8;
- break;
- }
-
- if (-1 != s->time_const) {
-#if 1
- int tmp = 256 - s->time_const;
- s->freq = (1000000 + (tmp / 2)) / tmp;
-#else
- /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
- s->freq = 1000000 / ((255 - s->time_const));
-#endif
- s->time_const = -1;
- }
-
- s->block_size = dma_len + 1;
- s->block_size <<= (s->fmt_bits == 16);
- if (!s->dma_auto) {
- /* It is clear that for DOOM and auto-init this value
- shouldn't take stereo into account, while Miles Sound Systems
- setsound.exe with single transfer mode wouldn't work without it
- wonders of SB16 yet again */
- s->block_size <<= s->fmt_stereo;
- }
-
- ldebug ("freq %d, stereo %d, sign %d, bits %d, "
- "dma %d, auto %d, fifo %d, high %d\n",
- s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
- s->block_size, s->dma_auto, s->fifo, s->highspeed);
-
- if (16 == s->fmt_bits) {
- if (s->fmt_signed) {
- s->fmt = AUD_FMT_S16;
- }
- else {
- s->fmt = AUD_FMT_U16;
- }
- }
- else {
- if (s->fmt_signed) {
- s->fmt = AUD_FMT_S8;
- }
- else {
- s->fmt = AUD_FMT_U8;
- }
- }
-
- s->left_till_irq = s->block_size;
-
- s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
- s->highspeed = 0;
- s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
- if (s->block_size & s->align) {
- dolog ("warning: misaligned block size %d, alignment %d\n",
- s->block_size, s->align + 1);
- }
-
- if (s->freq) {
- audsettings_t as;
-
- s->audio_free = 0;
-
- as.freq = s->freq;
- as.nchannels = 1 << s->fmt_stereo;
- as.fmt = s->fmt;
- as.endianness = 0;
-
- s->voice = AUD_open_out (
- &s->card,
- s->voice,
- "sb16",
- s,
- SB_audio_callback,
- &as
- );
- }
-
- control (s, 1);
- speaker (s, 1);
-}
-
-static inline void dsp_out_data (SB16State *s, uint8_t val)
-{
- ldebug ("outdata %#x\n", val);
- if ((size_t) s->out_data_len < sizeof (s->out_data)) {
- s->out_data[s->out_data_len++] = val;
- }
-}
-
-static inline uint8_t dsp_get_data (SB16State *s)
-{
- if (s->in_index) {
- return s->in2_data[--s->in_index];
- }
- else {
- dolog ("buffer underflow\n");
- return 0;
- }
-}
-
-static void command (SB16State *s, uint8_t cmd)
-{
- ldebug ("command %#x\n", cmd);
-
- if (cmd > 0xaf && cmd < 0xd0) {
- if (cmd & 8) {
- dolog ("ADC not yet supported (command %#x)\n", cmd);
- }
-
- switch (cmd >> 4) {
- case 11:
- case 12:
- break;
- default:
- dolog ("%#x wrong bits\n", cmd);
- }
- s->needed_bytes = 3;
- }
- else {
- s->needed_bytes = 0;
-
- switch (cmd) {
- case 0x03:
- dsp_out_data (s, 0x10); /* s->csp_param); */
- goto warn;
-
- case 0x04:
- s->needed_bytes = 1;
- goto warn;
-
- case 0x05:
- s->needed_bytes = 2;
- goto warn;
-
- case 0x08:
- /* __asm__ ("int3"); */
- goto warn;
-
- case 0x0e:
- s->needed_bytes = 2;
- goto warn;
-
- case 0x09:
- dsp_out_data (s, 0xf8);
- goto warn;
-
- case 0x0f:
- s->needed_bytes = 1;
- goto warn;
-
- case 0x10:
- s->needed_bytes = 1;
- goto warn;
-
- case 0x14:
- s->needed_bytes = 2;
- s->block_size = 0;
- break;
-
- case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
- dma_cmd8 (s, DMA8_AUTO, -1);
- break;
-
- case 0x20: /* Direct ADC, Juice/PL */
- dsp_out_data (s, 0xff);
- goto warn;
-
- case 0x35:
- dolog ("0x35 - MIDI command not implemented\n");
- break;
-
- case 0x40:
- s->freq = -1;
- s->time_const = -1;
- s->needed_bytes = 1;
- break;
-
- case 0x41:
- s->freq = -1;
- s->time_const = -1;
- s->needed_bytes = 2;
- break;
-
- case 0x42:
- s->freq = -1;
- s->time_const = -1;
- s->needed_bytes = 2;
- goto warn;
-
- case 0x45:
- dsp_out_data (s, 0xaa);
- goto warn;
-
- case 0x47: /* Continue Auto-Initialize DMA 16bit */
- break;
-
- case 0x48:
- s->needed_bytes = 2;
- break;
-
- case 0x74:
- s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
- dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
- break;
-
- case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
- s->needed_bytes = 2;
- dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
- break;
-
- case 0x76: /* DMA DAC, 2.6-bit ADPCM */
- s->needed_bytes = 2;
- dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
- break;
-
- case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
- s->needed_bytes = 2;
- dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
- break;
-
- case 0x7d:
- dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
- dolog ("not implemented\n");
- break;
-
- case 0x7f:
- dolog (
- "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
- );
- dolog ("not implemented\n");
- break;
-
- case 0x80:
- s->needed_bytes = 2;
- break;
-
- case 0x90:
- case 0x91:
- dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
- break;
-
- case 0xd0: /* halt DMA operation. 8bit */
- control (s, 0);
- break;
-
- case 0xd1: /* speaker on */
- speaker (s, 1);
- break;
-
- case 0xd3: /* speaker off */
- speaker (s, 0);
- break;
-
- case 0xd4: /* continue DMA operation. 8bit */
- /* KQ6 (or maybe Sierras audblst.drv in general) resets
- the frequency between halt/continue */
- continue_dma8 (s);
- break;
-
- case 0xd5: /* halt DMA operation. 16bit */
- control (s, 0);
- break;
-
- case 0xd6: /* continue DMA operation. 16bit */
- control (s, 1);
- break;
-
- case 0xd9: /* exit auto-init DMA after this block. 16bit */
- s->dma_auto = 0;
- break;
-
- case 0xda: /* exit auto-init DMA after this block. 8bit */
- s->dma_auto = 0;
- break;
-
- case 0xe0: /* DSP identification */
- s->needed_bytes = 1;
- break;
-
- case 0xe1:
- dsp_out_data (s, s->ver & 0xff);
- dsp_out_data (s, s->ver >> 8);
- break;
-
- case 0xe2:
- s->needed_bytes = 1;
- goto warn;
-
- case 0xe3:
- {
- int i;
- for (i = sizeof (e3) - 1; i >= 0; --i)
- dsp_out_data (s, e3[i]);
- }
- break;
-
- case 0xe4: /* write test reg */
- s->needed_bytes = 1;
- break;
-
- case 0xe7:
- dolog ("Attempt to probe for ESS (0xe7)?\n");
- break;
-
- case 0xe8: /* read test reg */
- dsp_out_data (s, s->test_reg);
- break;
-
- case 0xf2:
- case 0xf3:
- dsp_out_data (s, 0xaa);
- s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
- pic_set_irq (s->irq, 1);
- break;
-
- case 0xf9:
- s->needed_bytes = 1;
- goto warn;
-
- case 0xfa:
- dsp_out_data (s, 0);
- goto warn;
-
- case 0xfc: /* FIXME */
- dsp_out_data (s, 0);
- goto warn;
-
- default:
- dolog ("Unrecognized command %#x\n", cmd);
- break;
- }
- }
-
- if (!s->needed_bytes) {
- ldebug ("\n");
- }
-
- exit:
- if (!s->needed_bytes) {
- s->cmd = -1;
- }
- else {
- s->cmd = cmd;
- }
- return;
-
- warn:
- dolog ("warning: command %#x,%d is not truly understood yet\n",
- cmd, s->needed_bytes);
- goto exit;
-
-}
-
-static uint16_t dsp_get_lohi (SB16State *s)
-{
- uint8_t hi = dsp_get_data (s);
- uint8_t lo = dsp_get_data (s);
- return (hi << 8) | lo;
-}
-
-static uint16_t dsp_get_hilo (SB16State *s)
-{
- uint8_t lo = dsp_get_data (s);
- uint8_t hi = dsp_get_data (s);
- return (hi << 8) | lo;
-}
-
-static void complete (SB16State *s)
-{
- int d0, d1, d2;
- ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
- s->cmd, s->in_index, s->needed_bytes);
-
- if (s->cmd > 0xaf && s->cmd < 0xd0) {
- d2 = dsp_get_data (s);
- d1 = dsp_get_data (s);
- d0 = dsp_get_data (s);
-
- if (s->cmd & 8) {
- dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
- s->cmd, d0, d1, d2);
- }
- else {
- ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
- s->cmd, d0, d1, d2);
- dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
- }
- }
- else {
- switch (s->cmd) {
- case 0x04:
- s->csp_mode = dsp_get_data (s);
- s->csp_reg83r = 0;
- s->csp_reg83w = 0;
- ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
- break;
-
- case 0x05:
- s->csp_param = dsp_get_data (s);
- s->csp_value = dsp_get_data (s);
- ldebug ("CSP command 0x05: param=%#x value=%#x\n",
- s->csp_param,
- s->csp_value);
- break;
-
- case 0x0e:
- d0 = dsp_get_data (s);
- d1 = dsp_get_data (s);
- ldebug ("write CSP register %d <- %#x\n", d1, d0);
- if (d1 == 0x83) {
- ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
- s->csp_reg83[s->csp_reg83r % 4] = d0;
- s->csp_reg83r += 1;
- }
- else {
- s->csp_regs[d1] = d0;
- }
- break;
-
- case 0x0f:
- d0 = dsp_get_data (s);
- ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
- d0, s->csp_regs[d0], s->csp_mode);
- if (d0 == 0x83) {
- ldebug ("0x83[%d] -> %#x\n",
- s->csp_reg83w,
- s->csp_reg83[s->csp_reg83w % 4]);
- dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
- s->csp_reg83w += 1;
- }
- else {
- dsp_out_data (s, s->csp_regs[d0]);
- }
- break;
-
- case 0x10:
- d0 = dsp_get_data (s);
- dolog ("cmd 0x10 d0=%#x\n", d0);
- break;
-
- case 0x14:
- dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
- break;
-
- case 0x40:
- s->time_const = dsp_get_data (s);
- ldebug ("set time const %d\n", s->time_const);
- break;
-
- case 0x42: /* FT2 sets output freq with this, go figure */
-#if 0
- dolog ("cmd 0x42 might not do what it think it should\n");
-#endif
- case 0x41:
- s->freq = dsp_get_hilo (s);
- ldebug ("set freq %d\n", s->freq);
- break;
-
- case 0x48:
- s->block_size = dsp_get_lohi (s) + 1;
- ldebug ("set dma block len %d\n", s->block_size);
- break;
-
- case 0x74:
- case 0x75:
- case 0x76:
- case 0x77:
- /* ADPCM stuff, ignore */
- break;
-
- case 0x80:
- {
- int freq, samples, bytes;
- int64_t ticks;
-
- freq = s->freq > 0 ? s->freq : 11025;
- samples = dsp_get_lohi (s) + 1;
- bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
- ticks = (bytes * ticks_per_sec) / freq;
- if (ticks < ticks_per_sec / 1024) {
- pic_set_irq (s->irq, 1);
- }
- else {
- if (s->aux_ts) {
- qemu_mod_timer (
- s->aux_ts,
- qemu_get_clock (vm_clock) + ticks
- );
- }
- }
- ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
- }
- break;
-
- case 0xe0:
- d0 = dsp_get_data (s);
- s->out_data_len = 0;
- ldebug ("E0 data = %#x\n", d0);
- dsp_out_data (s, ~d0);
- break;
-
- case 0xe2:
- d0 = dsp_get_data (s);
- ldebug ("E2 = %#x\n", d0);
- break;
-
- case 0xe4:
- s->test_reg = dsp_get_data (s);
- break;
-
- case 0xf9:
- d0 = dsp_get_data (s);
- ldebug ("command 0xf9 with %#x\n", d0);
- switch (d0) {
- case 0x0e:
- dsp_out_data (s, 0xff);
- break;
-
- case 0x0f:
- dsp_out_data (s, 0x07);
- break;
-
- case 0x37:
- dsp_out_data (s, 0x38);
- break;
-
- default:
- dsp_out_data (s, 0x00);
- break;
- }
- break;
-
- default:
- dolog ("complete: unrecognized command %#x\n", s->cmd);
- return;
- }
- }
-
- ldebug ("\n");
- s->cmd = -1;
- return;
-}
-
-static void legacy_reset (SB16State *s)
-{
- audsettings_t as;
-
- s->freq = 11025;
- s->fmt_signed = 0;
- s->fmt_bits = 8;
- s->fmt_stereo = 0;
-
- as.freq = s->freq;
- as.nchannels = 1;
- as.fmt = AUD_FMT_U8;
- as.endianness = 0;
-
- s->voice = AUD_open_out (
- &s->card,
- s->voice,
- "sb16",
- s,
- SB_audio_callback,
- &as
- );
-
- /* Not sure about that... */
- /* AUD_set_active_out (s->voice, 1); */
-}
-
-static void reset (SB16State *s)
-{
- pic_set_irq (s->irq, 0);
- if (s->dma_auto) {
- pic_set_irq (s->irq, 1);
- pic_set_irq (s->irq, 0);
- }
-
- s->mixer_regs[0x82] = 0;
- s->dma_auto = 0;
- s->in_index = 0;
- s->out_data_len = 0;
- s->left_till_irq = 0;
- s->needed_bytes = 0;
- s->block_size = -1;
- s->nzero = 0;
- s->highspeed = 0;
- s->v2x6 = 0;
- s->cmd = -1;
-
- dsp_out_data(s, 0xaa);
- speaker (s, 0);
- control (s, 0);
- legacy_reset (s);
-}
-
-static IO_WRITE_PROTO (dsp_write)
-{
- SB16State *s = opaque;
- int iport;
-
- iport = nport - s->port;
-
- ldebug ("write %#x <- %#x\n", nport, val);
- switch (iport) {
- case 0x06:
- switch (val) {
- case 0x00:
- if (s->v2x6 == 1) {
- if (0 && s->highspeed) {
- s->highspeed = 0;
- pic_set_irq (s->irq, 0);
- control (s, 0);
- }
- else {
- reset (s);
- }
- }
- s->v2x6 = 0;
- break;
-
- case 0x01:
- case 0x03: /* FreeBSD kludge */
- s->v2x6 = 1;
- break;
-
- case 0xc6:
- s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
- break;
-
- case 0xb8: /* Panic */
- reset (s);
- break;
-
- case 0x39:
- dsp_out_data (s, 0x38);
- reset (s);
- s->v2x6 = 0x39;
- break;
-
- default:
- s->v2x6 = val;
- break;
- }
- break;
-
- case 0x0c: /* write data or command | write status */
-/* if (s->highspeed) */
-/* break; */
-
- if (0 == s->needed_bytes) {
- command (s, val);
-#if 0
- if (0 == s->needed_bytes) {
- log_dsp (s);
- }
-#endif
- }
- else {
- if (s->in_index == sizeof (s->in2_data)) {
- dolog ("in data overrun\n");
- }
- else {
- s->in2_data[s->in_index++] = val;
- if (s->in_index == s->needed_bytes) {
- s->needed_bytes = 0;
- complete (s);
-#if 0
- log_dsp (s);
-#endif
- }
- }
- }
- break;
-
- default:
- ldebug ("(nport=%#x, val=%#x)\n", nport, val);
- break;
- }
-}
-
-static IO_READ_PROTO (dsp_read)
-{
- SB16State *s = opaque;
- int iport, retval, ack = 0;
-
- iport = nport - s->port;
-
- switch (iport) {
- case 0x06: /* reset */
- retval = 0xff;
- break;
-
- case 0x0a: /* read data */
- if (s->out_data_len) {
- retval = s->out_data[--s->out_data_len];
- s->last_read_byte = retval;
- }
- else {
- if (s->cmd != -1) {
- dolog ("empty output buffer for command %#x\n",
- s->cmd);
- }
- retval = s->last_read_byte;
- /* goto error; */
- }
- break;
-
- case 0x0c: /* 0 can write */
- retval = s->can_write ? 0 : 0x80;
- break;
-
- case 0x0d: /* timer interrupt clear */
- /* dolog ("timer interrupt clear\n"); */
- retval = 0;
- break;
-
- case 0x0e: /* data available status | irq 8 ack */
- retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
- if (s->mixer_regs[0x82] & 1) {
- ack = 1;
- s->mixer_regs[0x82] &= 1;
- pic_set_irq (s->irq, 0);
- }
- break;
-
- case 0x0f: /* irq 16 ack */
- retval = 0xff;
- if (s->mixer_regs[0x82] & 2) {
- ack = 1;
- s->mixer_regs[0x82] &= 2;
- pic_set_irq (s->irq, 0);
- }
- break;
-
- default:
- goto error;
- }
-
- if (!ack) {
- ldebug ("read %#x -> %#x\n", nport, retval);
- }
-
- return retval;
-
- error:
- dolog ("warning: dsp_read %#x error\n", nport);
- return 0xff;
-}
-
-static void reset_mixer (SB16State *s)
-{
- int i;
-
- memset (s->mixer_regs, 0xff, 0x7f);
- memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
-
- s->mixer_regs[0x02] = 4; /* master volume 3bits */
- s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
- s->mixer_regs[0x08] = 0; /* CD volume 3bits */
- s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
-
- /* d5=input filt, d3=lowpass filt, d1,d2=input source */
- s->mixer_regs[0x0c] = 0;
-
- /* d5=output filt, d1=stereo switch */
- s->mixer_regs[0x0e] = 0;
-
- /* voice volume L d5,d7, R d1,d3 */
- s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
- /* master ... */
- s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
- /* MIDI ... */
- s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
-
- for (i = 0x30; i < 0x48; i++) {
- s->mixer_regs[i] = 0x20;
- }
-}
-
-static IO_WRITE_PROTO(mixer_write_indexb)
-{
- SB16State *s = opaque;
- (void) nport;
- s->mixer_nreg = val;
-}
-
-static IO_WRITE_PROTO(mixer_write_datab)
-{
- SB16State *s = opaque;
-
- (void) nport;
- ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
-
- switch (s->mixer_nreg) {
- case 0x00:
- reset_mixer (s);
- break;
-
- case 0x80:
- {
- int irq = irq_of_magic (val);
- ldebug ("setting irq to %d (val=%#x)\n", irq, val);
- if (irq > 0) {
- s->irq = irq;
- }
- }
- break;
-
- case 0x81:
- {
- int dma, hdma;
-
- dma = lsbindex (val & 0xf);
- hdma = lsbindex (val & 0xf0);
- if (dma != s->dma || hdma != s->hdma) {
- dolog (
- "attempt to change DMA "
- "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
- dma, s->dma, hdma, s->hdma, val);
- }
-#if 0
- s->dma = dma;
- s->hdma = hdma;
-#endif
- }
- break;
-
- case 0x82:
- dolog ("attempt to write into IRQ status register (val=%#x)\n",
- val);
- return;
-
- default:
- if (s->mixer_nreg >= 0x80) {
- ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
- }
- break;
- }
-
- s->mixer_regs[s->mixer_nreg] = val;
-}
-
-static IO_WRITE_PROTO(mixer_write_indexw)
-{
- mixer_write_indexb (opaque, nport, val & 0xff);
- mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
-}
-
-static IO_READ_PROTO(mixer_read)
-{
- SB16State *s = opaque;
-
- (void) nport;
-#ifndef DEBUG_SB16_MOST
- if (s->mixer_nreg != 0x82) {
- ldebug ("mixer_read[%#x] -> %#x\n",
- s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
- }
-#else
- ldebug ("mixer_read[%#x] -> %#x\n",
- s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
-#endif
- return s->mixer_regs[s->mixer_nreg];
-}
-
-static int write_audio (SB16State *s, int nchan, int dma_pos,
- int dma_len, int len)
-{
- int temp, net;
- uint8_t tmpbuf[4096];
-
- temp = len;
- net = 0;
-
- while (temp) {
- int left = dma_len - dma_pos;
- int copied;
- size_t to_copy;
-
- to_copy = audio_MIN (temp, left);
- if (to_copy > sizeof (tmpbuf)) {
- to_copy = sizeof (tmpbuf);
- }
-
- copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
- copied = AUD_write (s->voice, tmpbuf, copied);
-
- temp -= copied;
- dma_pos = (dma_pos + copied) % dma_len;
- net += copied;
-
- if (!copied) {
- break;
- }
- }
-
- return net;
-}
-
-static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
-{
- SB16State *s = opaque;
- int till, copy, written, free;
-
- if (s->block_size <= 0) {
- dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
- s->block_size, nchan, dma_pos, dma_len);
- return dma_pos;
- }
-
- if (s->left_till_irq < 0) {
- s->left_till_irq = s->block_size;
- }
-
- if (s->voice) {
- free = s->audio_free & ~s->align;
- if ((free <= 0) || !dma_len) {
- return dma_pos;
- }
- }
- else {
- free = dma_len;
- }
-
- copy = free;
- till = s->left_till_irq;
-
-#ifdef DEBUG_SB16_MOST
- dolog ("pos:%06d %d till:%d len:%d\n",
- dma_pos, free, till, dma_len);
-#endif
-
- if (till <= copy) {
- if (0 == s->dma_auto) {
- copy = till;
- }
- }
-
- written = write_audio (s, nchan, dma_pos, dma_len, copy);
- dma_pos = (dma_pos + written) % dma_len;
- s->left_till_irq -= written;
-
- if (s->left_till_irq <= 0) {
- s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
- pic_set_irq (s->irq, 1);
- if (0 == s->dma_auto) {
- control (s, 0);
- speaker (s, 0);
- }
- }
-
-#ifdef DEBUG_SB16_MOST
- ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
- dma_pos, free, dma_len, s->left_till_irq, copy, written,
- s->block_size);
-#endif
-
- while (s->left_till_irq <= 0) {
- s->left_till_irq = s->block_size + s->left_till_irq;
- }
-
- return dma_pos;
-}
-
-static void SB_audio_callback (void *opaque, int free)
-{
- SB16State *s = opaque;
- s->audio_free = free;
-}
-
-static void SB_save (QEMUFile *f, void *opaque)
-{
- SB16State *s = opaque;
-
- qemu_put_be32s (f, &s->irq);
- qemu_put_be32s (f, &s->dma);
- qemu_put_be32s (f, &s->hdma);
- qemu_put_be32s (f, &s->port);
- qemu_put_be32s (f, &s->ver);
- qemu_put_be32s (f, &s->in_index);
- qemu_put_be32s (f, &s->out_data_len);
- qemu_put_be32s (f, &s->fmt_stereo);
- qemu_put_be32s (f, &s->fmt_signed);
- qemu_put_be32s (f, &s->fmt_bits);
- qemu_put_be32s (f, &s->fmt);
- qemu_put_be32s (f, &s->dma_auto);
- qemu_put_be32s (f, &s->block_size);
- qemu_put_be32s (f, &s->fifo);
- qemu_put_be32s (f, &s->freq);
- qemu_put_be32s (f, &s->time_const);
- qemu_put_be32s (f, &s->speaker);
- qemu_put_be32s (f, &s->needed_bytes);
- qemu_put_be32s (f, &s->cmd);
- qemu_put_be32s (f, &s->use_hdma);
- qemu_put_be32s (f, &s->highspeed);
- qemu_put_be32s (f, &s->can_write);
- qemu_put_be32s (f, &s->v2x6);
-
- qemu_put_8s (f, &s->csp_param);
- qemu_put_8s (f, &s->csp_value);
- qemu_put_8s (f, &s->csp_mode);
- qemu_put_8s (f, &s->csp_param);
- qemu_put_buffer (f, s->csp_regs, 256);
- qemu_put_8s (f, &s->csp_index);
- qemu_put_buffer (f, s->csp_reg83, 4);
- qemu_put_be32s (f, &s->csp_reg83r);
- qemu_put_be32s (f, &s->csp_reg83w);
-
- qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
- qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
- qemu_put_8s (f, &s->test_reg);
- qemu_put_8s (f, &s->last_read_byte);
-
- qemu_put_be32s (f, &s->nzero);
- qemu_put_be32s (f, &s->left_till_irq);
- qemu_put_be32s (f, &s->dma_running);
- qemu_put_be32s (f, &s->bytes_per_second);
- qemu_put_be32s (f, &s->align);
-
- qemu_put_be32s (f, &s->mixer_nreg);
- qemu_put_buffer (f, s->mixer_regs, 256);
-}
-
-static int SB_load (QEMUFile *f, void *opaque, int version_id)
-{
- SB16State *s = opaque;
-
- if (version_id != 1) {
- return -EINVAL;
- }
-
- qemu_get_be32s (f, &s->irq);
- qemu_get_be32s (f, &s->dma);
- qemu_get_be32s (f, &s->hdma);
- qemu_get_be32s (f, &s->port);
- qemu_get_be32s (f, &s->ver);
- qemu_get_be32s (f, &s->in_index);
- qemu_get_be32s (f, &s->out_data_len);
- qemu_get_be32s (f, &s->fmt_stereo);
- qemu_get_be32s (f, &s->fmt_signed);
- qemu_get_be32s (f, &s->fmt_bits);
- qemu_get_be32s (f, &s->fmt);
- qemu_get_be32s (f, &s->dma_auto);
- qemu_get_be32s (f, &s->block_size);
- qemu_get_be32s (f, &s->fifo);
- qemu_get_be32s (f, &s->freq);
- qemu_get_be32s (f, &s->time_const);
- qemu_get_be32s (f, &s->speaker);
- qemu_get_be32s (f, &s->needed_bytes);
- qemu_get_be32s (f, &s->cmd);
- qemu_get_be32s (f, &s->use_hdma);
- qemu_get_be32s (f, &s->highspeed);
- qemu_get_be32s (f, &s->can_write);
- qemu_get_be32s (f, &s->v2x6);
-
- qemu_get_8s (f, &s->csp_param);
- qemu_get_8s (f, &s->csp_value);
- qemu_get_8s (f, &s->csp_mode);
- qemu_get_8s (f, &s->csp_param);
- qemu_get_buffer (f, s->csp_regs, 256);
- qemu_get_8s (f, &s->csp_index);
- qemu_get_buffer (f, s->csp_reg83, 4);
- qemu_get_be32s (f, &s->csp_reg83r);
- qemu_get_be32s (f, &s->csp_reg83w);
-
- qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
- qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
- qemu_get_8s (f, &s->test_reg);
- qemu_get_8s (f, &s->last_read_byte);
-
- qemu_get_be32s (f, &s->nzero);
- qemu_get_be32s (f, &s->left_till_irq);
- qemu_get_be32s (f, &s->dma_running);
- qemu_get_be32s (f, &s->bytes_per_second);
- qemu_get_be32s (f, &s->align);
-
- qemu_get_be32s (f, &s->mixer_nreg);
- qemu_get_buffer (f, s->mixer_regs, 256);
-
- if (s->voice) {
- AUD_close_out (&s->card, s->voice);
- s->voice = NULL;
- }
-
- if (s->dma_running) {
- if (s->freq) {
- audsettings_t as;
-
- s->audio_free = 0;
-
- as.freq = s->freq;
- as.nchannels = 1 << s->fmt_stereo;
- as.fmt = s->fmt;
- as.endianness = 0;
-
- s->voice = AUD_open_out (
- &s->card,
- s->voice,
- "sb16",
- s,
- SB_audio_callback,
- &as
- );
- }
-
- control (s, 1);
- speaker (s, s->speaker);
- }
- return 0;
-}
-
-int SB16_init (AudioState *audio)
-{
- SB16State *s;
- int i;
- static const uint8_t dsp_write_ports[] = {0x6, 0xc};
- static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
-
- if (!audio) {
- dolog ("No audio state\n");
- return -1;
- }
-
- s = qemu_mallocz (sizeof (*s));
- if (!s) {
- dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
- sizeof (*s));
- return -1;
- }
-
- s->cmd = -1;
- s->irq = conf.irq;
- s->dma = conf.dma;
- s->hdma = conf.hdma;
- s->port = conf.port;
- s->ver = conf.ver_lo | (conf.ver_hi << 8);
-
- s->mixer_regs[0x80] = magic_of_irq (s->irq);
- s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
- s->mixer_regs[0x82] = 2 << 5;
-
- s->csp_regs[5] = 1;
- s->csp_regs[9] = 0xf8;
-
- reset_mixer (s);
- s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
- if (!s->aux_ts) {
- dolog ("warning: Could not create auxiliary timer\n");
- }
-
- for (i = 0; i < LENOFA (dsp_write_ports); i++) {
- register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
- }
-
- for (i = 0; i < LENOFA (dsp_read_ports); i++) {
- register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
- }
-
- register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
- register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
- register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
- register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
-
- DMA_register_channel (s->hdma, SB_read_DMA, s);
- DMA_register_channel (s->dma, SB_read_DMA, s);
- s->can_write = 1;
-
- register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
- AUD_register_card (audio, "sb16", &s->card);
- return 0;
-}
diff --git a/tools/ioemu/hw/scsi-disk.c b/tools/ioemu/hw/scsi-disk.c
deleted file mode 100644
index 2ad204ba26..0000000000
--- a/tools/ioemu/hw/scsi-disk.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * SCSI Device emulation
- *
- * Copyright (c) 2006 CodeSourcery.
- * Based on code by Fabrice Bellard
- *
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- * Note that this file only handles the SCSI architecture model and device
- * commands. Emultion of interface/link layer protocols is handled by
- * the host adapter emulation.
- */
-
-//#define DEBUG_SCSI
-
-#ifdef DEBUG_SCSI
-#define DPRINTF(fmt, args...) \
-do { printf("scsi-disk: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-#define BADF(fmt, args...) \
-do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
-
-#include "vl.h"
-#include <malloc.h>
-
-#define SENSE_NO_SENSE 0
-#define SENSE_NOT_READY 2
-#define SENSE_HARDWARE_ERROR 4
-#define SENSE_ILLEGAL_REQUEST 5
-
-#ifdef CONFIG_STUBDOM
-#include <xen/io/blkif.h>
-#define SCSI_DMA_BUF_SIZE (BLKIF_MAX_SEGMENTS_PER_REQUEST * TARGET_PAGE_SIZE)
-#else
-#define SCSI_DMA_BUF_SIZE 131072
-#endif
-
-typedef struct SCSIRequest {
- SCSIDevice *dev;
- uint32_t tag;
- /* ??? We should probably keep track of whether the data trasfer is
- a read or a write. Currently we rely on the host getting it right. */
- /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
- int sector;
- int sector_count;
- /* The amounnt of data in the buffer. */
- int buf_len;
- uint8_t *dma_buf;
- BlockDriverAIOCB *aiocb;
- struct SCSIRequest *next;
-} SCSIRequest;
-
-struct SCSIDevice
-{
- BlockDriverState *bdrv;
- SCSIRequest *requests;
- /* The qemu block layer uses a fixed 512 byte sector size.
- This is the number of 512 byte blocks in a single scsi sector. */
- int cluster_size;
- int sense;
- int tcq;
- /* Completion functions may be called from either scsi_{read,write}_data
- or from the AIO completion routines. */
- scsi_completionfn completion;
- void *opaque;
-};
-
-/* Global pool of SCSIRequest structures. */
-static SCSIRequest *free_requests = NULL;
-
-static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag)
-{
- SCSIRequest *r;
-
- if (free_requests) {
- r = free_requests;
- free_requests = r->next;
- } else {
- r = qemu_malloc(sizeof(SCSIRequest));
- r->dma_buf = qemu_memalign(getpagesize(), SCSI_DMA_BUF_SIZE);
- }
- r->dev = s;
- r->tag = tag;
- r->sector_count = 0;
- r->buf_len = 0;
- r->aiocb = NULL;
-
- r->next = s->requests;
- s->requests = r;
- return r;
-}
-
-static void scsi_remove_request(SCSIRequest *r)
-{
- SCSIRequest *last;
- SCSIDevice *s = r->dev;
-
- if (s->requests == r) {
- s->requests = r->next;
- } else {
- last = s->requests;
- while (last && last->next != r)
- last = last->next;
- if (last) {
- last->next = r->next;
- } else {
- BADF("Orphaned request\n");
- }
- }
- r->next = free_requests;
- free_requests = r;
-}
-
-static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag)
-{
- SCSIRequest *r;
-
- r = s->requests;
- while (r && r->tag != tag)
- r = r->next;
-
- return r;
-}
-
-/* Helper function for command completion. */
-static void scsi_command_complete(SCSIRequest *r, int sense)
-{
- SCSIDevice *s = r->dev;
- uint32_t tag;
- DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
- s->sense = sense;
- tag = r->tag;
- scsi_remove_request(r);
- s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
-}
-
-/* Cancel a pending data transfer. */
-void scsi_cancel_io(SCSIDevice *s, uint32_t tag)
-{
- SCSIRequest *r;
- DPRINTF("Cancel tag=0x%x\n", tag);
- r = scsi_find_request(s, tag);
- if (r) {
- if (r->aiocb)
- bdrv_aio_cancel(r->aiocb);
- r->aiocb = NULL;
- scsi_remove_request(r);
- }
-}
-
-static void scsi_read_complete(void * opaque, int ret)
-{
- SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDevice *s = r->dev;
-
- if (ret) {
- DPRINTF("IO error\n");
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return;
- }
- DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
-
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
-}
-
-/* Read more data from scsi device into buffer. */
-void scsi_read_data(SCSIDevice *s, uint32_t tag)
-{
- SCSIRequest *r;
- uint32_t n;
-
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad read tag 0x%x\n", tag);
- /* ??? This is the wrong error. */
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return;
- }
- if (r->sector_count == (uint32_t)-1) {
- DPRINTF("Read buf_len=%d\n", r->buf_len);
- r->sector_count = 0;
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
- return;
- }
- DPRINTF("Read sector_count=%d\n", r->sector_count);
- if (r->sector_count == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- return;
- }
-
- n = r->sector_count;
- if (n > SCSI_DMA_BUF_SIZE / 512)
- n = SCSI_DMA_BUF_SIZE / 512;
-
- r->buf_len = n * 512;
- r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
- scsi_read_complete, r);
- if (r->aiocb == NULL)
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- r->sector += n;
- r->sector_count -= n;
-}
-
-static void scsi_write_complete(void * opaque, int ret)
-{
- SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDevice *s = r->dev;
- uint32_t len;
-
- if (ret) {
- fprintf(stderr, "scsi-disc: IO write error\n");
- exit(1);
- }
-
- r->aiocb = NULL;
- if (r->sector_count == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- } else {
- len = r->sector_count * 512;
- if (len > SCSI_DMA_BUF_SIZE) {
- len = SCSI_DMA_BUF_SIZE;
- }
- r->buf_len = len;
- DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
- }
-}
-
-/* Write data to a scsi device. Returns nonzero on failure.
- The transfer may complete asynchronously. */
-int scsi_write_data(SCSIDevice *s, uint32_t tag)
-{
- SCSIRequest *r;
- uint32_t n;
-
- DPRINTF("Write data tag=0x%x\n", tag);
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad write tag 0x%x\n", tag);
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return 1;
- }
- if (r->aiocb)
- BADF("Data transfer already in progress\n");
- n = r->buf_len / 512;
- if (n) {
- r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
- scsi_write_complete, r);
- if (r->aiocb == NULL)
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- r->sector += n;
- r->sector_count -= n;
- } else {
- /* Invoke completion routine to fetch data from host. */
- scsi_write_complete(r, 0);
- }
-
- return 0;
-}
-
-/* Return a pointer to the data buffer. */
-uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag)
-{
- SCSIRequest *r;
-
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad buffer tag 0x%x\n", tag);
- return NULL;
- }
- return r->dma_buf;
-}
-
-/* Execute a scsi command. Returns the length of the data expected by the
- command. This will be Positive for data transfers from the device
- (eg. disk reads), negative for transfers to the device (eg. disk writes),
- and zero if the command does not transfer any data. */
-
-int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
-{
- int64_t nb_sectors;
- uint32_t lba;
- uint32_t len;
- int cmdlen;
- int is_write;
- uint8_t command;
- uint8_t *outbuf;
- SCSIRequest *r;
- int ret;
-
- command = buf[0];
- r = scsi_find_request(s, tag);
- if (r) {
- BADF("Tag 0x%x already in use\n", tag);
- scsi_cancel_io(s, tag);
- }
- /* ??? Tags are not unique for different luns. We only implement a
- single lun, so this should not matter. */
- r = scsi_new_request(s, tag);
- outbuf = r->dma_buf;
- is_write = 0;
- DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
- switch (command >> 5) {
- case 0:
- lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
- len = buf[4];
- cmdlen = 6;
- break;
- case 1:
- case 2:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[8] | (buf[7] << 8);
- cmdlen = 10;
- break;
- case 4:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
- cmdlen = 16;
- break;
- case 5:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
- cmdlen = 12;
- break;
- default:
- BADF("Unsupported command length, command %x\n", command);
- goto fail;
- }
-#ifdef DEBUG_SCSI
- {
- int i;
- for (i = 1; i < cmdlen; i++) {
- printf(" 0x%02x", buf[i]);
- }
- printf("\n");
- }
-#endif
- if (lun || buf[1] >> 5) {
- /* Only LUN 0 supported. */
- DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
- goto fail;
- }
- switch (command) {
- case 0x0:
- DPRINTF("Test Unit Ready\n");
- break;
- case 0x03:
- DPRINTF("Request Sense (len %d)\n", len);
- if (len < 4)
- goto fail;
- memset(buf, 0, 4);
- outbuf[0] = 0xf0;
- outbuf[1] = 0;
- outbuf[2] = s->sense;
- r->buf_len = 4;
- break;
- case 0x12:
- DPRINTF("Inquiry (len %d)\n", len);
- if (len < 36) {
- BADF("Inquiry buffer too small (%d)\n", len);
- }
- memset(outbuf, 0, 36);
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[0] = 5;
- outbuf[1] = 0x80;
- memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
- } else {
- outbuf[0] = 0;
- memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
- }
- memcpy(&outbuf[8], "QEMU ", 8);
- memcpy(&outbuf[32], QEMU_VERSION, 4);
- /* Identify device as SCSI-3 rev 1.
- Some later commands are also implemented. */
- outbuf[2] = 3;
- outbuf[3] = 2; /* Format 2 */
- outbuf[4] = 32;
- /* Sync data transfer and TCQ. */
- outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
- r->buf_len = 36;
- break;
- case 0x16:
- DPRINTF("Reserve(6)\n");
- if (buf[1] & 1)
- goto fail;
- break;
- case 0x17:
- DPRINTF("Release(6)\n");
- if (buf[1] & 1)
- goto fail;
- break;
- case 0x1a:
- case 0x5a:
- {
- uint8_t *p;
- int page;
-
- page = buf[2] & 0x3f;
- DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
- p = outbuf;
- memset(p, 0, 4);
- outbuf[1] = 0; /* Default media type. */
- outbuf[3] = 0; /* Block descriptor length. */
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[2] = 0x80; /* Readonly. */
- }
- p += 4;
- if ((page == 8 || page == 0x3f)) {
- /* Caching page. */
- p[0] = 8;
- p[1] = 0x12;
- p[2] = 4; /* WCE */
- p += 19;
- }
- if ((page == 0x3f || page == 0x2a)
- && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
- /* CD Capabilities and Mechanical Status page. */
- p[0] = 0x2a;
- p[1] = 0x14;
- p[2] = 3; // CD-R & CD-RW read
- p[3] = 0; // Writing not supported
- p[4] = 0x7f; /* Audio, composite, digital out,
- mode 2 form 1&2, multi session */
- p[5] = 0xff; /* CD DA, DA accurate, RW supported,
- RW corrected, C2 errors, ISRC,
- UPC, Bar code */
- p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
- /* Locking supported, jumper present, eject, tray */
- p[7] = 0; /* no volume & mute control, no
- changer */
- p[8] = (50 * 176) >> 8; // 50x read speed
- p[9] = (50 * 176) & 0xff;
- p[10] = 0 >> 8; // No volume
- p[11] = 0 & 0xff;
- p[12] = 2048 >> 8; // 2M buffer
- p[13] = 2048 & 0xff;
- p[14] = (16 * 176) >> 8; // 16x read speed current
- p[15] = (16 * 176) & 0xff;
- p[18] = (16 * 176) >> 8; // 16x write speed
- p[19] = (16 * 176) & 0xff;
- p[20] = (16 * 176) >> 8; // 16x write speed current
- p[21] = (16 * 176) & 0xff;
- p += 21;
- }
- r->buf_len = p - outbuf;
- outbuf[0] = r->buf_len - 4;
- if (r->buf_len > len)
- r->buf_len = len;
- }
- break;
- case 0x1b:
- DPRINTF("Start Stop Unit\n");
- break;
- case 0x1e:
- DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
- bdrv_set_locked(s->bdrv, buf[4] & 1);
- break;
- case 0x25:
- DPRINTF("Read Capacity\n");
- /* The normal LEN field for this command is zero. */
- memset(outbuf, 0, 8);
- bdrv_get_geometry(s->bdrv, &nb_sectors);
- /* Returned value is the address of the last sector. */
- if (nb_sectors) {
- nb_sectors--;
- outbuf[0] = (nb_sectors >> 24) & 0xff;
- outbuf[1] = (nb_sectors >> 16) & 0xff;
- outbuf[2] = (nb_sectors >> 8) & 0xff;
- outbuf[3] = nb_sectors & 0xff;
- outbuf[4] = 0;
- outbuf[5] = 0;
- outbuf[6] = s->cluster_size * 2;
- outbuf[7] = 0;
- r->buf_len = 8;
- } else {
- scsi_command_complete(r, SENSE_NOT_READY);
- return 0;
- }
- break;
- case 0x08:
- case 0x28:
- DPRINTF("Read (sector %d, count %d)\n", lba, len);
- r->sector = lba * s->cluster_size;
- r->sector_count = len * s->cluster_size;
- break;
- case 0x0a:
- case 0x2a:
- DPRINTF("Write (sector %d, count %d)\n", lba, len);
- r->sector = lba * s->cluster_size;
- r->sector_count = len * s->cluster_size;
- is_write = 1;
- break;
- case 0x35:
- DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
- ret = bdrv_flush(s->bdrv);
- if (ret) {
- DPRINTF("IO error on bdrv_flush\n");
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return 0;
- }
- break;
- case 0x43:
- {
- int start_track, format, msf, toclen;
-
- msf = buf[1] & 2;
- format = buf[2] & 0xf;
- start_track = buf[6];
- bdrv_get_geometry(s->bdrv, &nb_sectors);
- DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
- switch(format) {
- case 0:
- toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
- break;
- case 1:
- /* multi session : only a single session defined */
- toclen = 12;
- memset(outbuf, 0, 12);
- outbuf[1] = 0x0a;
- outbuf[2] = 0x01;
- outbuf[3] = 0x01;
- break;
- case 2:
- toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
- break;
- default:
- goto error_cmd;
- }
- if (toclen > 0) {
- if (len > toclen)
- len = toclen;
- r->buf_len = len;
- break;
- }
- error_cmd:
- DPRINTF("Read TOC error\n");
- goto fail;
- }
- case 0x46:
- DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
- memset(outbuf, 0, 8);
- /* ??? This shoud probably return much more information. For now
- just return the basic header indicating the CD-ROM profile. */
- outbuf[7] = 8; // CD-ROM
- r->buf_len = 8;
- break;
- case 0x56:
- DPRINTF("Reserve(10)\n");
- if (buf[1] & 3)
- goto fail;
- break;
- case 0x57:
- DPRINTF("Release(10)\n");
- if (buf[1] & 3)
- goto fail;
- break;
- case 0xa0:
- DPRINTF("Report LUNs (len %d)\n", len);
- if (len < 16)
- goto fail;
- memset(outbuf, 0, 16);
- outbuf[3] = 8;
- r->buf_len = 16;
- break;
- default:
- DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
- fail:
- scsi_command_complete(r, SENSE_ILLEGAL_REQUEST);
- return 0;
- }
- if (r->sector_count == 0 && r->buf_len == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- }
- len = r->sector_count * 512 + r->buf_len;
- if (is_write) {
- return -len;
- } else {
- if (!r->sector_count)
- r->sector_count = -1;
- return len;
- }
-}
-
-void scsi_disk_destroy(SCSIDevice *s)
-{
- qemu_free(s);
-}
-
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
- int tcq,
- scsi_completionfn completion,
- void *opaque)
-{
- SCSIDevice *s;
-
- s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
- s->bdrv = bdrv;
- s->tcq = tcq;
- s->completion = completion;
- s->opaque = opaque;
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- s->cluster_size = 4;
- } else {
- s->cluster_size = 1;
- }
-
- return s;
-}
-
diff --git a/tools/ioemu/hw/serial.c b/tools/ioemu/hw/serial.c
deleted file mode 100644
index b0e0ec960d..0000000000
--- a/tools/ioemu/hw/serial.c
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- * QEMU 16550A UART emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-#include <sys/time.h>
-#include <time.h>
-#include <assert.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-
-//#define DEBUG_SERIAL
-
-#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
-
-#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
-#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
-#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
-#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
-
-#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
-#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
-
-#define UART_IIR_MSI 0x00 /* Modem status interrupt */
-#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
-#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
-#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
-#define UART_IIR_CTI 0x0C /* Character Timeout Indication */
-
-#define UART_IIR_FENF 0x80 /* Fifo enabled, but not functionning */
-#define UART_IIR_FE 0xC0 /* Fifo enabled */
-
-/*
- * These are the definitions for the Modem Control Register
- */
-#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
-#define UART_MCR_OUT2 0x08 /* Out2 complement */
-#define UART_MCR_OUT1 0x04 /* Out1 complement */
-#define UART_MCR_RTS 0x02 /* RTS complement */
-#define UART_MCR_DTR 0x01 /* DTR complement */
-
-/*
- * These are the definitions for the Modem Status Register
- */
-#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
-#define UART_MSR_RI 0x40 /* Ring Indicator */
-#define UART_MSR_DSR 0x20 /* Data Set Ready */
-#define UART_MSR_CTS 0x10 /* Clear to Send */
-#define UART_MSR_DDCD 0x08 /* Delta DCD */
-#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
-#define UART_MSR_DDSR 0x02 /* Delta DSR */
-#define UART_MSR_DCTS 0x01 /* Delta CTS */
-#define UART_MSR_ANY_DELTA 0x0F /* Any of the msr delta bits */
-
-#define UART_LSR_TEMT 0x40 /* Transmitter empty */
-#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
-#define UART_LSR_BI 0x10 /* Break interrupt indicator */
-#define UART_LSR_FE 0x08 /* Frame error indicator */
-#define UART_LSR_PE 0x04 /* Parity error indicator */
-#define UART_LSR_OE 0x02 /* Overrun error indicator */
-#define UART_LSR_DR 0x01 /* Receiver data ready */
-#define UART_LSR_INT_ANY 0x1E /* Any of the lsr-interrupt-triggering status bits */
-
-/* Interrupt trigger levels. The byte-counts are for 16550A - in newer UARTs the byte-count for each ITL is higher. */
-
-#define UART_FCR_ITL_1 0x00 /* 1 byte ITL */
-#define UART_FCR_ITL_2 0x40 /* 4 bytes ITL */
-#define UART_FCR_ITL_3 0x80 /* 8 bytes ITL */
-#define UART_FCR_ITL_4 0xC0 /* 14 bytes ITL */
-
-#define UART_FCR_DMS 0x08 /* DMA Mode Select */
-#define UART_FCR_XFR 0x04 /* XMIT Fifo Reset */
-#define UART_FCR_RFR 0x02 /* RCVR Fifo Reset */
-#define UART_FCR_FE 0x01 /* FIFO Enable */
-
-#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
-
-#define XMIT_FIFO 0
-#define RECV_FIFO 1
-#define MAX_XMIT_RETRY 4
-
-struct SerialFIFO {
- uint8_t data[UART_FIFO_LENGTH];
- uint8_t count;
- uint8_t itl; /* Interrupt Trigger Level */
- uint8_t tail;
- uint8_t head;
-} typedef SerialFIFO;
-
-struct SerialState {
- uint16_t divider;
- uint8_t rbr; /* receive register */
- uint8_t thr; /* transmit holding register */
- uint8_t tsr; /* transmit shift register */
- uint8_t ier;
- uint8_t iir; /* read only */
- uint8_t lcr;
- uint8_t mcr;
- uint8_t lsr; /* read only */
- uint8_t msr; /* read only */
- uint8_t scr;
- uint8_t fcr;
- /* NOTE: this hidden state is necessary for tx irq generation as
- it can be reset while reading iir */
- int thr_ipending;
- SetIRQFunc *set_irq;
- void *irq_opaque;
- int irq;
- CharDriverState *chr;
- int last_break_enable;
- target_ulong base;
- int it_shift;
- int tsr_retry;
-
- uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */
- SerialFIFO recv_fifo;
- SerialFIFO xmit_fifo;
-
- struct QEMUTimer *fifo_timeout_timer;
- int timeout_ipending; /* timeout interrupt pending state */
- struct QEMUTimer *transmit_timer;
-
-
- uint64_t char_transmit_time; /* time to transmit a char in ticks*/
- int poll_msl;
-
- struct QEMUTimer *modem_status_poll;
-};
-
-/* Rate limit serial requests so that e.g. grub on a serial console
- doesn't kill dom0. Simple token bucket. If we get some actual
- data from the user, instantly refil the bucket. */
-
-/* How long it takes to generate a token, in microseconds. */
-#define TOKEN_PERIOD 1000
-/* Maximum and initial size of token bucket */
-#define TOKENS_MAX 100000
-
-static int tokens_avail;
-
-static void fifo_clear(SerialState *s, int fifo) {
- SerialFIFO *f = ( fifo ) ? &s->recv_fifo : &s->xmit_fifo;
- memset(f->data, 0, UART_FIFO_LENGTH);
- f->count = 0;
- f->head = 0;
- f->tail = 0;
-}
-
-static int fifo_put(SerialState *s, int fifo, uint8_t chr) {
- SerialFIFO *f = ( fifo ) ? &s->recv_fifo : &s->xmit_fifo;
-
- f->data[f->head++] = chr;
-
- if (f->head == UART_FIFO_LENGTH)
- f->head = 0;
- f->count++;
-
- tokens_avail = TOKENS_MAX;
-
- return 1;
-}
-
-uint8_t fifo_get(SerialState *s, int fifo) {
- SerialFIFO *f = ( fifo ) ? &s->recv_fifo : &s->xmit_fifo;
- uint8_t c;
-
- if( f->count == 0 )
- return 0;
-
- c = f->data[f->tail++];
- if (f->tail == UART_FIFO_LENGTH)
- f->tail = 0;
- f->count--;
-
- tokens_avail = TOKENS_MAX;
-
- return c;
-}
-
-static void serial_update_irq(SerialState *s)
-{
- uint8_t tmp_iir = UART_IIR_NO_INT;
-
- if (!s->ier) {
- s->set_irq(s->irq_opaque, s->irq, 0);
- return;
- }
-
- if ( ( s->ier & UART_IER_RLSI ) && (s->lsr & UART_LSR_INT_ANY ) ) {
- tmp_iir = UART_IIR_RLSI;
- } else if ( s->timeout_ipending ) {
- tmp_iir = UART_IIR_CTI;
- } else if ( ( s->ier & UART_IER_RDI ) && (s->lsr & UART_LSR_DR ) ) {
- if ( !(s->fcr & UART_FCR_FE) ) {
- tmp_iir = UART_IIR_RDI;
- } else if ( s->recv_fifo.count >= s->recv_fifo.itl ) {
- tmp_iir = UART_IIR_RDI;
- }
- } else if ( (s->ier & UART_IER_THRI) && s->thr_ipending ) {
- tmp_iir = UART_IIR_THRI;
- } else if ( (s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA) ) {
- tmp_iir = UART_IIR_MSI;
- }
-
- s->iir = tmp_iir | ( s->iir & 0xF0 );
-
- if ( tmp_iir != UART_IIR_NO_INT ) {
- s->set_irq(s->irq_opaque, s->irq, 1);
- } else {
- s->set_irq(s->irq_opaque, s->irq, 0);
- }
-}
-
-static void serial_update_parameters(SerialState *s)
-{
- int speed, parity, data_bits, stop_bits, frame_size;
- QEMUSerialSetParams ssp;
-
- if (s->divider == 0)
- return;
-
- frame_size = 1;
- if (s->lcr & 0x08) {
- if (s->lcr & 0x10)
- parity = 'E';
- else
- parity = 'O';
- } else {
- parity = 'N';
- frame_size = 0;
- }
- if (s->lcr & 0x04)
- stop_bits = 2;
- else
- stop_bits = 1;
-
- data_bits = (s->lcr & 0x03) + 5;
- frame_size += data_bits + stop_bits;
-
- speed = 115200 / s->divider;
- ssp.speed = speed;
- ssp.parity = parity;
- ssp.data_bits = data_bits;
- ssp.stop_bits = stop_bits;
- s->char_transmit_time = ( ticks_per_sec / speed ) * frame_size;
- qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
-#if 0
- printf("speed=%d parity=%c data=%d stop=%d\n",
- speed, parity, data_bits, stop_bits);
-#endif
-}
-
-static void serial_get_token(void)
-{
- static struct timeval last_refil_time;
- static int started;
-
- assert(tokens_avail >= 0);
- if (!tokens_avail) {
- struct timeval delta, now;
- int generated;
-
- if (!started) {
- gettimeofday(&last_refil_time, NULL);
- tokens_avail = TOKENS_MAX;
- started = 1;
- return;
- }
- retry:
- gettimeofday(&now, NULL);
- delta.tv_sec = now.tv_sec - last_refil_time.tv_sec;
- delta.tv_usec = now.tv_usec - last_refil_time.tv_usec;
- if (delta.tv_usec < 0) {
- delta.tv_usec += 1000000;
- delta.tv_sec--;
- }
- assert(delta.tv_usec >= 0 && delta.tv_sec >= 0);
- if (delta.tv_usec < TOKEN_PERIOD) {
- struct timespec ts;
- /* Wait until at least one token is available. */
- ts.tv_sec = TOKEN_PERIOD / 1000000;
- ts.tv_nsec = (TOKEN_PERIOD % 1000000) * 1000;
- while (nanosleep(&ts, &ts) < 0 && errno == EINTR)
- ;
- goto retry;
- }
- generated = (delta.tv_sec * 1000000) / TOKEN_PERIOD;
- generated +=
- ((delta.tv_sec * 1000000) % TOKEN_PERIOD + delta.tv_usec) / TOKEN_PERIOD;
- assert(generated > 0);
-
- last_refil_time.tv_usec += (generated * TOKEN_PERIOD) % 1000000;
- last_refil_time.tv_sec += last_refil_time.tv_usec / 1000000;
- last_refil_time.tv_usec %= 1000000;
- last_refil_time.tv_sec += (generated * TOKEN_PERIOD) / 1000000;
- if (generated > TOKENS_MAX)
- generated = TOKENS_MAX;
- tokens_avail = generated;
- }
- tokens_avail--;
-}
-
-static void serial_update_msl( SerialState *s )
-{
- uint8_t omsr;
- int flags;
-
- qemu_del_timer(s->modem_status_poll);
-
- if ( qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP ) {
- s->poll_msl = -1;
- return;
- }
-
- omsr = s->msr;
-
- s->msr = ( flags & TIOCM_CTS ) ? s->msr | UART_MSR_CTS : s->msr & ~UART_MSR_CTS;
- s->msr = ( flags & TIOCM_DSR ) ? s->msr | UART_MSR_DSR : s->msr & ~UART_MSR_DSR;
- s->msr = ( flags & TIOCM_CAR ) ? s->msr | UART_MSR_DCD : s->msr & ~UART_MSR_DCD;
- s->msr = ( flags & TIOCM_RI ) ? s->msr | UART_MSR_RI : s->msr & ~UART_MSR_RI;
-
- if ( s->msr != omsr ) {
- /* Set delta bits */
- s->msr = s->msr | ( ( s->msr >> 4 ) ^ ( omsr >> 4 ) );
- /* UART_MSR_TERI only if change was from 1 -> 0 */
- if ( ( s->msr & UART_MSR_TERI ) && !( omsr & UART_MSR_RI ) )
- s->msr &= ~UART_MSR_TERI;
- serial_update_irq(s);
- }
-
- /* The real 16550A apparently has a 250ns response latency to line status changes.
- We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */
-
- if ( s->poll_msl )
- qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + ticks_per_sec / 100);
-}
-
-static void serial_xmit(void *opaque) {
- SerialState *s = opaque;
- uint64_t new_xmit_ts = qemu_get_clock(vm_clock);
-
- if ( s->tsr_retry <= 0 ) {
- if (s->fcr & UART_FCR_FE) {
- s->tsr = fifo_get(s,XMIT_FIFO);
- if ( !s->xmit_fifo.count )
- s->lsr |= UART_LSR_THRE;
- } else {
- s->tsr = s->thr;
- s->lsr |= UART_LSR_THRE;
- }
- }
-
- if ( qemu_chr_write(s->chr, &s->tsr, 1) != 1 ) {
- if ( ( s->tsr_retry > 0 ) && ( s->tsr_retry <= MAX_XMIT_RETRY ) ) {
- s->tsr_retry++;
- qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time );
- return;
- } else if ( s->poll_msl < 0 ) {
- /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then
- drop any further failed writes instantly, until we get one that goes through.
- This is to prevent guests that log to unconnected pipes or pty's from stalling. */
- s->tsr_retry = -1;
- }
- }
- else {
- s->tsr_retry = 0;
- }
-
- s->last_xmit_ts = qemu_get_clock(vm_clock);
- if ( !(s->lsr & UART_LSR_THRE) )
- qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time );
-
- if ( s->lsr & UART_LSR_THRE ) {
- s->lsr |= UART_LSR_TEMT;
- s->thr_ipending = 1;
- serial_update_irq(s);
- }
-}
-
-
-static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- SerialState *s = opaque;
-
- addr &= 7;
-#ifdef DEBUG_SERIAL
- printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
-#endif
- switch(addr) {
- default:
- case 0:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0xff00) | val;
- serial_update_parameters(s);
- } else {
- s->thr = (uint8_t) val;
- if(s->fcr & UART_FCR_FE) {
- fifo_put(s, XMIT_FIFO, s->thr);
- s->thr_ipending = 0;
- s->lsr &= ~UART_LSR_TEMT;
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
- } else {
- s->thr_ipending = 0;
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
- }
- serial_xmit(s);
- }
- break;
- case 1:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0x00ff) | (val << 8);
- serial_update_parameters(s);
- } else {
- s->ier = val & 0x0f;
- /* If the backend device is a real serial port, turn polling of the modem
- status lines on physical port on or off depending on UART_IER_MSI state */
- if ( s->poll_msl >= 0 ) {
- if ( s->ier & UART_IER_MSI ) {
- s->poll_msl = 1;
- serial_update_msl(s);
- } else {
- qemu_del_timer(s->modem_status_poll);
- s->poll_msl = 0;
- }
- }
- if (s->lsr & UART_LSR_THRE) {
- s->thr_ipending = 1;
- serial_update_irq(s);
- }
- }
- break;
- case 2:
- val = val & 0xFF;
-
- if ( s->fcr == val)
- break;
-
- /* Did the enable/disable flag change? If so, make sure FIFOs get flushed */
- if ( (val ^ s->fcr) & UART_FCR_FE )
- val |= UART_FCR_XFR | UART_FCR_RFR;
-
- /* FIFO clear */
-
- if ( val & UART_FCR_RFR ) {
- qemu_del_timer(s->fifo_timeout_timer);
- s->timeout_ipending=0;
- fifo_clear(s,RECV_FIFO);
- }
-
- if ( val & UART_FCR_XFR ) {
- fifo_clear(s,XMIT_FIFO);
- }
-
- if ( val & UART_FCR_FE ) {
- s->iir |= UART_IIR_FE;
- /* Set RECV_FIFO trigger Level */
- switch ( val & 0xC0 ) {
- case UART_FCR_ITL_1:
- s->recv_fifo.itl = 1;
- break;
- case UART_FCR_ITL_2:
- s->recv_fifo.itl = 4;
- break;
- case UART_FCR_ITL_3:
- s->recv_fifo.itl = 8;
- break;
- case UART_FCR_ITL_4:
- s->recv_fifo.itl = 14;
- break;
- }
- } else
- s->iir &= ~UART_IIR_FE;
-
- /* Set fcr - or at least the bits in it that are supposed to "stick" */
- s->fcr = val & 0xC9;
- serial_update_irq(s);
- break;
- case 3:
- {
- int break_enable;
- s->lcr = val;
- serial_update_parameters(s);
- break_enable = (val >> 6) & 1;
- if (break_enable != s->last_break_enable) {
- s->last_break_enable = break_enable;
- qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
- &break_enable);
- }
- }
- break;
- case 4:
- {
- int flags;
- int old_mcr = s->mcr;
- s->mcr = val & 0x1f;
- if ( val & UART_MCR_LOOP )
- break;
-
- if ( s->poll_msl >= 0 && old_mcr != s->mcr ) {
-
- qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
-
- flags &= ~( TIOCM_RTS | TIOCM_DTR );
-
- if ( val & UART_MCR_RTS )
- flags |= TIOCM_RTS;
- if ( val & UART_MCR_DTR )
- flags |= TIOCM_DTR;
-
- qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
- /* Update the modem status after a one-character-send wait-time, since there may be a response
- from the device/computer at the other end of the serial line */
- qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + s->char_transmit_time );
- }
- }
- break;
- case 5:
- break;
- case 6:
- break;
- case 7:
- s->scr = val;
- break;
- }
-}
-
-static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
-{
- SerialState *s = opaque;
- uint32_t ret;
-
- addr &= 7;
- switch(addr) {
- default:
- case 0:
- if (s->lcr & UART_LCR_DLAB) {
- ret = s->divider & 0xff;
- } else {
- if(s->fcr & UART_FCR_FE) {
- ret = fifo_get(s,RECV_FIFO);
- if ( s->recv_fifo.count == 0 )
- s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
- else
- qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4 );
- s->timeout_ipending = 0;
- } else {
- ret = s->rbr;
- s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
- }
- serial_update_irq(s);
- }
- break;
- case 1:
- if (s->lcr & UART_LCR_DLAB) {
- ret = (s->divider >> 8) & 0xff;
- } else {
- ret = s->ier;
- }
- break;
- case 2:
- ret = s->iir;
- s->thr_ipending = 0;
- serial_update_irq(s);
- break;
- case 3:
- ret = s->lcr;
- break;
- case 4:
- ret = s->mcr;
- break;
- case 5:
- serial_get_token();
- ret = s->lsr;
- /* Clear break interrupt */
- if ( s->lsr & UART_LSR_BI ) {
- s->lsr &= ~UART_LSR_BI;
- serial_update_irq(s);
- }
- break;
- case 6:
- serial_get_token();
- if (s->mcr & UART_MCR_LOOP) {
- /* in loopback, the modem output pins are connected to the
- inputs */
- ret = (s->mcr & 0x0c) << 4;
- ret |= (s->mcr & 0x02) << 3;
- ret |= (s->mcr & 0x01) << 5;
- } else {
- if ( s->poll_msl >= 0 )
- serial_update_msl(s);
- ret = s->msr;
- /* Clear delta bits & msr int after read, if they were set */
- if ( s->msr & UART_MSR_ANY_DELTA ) {
- s->msr &= 0xF0;
- serial_update_irq(s);
- }
- }
- break;
- case 7:
- ret = s->scr;
- break;
- }
-#ifdef DEBUG_SERIAL
- printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
-#endif
- return ret;
-}
-
-static int serial_can_receive(SerialState *s)
-{
- if(s->fcr & UART_FCR_FE) {
- if(s->recv_fifo.count < UART_FIFO_LENGTH)
- /* Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1 if above. If UART_FIFO_LENGTH - fifo.count is
- advertised the effect will be to almost always fill the fifo completely before the guest has a chance to respond,
- effectively overriding the ITL that the guest has set. */
- return ( s->recv_fifo.count <= s->recv_fifo.itl ) ? s->recv_fifo.itl - s->recv_fifo.count : 1;
- else
- return 0;
- } else {
- return !(s->lsr & UART_LSR_DR);
- }
-}
-
-static void serial_receive_break(SerialState *s)
-{
- s->rbr = 0;
- s->lsr |= UART_LSR_BI | UART_LSR_DR;
- serial_update_irq(s);
-}
-
-/* There's data in recv_fifo and s->rbr has not been read for 4 char transmit times */
-static void fifo_timeout_int (void *opaque) {
- SerialState *s = opaque;
- if ( s->recv_fifo.count ) {
- s->timeout_ipending = 1;
- serial_update_irq(s);
- }
-}
-
-static int serial_can_receive1(void *opaque)
-{
- SerialState *s = opaque;
- return serial_can_receive(s);
-}
-
-static void serial_receive1(void *opaque, const uint8_t *buf, int size)
-{
- SerialState *s = opaque;
- tokens_avail = TOKENS_MAX;
- if(s->fcr & UART_FCR_FE) {
- int i;
- for (i = 0; i < size; i++) {
- fifo_put(s, RECV_FIFO, buf[i]);
- }
- s->lsr |= UART_LSR_DR;
- /* call the timeout receive callback in 4 char transmit time */
- qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
- } else {
- s->rbr = buf[0];
- s->lsr |= UART_LSR_DR;
- }
- serial_update_irq(s);
-}
-
-static void serial_event(void *opaque, int event)
-{
- SerialState *s = opaque;
- tokens_avail = TOKENS_MAX;
- if (event == CHR_EVENT_BREAK)
- serial_receive_break(s);
-}
-
-static void serial_save(QEMUFile *f, void *opaque)
-{
- SerialState *s = opaque;
-
- qemu_put_be16s(f,&s->divider);
- qemu_put_8s(f,&s->rbr);
- qemu_put_8s(f,&s->ier);
- qemu_put_8s(f,&s->iir);
- qemu_put_8s(f,&s->lcr);
- qemu_put_8s(f,&s->mcr);
- qemu_put_8s(f,&s->lsr);
- qemu_put_8s(f,&s->msr);
- qemu_put_8s(f,&s->scr);
- qemu_put_8s(f,&s->fcr);
-}
-
-static int serial_load(QEMUFile *f, void *opaque, int version_id)
-{
- SerialState *s = opaque;
- uint8_t fcr = 0;
-
- if(version_id > 2)
- return -EINVAL;
-
- if (version_id >= 2)
- qemu_get_be16s(f, &s->divider);
- else
- s->divider = qemu_get_byte(f);
- qemu_get_8s(f,&s->rbr);
- qemu_get_8s(f,&s->ier);
- qemu_get_8s(f,&s->iir);
- qemu_get_8s(f,&s->lcr);
- qemu_get_8s(f,&s->mcr);
- qemu_get_8s(f,&s->lsr);
- qemu_get_8s(f,&s->msr);
- qemu_get_8s(f,&s->scr);
-
- if (version_id >= 2)
- qemu_get_8s(f,&fcr);
-
- /* Initialize fcr via setter to perform essential side-effects */
- serial_ioport_write(s, 0x02, fcr);
- return 0;
-}
-
-/* If fd is zero, it means that the serial device uses the console */
-SerialState *serial_init(SetIRQFunc *set_irq, void *opaque,
- int base, int irq, CharDriverState *chr)
-{
- SerialState *s;
-
- s = qemu_mallocz(sizeof(SerialState));
- if (!s)
- return NULL;
- s->set_irq = set_irq;
- s->irq_opaque = opaque;
- s->irq = irq;
- s->ier = 0;
- s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
- s->iir = UART_IIR_NO_INT;
- s->mcr = UART_MCR_OUT2;
- s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
- /* Default to 9600 baud, no parity, one stop bit */
- s->divider = 0x0C;
- s->tsr_retry = 0;
- s->char_transmit_time = ( ticks_per_sec / 9600 ) * 9;
-
- s->modem_status_poll = qemu_new_timer(vm_clock, ( QEMUTimerCB *) serial_update_msl, s);
-
- s->poll_msl = 0;
-
- fifo_clear(s,RECV_FIFO);
- fifo_clear(s,XMIT_FIFO);
- s->last_xmit_ts = qemu_get_clock(vm_clock);
- s->fifo_timeout_timer = qemu_new_timer(vm_clock, ( QEMUTimerCB *) fifo_timeout_int, s);
- s->transmit_timer = qemu_new_timer(vm_clock, ( QEMUTimerCB *) serial_xmit, s);
-
- register_savevm("serial", base, 2, serial_save, serial_load, s);
-
- register_ioport_write(base, 8, 1, serial_ioport_write, s);
- register_ioport_read(base, 8, 1, serial_ioport_read, s);
- s->chr = chr;
- qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
- serial_event, s);
- serial_update_msl(s);
- return s;
-}
diff --git a/tools/ioemu/hw/sh7750.c b/tools/ioemu/hw/sh7750.c
deleted file mode 100644
index 164ce71623..0000000000
--- a/tools/ioemu/hw/sh7750.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * SH7750 device
- *
- * Copyright (c) 2005 Samuel Tardieu
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <stdio.h>
-#include <assert.h>
-#include "vl.h"
-#include "sh7750_regs.h"
-#include "sh7750_regnames.h"
-
-typedef struct {
- uint8_t data[16];
- uint8_t length; /* Number of characters in the FIFO */
- uint8_t write_idx; /* Index of first character to write */
- uint8_t read_idx; /* Index of first character to read */
-} fifo;
-
-#define NB_DEVICES 4
-
-typedef struct SH7750State {
- /* CPU */
- CPUSH4State *cpu;
- /* Peripheral frequency in Hz */
- uint32_t periph_freq;
- /* SDRAM controller */
- uint16_t rfcr;
- /* First serial port */
- CharDriverState *serial1;
- uint8_t scscr1;
- uint8_t scsmr1;
- uint8_t scbrr1;
- uint8_t scssr1;
- uint8_t scssr1_read;
- uint8_t sctsr1;
- uint8_t sctsr1_loaded;
- uint8_t sctdr1;
- uint8_t scrdr1;
- /* Second serial port */
- CharDriverState *serial2;
- uint16_t sclsr2;
- uint16_t scscr2;
- uint16_t scfcr2;
- uint16_t scfsr2;
- uint16_t scsmr2;
- uint8_t scbrr2;
- fifo serial2_receive_fifo;
- fifo serial2_transmit_fifo;
- /* Timers */
- uint8_t tstr;
- /* Timer 0 */
- QEMUTimer *timer0;
- uint16_t tcr0;
- uint32_t tcor0;
- uint32_t tcnt0;
- /* IO ports */
- uint16_t gpioic;
- uint32_t pctra;
- uint32_t pctrb;
- uint16_t portdira; /* Cached */
- uint16_t portpullupa; /* Cached */
- uint16_t portdirb; /* Cached */
- uint16_t portpullupb; /* Cached */
- uint16_t pdtra;
- uint16_t pdtrb;
- uint16_t periph_pdtra; /* Imposed by the peripherals */
- uint16_t periph_portdira; /* Direction seen from the peripherals */
- uint16_t periph_pdtrb; /* Imposed by the peripherals */
- uint16_t periph_portdirb; /* Direction seen from the peripherals */
- sh7750_io_device *devices[NB_DEVICES]; /* External peripherals */
- /* Cache */
- uint32_t ccr;
-} SH7750State;
-
-/**********************************************************************
- Timers
-**********************************************************************/
-
-/* XXXXX At this time, timer0 works in underflow only mode, that is
- the value of tcnt0 is read at alarm computation time and cannot
- be read back by the guest OS */
-
-static void start_timer0(SH7750State * s)
-{
- uint64_t now, next, prescaler;
-
- if ((s->tcr0 & 6) == 6) {
- fprintf(stderr, "rtc clock for timer 0 not supported\n");
- assert(0);
- }
-
- if ((s->tcr0 & 7) == 5) {
- fprintf(stderr, "timer 0 configuration not supported\n");
- assert(0);
- }
-
- if ((s->tcr0 & 4) == 4)
- prescaler = 1024;
- else
- prescaler = 4 << (s->tcr0 & 3);
-
- now = qemu_get_clock(vm_clock);
- /* XXXXX */
- next =
- now + muldiv64(prescaler * s->tcnt0, ticks_per_sec,
- s->periph_freq);
- if (next == now)
- next = now + 1;
- fprintf(stderr, "now=%016" PRIx64 ", next=%016" PRIx64 "\n", now, next);
- fprintf(stderr, "timer will underflow in %f seconds\n",
- (float) (next - now) / (float) ticks_per_sec);
-
- qemu_mod_timer(s->timer0, next);
-}
-
-static void timer_start_changed(SH7750State * s)
-{
- if (s->tstr & SH7750_TSTR_STR0) {
- start_timer0(s);
- } else {
- fprintf(stderr, "timer 0 is stopped\n");
- qemu_del_timer(s->timer0);
- }
-}
-
-static void timer0_cb(void *opaque)
-{
- SH7750State *s = opaque;
-
- s->tcnt0 = (uint32_t) 0; /* XXXXX */
- if (--s->tcnt0 == (uint32_t) - 1) {
- fprintf(stderr, "timer 0 underflow\n");
- s->tcnt0 = s->tcor0;
- s->tcr0 |= SH7750_TCR_UNF;
- if (s->tcr0 & SH7750_TCR_UNIE) {
- fprintf(stderr,
- "interrupt generation for timer 0 not supported\n");
- assert(0);
- }
- }
- start_timer0(s);
-}
-
-static void init_timers(SH7750State * s)
-{
- s->tcor0 = 0xffffffff;
- s->tcnt0 = 0xffffffff;
- s->timer0 = qemu_new_timer(vm_clock, &timer0_cb, s);
-}
-
-/**********************************************************************
- First serial port
-**********************************************************************/
-
-static int serial1_can_receive(void *opaque)
-{
- SH7750State *s = opaque;
-
- return s->scscr1 & SH7750_SCSCR_RE;
-}
-
-static void serial1_receive_char(SH7750State * s, uint8_t c)
-{
- if (s->scssr1 & SH7750_SCSSR1_RDRF) {
- s->scssr1 |= SH7750_SCSSR1_ORER;
- return;
- }
-
- s->scrdr1 = c;
- s->scssr1 |= SH7750_SCSSR1_RDRF;
-}
-
-static void serial1_receive(void *opaque, const uint8_t * buf, int size)
-{
- SH7750State *s = opaque;
- int i;
-
- for (i = 0; i < size; i++) {
- serial1_receive_char(s, buf[i]);
- }
-}
-
-static void serial1_event(void *opaque, int event)
-{
- assert(0);
-}
-
-static void serial1_maybe_send(SH7750State * s)
-{
- uint8_t c;
-
- if (s->scssr1 & SH7750_SCSSR1_TDRE)
- return;
- c = s->sctdr1;
- s->scssr1 |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
- if (s->scscr1 & SH7750_SCSCR_TIE) {
- fprintf(stderr, "interrupts for serial port 1 not implemented\n");
- assert(0);
- }
- /* XXXXX Check for errors in write */
- qemu_chr_write(s->serial1, &c, 1);
-}
-
-static void serial1_change_scssr1(SH7750State * s, uint8_t mem_value)
-{
- uint8_t new_flags;
-
- /* If transmit disable, TDRE and TEND stays up */
- if ((s->scscr1 & SH7750_SCSCR_TE) == 0) {
- mem_value |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
- }
-
- /* Only clear bits which have been read before and do not set any bit
- in the flags */
- new_flags = s->scssr1 & ~s->scssr1_read; /* Preserve unread flags */
- new_flags &= mem_value | ~s->scssr1_read; /* Clear read flags */
-
- s->scssr1 = (new_flags & 0xf8) | (mem_value & 1);
- s->scssr1_read &= mem_value;
-
- /* If TDRE has been cleared, TEND will also be cleared */
- if ((s->scssr1 & SH7750_SCSSR1_TDRE) == 0) {
- s->scssr1 &= ~SH7750_SCSSR1_TEND;
- }
-
- /* Check for transmission to start */
- serial1_maybe_send(s);
-}
-
-static void serial1_update_parameters(SH7750State * s)
-{
- QEMUSerialSetParams ssp;
-
- if (s->scsmr1 & SH7750_SCSMR_CHR_7)
- ssp.data_bits = 7;
- else
- ssp.data_bits = 8;
- if (s->scsmr1 & SH7750_SCSMR_PE) {
- if (s->scsmr1 & SH7750_SCSMR_PM_ODD)
- ssp.parity = 'O';
- else
- ssp.parity = 'E';
- } else
- ssp.parity = 'N';
- if (s->scsmr1 & SH7750_SCSMR_STOP_2)
- ssp.stop_bits = 2;
- else
- ssp.stop_bits = 1;
- fprintf(stderr, "SCSMR1=%04x SCBRR1=%02x\n", s->scsmr1, s->scbrr1);
- ssp.speed = s->periph_freq /
- (32 * s->scbrr1 * (1 << (2 * (s->scsmr1 & 3)))) - 1;
- fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
- ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
- qemu_chr_ioctl(s->serial1, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
-}
-
-static void scscr1_changed(SH7750State * s)
-{
- if (s->scscr1 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
- if (!s->serial1) {
- fprintf(stderr, "serial port 1 not bound to anything\n");
- assert(0);
- }
- serial1_update_parameters(s);
- }
- if ((s->scscr1 & SH7750_SCSCR_RE) == 0) {
- s->scssr1 |= SH7750_SCSSR1_TDRE;
- }
-}
-
-static void init_serial1(SH7750State * s, int serial_nb)
-{
- CharDriverState *chr;
-
- s->scssr1 = 0x84;
- chr = serial_hds[serial_nb];
- if (!chr) {
- fprintf(stderr,
- "no serial port associated to SH7750 first serial port\n");
- return;
- }
-
- s->serial1 = chr;
- qemu_chr_add_handlers(chr, serial1_can_receive,
- serial1_receive, serial1_event, s);
-}
-
-/**********************************************************************
- Second serial port
-**********************************************************************/
-
-static int serial2_can_receive(void *opaque)
-{
- SH7750State *s = opaque;
- static uint8_t max_fifo_size[] = { 15, 1, 4, 6, 8, 10, 12, 14 };
-
- return s->serial2_receive_fifo.length <
- max_fifo_size[(s->scfcr2 >> 9) & 7];
-}
-
-static void serial2_adjust_receive_flags(SH7750State * s)
-{
- static uint8_t max_fifo_size[] = { 1, 4, 8, 14 };
-
- /* XXXXX Add interrupt generation */
- if (s->serial2_receive_fifo.length >=
- max_fifo_size[(s->scfcr2 >> 7) & 3]) {
- s->scfsr2 |= SH7750_SCFSR2_RDF;
- s->scfsr2 &= ~SH7750_SCFSR2_DR;
- } else {
- s->scfsr2 &= ~SH7750_SCFSR2_RDF;
- if (s->serial2_receive_fifo.length > 0)
- s->scfsr2 |= SH7750_SCFSR2_DR;
- else
- s->scfsr2 &= ~SH7750_SCFSR2_DR;
- }
-}
-
-static void serial2_append_char(SH7750State * s, uint8_t c)
-{
- if (s->serial2_receive_fifo.length == 16) {
- /* Overflow */
- s->sclsr2 |= SH7750_SCLSR2_ORER;
- return;
- }
-
- s->serial2_receive_fifo.data[s->serial2_receive_fifo.write_idx++] = c;
- s->serial2_receive_fifo.length++;
- serial2_adjust_receive_flags(s);
-}
-
-static void serial2_receive(void *opaque, const uint8_t * buf, int size)
-{
- SH7750State *s = opaque;
- int i;
-
- for (i = 0; i < size; i++)
- serial2_append_char(s, buf[i]);
-}
-
-static void serial2_event(void *opaque, int event)
-{
- /* XXXXX */
- assert(0);
-}
-
-static void serial2_update_parameters(SH7750State * s)
-{
- QEMUSerialSetParams ssp;
-
- if (s->scsmr2 & SH7750_SCSMR_CHR_7)
- ssp.data_bits = 7;
- else
- ssp.data_bits = 8;
- if (s->scsmr2 & SH7750_SCSMR_PE) {
- if (s->scsmr2 & SH7750_SCSMR_PM_ODD)
- ssp.parity = 'O';
- else
- ssp.parity = 'E';
- } else
- ssp.parity = 'N';
- if (s->scsmr2 & SH7750_SCSMR_STOP_2)
- ssp.stop_bits = 2;
- else
- ssp.stop_bits = 1;
- fprintf(stderr, "SCSMR2=%04x SCBRR2=%02x\n", s->scsmr2, s->scbrr2);
- ssp.speed = s->periph_freq /
- (32 * s->scbrr2 * (1 << (2 * (s->scsmr2 & 3)))) - 1;
- fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
- ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
- qemu_chr_ioctl(s->serial2, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
-}
-
-static void scscr2_changed(SH7750State * s)
-{
- if (s->scscr2 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
- if (!s->serial2) {
- fprintf(stderr, "serial port 2 not bound to anything\n");
- assert(0);
- }
- serial2_update_parameters(s);
- }
-}
-
-static void init_serial2(SH7750State * s, int serial_nb)
-{
- CharDriverState *chr;
-
- s->scfsr2 = 0x0060;
-
- chr = serial_hds[serial_nb];
- if (!chr) {
- fprintf(stderr,
- "no serial port associated to SH7750 second serial port\n");
- return;
- }
-
- s->serial2 = chr;
- qemu_chr_add_handlers(chr, serial2_can_receive,
- serial2_receive, serial1_event, s);
-}
-
-static void init_serial_ports(SH7750State * s)
-{
- init_serial1(s, 0);
- init_serial2(s, 1);
-}
-
-/**********************************************************************
- I/O ports
-**********************************************************************/
-
-int sh7750_register_io_device(SH7750State * s, sh7750_io_device * device)
-{
- int i;
-
- for (i = 0; i < NB_DEVICES; i++) {
- if (s->devices[i] == NULL) {
- s->devices[i] = device;
- return 0;
- }
- }
- return -1;
-}
-
-static uint16_t portdir(uint32_t v)
-{
-#define EVENPORTMASK(n) ((v & (1<<((n)<<1))) >> (n))
- return
- EVENPORTMASK(15) | EVENPORTMASK(14) | EVENPORTMASK(13) |
- EVENPORTMASK(12) | EVENPORTMASK(11) | EVENPORTMASK(10) |
- EVENPORTMASK(9) | EVENPORTMASK(8) | EVENPORTMASK(7) |
- EVENPORTMASK(6) | EVENPORTMASK(5) | EVENPORTMASK(4) |
- EVENPORTMASK(3) | EVENPORTMASK(2) | EVENPORTMASK(1) |
- EVENPORTMASK(0);
-}
-
-static uint16_t portpullup(uint32_t v)
-{
-#define ODDPORTMASK(n) ((v & (1<<(((n)<<1)+1))) >> (n))
- return
- ODDPORTMASK(15) | ODDPORTMASK(14) | ODDPORTMASK(13) |
- ODDPORTMASK(12) | ODDPORTMASK(11) | ODDPORTMASK(10) |
- ODDPORTMASK(9) | ODDPORTMASK(8) | ODDPORTMASK(7) | ODDPORTMASK(6) |
- ODDPORTMASK(5) | ODDPORTMASK(4) | ODDPORTMASK(3) | ODDPORTMASK(2) |
- ODDPORTMASK(1) | ODDPORTMASK(0);
-}
-
-static uint16_t porta_lines(SH7750State * s)
-{
- return (s->portdira & s->pdtra) | /* CPU */
- (s->periph_portdira & s->periph_pdtra) | /* Peripherals */
- (~(s->portdira | s->periph_portdira) & s->portpullupa); /* Pullups */
-}
-
-static uint16_t portb_lines(SH7750State * s)
-{
- return (s->portdirb & s->pdtrb) | /* CPU */
- (s->periph_portdirb & s->periph_pdtrb) | /* Peripherals */
- (~(s->portdirb | s->periph_portdirb) & s->portpullupb); /* Pullups */
-}
-
-static void gen_port_interrupts(SH7750State * s)
-{
- /* XXXXX interrupts not generated */
-}
-
-static void porta_changed(SH7750State * s, uint16_t prev)
-{
- uint16_t currenta, changes;
- int i, r = 0;
-
-#if 0
- fprintf(stderr, "porta changed from 0x%04x to 0x%04x\n",
- prev, porta_lines(s));
- fprintf(stderr, "pdtra=0x%04x, pctra=0x%08x\n", s->pdtra, s->pctra);
-#endif
- currenta = porta_lines(s);
- if (currenta == prev)
- return;
- changes = currenta ^ prev;
-
- for (i = 0; i < NB_DEVICES; i++) {
- if (s->devices[i] && (s->devices[i]->portamask_trigger & changes)) {
- r |= s->devices[i]->port_change_cb(currenta, portb_lines(s),
- &s->periph_pdtra,
- &s->periph_portdira,
- &s->periph_pdtrb,
- &s->periph_portdirb);
- }
- }
-
- if (r)
- gen_port_interrupts(s);
-}
-
-static void portb_changed(SH7750State * s, uint16_t prev)
-{
- uint16_t currentb, changes;
- int i, r = 0;
-
- currentb = portb_lines(s);
- if (currentb == prev)
- return;
- changes = currentb ^ prev;
-
- for (i = 0; i < NB_DEVICES; i++) {
- if (s->devices[i] && (s->devices[i]->portbmask_trigger & changes)) {
- r |= s->devices[i]->port_change_cb(portb_lines(s), currentb,
- &s->periph_pdtra,
- &s->periph_portdira,
- &s->periph_pdtrb,
- &s->periph_portdirb);
- }
- }
-
- if (r)
- gen_port_interrupts(s);
-}
-
-/**********************************************************************
- Memory
-**********************************************************************/
-
-static void error_access(const char *kind, target_phys_addr_t addr)
-{
- fprintf(stderr, "%s to %s (0x%08x) not supported\n",
- kind, regname(addr), addr);
-}
-
-static void ignore_access(const char *kind, target_phys_addr_t addr)
-{
- fprintf(stderr, "%s to %s (0x%08x) ignored\n",
- kind, regname(addr), addr);
-}
-
-static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- SH7750State *s = opaque;
- uint8_t r;
-
- switch (addr) {
- case SH7750_SCSSR1_A7:
- r = s->scssr1;
- s->scssr1_read |= r;
- return s->scssr1;
- case SH7750_SCRDR1_A7:
- s->scssr1 &= ~SH7750_SCSSR1_RDRF;
- return s->scrdr1;
- default:
- error_access("byte read", addr);
- assert(0);
- }
-}
-
-static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- SH7750State *s = opaque;
- uint16_t r;
-
- switch (addr) {
- case SH7750_RFCR_A7:
- fprintf(stderr,
- "Read access to refresh count register, incrementing\n");
- return s->rfcr++;
- case SH7750_TCR0_A7:
- return s->tcr0;
- case SH7750_SCLSR2_A7:
- /* Read and clear overflow bit */
- r = s->sclsr2;
- s->sclsr2 = 0;
- return r;
- case SH7750_SCSFR2_A7:
- return s->scfsr2;
- case SH7750_PDTRA_A7:
- return porta_lines(s);
- case SH7750_PDTRB_A7:
- return portb_lines(s);
- default:
- error_access("word read", addr);
- assert(0);
- }
-}
-
-static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- SH7750State *s = opaque;
-
- switch (addr) {
- case SH7750_MMUCR_A7:
- return s->cpu->mmucr;
- case SH7750_PTEH_A7:
- return s->cpu->pteh;
- case SH7750_PTEL_A7:
- return s->cpu->ptel;
- case SH7750_TTB_A7:
- return s->cpu->ttb;
- case SH7750_TEA_A7:
- return s->cpu->tea;
- case SH7750_TRA_A7:
- return s->cpu->tra;
- case SH7750_EXPEVT_A7:
- return s->cpu->expevt;
- case SH7750_INTEVT_A7:
- return s->cpu->intevt;
- case SH7750_CCR_A7:
- return s->ccr;
- case 0x1f000030: /* Processor version PVR */
- return 0x00050000; /* SH7750R */
- case 0x1f000040: /* Processor version CVR */
- return 0x00110000; /* Minimum caches */
- case 0x1f000044: /* Processor version PRR */
- return 0x00000100; /* SH7750R */
- default:
- error_access("long read", addr);
- assert(0);
- }
-}
-
-static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t mem_value)
-{
- SH7750State *s = opaque;
-
- switch (addr) {
- /* PRECHARGE ? XXXXX */
- case SH7750_PRECHARGE0_A7:
- case SH7750_PRECHARGE1_A7:
- ignore_access("byte write", addr);
- return;
- case SH7750_SCBRR2_A7:
- s->scbrr2 = mem_value;
- return;
- case SH7750_TSTR_A7:
- s->tstr = mem_value;
- timer_start_changed(s);
- return;
- case SH7750_SCSCR1_A7:
- s->scscr1 = mem_value;
- scscr1_changed(s);
- return;
- case SH7750_SCSMR1_A7:
- s->scsmr1 = mem_value;
- return;
- case SH7750_SCBRR1_A7:
- s->scbrr1 = mem_value;
- return;
- case SH7750_SCTDR1_A7:
- s->scssr1 &= ~SH7750_SCSSR1_TEND;
- s->sctdr1 = mem_value;
- return;
- case SH7750_SCSSR1_A7:
- serial1_change_scssr1(s, mem_value);
- return;
- default:
- error_access("byte write", addr);
- assert(0);
- }
-}
-
-static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
- uint32_t mem_value)
-{
- SH7750State *s = opaque;
- uint16_t temp;
-
- switch (addr) {
- /* SDRAM controller */
- case SH7750_SCBRR1_A7:
- case SH7750_SCBRR2_A7:
- case SH7750_BCR2_A7:
- case SH7750_BCR3_A7:
- case SH7750_RTCOR_A7:
- case SH7750_RTCNT_A7:
- case SH7750_RTCSR_A7:
- ignore_access("word write", addr);
- return;
- /* IO ports */
- case SH7750_PDTRA_A7:
- temp = porta_lines(s);
- s->pdtra = mem_value;
- porta_changed(s, temp);
- return;
- case SH7750_PDTRB_A7:
- temp = portb_lines(s);
- s->pdtrb = mem_value;
- portb_changed(s, temp);
- return;
- case SH7750_RFCR_A7:
- fprintf(stderr, "Write access to refresh count register\n");
- s->rfcr = mem_value;
- return;
- case SH7750_SCLSR2_A7:
- s->sclsr2 = mem_value;
- return;
- case SH7750_SCSCR2_A7:
- s->scscr2 = mem_value;
- scscr2_changed(s);
- return;
- case SH7750_SCFCR2_A7:
- s->scfcr2 = mem_value;
- return;
- case SH7750_SCSMR2_A7:
- s->scsmr2 = mem_value;
- return;
- case SH7750_TCR0_A7:
- s->tcr0 = mem_value;
- return;
- case SH7750_GPIOIC_A7:
- s->gpioic = mem_value;
- if (mem_value != 0) {
- fprintf(stderr, "I/O interrupts not implemented\n");
- assert(0);
- }
- return;
- default:
- error_access("word write", addr);
- assert(0);
- }
-}
-
-static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
- uint32_t mem_value)
-{
- SH7750State *s = opaque;
- uint16_t temp;
-
- switch (addr) {
- /* SDRAM controller */
- case SH7750_BCR1_A7:
- case SH7750_BCR4_A7:
- case SH7750_WCR1_A7:
- case SH7750_WCR2_A7:
- case SH7750_WCR3_A7:
- case SH7750_MCR_A7:
- ignore_access("long write", addr);
- return;
- /* IO ports */
- case SH7750_PCTRA_A7:
- temp = porta_lines(s);
- s->pctra = mem_value;
- s->portdira = portdir(mem_value);
- s->portpullupa = portpullup(mem_value);
- porta_changed(s, temp);
- return;
- case SH7750_PCTRB_A7:
- temp = portb_lines(s);
- s->pctrb = mem_value;
- s->portdirb = portdir(mem_value);
- s->portpullupb = portpullup(mem_value);
- portb_changed(s, temp);
- return;
- case SH7750_TCNT0_A7:
- s->tcnt0 = mem_value & 0xf;
- return;
- case SH7750_MMUCR_A7:
- s->cpu->mmucr = mem_value;
- return;
- case SH7750_PTEH_A7:
- s->cpu->pteh = mem_value;
- return;
- case SH7750_PTEL_A7:
- s->cpu->ptel = mem_value;
- return;
- case SH7750_TTB_A7:
- s->cpu->ttb = mem_value;
- return;
- case SH7750_TEA_A7:
- s->cpu->tea = mem_value;
- return;
- case SH7750_TRA_A7:
- s->cpu->tra = mem_value & 0x000007ff;
- return;
- case SH7750_EXPEVT_A7:
- s->cpu->expevt = mem_value & 0x000007ff;
- return;
- case SH7750_INTEVT_A7:
- s->cpu->intevt = mem_value & 0x000007ff;
- return;
- case SH7750_CCR_A7:
- s->ccr = mem_value;
- return;
- default:
- error_access("long write", addr);
- assert(0);
- }
-}
-
-static CPUReadMemoryFunc *sh7750_mem_read[] = {
- sh7750_mem_readb,
- sh7750_mem_readw,
- sh7750_mem_readl
-};
-
-static CPUWriteMemoryFunc *sh7750_mem_write[] = {
- sh7750_mem_writeb,
- sh7750_mem_writew,
- sh7750_mem_writel
-};
-
-SH7750State *sh7750_init(CPUSH4State * cpu)
-{
- SH7750State *s;
- int sh7750_io_memory;
-
- s = qemu_mallocz(sizeof(SH7750State));
- s->cpu = cpu;
- s->periph_freq = 60000000; /* 60MHz */
- sh7750_io_memory = cpu_register_io_memory(0,
- sh7750_mem_read,
- sh7750_mem_write, s);
- cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory);
- init_timers(s);
- init_serial_ports(s);
- return s;
-}
diff --git a/tools/ioemu/hw/sh7750_regnames.c b/tools/ioemu/hw/sh7750_regnames.c
deleted file mode 100644
index 5fcb0d6cca..0000000000
--- a/tools/ioemu/hw/sh7750_regnames.c
+++ /dev/null
@@ -1,128 +0,0 @@
-#include "vl.h"
-#include "sh7750_regs.h"
-
-#define REGNAME(r) {r, #r},
-
-typedef struct {
- uint32_t regaddr;
- const char *regname;
-} regname_t;
-
-static regname_t regnames[] = {
- REGNAME(SH7750_PTEH_A7)
- REGNAME(SH7750_PTEL_A7)
- REGNAME(SH7750_PTEA_A7)
- REGNAME(SH7750_TTB_A7)
- REGNAME(SH7750_TEA_A7)
- REGNAME(SH7750_MMUCR_A7)
- REGNAME(SH7750_CCR_A7)
- REGNAME(SH7750_QACR0_A7)
- REGNAME(SH7750_QACR1_A7)
- REGNAME(SH7750_TRA_A7)
- REGNAME(SH7750_EXPEVT_A7)
- REGNAME(SH7750_INTEVT_A7)
- REGNAME(SH7750_STBCR_A7)
- REGNAME(SH7750_STBCR2_A7)
- REGNAME(SH7750_FRQCR_A7)
- REGNAME(SH7750_WTCNT_A7)
- REGNAME(SH7750_WTCSR_A7)
- REGNAME(SH7750_R64CNT_A7)
- REGNAME(SH7750_RSECCNT_A7)
- REGNAME(SH7750_RMINCNT_A7)
- REGNAME(SH7750_RHRCNT_A7)
- REGNAME(SH7750_RWKCNT_A7)
- REGNAME(SH7750_RDAYCNT_A7)
- REGNAME(SH7750_RMONCNT_A7)
- REGNAME(SH7750_RYRCNT_A7)
- REGNAME(SH7750_RSECAR_A7)
- REGNAME(SH7750_RMINAR_A7)
- REGNAME(SH7750_RHRAR_A7)
- REGNAME(SH7750_RWKAR_A7)
- REGNAME(SH7750_RDAYAR_A7)
- REGNAME(SH7750_RMONAR_A7)
- REGNAME(SH7750_RCR1_A7)
- REGNAME(SH7750_RCR2_A7)
- REGNAME(SH7750_TOCR_A7)
- REGNAME(SH7750_TSTR_A7)
- REGNAME(SH7750_TCOR0_A7)
- REGNAME(SH7750_TCOR1_A7)
- REGNAME(SH7750_TCOR2_A7)
- REGNAME(SH7750_TCNT0_A7)
- REGNAME(SH7750_TCNT1_A7)
- REGNAME(SH7750_TCNT2_A7)
- REGNAME(SH7750_TCR0_A7)
- REGNAME(SH7750_TCR1_A7)
- REGNAME(SH7750_TCR2_A7)
- REGNAME(SH7750_TCPR2_A7)
- REGNAME(SH7750_BCR1_A7)
- REGNAME(SH7750_BCR2_A7)
- REGNAME(SH7750_WCR1_A7)
- REGNAME(SH7750_WCR2_A7)
- REGNAME(SH7750_WCR3_A7)
- REGNAME(SH7750_MCR_A7)
- REGNAME(SH7750_PCR_A7)
- REGNAME(SH7750_RTCSR_A7)
- REGNAME(SH7750_RTCNT_A7)
- REGNAME(SH7750_RTCOR_A7)
- REGNAME(SH7750_RFCR_A7)
- REGNAME(SH7750_SAR0_A7)
- REGNAME(SH7750_SAR1_A7)
- REGNAME(SH7750_SAR2_A7)
- REGNAME(SH7750_SAR3_A7)
- REGNAME(SH7750_DAR0_A7)
- REGNAME(SH7750_DAR1_A7)
- REGNAME(SH7750_DAR2_A7)
- REGNAME(SH7750_DAR3_A7)
- REGNAME(SH7750_DMATCR0_A7)
- REGNAME(SH7750_DMATCR1_A7)
- REGNAME(SH7750_DMATCR2_A7)
- REGNAME(SH7750_DMATCR3_A7)
- REGNAME(SH7750_CHCR0_A7)
- REGNAME(SH7750_CHCR1_A7)
- REGNAME(SH7750_CHCR2_A7)
- REGNAME(SH7750_CHCR3_A7)
- REGNAME(SH7750_DMAOR_A7)
- REGNAME(SH7750_SCRDR1_A7)
- REGNAME(SH7750_SCRDR2_A7)
- REGNAME(SH7750_SCTDR1_A7)
- REGNAME(SH7750_SCTDR2_A7)
- REGNAME(SH7750_SCSMR1_A7)
- REGNAME(SH7750_SCSMR2_A7)
- REGNAME(SH7750_SCSCR1_A7)
- REGNAME(SH7750_SCSCR2_A7)
- REGNAME(SH7750_SCSSR1_A7)
- REGNAME(SH7750_SCSFR2_A7)
- REGNAME(SH7750_SCSPTR1_A7)
- REGNAME(SH7750_SCSPTR2_A7)
- REGNAME(SH7750_SCBRR1_A7)
- REGNAME(SH7750_SCBRR2_A7)
- REGNAME(SH7750_SCFCR2_A7)
- REGNAME(SH7750_SCFDR2_A7)
- REGNAME(SH7750_SCLSR2_A7)
- REGNAME(SH7750_SCSCMR1_A7)
- REGNAME(SH7750_PCTRA_A7)
- REGNAME(SH7750_PDTRA_A7)
- REGNAME(SH7750_PCTRB_A7)
- REGNAME(SH7750_PDTRB_A7)
- REGNAME(SH7750_GPIOIC_A7)
- REGNAME(SH7750_ICR_A7)
- REGNAME(SH7750_IPRA_A7)
- REGNAME(SH7750_IPRB_A7)
- REGNAME(SH7750_IPRC_A7)
- REGNAME(SH7750_BCR3_A7)
- REGNAME(SH7750_BCR4_A7)
- REGNAME(SH7750_PRECHARGE0_A7)
- REGNAME(SH7750_PRECHARGE1_A7) {(uint32_t) - 1, 0}
-};
-
-const char *regname(uint32_t addr)
-{
- unsigned int i;
-
- for (i = 0; regnames[i].regaddr != (uint32_t) - 1; i++) {
- if (regnames[i].regaddr == addr)
- return regnames[i].regname;
- }
-
- return "<unknown reg>";
-}
diff --git a/tools/ioemu/hw/sh7750_regnames.h b/tools/ioemu/hw/sh7750_regnames.h
deleted file mode 100644
index 7463709b4c..0000000000
--- a/tools/ioemu/hw/sh7750_regnames.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _SH7750_REGNAMES_H
-#define _SH7750_REGNAMES_H
-
-const char *regname(uint32_t addr);
-
-#endif /* _SH7750_REGNAMES_H */
diff --git a/tools/ioemu/hw/sh7750_regs.h b/tools/ioemu/hw/sh7750_regs.h
deleted file mode 100644
index 44ae95be2b..0000000000
--- a/tools/ioemu/hw/sh7750_regs.h
+++ /dev/null
@@ -1,1623 +0,0 @@
-/*
- * SH-7750 memory-mapped registers
- * This file based on information provided in the following document:
- * "Hitachi SuperH (tm) RISC engine. SH7750 Series (SH7750, SH7750S)
- * Hardware Manual"
- * Document Number ADE-602-124C, Rev. 4.0, 4/21/00, Hitachi Ltd.
- *
- * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
- * Author: Alexandra Kossovsky <sasha@oktet.ru>
- * Victor V. Vengerov <vvv@oktet.ru>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
- *
- * @(#) sh7750_regs.h,v 1.2.4.1 2003/09/04 18:46:00 joel Exp
- */
-
-#ifndef __SH7750_REGS_H__
-#define __SH7750_REGS_H__
-
-/*
- * All register has 2 addresses: in 0xff000000 - 0xffffffff (P4 address) and
- * in 0x1f000000 - 0x1fffffff (area 7 address)
- */
-#define SH7750_P4_BASE 0xff000000 /* Accessable only in
- priveleged mode */
-#define SH7750_A7_BASE 0x1f000000 /* Accessable only using TLB */
-
-#define SH7750_P4_REG32(ofs) (SH7750_P4_BASE + (ofs))
-#define SH7750_A7_REG32(ofs) (SH7750_A7_BASE + (ofs))
-
-/*
- * MMU Registers
- */
-
-/* Page Table Entry High register - PTEH */
-#define SH7750_PTEH_REGOFS 0x000000 /* offset */
-#define SH7750_PTEH SH7750_P4_REG32(SH7750_PTEH_REGOFS)
-#define SH7750_PTEH_A7 SH7750_A7_REG32(SH7750_PTEH_REGOFS)
-#define SH7750_PTEH_VPN 0xfffffd00 /* Virtual page number */
-#define SH7750_PTEH_VPN_S 10
-#define SH7750_PTEH_ASID 0x000000ff /* Address space identifier */
-#define SH7750_PTEH_ASID_S 0
-
-/* Page Table Entry Low register - PTEL */
-#define SH7750_PTEL_REGOFS 0x000004 /* offset */
-#define SH7750_PTEL SH7750_P4_REG32(SH7750_PTEL_REGOFS)
-#define SH7750_PTEL_A7 SH7750_A7_REG32(SH7750_PTEL_REGOFS)
-#define SH7750_PTEL_PPN 0x1ffffc00 /* Physical page number */
-#define SH7750_PTEL_PPN_S 10
-#define SH7750_PTEL_V 0x00000100 /* Validity (0-entry is invalid) */
-#define SH7750_PTEL_SZ1 0x00000080 /* Page size bit 1 */
-#define SH7750_PTEL_SZ0 0x00000010 /* Page size bit 0 */
-#define SH7750_PTEL_SZ_1KB 0x00000000 /* 1-kbyte page */
-#define SH7750_PTEL_SZ_4KB 0x00000010 /* 4-kbyte page */
-#define SH7750_PTEL_SZ_64KB 0x00000080 /* 64-kbyte page */
-#define SH7750_PTEL_SZ_1MB 0x00000090 /* 1-Mbyte page */
-#define SH7750_PTEL_PR 0x00000060 /* Protection Key Data */
-#define SH7750_PTEL_PR_ROPO 0x00000000 /* read-only in priv mode */
-#define SH7750_PTEL_PR_RWPO 0x00000020 /* read-write in priv mode */
-#define SH7750_PTEL_PR_ROPU 0x00000040 /* read-only in priv or user mode */
-#define SH7750_PTEL_PR_RWPU 0x00000060 /* read-write in priv or user mode */
-#define SH7750_PTEL_C 0x00000008 /* Cacheability
- (0 - page not cacheable) */
-#define SH7750_PTEL_D 0x00000004 /* Dirty bit (1 - write has been
- performed to a page) */
-#define SH7750_PTEL_SH 0x00000002 /* Share Status bit (1 - page are
- shared by processes) */
-#define SH7750_PTEL_WT 0x00000001 /* Write-through bit, specifies the
- cache write mode:
- 0 - Copy-back mode
- 1 - Write-through mode */
-
-/* Page Table Entry Assistance register - PTEA */
-#define SH7750_PTEA_REGOFS 0x000034 /* offset */
-#define SH7750_PTEA SH7750_P4_REG32(SH7750_PTEA_REGOFS)
-#define SH7750_PTEA_A7 SH7750_A7_REG32(SH7750_PTEA_REGOFS)
-#define SH7750_PTEA_TC 0x00000008 /* Timing Control bit
- 0 - use area 5 wait states
- 1 - use area 6 wait states */
-#define SH7750_PTEA_SA 0x00000007 /* Space Attribute bits: */
-#define SH7750_PTEA_SA_UNDEF 0x00000000 /* 0 - undefined */
-#define SH7750_PTEA_SA_IOVAR 0x00000001 /* 1 - variable-size I/O space */
-#define SH7750_PTEA_SA_IO8 0x00000002 /* 2 - 8-bit I/O space */
-#define SH7750_PTEA_SA_IO16 0x00000003 /* 3 - 16-bit I/O space */
-#define SH7750_PTEA_SA_CMEM8 0x00000004 /* 4 - 8-bit common memory space */
-#define SH7750_PTEA_SA_CMEM16 0x00000005 /* 5 - 16-bit common memory space */
-#define SH7750_PTEA_SA_AMEM8 0x00000006 /* 6 - 8-bit attr memory space */
-#define SH7750_PTEA_SA_AMEM16 0x00000007 /* 7 - 16-bit attr memory space */
-
-
-/* Translation table base register */
-#define SH7750_TTB_REGOFS 0x000008 /* offset */
-#define SH7750_TTB SH7750_P4_REG32(SH7750_TTB_REGOFS)
-#define SH7750_TTB_A7 SH7750_A7_REG32(SH7750_TTB_REGOFS)
-
-/* TLB exeption address register - TEA */
-#define SH7750_TEA_REGOFS 0x00000c /* offset */
-#define SH7750_TEA SH7750_P4_REG32(SH7750_TEA_REGOFS)
-#define SH7750_TEA_A7 SH7750_A7_REG32(SH7750_TEA_REGOFS)
-
-/* MMU control register - MMUCR */
-#define SH7750_MMUCR_REGOFS 0x000010 /* offset */
-#define SH7750_MMUCR SH7750_P4_REG32(SH7750_MMUCR_REGOFS)
-#define SH7750_MMUCR_A7 SH7750_A7_REG32(SH7750_MMUCR_REGOFS)
-#define SH7750_MMUCR_AT 0x00000001 /* Address translation bit */
-#define SH7750_MMUCR_TI 0x00000004 /* TLB invalidate */
-#define SH7750_MMUCR_SV 0x00000100 /* Single Virtual Mode bit */
-#define SH7750_MMUCR_SQMD 0x00000200 /* Store Queue Mode bit */
-#define SH7750_MMUCR_URC 0x0000FC00 /* UTLB Replace Counter */
-#define SH7750_MMUCR_URC_S 10
-#define SH7750_MMUCR_URB 0x00FC0000 /* UTLB Replace Boundary */
-#define SH7750_MMUCR_URB_S 18
-#define SH7750_MMUCR_LRUI 0xFC000000 /* Least Recently Used ITLB */
-#define SH7750_MMUCR_LRUI_S 26
-
-
-
-
-/*
- * Cache registers
- * IC -- instructions cache
- * OC -- operand cache
- */
-
-/* Cache Control Register - CCR */
-#define SH7750_CCR_REGOFS 0x00001c /* offset */
-#define SH7750_CCR SH7750_P4_REG32(SH7750_CCR_REGOFS)
-#define SH7750_CCR_A7 SH7750_A7_REG32(SH7750_CCR_REGOFS)
-
-#define SH7750_CCR_IIX 0x00008000 /* IC index enable bit */
-#define SH7750_CCR_ICI 0x00000800 /* IC invalidation bit:
- set it to clear IC */
-#define SH7750_CCR_ICE 0x00000100 /* IC enable bit */
-#define SH7750_CCR_OIX 0x00000080 /* OC index enable bit */
-#define SH7750_CCR_ORA 0x00000020 /* OC RAM enable bit
- if you set OCE = 0,
- you should set ORA = 0 */
-#define SH7750_CCR_OCI 0x00000008 /* OC invalidation bit */
-#define SH7750_CCR_CB 0x00000004 /* Copy-back bit for P1 area */
-#define SH7750_CCR_WT 0x00000002 /* Write-through bit for P0,U0,P3 area */
-#define SH7750_CCR_OCE 0x00000001 /* OC enable bit */
-
-/* Queue address control register 0 - QACR0 */
-#define SH7750_QACR0_REGOFS 0x000038 /* offset */
-#define SH7750_QACR0 SH7750_P4_REG32(SH7750_QACR0_REGOFS)
-#define SH7750_QACR0_A7 SH7750_A7_REG32(SH7750_QACR0_REGOFS)
-
-/* Queue address control register 1 - QACR1 */
-#define SH7750_QACR1_REGOFS 0x00003c /* offset */
-#define SH7750_QACR1 SH7750_P4_REG32(SH7750_QACR1_REGOFS)
-#define SH7750_QACR1_A7 SH7750_A7_REG32(SH7750_QACR1_REGOFS)
-
-
-/*
- * Exeption-related registers
- */
-
-/* Immediate data for TRAPA instuction - TRA */
-#define SH7750_TRA_REGOFS 0x000020 /* offset */
-#define SH7750_TRA SH7750_P4_REG32(SH7750_TRA_REGOFS)
-#define SH7750_TRA_A7 SH7750_A7_REG32(SH7750_TRA_REGOFS)
-
-#define SH7750_TRA_IMM 0x000003fd /* Immediate data operand */
-#define SH7750_TRA_IMM_S 2
-
-/* Exeption event register - EXPEVT */
-#define SH7750_EXPEVT_REGOFS 0x000024
-#define SH7750_EXPEVT SH7750_P4_REG32(SH7750_EXPEVT_REGOFS)
-#define SH7750_EXPEVT_A7 SH7750_A7_REG32(SH7750_EXPEVT_REGOFS)
-
-#define SH7750_EXPEVT_EX 0x00000fff /* Exeption code */
-#define SH7750_EXPEVT_EX_S 0
-
-/* Interrupt event register */
-#define SH7750_INTEVT_REGOFS 0x000028
-#define SH7750_INTEVT SH7750_P4_REG32(SH7750_INTEVT_REGOFS)
-#define SH7750_INTEVT_A7 SH7750_A7_REG32(SH7750_INTEVT_REGOFS)
-#define SH7750_INTEVT_EX 0x00000fff /* Exeption code */
-#define SH7750_INTEVT_EX_S 0
-
-/*
- * Exception/interrupt codes
- */
-#define SH7750_EVT_TO_NUM(evt) ((evt) >> 5)
-
-/* Reset exception category */
-#define SH7750_EVT_POWER_ON_RST 0x000 /* Power-on reset */
-#define SH7750_EVT_MANUAL_RST 0x020 /* Manual reset */
-#define SH7750_EVT_TLB_MULT_HIT 0x140 /* TLB multiple-hit exception */
-
-/* General exception category */
-#define SH7750_EVT_USER_BREAK 0x1E0 /* User break */
-#define SH7750_EVT_IADDR_ERR 0x0E0 /* Instruction address error */
-#define SH7750_EVT_TLB_READ_MISS 0x040 /* ITLB miss exception /
- DTLB miss exception (read) */
-#define SH7750_EVT_TLB_READ_PROTV 0x0A0 /* ITLB protection violation /
- DTLB protection violation (read) */
-#define SH7750_EVT_ILLEGAL_INSTR 0x180 /* General Illegal Instruction
- exception */
-#define SH7750_EVT_SLOT_ILLEGAL_INSTR 0x1A0 /* Slot Illegal Instruction
- exception */
-#define SH7750_EVT_FPU_DISABLE 0x800 /* General FPU disable exception */
-#define SH7750_EVT_SLOT_FPU_DISABLE 0x820 /* Slot FPU disable exception */
-#define SH7750_EVT_DATA_READ_ERR 0x0E0 /* Data address error (read) */
-#define SH7750_EVT_DATA_WRITE_ERR 0x100 /* Data address error (write) */
-#define SH7750_EVT_DTLB_WRITE_MISS 0x060 /* DTLB miss exception (write) */
-#define SH7750_EVT_DTLB_WRITE_PROTV 0x0C0 /* DTLB protection violation
- exception (write) */
-#define SH7750_EVT_FPU_EXCEPTION 0x120 /* FPU exception */
-#define SH7750_EVT_INITIAL_PGWRITE 0x080 /* Initial Page Write exception */
-#define SH7750_EVT_TRAPA 0x160 /* Unconditional trap (TRAPA) */
-
-/* Interrupt exception category */
-#define SH7750_EVT_NMI 0x1C0 /* Non-maskable interrupt */
-#define SH7750_EVT_IRQ0 0x200 /* External Interrupt 0 */
-#define SH7750_EVT_IRQ1 0x220 /* External Interrupt 1 */
-#define SH7750_EVT_IRQ2 0x240 /* External Interrupt 2 */
-#define SH7750_EVT_IRQ3 0x260 /* External Interrupt 3 */
-#define SH7750_EVT_IRQ4 0x280 /* External Interrupt 4 */
-#define SH7750_EVT_IRQ5 0x2A0 /* External Interrupt 5 */
-#define SH7750_EVT_IRQ6 0x2C0 /* External Interrupt 6 */
-#define SH7750_EVT_IRQ7 0x2E0 /* External Interrupt 7 */
-#define SH7750_EVT_IRQ8 0x300 /* External Interrupt 8 */
-#define SH7750_EVT_IRQ9 0x320 /* External Interrupt 9 */
-#define SH7750_EVT_IRQA 0x340 /* External Interrupt A */
-#define SH7750_EVT_IRQB 0x360 /* External Interrupt B */
-#define SH7750_EVT_IRQC 0x380 /* External Interrupt C */
-#define SH7750_EVT_IRQD 0x3A0 /* External Interrupt D */
-#define SH7750_EVT_IRQE 0x3C0 /* External Interrupt E */
-
-/* Peripheral Module Interrupts - Timer Unit (TMU) */
-#define SH7750_EVT_TUNI0 0x400 /* TMU Underflow Interrupt 0 */
-#define SH7750_EVT_TUNI1 0x420 /* TMU Underflow Interrupt 1 */
-#define SH7750_EVT_TUNI2 0x440 /* TMU Underflow Interrupt 2 */
-#define SH7750_EVT_TICPI2 0x460 /* TMU Input Capture Interrupt 2 */
-
-/* Peripheral Module Interrupts - Real-Time Clock (RTC) */
-#define SH7750_EVT_RTC_ATI 0x480 /* Alarm Interrupt Request */
-#define SH7750_EVT_RTC_PRI 0x4A0 /* Periodic Interrupt Request */
-#define SH7750_EVT_RTC_CUI 0x4C0 /* Carry Interrupt Request */
-
-/* Peripheral Module Interrupts - Serial Communication Interface (SCI) */
-#define SH7750_EVT_SCI_ERI 0x4E0 /* Receive Error */
-#define SH7750_EVT_SCI_RXI 0x500 /* Receive Data Register Full */
-#define SH7750_EVT_SCI_TXI 0x520 /* Transmit Data Register Empty */
-#define SH7750_EVT_SCI_TEI 0x540 /* Transmit End */
-
-/* Peripheral Module Interrupts - Watchdog Timer (WDT) */
-#define SH7750_EVT_WDT_ITI 0x560 /* Interval Timer Interrupt
- (used when WDT operates in
- interval timer mode) */
-
-/* Peripheral Module Interrupts - Memory Refresh Unit (REF) */
-#define SH7750_EVT_REF_RCMI 0x580 /* Compare-match Interrupt */
-#define SH7750_EVT_REF_ROVI 0x5A0 /* Refresh Counter Overflow
- interrupt */
-
-/* Peripheral Module Interrupts - Hitachi User Debug Interface (H-UDI) */
-#define SH7750_EVT_HUDI 0x600 /* UDI interrupt */
-
-/* Peripheral Module Interrupts - General-Purpose I/O (GPIO) */
-#define SH7750_EVT_GPIO 0x620 /* GPIO Interrupt */
-
-/* Peripheral Module Interrupts - DMA Controller (DMAC) */
-#define SH7750_EVT_DMAC_DMTE0 0x640 /* DMAC 0 Transfer End Interrupt */
-#define SH7750_EVT_DMAC_DMTE1 0x660 /* DMAC 1 Transfer End Interrupt */
-#define SH7750_EVT_DMAC_DMTE2 0x680 /* DMAC 2 Transfer End Interrupt */
-#define SH7750_EVT_DMAC_DMTE3 0x6A0 /* DMAC 3 Transfer End Interrupt */
-#define SH7750_EVT_DMAC_DMAE 0x6C0 /* DMAC Address Error Interrupt */
-
-/* Peripheral Module Interrupts - Serial Communication Interface with FIFO */
-/* (SCIF) */
-#define SH7750_EVT_SCIF_ERI 0x700 /* Receive Error */
-#define SH7750_EVT_SCIF_RXI 0x720 /* Receive FIFO Data Full or
- Receive Data ready interrupt */
-#define SH7750_EVT_SCIF_BRI 0x740 /* Break or overrun error */
-#define SH7750_EVT_SCIF_TXI 0x760 /* Transmit FIFO Data Empty */
-
-/*
- * Power Management
- */
-#define SH7750_STBCR_REGOFS 0xC00004 /* offset */
-#define SH7750_STBCR SH7750_P4_REG32(SH7750_STBCR_REGOFS)
-#define SH7750_STBCR_A7 SH7750_A7_REG32(SH7750_STBCR_REGOFS)
-
-#define SH7750_STBCR_STBY 0x80 /* Specifies a transition to standby mode:
- 0 - Transition to SLEEP mode on SLEEP
- 1 - Transition to STANDBY mode on SLEEP */
-#define SH7750_STBCR_PHZ 0x40 /* State of peripheral module pins in
- standby mode:
- 0 - normal state
- 1 - high-impendance state */
-
-#define SH7750_STBCR_PPU 0x20 /* Peripheral module pins pull-up controls */
-#define SH7750_STBCR_MSTP4 0x10 /* Stopping the clock supply to DMAC */
-#define SH7750_STBCR_DMAC_STP SH7750_STBCR_MSTP4
-#define SH7750_STBCR_MSTP3 0x08 /* Stopping the clock supply to SCIF */
-#define SH7750_STBCR_SCIF_STP SH7750_STBCR_MSTP3
-#define SH7750_STBCR_MSTP2 0x04 /* Stopping the clock supply to TMU */
-#define SH7750_STBCR_TMU_STP SH7750_STBCR_MSTP2
-#define SH7750_STBCR_MSTP1 0x02 /* Stopping the clock supply to RTC */
-#define SH7750_STBCR_RTC_STP SH7750_STBCR_MSTP1
-#define SH7750_STBCR_MSPT0 0x01 /* Stopping the clock supply to SCI */
-#define SH7750_STBCR_SCI_STP SH7750_STBCR_MSTP0
-
-#define SH7750_STBCR_STBY 0x80
-
-
-#define SH7750_STBCR2_REGOFS 0xC00010 /* offset */
-#define SH7750_STBCR2 SH7750_P4_REG32(SH7750_STBCR2_REGOFS)
-#define SH7750_STBCR2_A7 SH7750_A7_REG32(SH7750_STBCR2_REGOFS)
-
-#define SH7750_STBCR2_DSLP 0x80 /* Specifies transition to deep sleep mode:
- 0 - transition to sleep or standby mode
- as it is specified in STBY bit
- 1 - transition to deep sleep mode on
- execution of SLEEP instruction */
-#define SH7750_STBCR2_MSTP6 0x02 /* Stopping the clock supply to Store Queue
- in the cache controller */
-#define SH7750_STBCR2_SQ_STP SH7750_STBCR2_MSTP6
-#define SH7750_STBCR2_MSTP5 0x01 /* Stopping the clock supply to the User
- Break Controller (UBC) */
-#define SH7750_STBCR2_UBC_STP SH7750_STBCR2_MSTP5
-
-/*
- * Clock Pulse Generator (CPG)
- */
-#define SH7750_FRQCR_REGOFS 0xC00000 /* offset */
-#define SH7750_FRQCR SH7750_P4_REG32(SH7750_FRQCR_REGOFS)
-#define SH7750_FRQCR_A7 SH7750_A7_REG32(SH7750_FRQCR_REGOFS)
-
-#define SH7750_FRQCR_CKOEN 0x0800 /* Clock Output Enable
- 0 - CKIO pin goes to HiZ/pullup
- 1 - Clock is output from CKIO */
-#define SH7750_FRQCR_PLL1EN 0x0400 /* PLL circuit 1 enable */
-#define SH7750_FRQCR_PLL2EN 0x0200 /* PLL circuit 2 enable */
-
-#define SH7750_FRQCR_IFC 0x01C0 /* CPU clock frequency division ratio: */
-#define SH7750_FRQCR_IFCDIV1 0x0000 /* 0 - * 1 */
-#define SH7750_FRQCR_IFCDIV2 0x0040 /* 1 - * 1/2 */
-#define SH7750_FRQCR_IFCDIV3 0x0080 /* 2 - * 1/3 */
-#define SH7750_FRQCR_IFCDIV4 0x00C0 /* 3 - * 1/4 */
-#define SH7750_FRQCR_IFCDIV6 0x0100 /* 4 - * 1/6 */
-#define SH7750_FRQCR_IFCDIV8 0x0140 /* 5 - * 1/8 */
-
-#define SH7750_FRQCR_BFC 0x0038 /* Bus clock frequency division ratio: */
-#define SH7750_FRQCR_BFCDIV1 0x0000 /* 0 - * 1 */
-#define SH7750_FRQCR_BFCDIV2 0x0008 /* 1 - * 1/2 */
-#define SH7750_FRQCR_BFCDIV3 0x0010 /* 2 - * 1/3 */
-#define SH7750_FRQCR_BFCDIV4 0x0018 /* 3 - * 1/4 */
-#define SH7750_FRQCR_BFCDIV6 0x0020 /* 4 - * 1/6 */
-#define SH7750_FRQCR_BFCDIV8 0x0028 /* 5 - * 1/8 */
-
-#define SH7750_FRQCR_PFC 0x0007 /* Peripheral module clock frequency
- division ratio: */
-#define SH7750_FRQCR_PFCDIV2 0x0000 /* 0 - * 1/2 */
-#define SH7750_FRQCR_PFCDIV3 0x0001 /* 1 - * 1/3 */
-#define SH7750_FRQCR_PFCDIV4 0x0002 /* 2 - * 1/4 */
-#define SH7750_FRQCR_PFCDIV6 0x0003 /* 3 - * 1/6 */
-#define SH7750_FRQCR_PFCDIV8 0x0004 /* 4 - * 1/8 */
-
-/*
- * Watchdog Timer (WDT)
- */
-
-/* Watchdog Timer Counter register - WTCNT */
-#define SH7750_WTCNT_REGOFS 0xC00008 /* offset */
-#define SH7750_WTCNT SH7750_P4_REG32(SH7750_WTCNT_REGOFS)
-#define SH7750_WTCNT_A7 SH7750_A7_REG32(SH7750_WTCNT_REGOFS)
-#define SH7750_WTCNT_KEY 0x5A00 /* When WTCNT byte register written,
- you have to set the upper byte to
- 0x5A */
-
-/* Watchdog Timer Control/Status register - WTCSR */
-#define SH7750_WTCSR_REGOFS 0xC0000C /* offset */
-#define SH7750_WTCSR SH7750_P4_REG32(SH7750_WTCSR_REGOFS)
-#define SH7750_WTCSR_A7 SH7750_A7_REG32(SH7750_WTCSR_REGOFS)
-#define SH7750_WTCSR_KEY 0xA500 /* When WTCSR byte register written,
- you have to set the upper byte to
- 0xA5 */
-#define SH7750_WTCSR_TME 0x80 /* Timer enable (1-upcount start) */
-#define SH7750_WTCSR_MODE 0x40 /* Timer Mode Select: */
-#define SH7750_WTCSR_MODE_WT 0x40 /* Watchdog Timer Mode */
-#define SH7750_WTCSR_MODE_IT 0x00 /* Interval Timer Mode */
-#define SH7750_WTCSR_RSTS 0x20 /* Reset Select: */
-#define SH7750_WTCSR_RST_MAN 0x20 /* Manual Reset */
-#define SH7750_WTCSR_RST_PWR 0x00 /* Power-on Reset */
-#define SH7750_WTCSR_WOVF 0x10 /* Watchdog Timer Overflow Flag */
-#define SH7750_WTCSR_IOVF 0x08 /* Interval Timer Overflow Flag */
-#define SH7750_WTCSR_CKS 0x07 /* Clock Select: */
-#define SH7750_WTCSR_CKS_DIV32 0x00 /* 1/32 of frequency divider 2 input */
-#define SH7750_WTCSR_CKS_DIV64 0x01 /* 1/64 */
-#define SH7750_WTCSR_CKS_DIV128 0x02 /* 1/128 */
-#define SH7750_WTCSR_CKS_DIV256 0x03 /* 1/256 */
-#define SH7750_WTCSR_CKS_DIV512 0x04 /* 1/512 */
-#define SH7750_WTCSR_CKS_DIV1024 0x05 /* 1/1024 */
-#define SH7750_WTCSR_CKS_DIV2048 0x06 /* 1/2048 */
-#define SH7750_WTCSR_CKS_DIV4096 0x07 /* 1/4096 */
-
-/*
- * Real-Time Clock (RTC)
- */
-/* 64-Hz Counter Register (byte, read-only) - R64CNT */
-#define SH7750_R64CNT_REGOFS 0xC80000 /* offset */
-#define SH7750_R64CNT SH7750_P4_REG32(SH7750_R64CNT_REGOFS)
-#define SH7750_R64CNT_A7 SH7750_A7_REG32(SH7750_R64CNT_REGOFS)
-
-/* Second Counter Register (byte, BCD-coded) - RSECCNT */
-#define SH7750_RSECCNT_REGOFS 0xC80004 /* offset */
-#define SH7750_RSECCNT SH7750_P4_REG32(SH7750_RSECCNT_REGOFS)
-#define SH7750_RSECCNT_A7 SH7750_A7_REG32(SH7750_RSECCNT_REGOFS)
-
-/* Minute Counter Register (byte, BCD-coded) - RMINCNT */
-#define SH7750_RMINCNT_REGOFS 0xC80008 /* offset */
-#define SH7750_RMINCNT SH7750_P4_REG32(SH7750_RMINCNT_REGOFS)
-#define SH7750_RMINCNT_A7 SH7750_A7_REG32(SH7750_RMINCNT_REGOFS)
-
-/* Hour Counter Register (byte, BCD-coded) - RHRCNT */
-#define SH7750_RHRCNT_REGOFS 0xC8000C /* offset */
-#define SH7750_RHRCNT SH7750_P4_REG32(SH7750_RHRCNT_REGOFS)
-#define SH7750_RHRCNT_A7 SH7750_A7_REG32(SH7750_RHRCNT_REGOFS)
-
-/* Day-of-Week Counter Register (byte) - RWKCNT */
-#define SH7750_RWKCNT_REGOFS 0xC80010 /* offset */
-#define SH7750_RWKCNT SH7750_P4_REG32(SH7750_RWKCNT_REGOFS)
-#define SH7750_RWKCNT_A7 SH7750_A7_REG32(SH7750_RWKCNT_REGOFS)
-
-#define SH7750_RWKCNT_SUN 0 /* Sunday */
-#define SH7750_RWKCNT_MON 1 /* Monday */
-#define SH7750_RWKCNT_TUE 2 /* Tuesday */
-#define SH7750_RWKCNT_WED 3 /* Wednesday */
-#define SH7750_RWKCNT_THU 4 /* Thursday */
-#define SH7750_RWKCNT_FRI 5 /* Friday */
-#define SH7750_RWKCNT_SAT 6 /* Saturday */
-
-/* Day Counter Register (byte, BCD-coded) - RDAYCNT */
-#define SH7750_RDAYCNT_REGOFS 0xC80014 /* offset */
-#define SH7750_RDAYCNT SH7750_P4_REG32(SH7750_RDAYCNT_REGOFS)
-#define SH7750_RDAYCNT_A7 SH7750_A7_REG32(SH7750_RDAYCNT_REGOFS)
-
-/* Month Counter Register (byte, BCD-coded) - RMONCNT */
-#define SH7750_RMONCNT_REGOFS 0xC80018 /* offset */
-#define SH7750_RMONCNT SH7750_P4_REG32(SH7750_RMONCNT_REGOFS)
-#define SH7750_RMONCNT_A7 SH7750_A7_REG32(SH7750_RMONCNT_REGOFS)
-
-/* Year Counter Register (half, BCD-coded) - RYRCNT */
-#define SH7750_RYRCNT_REGOFS 0xC8001C /* offset */
-#define SH7750_RYRCNT SH7750_P4_REG32(SH7750_RYRCNT_REGOFS)
-#define SH7750_RYRCNT_A7 SH7750_A7_REG32(SH7750_RYRCNT_REGOFS)
-
-/* Second Alarm Register (byte, BCD-coded) - RSECAR */
-#define SH7750_RSECAR_REGOFS 0xC80020 /* offset */
-#define SH7750_RSECAR SH7750_P4_REG32(SH7750_RSECAR_REGOFS)
-#define SH7750_RSECAR_A7 SH7750_A7_REG32(SH7750_RSECAR_REGOFS)
-#define SH7750_RSECAR_ENB 0x80 /* Second Alarm Enable */
-
-/* Minute Alarm Register (byte, BCD-coded) - RMINAR */
-#define SH7750_RMINAR_REGOFS 0xC80024 /* offset */
-#define SH7750_RMINAR SH7750_P4_REG32(SH7750_RMINAR_REGOFS)
-#define SH7750_RMINAR_A7 SH7750_A7_REG32(SH7750_RMINAR_REGOFS)
-#define SH7750_RMINAR_ENB 0x80 /* Minute Alarm Enable */
-
-/* Hour Alarm Register (byte, BCD-coded) - RHRAR */
-#define SH7750_RHRAR_REGOFS 0xC80028 /* offset */
-#define SH7750_RHRAR SH7750_P4_REG32(SH7750_RHRAR_REGOFS)
-#define SH7750_RHRAR_A7 SH7750_A7_REG32(SH7750_RHRAR_REGOFS)
-#define SH7750_RHRAR_ENB 0x80 /* Hour Alarm Enable */
-
-/* Day-of-Week Alarm Register (byte) - RWKAR */
-#define SH7750_RWKAR_REGOFS 0xC8002C /* offset */
-#define SH7750_RWKAR SH7750_P4_REG32(SH7750_RWKAR_REGOFS)
-#define SH7750_RWKAR_A7 SH7750_A7_REG32(SH7750_RWKAR_REGOFS)
-#define SH7750_RWKAR_ENB 0x80 /* Day-of-week Alarm Enable */
-
-#define SH7750_RWKAR_SUN 0 /* Sunday */
-#define SH7750_RWKAR_MON 1 /* Monday */
-#define SH7750_RWKAR_TUE 2 /* Tuesday */
-#define SH7750_RWKAR_WED 3 /* Wednesday */
-#define SH7750_RWKAR_THU 4 /* Thursday */
-#define SH7750_RWKAR_FRI 5 /* Friday */
-#define SH7750_RWKAR_SAT 6 /* Saturday */
-
-/* Day Alarm Register (byte, BCD-coded) - RDAYAR */
-#define SH7750_RDAYAR_REGOFS 0xC80030 /* offset */
-#define SH7750_RDAYAR SH7750_P4_REG32(SH7750_RDAYAR_REGOFS)
-#define SH7750_RDAYAR_A7 SH7750_A7_REG32(SH7750_RDAYAR_REGOFS)
-#define SH7750_RDAYAR_ENB 0x80 /* Day Alarm Enable */
-
-/* Month Counter Register (byte, BCD-coded) - RMONAR */
-#define SH7750_RMONAR_REGOFS 0xC80034 /* offset */
-#define SH7750_RMONAR SH7750_P4_REG32(SH7750_RMONAR_REGOFS)
-#define SH7750_RMONAR_A7 SH7750_A7_REG32(SH7750_RMONAR_REGOFS)
-#define SH7750_RMONAR_ENB 0x80 /* Month Alarm Enable */
-
-/* RTC Control Register 1 (byte) - RCR1 */
-#define SH7750_RCR1_REGOFS 0xC80038 /* offset */
-#define SH7750_RCR1 SH7750_P4_REG32(SH7750_RCR1_REGOFS)
-#define SH7750_RCR1_A7 SH7750_A7_REG32(SH7750_RCR1_REGOFS)
-#define SH7750_RCR1_CF 0x80 /* Carry Flag */
-#define SH7750_RCR1_CIE 0x10 /* Carry Interrupt Enable */
-#define SH7750_RCR1_AIE 0x08 /* Alarm Interrupt Enable */
-#define SH7750_RCR1_AF 0x01 /* Alarm Flag */
-
-/* RTC Control Register 2 (byte) - RCR2 */
-#define SH7750_RCR2_REGOFS 0xC8003C /* offset */
-#define SH7750_RCR2 SH7750_P4_REG32(SH7750_RCR2_REGOFS)
-#define SH7750_RCR2_A7 SH7750_A7_REG32(SH7750_RCR2_REGOFS)
-#define SH7750_RCR2_PEF 0x80 /* Periodic Interrupt Flag */
-#define SH7750_RCR2_PES 0x70 /* Periodic Interrupt Enable: */
-#define SH7750_RCR2_PES_DIS 0x00 /* Periodic Interrupt Disabled */
-#define SH7750_RCR2_PES_DIV256 0x10 /* Generated at 1/256 sec interval */
-#define SH7750_RCR2_PES_DIV64 0x20 /* Generated at 1/64 sec interval */
-#define SH7750_RCR2_PES_DIV16 0x30 /* Generated at 1/16 sec interval */
-#define SH7750_RCR2_PES_DIV4 0x40 /* Generated at 1/4 sec interval */
-#define SH7750_RCR2_PES_DIV2 0x50 /* Generated at 1/2 sec interval */
-#define SH7750_RCR2_PES_x1 0x60 /* Generated at 1 sec interval */
-#define SH7750_RCR2_PES_x2 0x70 /* Generated at 2 sec interval */
-#define SH7750_RCR2_RTCEN 0x08 /* RTC Crystal Oscillator is Operated */
-#define SH7750_RCR2_ADJ 0x04 /* 30-Second Adjastment */
-#define SH7750_RCR2_RESET 0x02 /* Frequency divider circuits are reset */
-#define SH7750_RCR2_START 0x01 /* 0 - sec, min, hr, day-of-week, month,
- year counters are stopped
- 1 - sec, min, hr, day-of-week, month,
- year counters operate normally */
-
-
-/*
- * Timer Unit (TMU)
- */
-/* Timer Output Control Register (byte) - TOCR */
-#define SH7750_TOCR_REGOFS 0xD80000 /* offset */
-#define SH7750_TOCR SH7750_P4_REG32(SH7750_TOCR_REGOFS)
-#define SH7750_TOCR_A7 SH7750_A7_REG32(SH7750_TOCR_REGOFS)
-#define SH7750_TOCR_TCOE 0x01 /* Timer Clock Pin Control:
- 0 - TCLK is used as external clock
- input or input capture control
- 1 - TCLK is used as on-chip RTC
- output clock pin */
-
-/* Timer Start Register (byte) - TSTR */
-#define SH7750_TSTR_REGOFS 0xD80004 /* offset */
-#define SH7750_TSTR SH7750_P4_REG32(SH7750_TSTR_REGOFS)
-#define SH7750_TSTR_A7 SH7750_A7_REG32(SH7750_TSTR_REGOFS)
-#define SH7750_TSTR_STR2 0x04 /* TCNT2 performs count operations */
-#define SH7750_TSTR_STR1 0x02 /* TCNT1 performs count operations */
-#define SH7750_TSTR_STR0 0x01 /* TCNT0 performs count operations */
-#define SH7750_TSTR_STR(n) (1 << (n))
-
-/* Timer Constant Register - TCOR0, TCOR1, TCOR2 */
-#define SH7750_TCOR_REGOFS(n) (0xD80008 + ((n)*12)) /* offset */
-#define SH7750_TCOR(n) SH7750_P4_REG32(SH7750_TCOR_REGOFS(n))
-#define SH7750_TCOR_A7(n) SH7750_A7_REG32(SH7750_TCOR_REGOFS(n))
-#define SH7750_TCOR0 SH7750_TCOR(0)
-#define SH7750_TCOR1 SH7750_TCOR(1)
-#define SH7750_TCOR2 SH7750_TCOR(2)
-#define SH7750_TCOR0_A7 SH7750_TCOR_A7(0)
-#define SH7750_TCOR1_A7 SH7750_TCOR_A7(1)
-#define SH7750_TCOR2_A7 SH7750_TCOR_A7(2)
-
-/* Timer Counter Register - TCNT0, TCNT1, TCNT2 */
-#define SH7750_TCNT_REGOFS(n) (0xD8000C + ((n)*12)) /* offset */
-#define SH7750_TCNT(n) SH7750_P4_REG32(SH7750_TCNT_REGOFS(n))
-#define SH7750_TCNT_A7(n) SH7750_A7_REG32(SH7750_TCNT_REGOFS(n))
-#define SH7750_TCNT0 SH7750_TCNT(0)
-#define SH7750_TCNT1 SH7750_TCNT(1)
-#define SH7750_TCNT2 SH7750_TCNT(2)
-#define SH7750_TCNT0_A7 SH7750_TCNT_A7(0)
-#define SH7750_TCNT1_A7 SH7750_TCNT_A7(1)
-#define SH7750_TCNT2_A7 SH7750_TCNT_A7(2)
-
-/* Timer Control Register (half) - TCR0, TCR1, TCR2 */
-#define SH7750_TCR_REGOFS(n) (0xD80010 + ((n)*12)) /* offset */
-#define SH7750_TCR(n) SH7750_P4_REG32(SH7750_TCR_REGOFS(n))
-#define SH7750_TCR_A7(n) SH7750_A7_REG32(SH7750_TCR_REGOFS(n))
-#define SH7750_TCR0 SH7750_TCR(0)
-#define SH7750_TCR1 SH7750_TCR(1)
-#define SH7750_TCR2 SH7750_TCR(2)
-#define SH7750_TCR0_A7 SH7750_TCR_A7(0)
-#define SH7750_TCR1_A7 SH7750_TCR_A7(1)
-#define SH7750_TCR2_A7 SH7750_TCR_A7(2)
-
-#define SH7750_TCR2_ICPF 0x200 /* Input Capture Interrupt Flag
- (1 - input capture has occured) */
-#define SH7750_TCR_UNF 0x100 /* Underflow flag */
-#define SH7750_TCR2_ICPE 0x0C0 /* Input Capture Control: */
-#define SH7750_TCR2_ICPE_DIS 0x000 /* Input Capture function is not used */
-#define SH7750_TCR2_ICPE_NOINT 0x080 /* Input Capture function is used, but
- input capture interrupt is not
- enabled */
-#define SH7750_TCR2_ICPE_INT 0x0C0 /* Input Capture function is used,
- input capture interrupt enabled */
-#define SH7750_TCR_UNIE 0x020 /* Underflow Interrupt Control
- (1 - underflow interrupt enabled) */
-#define SH7750_TCR_CKEG 0x018 /* Clock Edge selection: */
-#define SH7750_TCR_CKEG_RAISE 0x000 /* Count/capture on rising edge */
-#define SH7750_TCR_CKEG_FALL 0x008 /* Count/capture on falling edge */
-#define SH7750_TCR_CKEG_BOTH 0x018 /* Count/capture on both rising and
- falling edges */
-#define SH7750_TCR_TPSC 0x007 /* Timer prescaler */
-#define SH7750_TCR_TPSC_DIV4 0x000 /* Counts on peripheral clock/4 */
-#define SH7750_TCR_TPSC_DIV16 0x001 /* Counts on peripheral clock/16 */
-#define SH7750_TCR_TPSC_DIV64 0x002 /* Counts on peripheral clock/64 */
-#define SH7750_TCR_TPSC_DIV256 0x003 /* Counts on peripheral clock/256 */
-#define SH7750_TCR_TPSC_DIV1024 0x004 /* Counts on peripheral clock/1024 */
-#define SH7750_TCR_TPSC_RTC 0x006 /* Counts on on-chip RTC output clk */
-#define SH7750_TCR_TPSC_EXT 0x007 /* Counts on external clock */
-
-/* Input Capture Register (read-only) - TCPR2 */
-#define SH7750_TCPR2_REGOFS 0xD8002C /* offset */
-#define SH7750_TCPR2 SH7750_P4_REG32(SH7750_TCPR2_REGOFS)
-#define SH7750_TCPR2_A7 SH7750_A7_REG32(SH7750_TCPR2_REGOFS)
-
-/*
- * Bus State Controller - BSC
- */
-/* Bus Control Register 1 - BCR1 */
-#define SH7750_BCR1_REGOFS 0x800000 /* offset */
-#define SH7750_BCR1 SH7750_P4_REG32(SH7750_BCR1_REGOFS)
-#define SH7750_BCR1_A7 SH7750_A7_REG32(SH7750_BCR1_REGOFS)
-#define SH7750_BCR1_ENDIAN 0x80000000 /* Endianness (1 - little endian) */
-#define SH7750_BCR1_MASTER 0x40000000 /* Master/Slave mode (1-master) */
-#define SH7750_BCR1_A0MPX 0x20000000 /* Area 0 Memory Type (0-SRAM,1-MPX) */
-#define SH7750_BCR1_IPUP 0x02000000 /* Input Pin Pull-up Control:
- 0 - pull-up resistor is on for
- control input pins
- 1 - pull-up resistor is off */
-#define SH7750_BCR1_OPUP 0x01000000 /* Output Pin Pull-up Control:
- 0 - pull-up resistor is on for
- control output pins
- 1 - pull-up resistor is off */
-#define SH7750_BCR1_A1MBC 0x00200000 /* Area 1 SRAM Byte Control Mode:
- 0 - Area 1 SRAM is set to
- normal mode
- 1 - Area 1 SRAM is set to byte
- control mode */
-#define SH7750_BCR1_A4MBC 0x00100000 /* Area 4 SRAM Byte Control Mode:
- 0 - Area 4 SRAM is set to
- normal mode
- 1 - Area 4 SRAM is set to byte
- control mode */
-#define SH7750_BCR1_BREQEN 0x00080000 /* BREQ Enable:
- 0 - External requests are not
- accepted
- 1 - External requests are
- accepted */
-#define SH7750_BCR1_PSHR 0x00040000 /* Partial Sharing Bit:
- 0 - Master Mode
- 1 - Partial-sharing Mode */
-#define SH7750_BCR1_MEMMPX 0x00020000 /* Area 1 to 6 MPX Interface:
- 0 - SRAM/burst ROM interface
- 1 - MPX interface */
-#define SH7750_BCR1_HIZMEM 0x00008000 /* High Impendance Control. Specifies
- the state of A[25:0], BS\, CSn\,
- RD/WR\, CE2A\, CE2B\ in standby
- mode and when bus is released:
- 0 - signals go to High-Z mode
- 1 - signals driven */
-#define SH7750_BCR1_HIZCNT 0x00004000 /* High Impendance Control. Specifies
- the state of the RAS\, RAS2\, WEn\,
- CASn\, DQMn, RD\, CASS\, FRAME\,
- RD2\ signals in standby mode and
- when bus is released:
- 0 - signals go to High-Z mode
- 1 - signals driven */
-#define SH7750_BCR1_A0BST 0x00003800 /* Area 0 Burst ROM Control */
-#define SH7750_BCR1_A0BST_SRAM 0x0000 /* Area 0 accessed as SRAM i/f */
-#define SH7750_BCR1_A0BST_ROM4 0x0800 /* Area 0 accessed as burst ROM
- interface, 4 cosequtive access */
-#define SH7750_BCR1_A0BST_ROM8 0x1000 /* Area 0 accessed as burst ROM
- interface, 8 cosequtive access */
-#define SH7750_BCR1_A0BST_ROM16 0x1800 /* Area 0 accessed as burst ROM
- interface, 16 cosequtive access */
-#define SH7750_BCR1_A0BST_ROM32 0x2000 /* Area 0 accessed as burst ROM
- interface, 32 cosequtive access */
-
-#define SH7750_BCR1_A5BST 0x00000700 /* Area 5 Burst ROM Control */
-#define SH7750_BCR1_A5BST_SRAM 0x0000 /* Area 5 accessed as SRAM i/f */
-#define SH7750_BCR1_A5BST_ROM4 0x0100 /* Area 5 accessed as burst ROM
- interface, 4 cosequtive access */
-#define SH7750_BCR1_A5BST_ROM8 0x0200 /* Area 5 accessed as burst ROM
- interface, 8 cosequtive access */
-#define SH7750_BCR1_A5BST_ROM16 0x0300 /* Area 5 accessed as burst ROM
- interface, 16 cosequtive access */
-#define SH7750_BCR1_A5BST_ROM32 0x0400 /* Area 5 accessed as burst ROM
- interface, 32 cosequtive access */
-
-#define SH7750_BCR1_A6BST 0x000000E0 /* Area 6 Burst ROM Control */
-#define SH7750_BCR1_A6BST_SRAM 0x0000 /* Area 6 accessed as SRAM i/f */
-#define SH7750_BCR1_A6BST_ROM4 0x0020 /* Area 6 accessed as burst ROM
- interface, 4 cosequtive access */
-#define SH7750_BCR1_A6BST_ROM8 0x0040 /* Area 6 accessed as burst ROM
- interface, 8 cosequtive access */
-#define SH7750_BCR1_A6BST_ROM16 0x0060 /* Area 6 accessed as burst ROM
- interface, 16 cosequtive access */
-#define SH7750_BCR1_A6BST_ROM32 0x0080 /* Area 6 accessed as burst ROM
- interface, 32 cosequtive access */
-
-#define SH7750_BCR1_DRAMTP 0x001C /* Area 2 and 3 Memory Type */
-#define SH7750_BCR1_DRAMTP_2SRAM_3SRAM 0x0000 /* Area 2 and 3 are SRAM or MPX
- interface. */
-#define SH7750_BCR1_DRAMTP_2SRAM_3SDRAM 0x0008 /* Area 2 - SRAM/MPX, Area 3 -
- synchronous DRAM */
-#define SH7750_BCR1_DRAMTP_2SDRAM_3SDRAM 0x000C /* Area 2 and 3 are synchronous
- DRAM interface */
-#define SH7750_BCR1_DRAMTP_2SRAM_3DRAM 0x0010 /* Area 2 - SRAM/MPX, Area 3 -
- DRAM interface */
-#define SH7750_BCR1_DRAMTP_2DRAM_3DRAM 0x0014 /* Area 2 and 3 are DRAM
- interface */
-
-#define SH7750_BCR1_A56PCM 0x00000001 /* Area 5 and 6 Bus Type:
- 0 - SRAM interface
- 1 - PCMCIA interface */
-
-/* Bus Control Register 2 (half) - BCR2 */
-#define SH7750_BCR2_REGOFS 0x800004 /* offset */
-#define SH7750_BCR2 SH7750_P4_REG32(SH7750_BCR2_REGOFS)
-#define SH7750_BCR2_A7 SH7750_A7_REG32(SH7750_BCR2_REGOFS)
-
-#define SH7750_BCR2_A0SZ 0xC000 /* Area 0 Bus Width */
-#define SH7750_BCR2_A0SZ_S 14
-#define SH7750_BCR2_A6SZ 0x3000 /* Area 6 Bus Width */
-#define SH7750_BCR2_A6SZ_S 12
-#define SH7750_BCR2_A5SZ 0x0C00 /* Area 5 Bus Width */
-#define SH7750_BCR2_A5SZ_S 10
-#define SH7750_BCR2_A4SZ 0x0300 /* Area 4 Bus Width */
-#define SH7750_BCR2_A4SZ_S 8
-#define SH7750_BCR2_A3SZ 0x00C0 /* Area 3 Bus Width */
-#define SH7750_BCR2_A3SZ_S 6
-#define SH7750_BCR2_A2SZ 0x0030 /* Area 2 Bus Width */
-#define SH7750_BCR2_A2SZ_S 4
-#define SH7750_BCR2_A1SZ 0x000C /* Area 1 Bus Width */
-#define SH7750_BCR2_A1SZ_S 2
-#define SH7750_BCR2_SZ_64 0 /* 64 bits */
-#define SH7750_BCR2_SZ_8 1 /* 8 bits */
-#define SH7750_BCR2_SZ_16 2 /* 16 bits */
-#define SH7750_BCR2_SZ_32 3 /* 32 bits */
-#define SH7750_BCR2_PORTEN 0x0001 /* Port Function Enable :
- 0 - D51-D32 are not used as a port
- 1 - D51-D32 are used as a port */
-
-/* Wait Control Register 1 - WCR1 */
-#define SH7750_WCR1_REGOFS 0x800008 /* offset */
-#define SH7750_WCR1 SH7750_P4_REG32(SH7750_WCR1_REGOFS)
-#define SH7750_WCR1_A7 SH7750_A7_REG32(SH7750_WCR1_REGOFS)
-#define SH7750_WCR1_DMAIW 0x70000000 /* DACK Device Inter-Cycle Idle
- specification */
-#define SH7750_WCR1_DMAIW_S 28
-#define SH7750_WCR1_A6IW 0x07000000 /* Area 6 Inter-Cycle Idle spec. */
-#define SH7750_WCR1_A6IW_S 24
-#define SH7750_WCR1_A5IW 0x00700000 /* Area 5 Inter-Cycle Idle spec. */
-#define SH7750_WCR1_A5IW_S 20
-#define SH7750_WCR1_A4IW 0x00070000 /* Area 4 Inter-Cycle Idle spec. */
-#define SH7750_WCR1_A4IW_S 16
-#define SH7750_WCR1_A3IW 0x00007000 /* Area 3 Inter-Cycle Idle spec. */
-#define SH7750_WCR1_A3IW_S 12
-#define SH7750_WCR1_A2IW 0x00000700 /* Area 2 Inter-Cycle Idle spec. */
-#define SH7750_WCR1_A2IW_S 8
-#define SH7750_WCR1_A1IW 0x00000070 /* Area 1 Inter-Cycle Idle spec. */
-#define SH7750_WCR1_A1IW_S 4
-#define SH7750_WCR1_A0IW 0x00000007 /* Area 0 Inter-Cycle Idle spec. */
-#define SH7750_WCR1_A0IW_S 0
-
-/* Wait Control Register 2 - WCR2 */
-#define SH7750_WCR2_REGOFS 0x80000C /* offset */
-#define SH7750_WCR2 SH7750_P4_REG32(SH7750_WCR2_REGOFS)
-#define SH7750_WCR2_A7 SH7750_A7_REG32(SH7750_WCR2_REGOFS)
-
-#define SH7750_WCR2_A6W 0xE0000000 /* Area 6 Wait Control */
-#define SH7750_WCR2_A6W_S 29
-#define SH7750_WCR2_A6B 0x1C000000 /* Area 6 Burst Pitch */
-#define SH7750_WCR2_A6B_S 26
-#define SH7750_WCR2_A5W 0x03800000 /* Area 5 Wait Control */
-#define SH7750_WCR2_A5W_S 23
-#define SH7750_WCR2_A5B 0x00700000 /* Area 5 Burst Pitch */
-#define SH7750_WCR2_A5B_S 20
-#define SH7750_WCR2_A4W 0x000E0000 /* Area 4 Wait Control */
-#define SH7750_WCR2_A4W_S 17
-#define SH7750_WCR2_A3W 0x0000E000 /* Area 3 Wait Control */
-#define SH7750_WCR2_A3W_S 13
-#define SH7750_WCR2_A2W 0x00000E00 /* Area 2 Wait Control */
-#define SH7750_WCR2_A2W_S 9
-#define SH7750_WCR2_A1W 0x000001C0 /* Area 1 Wait Control */
-#define SH7750_WCR2_A1W_S 6
-#define SH7750_WCR2_A0W 0x00000038 /* Area 0 Wait Control */
-#define SH7750_WCR2_A0W_S 3
-#define SH7750_WCR2_A0B 0x00000007 /* Area 0 Burst Pitch */
-#define SH7750_WCR2_A0B_S 0
-
-#define SH7750_WCR2_WS0 0 /* 0 wait states inserted */
-#define SH7750_WCR2_WS1 1 /* 1 wait states inserted */
-#define SH7750_WCR2_WS2 2 /* 2 wait states inserted */
-#define SH7750_WCR2_WS3 3 /* 3 wait states inserted */
-#define SH7750_WCR2_WS6 4 /* 6 wait states inserted */
-#define SH7750_WCR2_WS9 5 /* 9 wait states inserted */
-#define SH7750_WCR2_WS12 6 /* 12 wait states inserted */
-#define SH7750_WCR2_WS15 7 /* 15 wait states inserted */
-
-#define SH7750_WCR2_BPWS0 0 /* 0 wait states inserted from 2nd access */
-#define SH7750_WCR2_BPWS1 1 /* 1 wait states inserted from 2nd access */
-#define SH7750_WCR2_BPWS2 2 /* 2 wait states inserted from 2nd access */
-#define SH7750_WCR2_BPWS3 3 /* 3 wait states inserted from 2nd access */
-#define SH7750_WCR2_BPWS4 4 /* 4 wait states inserted from 2nd access */
-#define SH7750_WCR2_BPWS5 5 /* 5 wait states inserted from 2nd access */
-#define SH7750_WCR2_BPWS6 6 /* 6 wait states inserted from 2nd access */
-#define SH7750_WCR2_BPWS7 7 /* 7 wait states inserted from 2nd access */
-
-/* DRAM CAS\ Assertion Delay (area 3,2) */
-#define SH7750_WCR2_DRAM_CAS_ASW1 0 /* 1 cycle */
-#define SH7750_WCR2_DRAM_CAS_ASW2 1 /* 2 cycles */
-#define SH7750_WCR2_DRAM_CAS_ASW3 2 /* 3 cycles */
-#define SH7750_WCR2_DRAM_CAS_ASW4 3 /* 4 cycles */
-#define SH7750_WCR2_DRAM_CAS_ASW7 4 /* 7 cycles */
-#define SH7750_WCR2_DRAM_CAS_ASW10 5 /* 10 cycles */
-#define SH7750_WCR2_DRAM_CAS_ASW13 6 /* 13 cycles */
-#define SH7750_WCR2_DRAM_CAS_ASW16 7 /* 16 cycles */
-
-/* SDRAM CAS\ Latency Cycles */
-#define SH7750_WCR2_SDRAM_CAS_LAT1 1 /* 1 cycle */
-#define SH7750_WCR2_SDRAM_CAS_LAT2 2 /* 2 cycles */
-#define SH7750_WCR2_SDRAM_CAS_LAT3 3 /* 3 cycles */
-#define SH7750_WCR2_SDRAM_CAS_LAT4 4 /* 4 cycles */
-#define SH7750_WCR2_SDRAM_CAS_LAT5 5 /* 5 cycles */
-
-/* Wait Control Register 3 - WCR3 */
-#define SH7750_WCR3_REGOFS 0x800010 /* offset */
-#define SH7750_WCR3 SH7750_P4_REG32(SH7750_WCR3_REGOFS)
-#define SH7750_WCR3_A7 SH7750_A7_REG32(SH7750_WCR3_REGOFS)
-
-#define SH7750_WCR3_A6S 0x04000000 /* Area 6 Write Strobe Setup time */
-#define SH7750_WCR3_A6H 0x03000000 /* Area 6 Data Hold Time */
-#define SH7750_WCR3_A6H_S 24
-#define SH7750_WCR3_A5S 0x00400000 /* Area 5 Write Strobe Setup time */
-#define SH7750_WCR3_A5H 0x00300000 /* Area 5 Data Hold Time */
-#define SH7750_WCR3_A5H_S 20
-#define SH7750_WCR3_A4S 0x00040000 /* Area 4 Write Strobe Setup time */
-#define SH7750_WCR3_A4H 0x00030000 /* Area 4 Data Hold Time */
-#define SH7750_WCR3_A4H_S 16
-#define SH7750_WCR3_A3S 0x00004000 /* Area 3 Write Strobe Setup time */
-#define SH7750_WCR3_A3H 0x00003000 /* Area 3 Data Hold Time */
-#define SH7750_WCR3_A3H_S 12
-#define SH7750_WCR3_A2S 0x00000400 /* Area 2 Write Strobe Setup time */
-#define SH7750_WCR3_A2H 0x00000300 /* Area 2 Data Hold Time */
-#define SH7750_WCR3_A2H_S 8
-#define SH7750_WCR3_A1S 0x00000040 /* Area 1 Write Strobe Setup time */
-#define SH7750_WCR3_A1H 0x00000030 /* Area 1 Data Hold Time */
-#define SH7750_WCR3_A1H_S 4
-#define SH7750_WCR3_A0S 0x00000004 /* Area 0 Write Strobe Setup time */
-#define SH7750_WCR3_A0H 0x00000003 /* Area 0 Data Hold Time */
-#define SH7750_WCR3_A0H_S 0
-
-#define SH7750_WCR3_DHWS_0 0 /* 0 wait states data hold time */
-#define SH7750_WCR3_DHWS_1 1 /* 1 wait states data hold time */
-#define SH7750_WCR3_DHWS_2 2 /* 2 wait states data hold time */
-#define SH7750_WCR3_DHWS_3 3 /* 3 wait states data hold time */
-
-#define SH7750_MCR_REGOFS 0x800014 /* offset */
-#define SH7750_MCR SH7750_P4_REG32(SH7750_MCR_REGOFS)
-#define SH7750_MCR_A7 SH7750_A7_REG32(SH7750_MCR_REGOFS)
-
-#define SH7750_MCR_RASD 0x80000000 /* RAS Down mode */
-#define SH7750_MCR_MRSET 0x40000000 /* SDRAM Mode Register Set */
-#define SH7750_MCR_PALL 0x00000000 /* SDRAM Precharge All cmd. Mode */
-#define SH7750_MCR_TRC 0x38000000 /* RAS Precharge Time at End of
- Refresh: */
-#define SH7750_MCR_TRC_0 0x00000000 /* 0 */
-#define SH7750_MCR_TRC_3 0x08000000 /* 3 */
-#define SH7750_MCR_TRC_6 0x10000000 /* 6 */
-#define SH7750_MCR_TRC_9 0x18000000 /* 9 */
-#define SH7750_MCR_TRC_12 0x20000000 /* 12 */
-#define SH7750_MCR_TRC_15 0x28000000 /* 15 */
-#define SH7750_MCR_TRC_18 0x30000000 /* 18 */
-#define SH7750_MCR_TRC_21 0x38000000 /* 21 */
-
-#define SH7750_MCR_TCAS 0x00800000 /* CAS Negation Period */
-#define SH7750_MCR_TCAS_1 0x00000000 /* 1 */
-#define SH7750_MCR_TCAS_2 0x00800000 /* 2 */
-
-#define SH7750_MCR_TPC 0x00380000 /* DRAM: RAS Precharge Period
- SDRAM: minimum number of cycles
- until the next bank active cmd
- is output after precharging */
-#define SH7750_MCR_TPC_S 19
-#define SH7750_MCR_TPC_SDRAM_1 0x00000000 /* 1 cycle */
-#define SH7750_MCR_TPC_SDRAM_2 0x00080000 /* 2 cycles */
-#define SH7750_MCR_TPC_SDRAM_3 0x00100000 /* 3 cycles */
-#define SH7750_MCR_TPC_SDRAM_4 0x00180000 /* 4 cycles */
-#define SH7750_MCR_TPC_SDRAM_5 0x00200000 /* 5 cycles */
-#define SH7750_MCR_TPC_SDRAM_6 0x00280000 /* 6 cycles */
-#define SH7750_MCR_TPC_SDRAM_7 0x00300000 /* 7 cycles */
-#define SH7750_MCR_TPC_SDRAM_8 0x00380000 /* 8 cycles */
-
-#define SH7750_MCR_RCD 0x00030000 /* DRAM: RAS-CAS Assertion Delay time
- SDRAM: bank active-read/write cmd
- delay time */
-#define SH7750_MCR_RCD_DRAM_2 0x00000000 /* DRAM delay 2 clocks */
-#define SH7750_MCR_RCD_DRAM_3 0x00010000 /* DRAM delay 3 clocks */
-#define SH7750_MCR_RCD_DRAM_4 0x00020000 /* DRAM delay 4 clocks */
-#define SH7750_MCR_RCD_DRAM_5 0x00030000 /* DRAM delay 5 clocks */
-#define SH7750_MCR_RCD_SDRAM_2 0x00010000 /* DRAM delay 2 clocks */
-#define SH7750_MCR_RCD_SDRAM_3 0x00020000 /* DRAM delay 3 clocks */
-#define SH7750_MCR_RCD_SDRAM_4 0x00030000 /* DRAM delay 4 clocks */
-
-#define SH7750_MCR_TRWL 0x0000E000 /* SDRAM Write Precharge Delay */
-#define SH7750_MCR_TRWL_1 0x00000000 /* 1 */
-#define SH7750_MCR_TRWL_2 0x00002000 /* 2 */
-#define SH7750_MCR_TRWL_3 0x00004000 /* 3 */
-#define SH7750_MCR_TRWL_4 0x00006000 /* 4 */
-#define SH7750_MCR_TRWL_5 0x00008000 /* 5 */
-
-#define SH7750_MCR_TRAS 0x00001C00 /* DRAM: CAS-Before-RAS Refresh RAS
- asserting period
- SDRAM: Command interval after
- synchronous DRAM refresh */
-#define SH7750_MCR_TRAS_DRAM_2 0x00000000 /* 2 */
-#define SH7750_MCR_TRAS_DRAM_3 0x00000400 /* 3 */
-#define SH7750_MCR_TRAS_DRAM_4 0x00000800 /* 4 */
-#define SH7750_MCR_TRAS_DRAM_5 0x00000C00 /* 5 */
-#define SH7750_MCR_TRAS_DRAM_6 0x00001000 /* 6 */
-#define SH7750_MCR_TRAS_DRAM_7 0x00001400 /* 7 */
-#define SH7750_MCR_TRAS_DRAM_8 0x00001800 /* 8 */
-#define SH7750_MCR_TRAS_DRAM_9 0x00001C00 /* 9 */
-
-#define SH7750_MCR_TRAS_SDRAM_TRC_4 0x00000000 /* 4 + TRC */
-#define SH7750_MCR_TRAS_SDRAM_TRC_5 0x00000400 /* 5 + TRC */
-#define SH7750_MCR_TRAS_SDRAM_TRC_6 0x00000800 /* 6 + TRC */
-#define SH7750_MCR_TRAS_SDRAM_TRC_7 0x00000C00 /* 7 + TRC */
-#define SH7750_MCR_TRAS_SDRAM_TRC_8 0x00001000 /* 8 + TRC */
-#define SH7750_MCR_TRAS_SDRAM_TRC_9 0x00001400 /* 9 + TRC */
-#define SH7750_MCR_TRAS_SDRAM_TRC_10 0x00001800 /* 10 + TRC */
-#define SH7750_MCR_TRAS_SDRAM_TRC_11 0x00001C00 /* 11 + TRC */
-
-#define SH7750_MCR_BE 0x00000200 /* Burst Enable */
-#define SH7750_MCR_SZ 0x00000180 /* Memory Data Size */
-#define SH7750_MCR_SZ_64 0x00000000 /* 64 bits */
-#define SH7750_MCR_SZ_16 0x00000100 /* 16 bits */
-#define SH7750_MCR_SZ_32 0x00000180 /* 32 bits */
-
-#define SH7750_MCR_AMX 0x00000078 /* Address Multiplexing */
-#define SH7750_MCR_AMX_S 3
-#define SH7750_MCR_AMX_DRAM_8BIT_COL 0x00000000 /* 8-bit column addr */
-#define SH7750_MCR_AMX_DRAM_9BIT_COL 0x00000008 /* 9-bit column addr */
-#define SH7750_MCR_AMX_DRAM_10BIT_COL 0x00000010 /* 10-bit column addr */
-#define SH7750_MCR_AMX_DRAM_11BIT_COL 0x00000018 /* 11-bit column addr */
-#define SH7750_MCR_AMX_DRAM_12BIT_COL 0x00000020 /* 12-bit column addr */
-/* See SH7750 Hardware Manual for SDRAM address multiplexor selection */
-
-#define SH7750_MCR_RFSH 0x00000004 /* Refresh Control */
-#define SH7750_MCR_RMODE 0x00000002 /* Refresh Mode: */
-#define SH7750_MCR_RMODE_NORMAL 0x00000000 /* Normal Refresh Mode */
-#define SH7750_MCR_RMODE_SELF 0x00000002 /* Self-Refresh Mode */
-#define SH7750_MCR_RMODE_EDO 0x00000001 /* EDO Mode */
-
-/* SDRAM Mode Set address */
-#define SH7750_SDRAM_MODE_A2_BASE 0xFF900000
-#define SH7750_SDRAM_MODE_A3_BASE 0xFF940000
-#define SH7750_SDRAM_MODE_A2_32BIT(x) (SH7750_SDRAM_MODE_A2_BASE + ((x) << 2))
-#define SH7750_SDRAM_MODE_A3_32BIT(x) (SH7750_SDRAM_MODE_A3_BASE + ((x) << 2))
-#define SH7750_SDRAM_MODE_A2_64BIT(x) (SH7750_SDRAM_MODE_A2_BASE + ((x) << 3))
-#define SH7750_SDRAM_MODE_A3_64BIT(x) (SH7750_SDRAM_MODE_A3_BASE + ((x) << 3))
-
-
-/* PCMCIA Control Register (half) - PCR */
-#define SH7750_PCR_REGOFS 0x800018 /* offset */
-#define SH7750_PCR SH7750_P4_REG32(SH7750_PCR_REGOFS)
-#define SH7750_PCR_A7 SH7750_A7_REG32(SH7750_PCR_REGOFS)
-
-#define SH7750_PCR_A5PCW 0xC000 /* Area 5 PCMCIA Wait - Number of wait
- states to be added to the number of
- waits specified by WCR2 in a low-speed
- PCMCIA wait cycle */
-#define SH7750_PCR_A5PCW_0 0x0000 /* 0 waits inserted */
-#define SH7750_PCR_A5PCW_15 0x4000 /* 15 waits inserted */
-#define SH7750_PCR_A5PCW_30 0x8000 /* 30 waits inserted */
-#define SH7750_PCR_A5PCW_50 0xC000 /* 50 waits inserted */
-
-#define SH7750_PCR_A6PCW 0x3000 /* Area 6 PCMCIA Wait - Number of wait
- states to be added to the number of
- waits specified by WCR2 in a low-speed
- PCMCIA wait cycle */
-#define SH7750_PCR_A6PCW_0 0x0000 /* 0 waits inserted */
-#define SH7750_PCR_A6PCW_15 0x1000 /* 15 waits inserted */
-#define SH7750_PCR_A6PCW_30 0x2000 /* 30 waits inserted */
-#define SH7750_PCR_A6PCW_50 0x3000 /* 50 waits inserted */
-
-#define SH7750_PCR_A5TED 0x0E00 /* Area 5 Address-OE\/WE\ Assertion Delay,
- delay time from address output to
- OE\/WE\ assertion on the connected
- PCMCIA interface */
-#define SH7750_PCR_A5TED_S 9
-#define SH7750_PCR_A6TED 0x01C0 /* Area 6 Address-OE\/WE\ Assertion Delay */
-#define SH7750_PCR_A6TED_S 6
-
-#define SH7750_PCR_TED_0WS 0 /* 0 Waits inserted */
-#define SH7750_PCR_TED_1WS 1 /* 1 Waits inserted */
-#define SH7750_PCR_TED_2WS 2 /* 2 Waits inserted */
-#define SH7750_PCR_TED_3WS 3 /* 3 Waits inserted */
-#define SH7750_PCR_TED_6WS 4 /* 6 Waits inserted */
-#define SH7750_PCR_TED_9WS 5 /* 9 Waits inserted */
-#define SH7750_PCR_TED_12WS 6 /* 12 Waits inserted */
-#define SH7750_PCR_TED_15WS 7 /* 15 Waits inserted */
-
-#define SH7750_PCR_A5TEH 0x0038 /* Area 5 OE\/WE\ Negation Address delay,
- address hold delay time from OE\/WE\
- negation in a write on the connected
- PCMCIA interface */
-#define SH7750_PCR_A5TEH_S 3
-
-#define SH7750_PCR_A6TEH 0x0007 /* Area 6 OE\/WE\ Negation Address delay */
-#define SH7750_PCR_A6TEH_S 0
-
-#define SH7750_PCR_TEH_0WS 0 /* 0 Waits inserted */
-#define SH7750_PCR_TEH_1WS 1 /* 1 Waits inserted */
-#define SH7750_PCR_TEH_2WS 2 /* 2 Waits inserted */
-#define SH7750_PCR_TEH_3WS 3 /* 3 Waits inserted */
-#define SH7750_PCR_TEH_6WS 4 /* 6 Waits inserted */
-#define SH7750_PCR_TEH_9WS 5 /* 9 Waits inserted */
-#define SH7750_PCR_TEH_12WS 6 /* 12 Waits inserted */
-#define SH7750_PCR_TEH_15WS 7 /* 15 Waits inserted */
-
-/* Refresh Timer Control/Status Register (half) - RTSCR */
-#define SH7750_RTCSR_REGOFS 0x80001C /* offset */
-#define SH7750_RTCSR SH7750_P4_REG32(SH7750_RTCSR_REGOFS)
-#define SH7750_RTCSR_A7 SH7750_A7_REG32(SH7750_RTCSR_REGOFS)
-
-#define SH7750_RTCSR_KEY 0xA500 /* RTCSR write key */
-#define SH7750_RTCSR_CMF 0x0080 /* Compare-Match Flag (indicates a
- match between the refresh timer
- counter and refresh time constant) */
-#define SH7750_RTCSR_CMIE 0x0040 /* Compare-Match Interrupt Enable */
-#define SH7750_RTCSR_CKS 0x0038 /* Refresh Counter Clock Selects */
-#define SH7750_RTCSR_CKS_DIS 0x0000 /* Clock Input Disabled */
-#define SH7750_RTCSR_CKS_CKIO_DIV4 0x0008 /* Bus Clock / 4 */
-#define SH7750_RTCSR_CKS_CKIO_DIV16 0x0010 /* Bus Clock / 16 */
-#define SH7750_RTCSR_CKS_CKIO_DIV64 0x0018 /* Bus Clock / 64 */
-#define SH7750_RTCSR_CKS_CKIO_DIV256 0x0020 /* Bus Clock / 256 */
-#define SH7750_RTCSR_CKS_CKIO_DIV1024 0x0028 /* Bus Clock / 1024 */
-#define SH7750_RTCSR_CKS_CKIO_DIV2048 0x0030 /* Bus Clock / 2048 */
-#define SH7750_RTCSR_CKS_CKIO_DIV4096 0x0038 /* Bus Clock / 4096 */
-
-#define SH7750_RTCSR_OVF 0x0004 /* Refresh Count Overflow Flag */
-#define SH7750_RTCSR_OVIE 0x0002 /* Refresh Count Overflow Interrupt
- Enable */
-#define SH7750_RTCSR_LMTS 0x0001 /* Refresh Count Overflow Limit Select */
-#define SH7750_RTCSR_LMTS_1024 0x0000 /* Count Limit is 1024 */
-#define SH7750_RTCSR_LMTS_512 0x0001 /* Count Limit is 512 */
-
-/* Refresh Timer Counter (half) - RTCNT */
-#define SH7750_RTCNT_REGOFS 0x800020 /* offset */
-#define SH7750_RTCNT SH7750_P4_REG32(SH7750_RTCNT_REGOFS)
-#define SH7750_RTCNT_A7 SH7750_A7_REG32(SH7750_RTCNT_REGOFS)
-
-#define SH7750_RTCNT_KEY 0xA500 /* RTCNT write key */
-
-/* Refresh Time Constant Register (half) - RTCOR */
-#define SH7750_RTCOR_REGOFS 0x800024 /* offset */
-#define SH7750_RTCOR SH7750_P4_REG32(SH7750_RTCOR_REGOFS)
-#define SH7750_RTCOR_A7 SH7750_A7_REG32(SH7750_RTCOR_REGOFS)
-
-#define SH7750_RTCOR_KEY 0xA500 /* RTCOR write key */
-
-/* Refresh Count Register (half) - RFCR */
-#define SH7750_RFCR_REGOFS 0x800028 /* offset */
-#define SH7750_RFCR SH7750_P4_REG32(SH7750_RFCR_REGOFS)
-#define SH7750_RFCR_A7 SH7750_A7_REG32(SH7750_RFCR_REGOFS)
-
-#define SH7750_RFCR_KEY 0xA400 /* RFCR write key */
-
-/*
- * Direct Memory Access Controller (DMAC)
- */
-
-/* DMA Source Address Register - SAR0, SAR1, SAR2, SAR3 */
-#define SH7750_SAR_REGOFS(n) (0xA00000 + ((n)*16)) /* offset */
-#define SH7750_SAR(n) SH7750_P4_REG32(SH7750_SAR_REGOFS(n))
-#define SH7750_SAR_A7(n) SH7750_A7_REG32(SH7750_SAR_REGOFS(n))
-#define SH7750_SAR0 SH7750_SAR(0)
-#define SH7750_SAR1 SH7750_SAR(1)
-#define SH7750_SAR2 SH7750_SAR(2)
-#define SH7750_SAR3 SH7750_SAR(3)
-#define SH7750_SAR0_A7 SH7750_SAR_A7(0)
-#define SH7750_SAR1_A7 SH7750_SAR_A7(1)
-#define SH7750_SAR2_A7 SH7750_SAR_A7(2)
-#define SH7750_SAR3_A7 SH7750_SAR_A7(3)
-
-/* DMA Destination Address Register - DAR0, DAR1, DAR2, DAR3 */
-#define SH7750_DAR_REGOFS(n) (0xA00004 + ((n)*16)) /* offset */
-#define SH7750_DAR(n) SH7750_P4_REG32(SH7750_DAR_REGOFS(n))
-#define SH7750_DAR_A7(n) SH7750_A7_REG32(SH7750_DAR_REGOFS(n))
-#define SH7750_DAR0 SH7750_DAR(0)
-#define SH7750_DAR1 SH7750_DAR(1)
-#define SH7750_DAR2 SH7750_DAR(2)
-#define SH7750_DAR3 SH7750_DAR(3)
-#define SH7750_DAR0_A7 SH7750_DAR_A7(0)
-#define SH7750_DAR1_A7 SH7750_DAR_A7(1)
-#define SH7750_DAR2_A7 SH7750_DAR_A7(2)
-#define SH7750_DAR3_A7 SH7750_DAR_A7(3)
-
-/* DMA Transfer Count Register - DMATCR0, DMATCR1, DMATCR2, DMATCR3 */
-#define SH7750_DMATCR_REGOFS(n) (0xA00008 + ((n)*16)) /* offset */
-#define SH7750_DMATCR(n) SH7750_P4_REG32(SH7750_DMATCR_REGOFS(n))
-#define SH7750_DMATCR_A7(n) SH7750_A7_REG32(SH7750_DMATCR_REGOFS(n))
-#define SH7750_DMATCR0_P4 SH7750_DMATCR(0)
-#define SH7750_DMATCR1_P4 SH7750_DMATCR(1)
-#define SH7750_DMATCR2_P4 SH7750_DMATCR(2)
-#define SH7750_DMATCR3_P4 SH7750_DMATCR(3)
-#define SH7750_DMATCR0_A7 SH7750_DMATCR_A7(0)
-#define SH7750_DMATCR1_A7 SH7750_DMATCR_A7(1)
-#define SH7750_DMATCR2_A7 SH7750_DMATCR_A7(2)
-#define SH7750_DMATCR3_A7 SH7750_DMATCR_A7(3)
-
-/* DMA Channel Control Register - CHCR0, CHCR1, CHCR2, CHCR3 */
-#define SH7750_CHCR_REGOFS(n) (0xA0000C + ((n)*16)) /* offset */
-#define SH7750_CHCR(n) SH7750_P4_REG32(SH7750_CHCR_REGOFS(n))
-#define SH7750_CHCR_A7(n) SH7750_A7_REG32(SH7750_CHCR_REGOFS(n))
-#define SH7750_CHCR0 SH7750_CHCR(0)
-#define SH7750_CHCR1 SH7750_CHCR(1)
-#define SH7750_CHCR2 SH7750_CHCR(2)
-#define SH7750_CHCR3 SH7750_CHCR(3)
-#define SH7750_CHCR0_A7 SH7750_CHCR_A7(0)
-#define SH7750_CHCR1_A7 SH7750_CHCR_A7(1)
-#define SH7750_CHCR2_A7 SH7750_CHCR_A7(2)
-#define SH7750_CHCR3_A7 SH7750_CHCR_A7(3)
-
-#define SH7750_CHCR_SSA 0xE0000000 /* Source Address Space Attribute */
-#define SH7750_CHCR_SSA_PCMCIA 0x00000000 /* Reserved in PCMCIA access */
-#define SH7750_CHCR_SSA_DYNBSZ 0x20000000 /* Dynamic Bus Sizing I/O space */
-#define SH7750_CHCR_SSA_IO8 0x40000000 /* 8-bit I/O space */
-#define SH7750_CHCR_SSA_IO16 0x60000000 /* 16-bit I/O space */
-#define SH7750_CHCR_SSA_CMEM8 0x80000000 /* 8-bit common memory space */
-#define SH7750_CHCR_SSA_CMEM16 0xA0000000 /* 16-bit common memory space */
-#define SH7750_CHCR_SSA_AMEM8 0xC0000000 /* 8-bit attribute memory space */
-#define SH7750_CHCR_SSA_AMEM16 0xE0000000 /* 16-bit attribute memory space */
-
-#define SH7750_CHCR_STC 0x10000000 /* Source Address Wait Control Select,
- specifies CS5 or CS6 space wait
- control for PCMCIA access */
-
-#define SH7750_CHCR_DSA 0x0E000000 /* Source Address Space Attribute */
-#define SH7750_CHCR_DSA_PCMCIA 0x00000000 /* Reserved in PCMCIA access */
-#define SH7750_CHCR_DSA_DYNBSZ 0x02000000 /* Dynamic Bus Sizing I/O space */
-#define SH7750_CHCR_DSA_IO8 0x04000000 /* 8-bit I/O space */
-#define SH7750_CHCR_DSA_IO16 0x06000000 /* 16-bit I/O space */
-#define SH7750_CHCR_DSA_CMEM8 0x08000000 /* 8-bit common memory space */
-#define SH7750_CHCR_DSA_CMEM16 0x0A000000 /* 16-bit common memory space */
-#define SH7750_CHCR_DSA_AMEM8 0x0C000000 /* 8-bit attribute memory space */
-#define SH7750_CHCR_DSA_AMEM16 0x0E000000 /* 16-bit attribute memory space */
-
-#define SH7750_CHCR_DTC 0x01000000 /* Destination Address Wait Control
- Select, specifies CS5 or CS6
- space wait control for PCMCIA
- access */
-
-#define SH7750_CHCR_DS 0x00080000 /* DREQ\ Select : */
-#define SH7750_CHCR_DS_LOWLVL 0x00000000 /* Low Level Detection */
-#define SH7750_CHCR_DS_FALL 0x00080000 /* Falling Edge Detection */
-
-#define SH7750_CHCR_RL 0x00040000 /* Request Check Level: */
-#define SH7750_CHCR_RL_ACTH 0x00000000 /* DRAK is an active high out */
-#define SH7750_CHCR_RL_ACTL 0x00040000 /* DRAK is an active low out */
-
-#define SH7750_CHCR_AM 0x00020000 /* Acknowledge Mode: */
-#define SH7750_CHCR_AM_RD 0x00000000 /* DACK is output in read cycle */
-#define SH7750_CHCR_AM_WR 0x00020000 /* DACK is output in write cycle */
-
-#define SH7750_CHCR_AL 0x00010000 /* Acknowledge Level: */
-#define SH7750_CHCR_AL_ACTH 0x00000000 /* DACK is an active high out */
-#define SH7750_CHCR_AL_ACTL 0x00010000 /* DACK is an active low out */
-
-#define SH7750_CHCR_DM 0x0000C000 /* Destination Address Mode: */
-#define SH7750_CHCR_DM_FIX 0x00000000 /* Destination Addr Fixed */
-#define SH7750_CHCR_DM_INC 0x00004000 /* Destination Addr Incremented */
-#define SH7750_CHCR_DM_DEC 0x00008000 /* Destination Addr Decremented */
-
-#define SH7750_CHCR_SM 0x00003000 /* Source Address Mode: */
-#define SH7750_CHCR_SM_FIX 0x00000000 /* Source Addr Fixed */
-#define SH7750_CHCR_SM_INC 0x00001000 /* Source Addr Incremented */
-#define SH7750_CHCR_SM_DEC 0x00002000 /* Source Addr Decremented */
-
-#define SH7750_CHCR_RS 0x00000F00 /* Request Source Select: */
-#define SH7750_CHCR_RS_ER_DA_EA_TO_EA 0x000 /* External Request, Dual Address
- Mode (External Addr Space->
- External Addr Space) */
-#define SH7750_CHCR_RS_ER_SA_EA_TO_ED 0x200 /* External Request, Single
- Address Mode (External Addr
- Space -> External Device) */
-#define SH7750_CHCR_RS_ER_SA_ED_TO_EA 0x300 /* External Request, Single
- Address Mode, (External
- Device -> External Addr
- Space) */
-#define SH7750_CHCR_RS_AR_EA_TO_EA 0x400 /* Auto-Request (External Addr
- Space -> External Addr Space) */
-
-#define SH7750_CHCR_RS_AR_EA_TO_OCP 0x500 /* Auto-Request (External Addr
- Space -> On-chip Peripheral
- Module) */
-#define SH7750_CHCR_RS_AR_OCP_TO_EA 0x600 /* Auto-Request (On-chip
- Peripheral Module ->
- External Addr Space */
-#define SH7750_CHCR_RS_SCITX_EA_TO_SC 0x800 /* SCI Transmit-Data-Empty intr
- transfer request (external
- address space -> SCTDR1) */
-#define SH7750_CHCR_RS_SCIRX_SC_TO_EA 0x900 /* SCI Receive-Data-Full intr
- transfer request (SCRDR1 ->
- External Addr Space) */
-#define SH7750_CHCR_RS_SCIFTX_EA_TO_SC 0xA00 /* SCIF Transmit-Data-Empty intr
- transfer request (external
- address space -> SCFTDR1) */
-#define SH7750_CHCR_RS_SCIFRX_SC_TO_EA 0xB00 /* SCIF Receive-Data-Full intr
- transfer request (SCFRDR2 ->
- External Addr Space) */
-#define SH7750_CHCR_RS_TMU2_EA_TO_EA 0xC00 /* TMU Channel 2 (input capture
- interrupt), (external address
- space -> external address
- space) */
-#define SH7750_CHCR_RS_TMU2_EA_TO_OCP 0xD00 /* TMU Channel 2 (input capture
- interrupt), (external address
- space -> on-chip peripheral
- module) */
-#define SH7750_CHCR_RS_TMU2_OCP_TO_EA 0xE00 /* TMU Channel 2 (input capture
- interrupt), (on-chip
- peripheral module -> external
- address space) */
-
-#define SH7750_CHCR_TM 0x00000080 /* Transmit mode: */
-#define SH7750_CHCR_TM_CSTEAL 0x00000000 /* Cycle Steal Mode */
-#define SH7750_CHCR_TM_BURST 0x00000080 /* Burst Mode */
-
-#define SH7750_CHCR_TS 0x00000070 /* Transmit Size: */
-#define SH7750_CHCR_TS_QUAD 0x00000000 /* Quadword Size (64 bits) */
-#define SH7750_CHCR_TS_BYTE 0x00000010 /* Byte Size (8 bit) */
-#define SH7750_CHCR_TS_WORD 0x00000020 /* Word Size (16 bit) */
-#define SH7750_CHCR_TS_LONG 0x00000030 /* Longword Size (32 bit) */
-#define SH7750_CHCR_TS_BLOCK 0x00000040 /* 32-byte block transfer */
-
-#define SH7750_CHCR_IE 0x00000004 /* Interrupt Enable */
-#define SH7750_CHCR_TE 0x00000002 /* Transfer End */
-#define SH7750_CHCR_DE 0x00000001 /* DMAC Enable */
-
-/* DMA Operation Register - DMAOR */
-#define SH7750_DMAOR_REGOFS 0xA00040 /* offset */
-#define SH7750_DMAOR SH7750_P4_REG32(SH7750_DMAOR_REGOFS)
-#define SH7750_DMAOR_A7 SH7750_A7_REG32(SH7750_DMAOR_REGOFS)
-
-#define SH7750_DMAOR_DDT 0x00008000 /* On-Demand Data Transfer Mode */
-
-#define SH7750_DMAOR_PR 0x00000300 /* Priority Mode: */
-#define SH7750_DMAOR_PR_0123 0x00000000 /* CH0 > CH1 > CH2 > CH3 */
-#define SH7750_DMAOR_PR_0231 0x00000100 /* CH0 > CH2 > CH3 > CH1 */
-#define SH7750_DMAOR_PR_2013 0x00000200 /* CH2 > CH0 > CH1 > CH3 */
-#define SH7750_DMAOR_PR_RR 0x00000300 /* Round-robin mode */
-
-#define SH7750_DMAOR_COD 0x00000010 /* Check Overrun for DREQ\ */
-#define SH7750_DMAOR_AE 0x00000004 /* Address Error flag */
-#define SH7750_DMAOR_NMIF 0x00000002 /* NMI Flag */
-#define SH7750_DMAOR_DME 0x00000001 /* DMAC Master Enable */
-
-/*
- * Serial Communication Interface - SCI
- * Serial Communication Interface with FIFO - SCIF
- */
-/* SCI Receive Data Register (byte, read-only) - SCRDR1, SCFRDR2 */
-#define SH7750_SCRDR_REGOFS(n) ((n) == 1 ? 0xE00014 : 0xE80014) /* offset */
-#define SH7750_SCRDR(n) SH7750_P4_REG32(SH7750_SCRDR_REGOFS(n))
-#define SH7750_SCRDR1 SH7750_SCRDR(1)
-#define SH7750_SCRDR2 SH7750_SCRDR(2)
-#define SH7750_SCRDR_A7(n) SH7750_A7_REG32(SH7750_SCRDR_REGOFS(n))
-#define SH7750_SCRDR1_A7 SH7750_SCRDR_A7(1)
-#define SH7750_SCRDR2_A7 SH7750_SCRDR_A7(2)
-
-/* SCI Transmit Data Register (byte) - SCTDR1, SCFTDR2 */
-#define SH7750_SCTDR_REGOFS(n) ((n) == 1 ? 0xE0000C : 0xE8000C) /* offset */
-#define SH7750_SCTDR(n) SH7750_P4_REG32(SH7750_SCTDR_REGOFS(n))
-#define SH7750_SCTDR1 SH7750_SCTDR(1)
-#define SH7750_SCTDR2 SH7750_SCTDR(2)
-#define SH7750_SCTDR_A7(n) SH7750_A7_REG32(SH7750_SCTDR_REGOFS(n))
-#define SH7750_SCTDR1_A7 SH7750_SCTDR_A7(1)
-#define SH7750_SCTDR2_A7 SH7750_SCTDR_A7(2)
-
-/* SCI Serial Mode Register - SCSMR1(byte), SCSMR2(half) */
-#define SH7750_SCSMR_REGOFS(n) ((n) == 1 ? 0xE00000 : 0xE80000) /* offset */
-#define SH7750_SCSMR(n) SH7750_P4_REG32(SH7750_SCSMR_REGOFS(n))
-#define SH7750_SCSMR1 SH7750_SCSMR(1)
-#define SH7750_SCSMR2 SH7750_SCSMR(2)
-#define SH7750_SCSMR_A7(n) SH7750_A7_REG32(SH7750_SCSMR_REGOFS(n))
-#define SH7750_SCSMR1_A7 SH7750_SCSMR_A7(1)
-#define SH7750_SCSMR2_A7 SH7750_SCSMR_A7(2)
-
-#define SH7750_SCSMR1_CA 0x80 /* Communication Mode (C/A\): */
-#define SH7750_SCSMR1_CA_ASYNC 0x00 /* Asynchronous Mode */
-#define SH7750_SCSMR1_CA_SYNC 0x80 /* Synchronous Mode */
-#define SH7750_SCSMR_CHR 0x40 /* Character Length: */
-#define SH7750_SCSMR_CHR_8 0x00 /* 8-bit data */
-#define SH7750_SCSMR_CHR_7 0x40 /* 7-bit data */
-#define SH7750_SCSMR_PE 0x20 /* Parity Enable */
-#define SH7750_SCSMR_PM 0x10 /* Parity Mode: */
-#define SH7750_SCSMR_PM_EVEN 0x00 /* Even Parity */
-#define SH7750_SCSMR_PM_ODD 0x10 /* Odd Parity */
-#define SH7750_SCSMR_STOP 0x08 /* Stop Bit Length: */
-#define SH7750_SCSMR_STOP_1 0x00 /* 1 stop bit */
-#define SH7750_SCSMR_STOP_2 0x08 /* 2 stop bit */
-#define SH7750_SCSMR1_MP 0x04 /* Multiprocessor Mode */
-#define SH7750_SCSMR_CKS 0x03 /* Clock Select */
-#define SH7750_SCSMR_CKS_S 0
-#define SH7750_SCSMR_CKS_DIV1 0x00 /* Periph clock */
-#define SH7750_SCSMR_CKS_DIV4 0x01 /* Periph clock / 4 */
-#define SH7750_SCSMR_CKS_DIV16 0x02 /* Periph clock / 16 */
-#define SH7750_SCSMR_CKS_DIV64 0x03 /* Periph clock / 64 */
-
-/* SCI Serial Control Register - SCSCR1(byte), SCSCR2(half) */
-#define SH7750_SCSCR_REGOFS(n) ((n) == 1 ? 0xE00008 : 0xE80008) /* offset */
-#define SH7750_SCSCR(n) SH7750_P4_REG32(SH7750_SCSCR_REGOFS(n))
-#define SH7750_SCSCR1 SH7750_SCSCR(1)
-#define SH7750_SCSCR2 SH7750_SCSCR(2)
-#define SH7750_SCSCR_A7(n) SH7750_A7_REG32(SH7750_SCSCR_REGOFS(n))
-#define SH7750_SCSCR1_A7 SH7750_SCSCR_A7(1)
-#define SH7750_SCSCR2_A7 SH7750_SCSCR_A7(2)
-
-#define SH7750_SCSCR_TIE 0x80 /* Transmit Interrupt Enable */
-#define SH7750_SCSCR_RIE 0x40 /* Receive Interrupt Enable */
-#define SH7750_SCSCR_TE 0x20 /* Transmit Enable */
-#define SH7750_SCSCR_RE 0x10 /* Receive Enable */
-#define SH7750_SCSCR1_MPIE 0x08 /* Multiprocessor Interrupt Enable */
-#define SH7750_SCSCR2_REIE 0x08 /* Receive Error Interrupt Enable */
-#define SH7750_SCSCR1_TEIE 0x04 /* Transmit End Interrupt Enable */
-#define SH7750_SCSCR1_CKE 0x03 /* Clock Enable: */
-#define SH7750_SCSCR_CKE_INTCLK 0x00 /* Use Internal Clock */
-#define SH7750_SCSCR_CKE_EXTCLK 0x02 /* Use External Clock from SCK */
-#define SH7750_SCSCR1_CKE_ASYNC_SCK_CLKOUT 0x01 /* Use SCK as a clock output
- in asynchronous mode */
-
-/* SCI Serial Status Register - SCSSR1(byte), SCSFR2(half) */
-#define SH7750_SCSSR_REGOFS(n) ((n) == 1 ? 0xE00010 : 0xE80010) /* offset */
-#define SH7750_SCSSR(n) SH7750_P4_REG32(SH7750_SCSSR_REGOFS(n))
-#define SH7750_SCSSR1 SH7750_SCSSR(1)
-#define SH7750_SCSFR2 SH7750_SCSSR(2)
-#define SH7750_SCSSR_A7(n) SH7750_A7_REG32(SH7750_SCSSR_REGOFS(n))
-#define SH7750_SCSSR1_A7 SH7750_SCSSR_A7(1)
-#define SH7750_SCSFR2_A7 SH7750_SCSSR_A7(2)
-
-#define SH7750_SCSSR1_TDRE 0x80 /* Transmit Data Register Empty */
-#define SH7750_SCSSR1_RDRF 0x40 /* Receive Data Register Full */
-#define SH7750_SCSSR1_ORER 0x20 /* Overrun Error */
-#define SH7750_SCSSR1_FER 0x10 /* Framing Error */
-#define SH7750_SCSSR1_PER 0x08 /* Parity Error */
-#define SH7750_SCSSR1_TEND 0x04 /* Transmit End */
-#define SH7750_SCSSR1_MPB 0x02 /* Multiprocessor Bit */
-#define SH7750_SCSSR1_MPBT 0x01 /* Multiprocessor Bit Transfer */
-
-#define SH7750_SCFSR2_PERN 0xF000 /* Number of Parity Errors */
-#define SH7750_SCFSR2_PERN_S 12
-#define SH7750_SCFSR2_FERN 0x0F00 /* Number of Framing Errors */
-#define SH7750_SCFSR2_FERN_S 8
-#define SH7750_SCFSR2_ER 0x0080 /* Receive Error */
-#define SH7750_SCFSR2_TEND 0x0040 /* Transmit End */
-#define SH7750_SCFSR2_TDFE 0x0020 /* Transmit FIFO Data Empty */
-#define SH7750_SCFSR2_BRK 0x0010 /* Break Detect */
-#define SH7750_SCFSR2_FER 0x0008 /* Framing Error */
-#define SH7750_SCFSR2_PER 0x0004 /* Parity Error */
-#define SH7750_SCFSR2_RDF 0x0002 /* Receive FIFO Data Full */
-#define SH7750_SCFSR2_DR 0x0001 /* Receive Data Ready */
-
-/* SCI Serial Port Register - SCSPTR1(byte) */
-#define SH7750_SCSPTR1_REGOFS 0xE0001C /* offset */
-#define SH7750_SCSPTR1 SH7750_P4_REG32(SH7750_SCSPTR1_REGOFS)
-#define SH7750_SCSPTR1_A7 SH7750_A7_REG32(SH7750_SCSPTR1_REGOFS)
-
-#define SH7750_SCSPTR1_EIO 0x80 /* Error Interrupt Only */
-#define SH7750_SCSPTR1_SPB1IO 0x08 /* 1: Output SPB1DT bit to SCK pin */
-#define SH7750_SCSPTR1_SPB1DT 0x04 /* Serial Port Clock Port Data */
-#define SH7750_SCSPTR1_SPB0IO 0x02 /* 1: Output SPB0DT bit to TxD pin */
-#define SH7750_SCSPTR1_SPB0DT 0x01 /* Serial Port Break Data */
-
-/* SCIF Serial Port Register - SCSPTR2(half) */
-#define SH7750_SCSPTR2_REGOFS 0xE80020 /* offset */
-#define SH7750_SCSPTR2 SH7750_P4_REG32(SH7750_SCSPTR2_REGOFS)
-#define SH7750_SCSPTR2_A7 SH7750_A7_REG32(SH7750_SCSPTR2_REGOFS)
-
-#define SH7750_SCSPTR2_RTSIO 0x80 /* 1: Output RTSDT bit to RTS2\ pin */
-#define SH7750_SCSPTR2_RTSDT 0x40 /* RTS Port Data */
-#define SH7750_SCSPTR2_CTSIO 0x20 /* 1: Output CTSDT bit to CTS2\ pin */
-#define SH7750_SCSPTR2_CTSDT 0x10 /* CTS Port Data */
-#define SH7750_SCSPTR2_SPB2IO 0x02 /* 1: Output SPBDT bit to TxD2 pin */
-#define SH7750_SCSPTR2_SPB2DT 0x01 /* Serial Port Break Data */
-
-/* SCI Bit Rate Register - SCBRR1(byte), SCBRR2(byte) */
-#define SH7750_SCBRR_REGOFS(n) ((n) == 1 ? 0xE00004 : 0xE80004) /* offset */
-#define SH7750_SCBRR(n) SH7750_P4_REG32(SH7750_SCBRR_REGOFS(n))
-#define SH7750_SCBRR1 SH7750_SCBRR_P4(1)
-#define SH7750_SCBRR2 SH7750_SCBRR_P4(2)
-#define SH7750_SCBRR_A7(n) SH7750_A7_REG32(SH7750_SCBRR_REGOFS(n))
-#define SH7750_SCBRR1_A7 SH7750_SCBRR_A7(1)
-#define SH7750_SCBRR2_A7 SH7750_SCBRR_A7(2)
-
-/* SCIF FIFO Control Register - SCFCR2(half) */
-#define SH7750_SCFCR2_REGOFS 0xE80018 /* offset */
-#define SH7750_SCFCR2 SH7750_P4_REG32(SH7750_SCFCR2_REGOFS)
-#define SH7750_SCFCR2_A7 SH7750_A7_REG32(SH7750_SCFCR2_REGOFS)
-
-#define SH7750_SCFCR2_RSTRG 0x700 /* RTS2\ Output Active Trigger; RTS2\
- signal goes to high level when the
- number of received data stored in
- FIFO exceeds the trigger number */
-#define SH7750_SCFCR2_RSTRG_15 0x000 /* 15 bytes */
-#define SH7750_SCFCR2_RSTRG_1 0x000 /* 1 byte */
-#define SH7750_SCFCR2_RSTRG_4 0x000 /* 4 bytes */
-#define SH7750_SCFCR2_RSTRG_6 0x000 /* 6 bytes */
-#define SH7750_SCFCR2_RSTRG_8 0x000 /* 8 bytes */
-#define SH7750_SCFCR2_RSTRG_10 0x000 /* 10 bytes */
-#define SH7750_SCFCR2_RSTRG_14 0x000 /* 14 bytes */
-
-#define SH7750_SCFCR2_RTRG 0x0C0 /* Receive FIFO Data Number Trigger,
- Receive Data Full (RDF) Flag sets
- when number of receive data bytes is
- equal or greater than the trigger
- number */
-#define SH7750_SCFCR2_RTRG_1 0x000 /* 1 byte */
-#define SH7750_SCFCR2_RTRG_4 0x040 /* 4 bytes */
-#define SH7750_SCFCR2_RTRG_8 0x080 /* 8 bytes */
-#define SH7750_SCFCR2_RTRG_14 0x0C0 /* 14 bytes */
-
-#define SH7750_SCFCR2_TTRG 0x030 /* Transmit FIFO Data Number Trigger,
- Transmit FIFO Data Register Empty (TDFE)
- flag sets when the number of remaining
- transmit data bytes is equal or less
- than the trigger number */
-#define SH7750_SCFCR2_TTRG_8 0x000 /* 8 bytes */
-#define SH7750_SCFCR2_TTRG_4 0x010 /* 4 bytes */
-#define SH7750_SCFCR2_TTRG_2 0x020 /* 2 bytes */
-#define SH7750_SCFCR2_TTRG_1 0x030 /* 1 byte */
-
-#define SH7750_SCFCR2_MCE 0x008 /* Modem Control Enable */
-#define SH7750_SCFCR2_TFRST 0x004 /* Transmit FIFO Data Register Reset,
- invalidates the transmit data in the
- transmit FIFO */
-#define SH7750_SCFCR2_RFRST 0x002 /* Receive FIFO Data Register Reset,
- invalidates the receive data in the
- receive FIFO data register and resets
- it to the empty state */
-#define SH7750_SCFCR2_LOOP 0x001 /* Loopback Test */
-
-/* SCIF FIFO Data Count Register - SCFDR2(half, read-only) */
-#define SH7750_SCFDR2_REGOFS 0xE8001C /* offset */
-#define SH7750_SCFDR2 SH7750_P4_REG32(SH7750_SCFDR2_REGOFS)
-#define SH7750_SCFDR2_A7 SH7750_A7_REG32(SH7750_SCFDR2_REGOFS)
-
-#define SH7750_SCFDR2_T 0x1F00 /* Number of untransmitted data bytes
- in transmit FIFO */
-#define SH7750_SCFDR2_T_S 8
-#define SH7750_SCFDR2_R 0x001F /* Number of received data bytes in
- receive FIFO */
-#define SH7750_SCFDR2_R_S 0
-
-/* SCIF Line Status Register - SCLSR2(half, read-only) */
-#define SH7750_SCLSR2_REGOFS 0xE80024 /* offset */
-#define SH7750_SCLSR2 SH7750_P4_REG32(SH7750_SCLSR2_REGOFS)
-#define SH7750_SCLSR2_A7 SH7750_A7_REG32(SH7750_SCLSR2_REGOFS)
-
-#define SH7750_SCLSR2_ORER 0x0001 /* Overrun Error */
-
-/*
- * SCI-based Smart Card Interface
- */
-/* Smart Card Mode Register - SCSCMR1(byte) */
-#define SH7750_SCSCMR1_REGOFS 0xE00018 /* offset */
-#define SH7750_SCSCMR1 SH7750_P4_REG32(SH7750_SCSCMR1_REGOFS)
-#define SH7750_SCSCMR1_A7 SH7750_A7_REG32(SH7750_SCSCMR1_REGOFS)
-
-#define SH7750_SCSCMR1_SDIR 0x08 /* Smart Card Data Transfer Direction: */
-#define SH7750_SCSCMR1_SDIR_LSBF 0x00 /* LSB-first */
-#define SH7750_SCSCMR1_SDIR_MSBF 0x08 /* MSB-first */
-
-#define SH7750_SCSCMR1_SINV 0x04 /* Smart Card Data Inversion */
-#define SH7750_SCSCMR1_SMIF 0x01 /* Smart Card Interface Mode Select */
-
-/* Smart-card specific bits in other registers */
-/* SCSMR1: */
-#define SH7750_SCSMR1_GSM 0x80 /* GSM mode select */
-
-/* SCSSR1: */
-#define SH7750_SCSSR1_ERS 0x10 /* Error Signal Status */
-
-/*
- * I/O Ports
- */
-/* Port Control Register A - PCTRA */
-#define SH7750_PCTRA_REGOFS 0x80002C /* offset */
-#define SH7750_PCTRA SH7750_P4_REG32(SH7750_PCTRA_REGOFS)
-#define SH7750_PCTRA_A7 SH7750_A7_REG32(SH7750_PCTRA_REGOFS)
-
-#define SH7750_PCTRA_PBPUP(n) 0 /* Bit n is pulled up */
-#define SH7750_PCTRA_PBNPUP(n) (1 << ((n)*2+1)) /* Bit n is not pulled up */
-#define SH7750_PCTRA_PBINP(n) 0 /* Bit n is an input */
-#define SH7750_PCTRA_PBOUT(n) (1 << ((n)*2)) /* Bit n is an output */
-
-/* Port Data Register A - PDTRA(half) */
-#define SH7750_PDTRA_REGOFS 0x800030 /* offset */
-#define SH7750_PDTRA SH7750_P4_REG32(SH7750_PDTRA_REGOFS)
-#define SH7750_PDTRA_A7 SH7750_A7_REG32(SH7750_PDTRA_REGOFS)
-
-#define SH7750_PDTRA_BIT(n) (1 << (n))
-
-/* Port Control Register B - PCTRB */
-#define SH7750_PCTRB_REGOFS 0x800040 /* offset */
-#define SH7750_PCTRB SH7750_P4_REG32(SH7750_PCTRB_REGOFS)
-#define SH7750_PCTRB_A7 SH7750_A7_REG32(SH7750_PCTRB_REGOFS)
-
-#define SH7750_PCTRB_PBPUP(n) 0 /* Bit n is pulled up */
-#define SH7750_PCTRB_PBNPUP(n) (1 << ((n-16)*2+1)) /* Bit n is not pulled up */
-#define SH7750_PCTRB_PBINP(n) 0 /* Bit n is an input */
-#define SH7750_PCTRB_PBOUT(n) (1 << ((n-16)*2)) /* Bit n is an output */
-
-/* Port Data Register B - PDTRB(half) */
-#define SH7750_PDTRB_REGOFS 0x800044 /* offset */
-#define SH7750_PDTRB SH7750_P4_REG32(SH7750_PDTRB_REGOFS)
-#define SH7750_PDTRB_A7 SH7750_A7_REG32(SH7750_PDTRB_REGOFS)
-
-#define SH7750_PDTRB_BIT(n) (1 << ((n)-16))
-
-/* GPIO Interrupt Control Register - GPIOIC(half) */
-#define SH7750_GPIOIC_REGOFS 0x800048 /* offset */
-#define SH7750_GPIOIC SH7750_P4_REG32(SH7750_GPIOIC_REGOFS)
-#define SH7750_GPIOIC_A7 SH7750_A7_REG32(SH7750_GPIOIC_REGOFS)
-
-#define SH7750_GPIOIC_PTIREN(n) (1 << (n)) /* Port n is used as a GPIO int */
-
-/*
- * Interrupt Controller - INTC
- */
-/* Interrupt Control Register - ICR (half) */
-#define SH7750_ICR_REGOFS 0xD00000 /* offset */
-#define SH7750_ICR SH7750_P4_REG32(SH7750_ICR_REGOFS)
-#define SH7750_ICR_A7 SH7750_A7_REG32(SH7750_ICR_REGOFS)
-
-#define SH7750_ICR_NMIL 0x8000 /* NMI Input Level */
-#define SH7750_ICR_MAI 0x4000 /* NMI Interrupt Mask */
-
-#define SH7750_ICR_NMIB 0x0200 /* NMI Block Mode: */
-#define SH7750_ICR_NMIB_BLK 0x0000 /* NMI requests held pending while
- SR.BL bit is set to 1 */
-#define SH7750_ICR_NMIB_NBLK 0x0200 /* NMI requests detected when SR.BL bit
- set to 1 */
-
-#define SH7750_ICR_NMIE 0x0100 /* NMI Edge Select: */
-#define SH7750_ICR_NMIE_FALL 0x0000 /* Interrupt request detected on falling
- edge of NMI input */
-#define SH7750_ICR_NMIE_RISE 0x0100 /* Interrupt request detected on rising
- edge of NMI input */
-
-#define SH7750_ICR_IRLM 0x0080 /* IRL Pin Mode: */
-#define SH7750_ICR_IRLM_ENC 0x0000 /* IRL\ pins used as a level-encoded
- interrupt requests */
-#define SH7750_ICR_IRLM_RAW 0x0080 /* IRL\ pins used as a four independent
- interrupt requests */
-
-/* Interrupt Priority Register A - IPRA (half) */
-#define SH7750_IPRA_REGOFS 0xD00004 /* offset */
-#define SH7750_IPRA SH7750_P4_REG32(SH7750_IPRA_REGOFS)
-#define SH7750_IPRA_A7 SH7750_A7_REG32(SH7750_IPRA_REGOFS)
-
-#define SH7750_IPRA_TMU0 0xF000 /* TMU0 interrupt priority */
-#define SH7750_IPRA_TMU0_S 12
-#define SH7750_IPRA_TMU1 0x0F00 /* TMU1 interrupt priority */
-#define SH7750_IPRA_TMU1_S 8
-#define SH7750_IPRA_TMU2 0x00F0 /* TMU2 interrupt priority */
-#define SH7750_IPRA_TMU2_S 4
-#define SH7750_IPRA_RTC 0x000F /* RTC interrupt priority */
-#define SH7750_IPRA_RTC_S 0
-
-/* Interrupt Priority Register B - IPRB (half) */
-#define SH7750_IPRB_REGOFS 0xD00008 /* offset */
-#define SH7750_IPRB SH7750_P4_REG32(SH7750_IPRB_REGOFS)
-#define SH7750_IPRB_A7 SH7750_A7_REG32(SH7750_IPRB_REGOFS)
-
-#define SH7750_IPRB_WDT 0xF000 /* WDT interrupt priority */
-#define SH7750_IPRB_WDT_S 12
-#define SH7750_IPRB_REF 0x0F00 /* Memory Refresh unit interrupt
- priority */
-#define SH7750_IPRB_REF_S 8
-#define SH7750_IPRB_SCI1 0x00F0 /* SCI1 interrupt priority */
-#define SH7750_IPRB_SCI1_S 4
-
-/* Interrupt Priority Register ó - IPRó (half) */
-#define SH7750_IPRC_REGOFS 0xD00004 /* offset */
-#define SH7750_IPRC SH7750_P4_REG32(SH7750_IPRC_REGOFS)
-#define SH7750_IPRC_A7 SH7750_A7_REG32(SH7750_IPRC_REGOFS)
-
-#define SH7750_IPRC_GPIO 0xF000 /* GPIO interrupt priority */
-#define SH7750_IPRC_GPIO_S 12
-#define SH7750_IPRC_DMAC 0x0F00 /* DMAC interrupt priority */
-#define SH7750_IPRC_DMAC_S 8
-#define SH7750_IPRC_SCIF 0x00F0 /* SCIF interrupt priority */
-#define SH7750_IPRC_SCIF_S 4
-#define SH7750_IPRC_HUDI 0x000F /* H-UDI interrupt priority */
-#define SH7750_IPRC_HUDI_S 0
-
-
-/*
- * User Break Controller registers
- */
-#define SH7750_BARA 0x200000 /* Break address regiser A */
-#define SH7750_BAMRA 0x200004 /* Break address mask regiser A */
-#define SH7750_BBRA 0x200008 /* Break bus cycle regiser A */
-#define SH7750_BARB 0x20000c /* Break address regiser B */
-#define SH7750_BAMRB 0x200010 /* Break address mask regiser B */
-#define SH7750_BBRB 0x200014 /* Break bus cycle regiser B */
-#define SH7750_BASRB 0x000018 /* Break ASID regiser B */
-#define SH7750_BDRB 0x200018 /* Break data regiser B */
-#define SH7750_BDMRB 0x20001c /* Break data mask regiser B */
-#define SH7750_BRCR 0x200020 /* Break control register */
-
-#define SH7750_BRCR_UDBE 0x0001 /* User break debug enable bit */
-
-/*
- * Missing in RTEMS, added for QEMU
- */
-#define SH7750_BCR3_A7 0x1f800050
-#define SH7750_BCR4_A7 0x1e0a00f0
-#define SH7750_PRECHARGE0_A7 0x1f900088
-#define SH7750_PRECHARGE1_A7 0x1f940088
-
-#endif
diff --git a/tools/ioemu/hw/shix.c b/tools/ioemu/hw/shix.c
deleted file mode 100644
index 9577c092c2..0000000000
--- a/tools/ioemu/hw/shix.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * SHIX 2.0 board description
- *
- * Copyright (c) 2005 Samuel Tardieu
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- Shix 2.0 board by Alexis Polti, described at
- http://perso.enst.fr/~polti/realisations/shix20/
-
- More information in target-sh4/README.sh4
-*/
-#include "vl.h"
-
-#define BIOS_FILENAME "shix_bios.bin"
-#define BIOS_ADDRESS 0xA0000000
-
-void DMA_run(void)
-{
- /* XXXXX */
-}
-
-void irq_info(void)
-{
- /* XXXXX */
-}
-
-void pic_set_irq(int irq, int level)
-{
- /* XXXXX */
-}
-
-void pic_info()
-{
- /* XXXXX */
-}
-
-void vga_update_display()
-{
- /* XXXXX */
-}
-
-void vga_invalidate_display()
-{
- /* XXXXX */
-}
-
-void vga_screen_dump(const char *filename)
-{
- /* XXXXX */
-}
-
-void shix_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState * ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- int ret;
- CPUState *env;
- struct SH7750State *s;
-
- printf("Initializing CPU\n");
- env = cpu_init();
-
- /* Allocate memory space */
- printf("Allocating ROM\n");
- cpu_register_physical_memory(0x00000000, 0x00004000, IO_MEM_ROM);
- printf("Allocating SDRAM 1\n");
- cpu_register_physical_memory(0x08000000, 0x01000000, 0x00004000);
- printf("Allocating SDRAM 2\n");
- cpu_register_physical_memory(0x0c000000, 0x01000000, 0x01004000);
-
- /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
- printf("%s: load BIOS '%s'\n", __func__, BIOS_FILENAME);
- ret = load_image(BIOS_FILENAME, phys_ram_base);
- if (ret < 0) { /* Check bios size */
- fprintf(stderr, "ret=%d\n", ret);
- fprintf(stderr, "qemu: could not load SHIX bios '%s'\n",
- BIOS_FILENAME);
- exit(1);
- }
-
- /* Register peripherals */
- s = sh7750_init(env);
- /* XXXXX Check success */
- tc58128_init(s, "shix_linux_nand.bin", NULL);
- fprintf(stderr, "initialization terminated\n");
-}
-
-QEMUMachine shix_machine = {
- "shix",
- "shix card",
- shix_init
-};
diff --git a/tools/ioemu/hw/slavio_intctl.c b/tools/ioemu/hw/slavio_intctl.c
deleted file mode 100644
index 288fb50f0a..0000000000
--- a/tools/ioemu/hw/slavio_intctl.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * QEMU Sparc SLAVIO interrupt controller emulation
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-//#define DEBUG_IRQ_COUNT
-//#define DEBUG_IRQ
-
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, args...) \
-do { printf("IRQ: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...)
-#endif
-
-/*
- * Registers of interrupt controller in sun4m.
- *
- * This is the interrupt controller part of chip STP2001 (Slave I/O), also
- * produced as NCR89C105. See
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
- *
- * There is a system master controller and one for each cpu.
- *
- */
-
-#define MAX_CPUS 16
-
-typedef struct SLAVIO_INTCTLState {
- uint32_t intreg_pending[MAX_CPUS];
- uint32_t intregm_pending;
- uint32_t intregm_disabled;
- uint32_t target_cpu;
-#ifdef DEBUG_IRQ_COUNT
- uint64_t irq_count[32];
-#endif
- CPUState *cpu_envs[MAX_CPUS];
-} SLAVIO_INTCTLState;
-
-#define INTCTL_MAXADDR 0xf
-#define INTCTLM_MAXADDR 0xf
-static void slavio_check_interrupts(void *opaque);
-
-// per-cpu interrupt controller
-static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- SLAVIO_INTCTLState *s = opaque;
- uint32_t saddr;
- int cpu;
-
- cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;
- saddr = (addr & INTCTL_MAXADDR) >> 2;
- switch (saddr) {
- case 0:
- return s->intreg_pending[cpu];
- default:
- break;
- }
- return 0;
-}
-
-static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- SLAVIO_INTCTLState *s = opaque;
- uint32_t saddr;
- int cpu;
-
- cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;
- saddr = (addr & INTCTL_MAXADDR) >> 2;
- switch (saddr) {
- case 1: // clear pending softints
- if (val & 0x4000)
- val |= 80000000;
- val &= 0xfffe0000;
- s->intreg_pending[cpu] &= ~val;
- DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
- break;
- case 2: // set softint
- val &= 0xfffe0000;
- s->intreg_pending[cpu] |= val;
- slavio_check_interrupts(s);
- DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
- break;
- default:
- break;
- }
-}
-
-static CPUReadMemoryFunc *slavio_intctl_mem_read[3] = {
- slavio_intctl_mem_readl,
- slavio_intctl_mem_readl,
- slavio_intctl_mem_readl,
-};
-
-static CPUWriteMemoryFunc *slavio_intctl_mem_write[3] = {
- slavio_intctl_mem_writel,
- slavio_intctl_mem_writel,
- slavio_intctl_mem_writel,
-};
-
-// master system interrupt controller
-static uint32_t slavio_intctlm_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- SLAVIO_INTCTLState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & INTCTLM_MAXADDR) >> 2;
- switch (saddr) {
- case 0:
- return s->intregm_pending & 0x7fffffff;
- case 1:
- return s->intregm_disabled;
- case 4:
- return s->target_cpu;
- default:
- break;
- }
- return 0;
-}
-
-static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- SLAVIO_INTCTLState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & INTCTLM_MAXADDR) >> 2;
- switch (saddr) {
- case 2: // clear (enable)
- // Force clear unused bits
- val &= ~0x4fb2007f;
- s->intregm_disabled &= ~val;
- DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
- slavio_check_interrupts(s);
- break;
- case 3: // set (disable, clear pending)
- // Force clear unused bits
- val &= ~0x4fb2007f;
- s->intregm_disabled |= val;
- s->intregm_pending &= ~val;
- DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
- break;
- case 4:
- s->target_cpu = val & (MAX_CPUS - 1);
- DPRINTF("Set master irq cpu %d\n", s->target_cpu);
- break;
- default:
- break;
- }
-}
-
-static CPUReadMemoryFunc *slavio_intctlm_mem_read[3] = {
- slavio_intctlm_mem_readl,
- slavio_intctlm_mem_readl,
- slavio_intctlm_mem_readl,
-};
-
-static CPUWriteMemoryFunc *slavio_intctlm_mem_write[3] = {
- slavio_intctlm_mem_writel,
- slavio_intctlm_mem_writel,
- slavio_intctlm_mem_writel,
-};
-
-void slavio_pic_info(void *opaque)
-{
- SLAVIO_INTCTLState *s = opaque;
- int i;
-
- for (i = 0; i < MAX_CPUS; i++) {
- term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]);
- }
- term_printf("master: pending 0x%08x, disabled 0x%08x\n", s->intregm_pending, s->intregm_disabled);
-}
-
-void slavio_irq_info(void *opaque)
-{
-#ifndef DEBUG_IRQ_COUNT
- term_printf("irq statistic code not compiled.\n");
-#else
- SLAVIO_INTCTLState *s = opaque;
- int i;
- int64_t count;
-
- term_printf("IRQ statistics:\n");
- for (i = 0; i < 32; i++) {
- count = s->irq_count[i];
- if (count > 0)
- term_printf("%2d: %" PRId64 "\n", i, count);
- }
-#endif
-}
-
-static const uint32_t intbit_to_level[32] = {
- 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
- 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
-};
-
-static void slavio_check_interrupts(void *opaque)
-{
- CPUState *env;
- SLAVIO_INTCTLState *s = opaque;
- uint32_t pending = s->intregm_pending;
- unsigned int i, j, max = 0;
-
- pending &= ~s->intregm_disabled;
-
- if (pending && !(s->intregm_disabled & 0x80000000)) {
- for (i = 0; i < 32; i++) {
- if (pending & (1 << i)) {
- if (max < intbit_to_level[i])
- max = intbit_to_level[i];
- }
- }
- env = s->cpu_envs[s->target_cpu];
- if (!env) {
- DPRINTF("No CPU %d, not triggered (pending %x)\n", s->target_cpu, pending);
- }
- else {
- if (env->halted)
- env->halted = 0;
- if (env->interrupt_index == 0) {
- DPRINTF("Triggered CPU %d pil %d\n", s->target_cpu, max);
-#ifdef DEBUG_IRQ_COUNT
- s->irq_count[max]++;
-#endif
- env->interrupt_index = TT_EXTINT | max;
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- }
- else
- DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);
- }
- }
- else
- DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled);
-
- for (i = 0; i < MAX_CPUS; i++) {
- max = 0;
- env = s->cpu_envs[i];
- if (!env)
- continue;
- for (j = 17; j < 32; j++) {
- if (s->intreg_pending[i] & (1 << j)) {
- if (max < j - 16)
- max = j - 16;
- }
- }
- if (max > 0) {
- if (env->halted)
- env->halted = 0;
- if (env->interrupt_index == 0) {
- DPRINTF("Triggered softint %d for cpu %d (pending %x)\n", max, i, pending);
-#ifdef DEBUG_IRQ_COUNT
- s->irq_count[max]++;
-#endif
- env->interrupt_index = TT_EXTINT | max;
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- }
- }
- }
-}
-
-/*
- * "irq" here is the bit number in the system interrupt register to
- * separate serial and keyboard interrupts sharing a level.
- */
-void slavio_pic_set_irq(void *opaque, int irq, int level)
-{
- SLAVIO_INTCTLState *s = opaque;
-
- DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level);
- if (irq < 32) {
- uint32_t mask = 1 << irq;
- uint32_t pil = intbit_to_level[irq];
- if (pil > 0) {
- if (level) {
- s->intregm_pending |= mask;
- s->intreg_pending[s->target_cpu] |= 1 << pil;
- }
- else {
- s->intregm_pending &= ~mask;
- s->intreg_pending[s->target_cpu] &= ~(1 << pil);
- }
- }
- }
- slavio_check_interrupts(s);
-}
-
-void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu)
-{
- SLAVIO_INTCTLState *s = opaque;
-
- DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level);
- if (cpu == (unsigned int)-1) {
- slavio_pic_set_irq(opaque, irq, level);
- return;
- }
- if (irq < 32) {
- uint32_t pil = intbit_to_level[irq];
- if (pil > 0) {
- if (level) {
- s->intreg_pending[cpu] |= 1 << pil;
- }
- else {
- s->intreg_pending[cpu] &= ~(1 << pil);
- }
- }
- }
- slavio_check_interrupts(s);
-}
-
-static void slavio_intctl_save(QEMUFile *f, void *opaque)
-{
- SLAVIO_INTCTLState *s = opaque;
- int i;
-
- for (i = 0; i < MAX_CPUS; i++) {
- qemu_put_be32s(f, &s->intreg_pending[i]);
- }
- qemu_put_be32s(f, &s->intregm_pending);
- qemu_put_be32s(f, &s->intregm_disabled);
- qemu_put_be32s(f, &s->target_cpu);
-}
-
-static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id)
-{
- SLAVIO_INTCTLState *s = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- for (i = 0; i < MAX_CPUS; i++) {
- qemu_get_be32s(f, &s->intreg_pending[i]);
- }
- qemu_get_be32s(f, &s->intregm_pending);
- qemu_get_be32s(f, &s->intregm_disabled);
- qemu_get_be32s(f, &s->target_cpu);
- return 0;
-}
-
-static void slavio_intctl_reset(void *opaque)
-{
- SLAVIO_INTCTLState *s = opaque;
- int i;
-
- for (i = 0; i < MAX_CPUS; i++) {
- s->intreg_pending[i] = 0;
- }
- s->intregm_disabled = ~0xffb2007f;
- s->intregm_pending = 0;
- s->target_cpu = 0;
-}
-
-void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env)
-{
- SLAVIO_INTCTLState *s = opaque;
- s->cpu_envs[cpu] = env;
-}
-
-void *slavio_intctl_init(uint32_t addr, uint32_t addrg)
-{
- int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
- SLAVIO_INTCTLState *s;
-
- s = qemu_mallocz(sizeof(SLAVIO_INTCTLState));
- if (!s)
- return NULL;
-
- for (i = 0; i < MAX_CPUS; i++) {
- slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);
- cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_MAXADDR, slavio_intctl_io_memory);
- }
-
- slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s);
- cpu_register_physical_memory(addrg, INTCTLM_MAXADDR, slavio_intctlm_io_memory);
-
- register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s);
- qemu_register_reset(slavio_intctl_reset, s);
- slavio_intctl_reset(s);
- return s;
-}
-
diff --git a/tools/ioemu/hw/slavio_misc.c b/tools/ioemu/hw/slavio_misc.c
deleted file mode 100644
index a48a7af5c0..0000000000
--- a/tools/ioemu/hw/slavio_misc.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * QEMU Sparc SLAVIO aux io port emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-/* debug misc */
-//#define DEBUG_MISC
-
-/*
- * This is the auxio port, chip control and system control part of
- * chip STP2001 (Slave I/O), also produced as NCR89C105. See
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
- *
- * This also includes the PMC CPU idle controller.
- */
-
-#ifdef DEBUG_MISC
-#define MISC_DPRINTF(fmt, args...) \
-do { printf("MISC: " fmt , ##args); } while (0)
-#else
-#define MISC_DPRINTF(fmt, args...)
-#endif
-
-typedef struct MiscState {
- int irq;
- uint8_t config;
- uint8_t aux1, aux2;
- uint8_t diag, mctrl, sysctrl;
-} MiscState;
-
-#define MISC_MAXADDR 1
-
-static void slavio_misc_update_irq(void *opaque)
-{
- MiscState *s = opaque;
-
- if ((s->aux2 & 0x4) && (s->config & 0x8)) {
- pic_set_irq(s->irq, 1);
- } else {
- pic_set_irq(s->irq, 0);
- }
-}
-
-static void slavio_misc_reset(void *opaque)
-{
- MiscState *s = opaque;
-
- // Diagnostic and system control registers not cleared in reset
- s->config = s->aux1 = s->aux2 = s->mctrl = 0;
-}
-
-void slavio_set_power_fail(void *opaque, int power_failing)
-{
- MiscState *s = opaque;
-
- MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing, s->config);
- if (power_failing && (s->config & 0x8)) {
- s->aux2 |= 0x4;
- } else {
- s->aux2 &= ~0x4;
- }
- slavio_misc_update_irq(s);
-}
-
-static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- MiscState *s = opaque;
-
- switch (addr & 0xfff0000) {
- case 0x1800000:
- MISC_DPRINTF("Write config %2.2x\n", val & 0xff);
- s->config = val & 0xff;
- slavio_misc_update_irq(s);
- break;
- case 0x1900000:
- MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff);
- s->aux1 = val & 0xff;
- break;
- case 0x1910000:
- val &= 0x3;
- MISC_DPRINTF("Write aux2 %2.2x\n", val);
- val |= s->aux2 & 0x4;
- if (val & 0x2) // Clear Power Fail int
- val &= 0x1;
- s->aux2 = val;
- if (val & 1)
- qemu_system_shutdown_request();
- slavio_misc_update_irq(s);
- break;
- case 0x1a00000:
- MISC_DPRINTF("Write diag %2.2x\n", val & 0xff);
- s->diag = val & 0xff;
- break;
- case 0x1b00000:
- MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff);
- s->mctrl = val & 0xff;
- break;
- case 0x1f00000:
- MISC_DPRINTF("Write system control %2.2x\n", val & 0xff);
- if (val & 1) {
- s->sysctrl = 0x2;
- qemu_system_reset_request();
- }
- break;
- case 0xa000000:
- MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
- break;
- }
-}
-
-static uint32_t slavio_misc_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- MiscState *s = opaque;
- uint32_t ret = 0;
-
- switch (addr & 0xfff0000) {
- case 0x1800000:
- ret = s->config;
- MISC_DPRINTF("Read config %2.2x\n", ret);
- break;
- case 0x1900000:
- ret = s->aux1;
- MISC_DPRINTF("Read aux1 %2.2x\n", ret);
- break;
- case 0x1910000:
- ret = s->aux2;
- MISC_DPRINTF("Read aux2 %2.2x\n", ret);
- break;
- case 0x1a00000:
- ret = s->diag;
- MISC_DPRINTF("Read diag %2.2x\n", ret);
- break;
- case 0x1b00000:
- ret = s->mctrl;
- MISC_DPRINTF("Read modem control %2.2x\n", ret);
- break;
- case 0x1f00000:
- MISC_DPRINTF("Read system control %2.2x\n", ret);
- ret = s->sysctrl;
- break;
- case 0xa000000:
- MISC_DPRINTF("Read power management %2.2x\n", ret);
- break;
- }
- return ret;
-}
-
-static CPUReadMemoryFunc *slavio_misc_mem_read[3] = {
- slavio_misc_mem_readb,
- slavio_misc_mem_readb,
- slavio_misc_mem_readb,
-};
-
-static CPUWriteMemoryFunc *slavio_misc_mem_write[3] = {
- slavio_misc_mem_writeb,
- slavio_misc_mem_writeb,
- slavio_misc_mem_writeb,
-};
-
-static void slavio_misc_save(QEMUFile *f, void *opaque)
-{
- MiscState *s = opaque;
-
- qemu_put_be32s(f, &s->irq);
- qemu_put_8s(f, &s->config);
- qemu_put_8s(f, &s->aux1);
- qemu_put_8s(f, &s->aux2);
- qemu_put_8s(f, &s->diag);
- qemu_put_8s(f, &s->mctrl);
- qemu_put_8s(f, &s->sysctrl);
-}
-
-static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
-{
- MiscState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->irq);
- qemu_get_8s(f, &s->config);
- qemu_get_8s(f, &s->aux1);
- qemu_get_8s(f, &s->aux2);
- qemu_get_8s(f, &s->diag);
- qemu_get_8s(f, &s->mctrl);
- qemu_get_8s(f, &s->sysctrl);
- return 0;
-}
-
-void *slavio_misc_init(uint32_t base, int irq)
-{
- int slavio_misc_io_memory;
- MiscState *s;
-
- s = qemu_mallocz(sizeof(MiscState));
- if (!s)
- return NULL;
-
- slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s);
- // Slavio control
- cpu_register_physical_memory(base + 0x1800000, MISC_MAXADDR, slavio_misc_io_memory);
- // AUX 1
- cpu_register_physical_memory(base + 0x1900000, MISC_MAXADDR, slavio_misc_io_memory);
- // AUX 2
- cpu_register_physical_memory(base + 0x1910000, MISC_MAXADDR, slavio_misc_io_memory);
- // Diagnostics
- cpu_register_physical_memory(base + 0x1a00000, MISC_MAXADDR, slavio_misc_io_memory);
- // Modem control
- cpu_register_physical_memory(base + 0x1b00000, MISC_MAXADDR, slavio_misc_io_memory);
- // System control
- cpu_register_physical_memory(base + 0x1f00000, MISC_MAXADDR, slavio_misc_io_memory);
- // Power management
- cpu_register_physical_memory(base + 0xa000000, MISC_MAXADDR, slavio_misc_io_memory);
-
- s->irq = irq;
-
- register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load, s);
- qemu_register_reset(slavio_misc_reset, s);
- slavio_misc_reset(s);
- return s;
-}
diff --git a/tools/ioemu/hw/slavio_serial.c b/tools/ioemu/hw/slavio_serial.c
deleted file mode 100644
index e72bb70e05..0000000000
--- a/tools/ioemu/hw/slavio_serial.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * QEMU Sparc SLAVIO serial port emulation
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-/* debug serial */
-//#define DEBUG_SERIAL
-
-/* debug keyboard */
-//#define DEBUG_KBD
-
-/* debug mouse */
-//#define DEBUG_MOUSE
-
-/*
- * This is the serial port, mouse and keyboard part of chip STP2001
- * (Slave I/O), also produced as NCR89C105. See
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
- *
- * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
- * mouse and keyboard ports don't implement all functions and they are
- * only asynchronous. There is no DMA.
- *
- */
-
-/*
- * Modifications:
- * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
- * serial mouse queue.
- * Implemented serial mouse protocol.
- */
-
-#ifdef DEBUG_SERIAL
-#define SER_DPRINTF(fmt, args...) \
-do { printf("SER: " fmt , ##args); } while (0)
-#define pic_set_irq(irq, level) \
-do { printf("SER: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0)
-#else
-#define SER_DPRINTF(fmt, args...)
-#endif
-#ifdef DEBUG_KBD
-#define KBD_DPRINTF(fmt, args...) \
-do { printf("KBD: " fmt , ##args); } while (0)
-#else
-#define KBD_DPRINTF(fmt, args...)
-#endif
-#ifdef DEBUG_MOUSE
-#define MS_DPRINTF(fmt, args...) \
-do { printf("MSC: " fmt , ##args); } while (0)
-#else
-#define MS_DPRINTF(fmt, args...)
-#endif
-
-typedef enum {
- chn_a, chn_b,
-} chn_id_t;
-
-#define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
-
-typedef enum {
- ser, kbd, mouse,
-} chn_type_t;
-
-#define SERIO_QUEUE_SIZE 256
-
-typedef struct {
- uint8_t data[SERIO_QUEUE_SIZE];
- int rptr, wptr, count;
-} SERIOQueue;
-
-typedef struct ChannelState {
- int irq;
- int reg;
- int rxint, txint, rxint_under_svc, txint_under_svc;
- chn_id_t chn; // this channel, A (base+4) or B (base+0)
- chn_type_t type;
- struct ChannelState *otherchn;
- uint8_t rx, tx, wregs[16], rregs[16];
- SERIOQueue queue;
- CharDriverState *chr;
-} ChannelState;
-
-struct SerialState {
- struct ChannelState chn[2];
-};
-
-#define SERIAL_MAXADDR 7
-
-static void handle_kbd_command(ChannelState *s, int val);
-static int serial_can_receive(void *opaque);
-static void serial_receive_byte(ChannelState *s, int ch);
-static inline void set_txint(ChannelState *s);
-
-static void put_queue(void *opaque, int b)
-{
- ChannelState *s = opaque;
- SERIOQueue *q = &s->queue;
-
- SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
- if (q->count >= SERIO_QUEUE_SIZE)
- return;
- q->data[q->wptr] = b;
- if (++q->wptr == SERIO_QUEUE_SIZE)
- q->wptr = 0;
- q->count++;
- serial_receive_byte(s, 0);
-}
-
-static uint32_t get_queue(void *opaque)
-{
- ChannelState *s = opaque;
- SERIOQueue *q = &s->queue;
- int val;
-
- if (q->count == 0) {
- return 0;
- } else {
- val = q->data[q->rptr];
- if (++q->rptr == SERIO_QUEUE_SIZE)
- q->rptr = 0;
- q->count--;
- }
- KBD_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
- if (q->count > 0)
- serial_receive_byte(s, 0);
- return val;
-}
-
-static int slavio_serial_update_irq_chn(ChannelState *s)
-{
- if ((s->wregs[1] & 1) && // interrupts enabled
- (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
- ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
- s->rxint == 1) || // rx ints enabled, pending
- ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
- return 1;
- }
- return 0;
-}
-
-static void slavio_serial_update_irq(ChannelState *s)
-{
- int irq;
-
- irq = slavio_serial_update_irq_chn(s);
- irq |= slavio_serial_update_irq_chn(s->otherchn);
-
- pic_set_irq(s->irq, irq);
-}
-
-static void slavio_serial_reset_chn(ChannelState *s)
-{
- int i;
-
- s->reg = 0;
- for (i = 0; i < SERIAL_MAXADDR; i++) {
- s->rregs[i] = 0;
- s->wregs[i] = 0;
- }
- s->wregs[4] = 4;
- s->wregs[9] = 0xc0;
- s->wregs[11] = 8;
- s->wregs[14] = 0x30;
- s->wregs[15] = 0xf8;
- s->rregs[0] = 0x44;
- s->rregs[1] = 6;
-
- s->rx = s->tx = 0;
- s->rxint = s->txint = 0;
- s->rxint_under_svc = s->txint_under_svc = 0;
-}
-
-static void slavio_serial_reset(void *opaque)
-{
- SerialState *s = opaque;
- slavio_serial_reset_chn(&s->chn[0]);
- slavio_serial_reset_chn(&s->chn[1]);
-}
-
-static inline void clr_rxint(ChannelState *s)
-{
- s->rxint = 0;
- s->rxint_under_svc = 0;
- if (s->chn == chn_a)
- s->rregs[3] &= ~0x20;
- else
- s->otherchn->rregs[3] &= ~4;
- if (s->txint)
- set_txint(s);
- else
- s->rregs[2] = 6;
- slavio_serial_update_irq(s);
-}
-
-static inline void set_rxint(ChannelState *s)
-{
- s->rxint = 1;
- if (!s->txint_under_svc) {
- s->rxint_under_svc = 1;
- if (s->chn == chn_a)
- s->rregs[3] |= 0x20;
- else
- s->otherchn->rregs[3] |= 4;
- s->rregs[2] = 4;
- slavio_serial_update_irq(s);
- }
-}
-
-static inline void clr_txint(ChannelState *s)
-{
- s->txint = 0;
- s->txint_under_svc = 0;
- if (s->chn == chn_a)
- s->rregs[3] &= ~0x10;
- else
- s->otherchn->rregs[3] &= ~2;
- if (s->rxint)
- set_rxint(s);
- else
- s->rregs[2] = 6;
- slavio_serial_update_irq(s);
-}
-
-static inline void set_txint(ChannelState *s)
-{
- s->txint = 1;
- if (!s->rxint_under_svc) {
- s->txint_under_svc = 1;
- if (s->chn == chn_a)
- s->rregs[3] |= 0x10;
- else
- s->otherchn->rregs[3] |= 2;
- s->rregs[2] = 0;
- slavio_serial_update_irq(s);
- }
-}
-
-static void slavio_serial_update_parameters(ChannelState *s)
-{
- int speed, parity, data_bits, stop_bits;
- QEMUSerialSetParams ssp;
-
- if (!s->chr || s->type != ser)
- return;
-
- if (s->wregs[4] & 1) {
- if (s->wregs[4] & 2)
- parity = 'E';
- else
- parity = 'O';
- } else {
- parity = 'N';
- }
- if ((s->wregs[4] & 0x0c) == 0x0c)
- stop_bits = 2;
- else
- stop_bits = 1;
- switch (s->wregs[5] & 0x60) {
- case 0x00:
- data_bits = 5;
- break;
- case 0x20:
- data_bits = 7;
- break;
- case 0x40:
- data_bits = 6;
- break;
- default:
- case 0x60:
- data_bits = 8;
- break;
- }
- speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
- switch (s->wregs[4] & 0xc0) {
- case 0x00:
- break;
- case 0x40:
- speed /= 16;
- break;
- case 0x80:
- speed /= 32;
- break;
- default:
- case 0xc0:
- speed /= 64;
- break;
- }
- ssp.speed = speed;
- ssp.parity = parity;
- ssp.data_bits = data_bits;
- ssp.stop_bits = stop_bits;
- SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
- speed, parity, data_bits, stop_bits);
- qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
-}
-
-static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- SerialState *ser = opaque;
- ChannelState *s;
- uint32_t saddr;
- int newreg, channel;
-
- val &= 0xff;
- saddr = (addr & 3) >> 1;
- channel = (addr & SERIAL_MAXADDR) >> 2;
- s = &ser->chn[channel];
- switch (saddr) {
- case 0:
- SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
- newreg = 0;
- switch (s->reg) {
- case 0:
- newreg = val & 7;
- val &= 0x38;
- switch (val) {
- case 8:
- newreg |= 0x8;
- break;
- case 0x28:
- clr_txint(s);
- break;
- case 0x38:
- if (s->rxint_under_svc)
- clr_rxint(s);
- else if (s->txint_under_svc)
- clr_txint(s);
- break;
- default:
- break;
- }
- break;
- case 1 ... 3:
- case 6 ... 8:
- case 10 ... 11:
- case 14 ... 15:
- s->wregs[s->reg] = val;
- break;
- case 4:
- case 5:
- case 12:
- case 13:
- s->wregs[s->reg] = val;
- slavio_serial_update_parameters(s);
- break;
- case 9:
- switch (val & 0xc0) {
- case 0:
- default:
- break;
- case 0x40:
- slavio_serial_reset_chn(&ser->chn[1]);
- return;
- case 0x80:
- slavio_serial_reset_chn(&ser->chn[0]);
- return;
- case 0xc0:
- slavio_serial_reset(ser);
- return;
- }
- break;
- default:
- break;
- }
- if (s->reg == 0)
- s->reg = newreg;
- else
- s->reg = 0;
- break;
- case 1:
- SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
- if (s->wregs[5] & 8) { // tx enabled
- s->tx = val;
- if (s->chr)
- qemu_chr_write(s->chr, &s->tx, 1);
- else if (s->type == kbd) {
- handle_kbd_command(s, val);
- }
- s->rregs[0] |= 4; // Tx buffer empty
- s->rregs[1] |= 1; // All sent
- set_txint(s);
- }
- break;
- default:
- break;
- }
-}
-
-static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- SerialState *ser = opaque;
- ChannelState *s;
- uint32_t saddr;
- uint32_t ret;
- int channel;
-
- saddr = (addr & 3) >> 1;
- channel = (addr & SERIAL_MAXADDR) >> 2;
- s = &ser->chn[channel];
- switch (saddr) {
- case 0:
- SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
- ret = s->rregs[s->reg];
- s->reg = 0;
- return ret;
- case 1:
- s->rregs[0] &= ~1;
- clr_rxint(s);
- if (s->type == kbd || s->type == mouse)
- ret = get_queue(s);
- else
- ret = s->rx;
- SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
- return ret;
- default:
- break;
- }
- return 0;
-}
-
-static int serial_can_receive(void *opaque)
-{
- ChannelState *s = opaque;
- int ret;
-
- if (((s->wregs[3] & 1) == 0) // Rx not enabled
- || ((s->rregs[0] & 1) == 1)) // char already available
- ret = 0;
- else
- ret = 1;
- //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
- return ret;
-}
-
-static void serial_receive_byte(ChannelState *s, int ch)
-{
- SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
- s->rregs[0] |= 1;
- s->rx = ch;
- set_rxint(s);
-}
-
-static void serial_receive_break(ChannelState *s)
-{
- s->rregs[0] |= 0x80;
- slavio_serial_update_irq(s);
-}
-
-static void serial_receive1(void *opaque, const uint8_t *buf, int size)
-{
- ChannelState *s = opaque;
- serial_receive_byte(s, buf[0]);
-}
-
-static void serial_event(void *opaque, int event)
-{
- ChannelState *s = opaque;
- if (event == CHR_EVENT_BREAK)
- serial_receive_break(s);
-}
-
-static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
- slavio_serial_mem_readb,
- slavio_serial_mem_readb,
- slavio_serial_mem_readb,
-};
-
-static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
- slavio_serial_mem_writeb,
- slavio_serial_mem_writeb,
- slavio_serial_mem_writeb,
-};
-
-static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
-{
- qemu_put_be32s(f, &s->irq);
- qemu_put_be32s(f, &s->reg);
- qemu_put_be32s(f, &s->rxint);
- qemu_put_be32s(f, &s->txint);
- qemu_put_be32s(f, &s->rxint_under_svc);
- qemu_put_be32s(f, &s->txint_under_svc);
- qemu_put_8s(f, &s->rx);
- qemu_put_8s(f, &s->tx);
- qemu_put_buffer(f, s->wregs, 16);
- qemu_put_buffer(f, s->rregs, 16);
-}
-
-static void slavio_serial_save(QEMUFile *f, void *opaque)
-{
- SerialState *s = opaque;
-
- slavio_serial_save_chn(f, &s->chn[0]);
- slavio_serial_save_chn(f, &s->chn[1]);
-}
-
-static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
-{
- if (version_id > 2)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->irq);
- qemu_get_be32s(f, &s->reg);
- qemu_get_be32s(f, &s->rxint);
- qemu_get_be32s(f, &s->txint);
- if (version_id >= 2) {
- qemu_get_be32s(f, &s->rxint_under_svc);
- qemu_get_be32s(f, &s->txint_under_svc);
- }
- qemu_get_8s(f, &s->rx);
- qemu_get_8s(f, &s->tx);
- qemu_get_buffer(f, s->wregs, 16);
- qemu_get_buffer(f, s->rregs, 16);
- return 0;
-}
-
-static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
-{
- SerialState *s = opaque;
- int ret;
-
- ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
- if (ret != 0)
- return ret;
- ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
- return ret;
-
-}
-
-SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
-{
- int slavio_serial_io_memory, i;
- SerialState *s;
-
- s = qemu_mallocz(sizeof(SerialState));
- if (!s)
- return NULL;
-
- slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
- cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
-
- s->chn[0].chr = chr1;
- s->chn[1].chr = chr2;
-
- for (i = 0; i < 2; i++) {
- s->chn[i].irq = irq;
- s->chn[i].chn = 1 - i;
- s->chn[i].type = ser;
- if (s->chn[i].chr) {
- qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
- serial_receive1, serial_event, &s->chn[i]);
- }
- }
- s->chn[0].otherchn = &s->chn[1];
- s->chn[1].otherchn = &s->chn[0];
- register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
- qemu_register_reset(slavio_serial_reset, s);
- slavio_serial_reset(s);
- return s;
-}
-
-static const uint8_t keycodes[128] = {
- 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
- 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
- 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
- 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
- 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
-};
-
-static void sunkbd_event(void *opaque, int ch)
-{
- ChannelState *s = opaque;
- int release = ch & 0x80;
-
- ch = keycodes[ch & 0x7f];
- KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
- put_queue(s, ch | release);
-}
-
-static void handle_kbd_command(ChannelState *s, int val)
-{
- KBD_DPRINTF("Command %d\n", val);
- switch (val) {
- case 1: // Reset, return type code
- put_queue(s, 0xff);
- put_queue(s, 5); // Type 5
- break;
- case 7: // Query layout
- put_queue(s, 0xfe);
- put_queue(s, 0x20); // XXX, layout?
- break;
- default:
- break;
- }
-}
-
-static void sunmouse_event(void *opaque,
- int dx, int dy, int dz, int buttons_state)
-{
- ChannelState *s = opaque;
- int ch;
-
- /* XXX: SDL sometimes generates nul events: we delete them */
- if (dx == 0 && dy == 0 && dz == 0 && buttons_state == 0)
- return;
- MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
-
- ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
-
- if (buttons_state & MOUSE_EVENT_LBUTTON)
- ch ^= 0x4;
- if (buttons_state & MOUSE_EVENT_MBUTTON)
- ch ^= 0x2;
- if (buttons_state & MOUSE_EVENT_RBUTTON)
- ch ^= 0x1;
-
- put_queue(s, ch);
-
- ch = dx;
-
- if (ch > 127)
- ch=127;
- else if (ch < -127)
- ch=-127;
-
- put_queue(s, ch & 0xff);
-
- ch = -dy;
-
- if (ch > 127)
- ch=127;
- else if (ch < -127)
- ch=-127;
-
- put_queue(s, ch & 0xff);
-
- // MSC protocol specify two extra motion bytes
-
- put_queue(s, 0);
- put_queue(s, 0);
-}
-
-void slavio_serial_ms_kbd_init(int base, int irq)
-{
- int slavio_serial_io_memory, i;
- SerialState *s;
-
- s = qemu_mallocz(sizeof(SerialState));
- if (!s)
- return;
- for (i = 0; i < 2; i++) {
- s->chn[i].irq = irq;
- s->chn[i].chn = 1 - i;
- s->chn[i].chr = NULL;
- }
- s->chn[0].otherchn = &s->chn[1];
- s->chn[1].otherchn = &s->chn[0];
- s->chn[0].type = mouse;
- s->chn[1].type = kbd;
-
- slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
- cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
-
- qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
- qemu_register_reset(slavio_serial_reset, s);
- slavio_serial_reset(s);
-}
diff --git a/tools/ioemu/hw/slavio_timer.c b/tools/ioemu/hw/slavio_timer.c
deleted file mode 100644
index 976f0d4db4..0000000000
--- a/tools/ioemu/hw/slavio_timer.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * QEMU Sparc SLAVIO timer controller emulation
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_TIMER
-
-#ifdef DEBUG_TIMER
-#define DPRINTF(fmt, args...) \
-do { printf("TIMER: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...)
-#endif
-
-/*
- * Registers of hardware timer in sun4m.
- *
- * This is the timer/counter part of chip STP2001 (Slave I/O), also
- * produced as NCR89C105. See
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
- *
- * The 31-bit counter is incremented every 500ns by bit 9. Bits 8..0
- * are zero. Bit 31 is 1 when count has been reached.
- *
- * Per-CPU timers interrupt local CPU, system timer uses normal
- * interrupt routing.
- *
- */
-
-typedef struct SLAVIO_TIMERState {
- uint32_t limit, count, counthigh;
- int64_t count_load_time;
- int64_t expire_time;
- int64_t stop_time, tick_offset;
- QEMUTimer *irq_timer;
- int irq;
- int reached, stopped;
- int mode; // 0 = processor, 1 = user, 2 = system
- unsigned int cpu;
-} SLAVIO_TIMERState;
-
-#define TIMER_MAXADDR 0x1f
-#define CNT_FREQ 2000000
-
-// Update count, set irq, update expire_time
-static void slavio_timer_get_out(SLAVIO_TIMERState *s)
-{
- int out;
- int64_t diff, ticks, count;
- uint32_t limit;
-
- // There are three clock tick units: CPU ticks, register units
- // (nanoseconds), and counter ticks (500 ns).
- if (s->mode == 1 && s->stopped)
- ticks = s->stop_time;
- else
- ticks = qemu_get_clock(vm_clock) - s->tick_offset;
-
- out = (ticks > s->expire_time);
- if (out)
- s->reached = 0x80000000;
- if (!s->limit)
- limit = 0x7fffffff;
- else
- limit = s->limit;
-
- // Convert register units to counter ticks
- limit = limit >> 9;
-
- // Convert cpu ticks to counter ticks
- diff = muldiv64(ticks - s->count_load_time, CNT_FREQ, ticks_per_sec);
-
- // Calculate what the counter should be, convert to register
- // units
- count = diff % limit;
- s->count = count << 9;
- s->counthigh = count >> 22;
-
- // Expire time: CPU ticks left to next interrupt
- // Convert remaining counter ticks to CPU ticks
- s->expire_time = ticks + muldiv64(limit - count, ticks_per_sec, CNT_FREQ);
-
- DPRINTF("irq %d limit %d reached %d d %" PRId64 " count %d s->c %x diff %" PRId64 " stopped %d mode %d\n", s->irq, limit, s->reached?1:0, (ticks-s->count_load_time), count, s->count, s->expire_time - ticks, s->stopped, s->mode);
-
- if (s->mode != 1)
- pic_set_irq_cpu(s->irq, out, s->cpu);
-}
-
-// timer callback
-static void slavio_timer_irq(void *opaque)
-{
- SLAVIO_TIMERState *s = opaque;
-
- if (!s->irq_timer)
- return;
- slavio_timer_get_out(s);
- if (s->mode != 1)
- qemu_mod_timer(s->irq_timer, s->expire_time);
-}
-
-static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- SLAVIO_TIMERState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & TIMER_MAXADDR) >> 2;
- switch (saddr) {
- case 0:
- // read limit (system counter mode) or read most signifying
- // part of counter (user mode)
- if (s->mode != 1) {
- // clear irq
- pic_set_irq_cpu(s->irq, 0, s->cpu);
- s->count_load_time = qemu_get_clock(vm_clock);
- s->reached = 0;
- return s->limit;
- }
- else {
- slavio_timer_get_out(s);
- return s->counthigh & 0x7fffffff;
- }
- case 1:
- // read counter and reached bit (system mode) or read lsbits
- // of counter (user mode)
- slavio_timer_get_out(s);
- if (s->mode != 1)
- return (s->count & 0x7fffffff) | s->reached;
- else
- return s->count;
- case 3:
- // read start/stop status
- return s->stopped;
- case 4:
- // read user/system mode
- return s->mode & 1;
- default:
- return 0;
- }
-}
-
-static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- SLAVIO_TIMERState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & TIMER_MAXADDR) >> 2;
- switch (saddr) {
- case 0:
- // set limit, reset counter
- s->count_load_time = qemu_get_clock(vm_clock);
- // fall through
- case 2:
- // set limit without resetting counter
- if (!val)
- s->limit = 0x7fffffff;
- else
- s->limit = val & 0x7fffffff;
- slavio_timer_irq(s);
- break;
- case 3:
- // start/stop user counter
- if (s->mode == 1) {
- if (val & 1) {
- s->stop_time = qemu_get_clock(vm_clock);
- s->stopped = 1;
- }
- else {
- if (s->stopped)
- s->tick_offset += qemu_get_clock(vm_clock) - s->stop_time;
- s->stopped = 0;
- }
- }
- break;
- case 4:
- // bit 0: user (1) or system (0) counter mode
- if (s->mode == 0 || s->mode == 1)
- s->mode = val & 1;
- break;
- default:
- break;
- }
-}
-
-static CPUReadMemoryFunc *slavio_timer_mem_read[3] = {
- slavio_timer_mem_readl,
- slavio_timer_mem_readl,
- slavio_timer_mem_readl,
-};
-
-static CPUWriteMemoryFunc *slavio_timer_mem_write[3] = {
- slavio_timer_mem_writel,
- slavio_timer_mem_writel,
- slavio_timer_mem_writel,
-};
-
-static void slavio_timer_save(QEMUFile *f, void *opaque)
-{
- SLAVIO_TIMERState *s = opaque;
-
- qemu_put_be32s(f, &s->limit);
- qemu_put_be32s(f, &s->count);
- qemu_put_be32s(f, &s->counthigh);
- qemu_put_be64s(f, &s->count_load_time);
- qemu_put_be64s(f, &s->expire_time);
- qemu_put_be64s(f, &s->stop_time);
- qemu_put_be64s(f, &s->tick_offset);
- qemu_put_be32s(f, &s->irq);
- qemu_put_be32s(f, &s->reached);
- qemu_put_be32s(f, &s->stopped);
- qemu_put_be32s(f, &s->mode);
-}
-
-static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id)
-{
- SLAVIO_TIMERState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->limit);
- qemu_get_be32s(f, &s->count);
- qemu_get_be32s(f, &s->counthigh);
- qemu_get_be64s(f, &s->count_load_time);
- qemu_get_be64s(f, &s->expire_time);
- qemu_get_be64s(f, &s->stop_time);
- qemu_get_be64s(f, &s->tick_offset);
- qemu_get_be32s(f, &s->irq);
- qemu_get_be32s(f, &s->reached);
- qemu_get_be32s(f, &s->stopped);
- qemu_get_be32s(f, &s->mode);
- return 0;
-}
-
-static void slavio_timer_reset(void *opaque)
-{
- SLAVIO_TIMERState *s = opaque;
-
- s->limit = 0;
- s->count = 0;
- s->count_load_time = qemu_get_clock(vm_clock);;
- s->stop_time = s->count_load_time;
- s->tick_offset = 0;
- s->reached = 0;
- s->mode &= 2;
- s->stopped = 1;
- slavio_timer_get_out(s);
-}
-
-void slavio_timer_init(uint32_t addr, int irq, int mode, unsigned int cpu)
-{
- int slavio_timer_io_memory;
- SLAVIO_TIMERState *s;
-
- s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
- if (!s)
- return;
- s->irq = irq;
- s->mode = mode;
- s->cpu = cpu;
- s->irq_timer = qemu_new_timer(vm_clock, slavio_timer_irq, s);
-
- slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
- slavio_timer_mem_write, s);
- cpu_register_physical_memory(addr, TIMER_MAXADDR, slavio_timer_io_memory);
- register_savevm("slavio_timer", addr, 1, slavio_timer_save, slavio_timer_load, s);
- qemu_register_reset(slavio_timer_reset, s);
- slavio_timer_reset(s);
-}
diff --git a/tools/ioemu/hw/smbus.h b/tools/ioemu/hw/smbus.h
deleted file mode 100644
index 76fc3c8395..0000000000
--- a/tools/ioemu/hw/smbus.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * QEMU SMBus API
- *
- * Copyright (c) 2007 Arastra, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-typedef struct SMBusDevice SMBusDevice;
-
-struct SMBusDevice {
- uint8_t addr;
- void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
- void (*send_byte)(SMBusDevice *dev, uint8_t val);
- uint8_t (*receive_byte)(SMBusDevice *dev);
- void (*write_byte)(SMBusDevice *dev, uint8_t cmd, uint8_t val);
- uint8_t (*read_byte)(SMBusDevice *dev, uint8_t cmd);
- void (*write_word)(SMBusDevice *dev, uint8_t cmd, uint16_t val);
- uint16_t (*read_word)(SMBusDevice *dev, uint8_t cmd);
- void (*write_block)(SMBusDevice *dev, uint8_t cmd, uint8_t len, uint8_t *buf);
- uint8_t (*read_block)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf);
-};
diff --git a/tools/ioemu/hw/smbus_eeprom.c b/tools/ioemu/hw/smbus_eeprom.c
deleted file mode 100644
index d401b17565..0000000000
--- a/tools/ioemu/hw/smbus_eeprom.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * QEMU SMBus EEPROM device
- *
- * Copyright (c) 2007 Arastra, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-
-//#define DEBUG
-
-typedef struct SMBusEEPROMDevice {
- SMBusDevice dev;
- uint8_t *data;
- uint8_t offset;
-} SMBusEEPROMDevice;
-
-static void eeprom_quick_cmd(SMBusDevice *dev, uint8_t read)
-{
-#ifdef DEBUG
- printf("eeprom_quick_cmd: addr=0x%02x read=%d\n", dev->addr, read);
-#endif
-}
-
-static void eeprom_send_byte(SMBusDevice *dev, uint8_t val)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
-#ifdef DEBUG
- printf("eeprom_send_byte: addr=0x%02x val=0x%02x\n", dev->addr, val);
-#endif
- eeprom->offset = val;
-}
-
-static uint8_t eeprom_receive_byte(SMBusDevice *dev)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
- uint8_t val = eeprom->data[eeprom->offset++];
-#ifdef DEBUG
- printf("eeprom_receive_byte: addr=0x%02x val=0x%02x\n", dev->addr, val);
-#endif
- return val;
-}
-
-static void eeprom_write_byte(SMBusDevice *dev, uint8_t cmd, uint8_t val)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
-#ifdef DEBUG
- printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", dev->addr,
- cmd, val);
-#endif
- eeprom->data[cmd] = val;
-}
-
-static uint8_t eeprom_read_byte(SMBusDevice *dev, uint8_t cmd)
-{
- SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
- uint8_t val = eeprom->data[cmd];
-#ifdef DEBUG
- printf("eeprom_read_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", dev->addr,
- cmd, val);
-#endif
- return val;
-}
-
-SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf)
-{
- SMBusEEPROMDevice *eeprom = qemu_mallocz(sizeof(SMBusEEPROMDevice));
- eeprom->dev.addr = addr;
- eeprom->dev.quick_cmd = eeprom_quick_cmd;
- eeprom->dev.send_byte = eeprom_send_byte;
- eeprom->dev.receive_byte = eeprom_receive_byte;
- eeprom->dev.write_byte = eeprom_write_byte;
- eeprom->dev.read_byte = eeprom_read_byte;
- eeprom->data = buf;
- eeprom->offset = 0;
- return (SMBusDevice *) eeprom;
-}
diff --git a/tools/ioemu/hw/smc91c111.c b/tools/ioemu/hw/smc91c111.c
deleted file mode 100644
index 0249cfe98b..0000000000
--- a/tools/ioemu/hw/smc91c111.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * SMSC 91C111 Ethernet interface emulation
- *
- * Copyright (c) 2005 CodeSourcery, LLC.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL
- */
-
-#include "vl.h"
-/* For crc32 */
-#include <zlib.h>
-
-/* Number of 2k memory pages available. */
-#define NUM_PACKETS 4
-
-typedef struct {
- uint32_t base;
- VLANClientState *vc;
- uint16_t tcr;
- uint16_t rcr;
- uint16_t cr;
- uint16_t ctr;
- uint16_t gpr;
- uint16_t ptr;
- uint16_t ercv;
- void *pic;
- int irq;
- int bank;
- int packet_num;
- int tx_alloc;
- /* Bitmask of allocated packets. */
- int allocated;
- int tx_fifo_len;
- int tx_fifo[NUM_PACKETS];
- int rx_fifo_len;
- int rx_fifo[NUM_PACKETS];
- int tx_fifo_done_len;
- int tx_fifo_done[NUM_PACKETS];
- /* Packet buffer memory. */
- uint8_t data[NUM_PACKETS][2048];
- uint8_t int_level;
- uint8_t int_mask;
- uint8_t macaddr[6];
-} smc91c111_state;
-
-#define RCR_SOFT_RST 0x8000
-#define RCR_STRIP_CRC 0x0200
-#define RCR_RXEN 0x0100
-
-#define TCR_EPH_LOOP 0x2000
-#define TCR_NOCRC 0x0100
-#define TCR_PAD_EN 0x0080
-#define TCR_FORCOL 0x0004
-#define TCR_LOOP 0x0002
-#define TCR_TXEN 0x0001
-
-#define INT_MD 0x80
-#define INT_ERCV 0x40
-#define INT_EPH 0x20
-#define INT_RX_OVRN 0x10
-#define INT_ALLOC 0x08
-#define INT_TX_EMPTY 0x04
-#define INT_TX 0x02
-#define INT_RCV 0x01
-
-#define CTR_AUTO_RELEASE 0x0800
-#define CTR_RELOAD 0x0002
-#define CTR_STORE 0x0001
-
-#define RS_ALGNERR 0x8000
-#define RS_BRODCAST 0x4000
-#define RS_BADCRC 0x2000
-#define RS_ODDFRAME 0x1000
-#define RS_TOOLONG 0x0800
-#define RS_TOOSHORT 0x0400
-#define RS_MULTICAST 0x0001
-
-/* Update interrupt status. */
-static void smc91c111_update(smc91c111_state *s)
-{
- int level;
-
- if (s->tx_fifo_len == 0)
- s->int_level |= INT_TX_EMPTY;
- if (s->tx_fifo_done_len != 0)
- s->int_level |= INT_TX;
- level = (s->int_level & s->int_mask) != 0;
- pic_set_irq_new(s->pic, s->irq, level);
-}
-
-/* Try to allocate a packet. Returns 0x80 on failure. */
-static int smc91c111_allocate_packet(smc91c111_state *s)
-{
- int i;
- if (s->allocated == (1 << NUM_PACKETS) - 1) {
- return 0x80;
- }
-
- for (i = 0; i < NUM_PACKETS; i++) {
- if ((s->allocated & (1 << i)) == 0)
- break;
- }
- s->allocated |= 1 << i;
- return i;
-}
-
-
-/* Process a pending TX allocate. */
-static void smc91c111_tx_alloc(smc91c111_state *s)
-{
- s->tx_alloc = smc91c111_allocate_packet(s);
- if (s->tx_alloc == 0x80)
- return;
- s->int_level |= INT_ALLOC;
- smc91c111_update(s);
-}
-
-/* Remove and item from the RX FIFO. */
-static void smc91c111_pop_rx_fifo(smc91c111_state *s)
-{
- int i;
-
- s->rx_fifo_len--;
- if (s->rx_fifo_len) {
- for (i = 0; i < s->rx_fifo_len; i++)
- s->rx_fifo[i] = s->rx_fifo[i + 1];
- s->int_level |= INT_RCV;
- } else {
- s->int_level &= ~INT_RCV;
- }
- smc91c111_update(s);
-}
-
-/* Remove an item from the TX completion FIFO. */
-static void smc91c111_pop_tx_fifo_done(smc91c111_state *s)
-{
- int i;
-
- if (s->tx_fifo_done_len == 0)
- return;
- s->tx_fifo_done_len--;
- for (i = 0; i < s->tx_fifo_done_len; i++)
- s->tx_fifo_done[i] = s->tx_fifo_done[i + 1];
-}
-
-/* Release the memory allocated to a packet. */
-static void smc91c111_release_packet(smc91c111_state *s, int packet)
-{
- s->allocated &= ~(1 << packet);
- if (s->tx_alloc == 0x80)
- smc91c111_tx_alloc(s);
-}
-
-/* Flush the TX FIFO. */
-static void smc91c111_do_tx(smc91c111_state *s)
-{
- int i;
- int len;
- int control;
- int add_crc;
- int packetnum;
- uint8_t *p;
-
- if ((s->tcr & TCR_TXEN) == 0)
- return;
- if (s->tx_fifo_len == 0)
- return;
- for (i = 0; i < s->tx_fifo_len; i++) {
- packetnum = s->tx_fifo[i];
- p = &s->data[packetnum][0];
- /* Set status word. */
- *(p++) = 0x01;
- *(p++) = 0x40;
- len = *(p++);
- len |= ((int)*(p++)) << 8;
- len -= 6;
- control = p[len + 1];
- if (control & 0x20)
- len++;
- /* ??? This overwrites the data following the buffer.
- Don't know what real hardware does. */
- if (len < 64 && (s->tcr & TCR_PAD_EN)) {
- memset(p + len, 0, 64 - len);
- len = 64;
- }
-#if 0
- /* The card is supposed to append the CRC to the frame. However
- none of the other network traffic has the CRC appended.
- Suspect this is low level ethernet detail we don't need to worry
- about. */
- add_crc = (control & 0x10) || (s->tcr & TCR_NOCRC) == 0;
- if (add_crc) {
- uint32_t crc;
-
- crc = crc32(~0, p, len);
- memcpy(p + len, &crc, 4);
- len += 4;
- }
-#else
- add_crc = 0;
-#endif
- if (s->ctr & CTR_AUTO_RELEASE)
- /* Race? */
- smc91c111_release_packet(s, packetnum);
- else if (s->tx_fifo_done_len < NUM_PACKETS)
- s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
- qemu_send_packet(s->vc, p, len);
- }
- s->tx_fifo_len = 0;
- smc91c111_update(s);
-}
-
-/* Add a packet to the TX FIFO. */
-static void smc91c111_queue_tx(smc91c111_state *s, int packet)
-{
- if (s->tx_fifo_len == NUM_PACKETS)
- return;
- s->tx_fifo[s->tx_fifo_len++] = packet;
- smc91c111_do_tx(s);
-}
-
-static void smc91c111_reset(smc91c111_state *s)
-{
- s->bank = 0;
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- s->rx_fifo_len = 0;
- s->allocated = 0;
- s->packet_num = 0;
- s->tx_alloc = 0;
- s->tcr = 0;
- s->rcr = 0;
- s->cr = 0xa0b1;
- s->ctr = 0x1210;
- s->ptr = 0;
- s->ercv = 0x1f;
- s->int_level = INT_TX_EMPTY;
- s->int_mask = 0;
- smc91c111_update(s);
-}
-
-#define SET_LOW(name, val) s->name = (s->name & 0xff00) | val
-#define SET_HIGH(name, val) s->name = (s->name & 0xff) | (val << 8)
-
-static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- offset -= s->base;
- if (offset == 14) {
- s->bank = value;
- return;
- }
- if (offset == 15)
- return;
- switch (s->bank) {
- case 0:
- switch (offset) {
- case 0: /* TCR */
- SET_LOW(tcr, value);
- return;
- case 1:
- SET_HIGH(tcr, value);
- return;
- case 4: /* RCR */
- SET_LOW(rcr, value);
- return;
- case 5:
- SET_HIGH(rcr, value);
- if (s->rcr & RCR_SOFT_RST)
- smc91c111_reset(s);
- return;
- case 10: case 11: /* RPCR */
- /* Ignored */
- return;
- }
- break;
-
- case 1:
- switch (offset) {
- case 0: /* CONFIG */
- SET_LOW(cr, value);
- return;
- case 1:
- SET_HIGH(cr,value);
- return;
- case 2: case 3: /* BASE */
- case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
- /* Not implemented. */
- return;
- case 10: /* Genral Purpose */
- SET_LOW(gpr, value);
- return;
- case 11:
- SET_HIGH(gpr, value);
- return;
- case 12: /* Control */
- if (value & 1)
- fprintf(stderr, "smc91c111:EEPROM store not implemented\n");
- if (value & 2)
- fprintf(stderr, "smc91c111:EEPROM reload not implemented\n");
- value &= ~3;
- SET_LOW(ctr, value);
- return;
- case 13:
- SET_HIGH(ctr, value);
- return;
- }
- break;
-
- case 2:
- switch (offset) {
- case 0: /* MMU Command */
- switch (value >> 5) {
- case 0: /* no-op */
- break;
- case 1: /* Allocate for TX. */
- s->tx_alloc = 0x80;
- s->int_level &= ~INT_ALLOC;
- smc91c111_update(s);
- smc91c111_tx_alloc(s);
- break;
- case 2: /* Reset MMU. */
- s->allocated = 0;
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- s->rx_fifo_len = 0;
- s->tx_alloc = 0;
- break;
- case 3: /* Remove from RX FIFO. */
- smc91c111_pop_rx_fifo(s);
- break;
- case 4: /* Remove from RX FIFO and release. */
- if (s->rx_fifo_len > 0) {
- smc91c111_release_packet(s, s->rx_fifo[0]);
- }
- smc91c111_pop_rx_fifo(s);
- break;
- case 5: /* Release. */
- smc91c111_release_packet(s, s->packet_num);
- break;
- case 6: /* Add to TX FIFO. */
- smc91c111_queue_tx(s, s->packet_num);
- break;
- case 7: /* Reset TX FIFO. */
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- break;
- }
- return;
- case 1:
- /* Ignore. */
- return;
- case 2: /* Packet Number Register */
- s->packet_num = value;
- return;
- case 3: case 4: case 5:
- /* Should be readonly, but linux writes to them anyway. Ignore. */
- return;
- case 6: /* Pointer */
- SET_LOW(ptr, value);
- return;
- case 7:
- SET_HIGH(ptr, value);
- return;
- case 8: case 9: case 10: case 11: /* Data */
- {
- int p;
- int n;
-
- if (s->ptr & 0x8000)
- n = s->rx_fifo[0];
- else
- n = s->packet_num;
- p = s->ptr & 0x07ff;
- if (s->ptr & 0x4000) {
- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x7ff);
- } else {
- p += (offset & 3);
- }
- s->data[n][p] = value;
- }
- return;
- case 12: /* Interrupt ACK. */
- s->int_level &= ~(value & 0xd6);
- if (value & INT_TX)
- smc91c111_pop_tx_fifo_done(s);
- smc91c111_update(s);
- return;
- case 13: /* Interrupt mask. */
- s->int_mask = value;
- smc91c111_update(s);
- return;
- }
- break;;
-
- case 3:
- switch (offset) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* Multicast table. */
- /* Not implemented. */
- return;
- case 8: case 9: /* Management Interface. */
- /* Not implemented. */
- return;
- case 12: /* Early receive. */
- s->ercv = value & 0x1f;
- case 13:
- /* Ignore. */
- return;
- }
- break;
- }
- cpu_abort (cpu_single_env, "smc91c111_write: Bad reg %d:%x\n",
- s->bank, offset);
-}
-
-static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- offset -= s->base;
- if (offset == 14) {
- return s->bank;
- }
- if (offset == 15)
- return 0x33;
- switch (s->bank) {
- case 0:
- switch (offset) {
- case 0: /* TCR */
- return s->tcr & 0xff;
- case 1:
- return s->tcr >> 8;
- case 2: /* EPH Status */
- return 0;
- case 3:
- return 0x40;
- case 4: /* RCR */
- return s->rcr & 0xff;
- case 5:
- return s->rcr >> 8;
- case 6: /* Counter */
- case 7:
- /* Not implemented. */
- return 0;
- case 8: /* Free memory available. */
- {
- int i;
- int n;
- n = 0;
- for (i = 0; i < NUM_PACKETS; i++) {
- if (s->allocated & (1 << i))
- n++;
- }
- return n;
- }
- case 9: /* Memory size. */
- return NUM_PACKETS;
- case 10: case 11: /* RPCR */
- /* Not implemented. */
- return 0;
- }
- break;
-
- case 1:
- switch (offset) {
- case 0: /* CONFIG */
- return s->cr & 0xff;
- case 1:
- return s->cr >> 8;
- case 2: case 3: /* BASE */
- /* Not implemented. */
- return 0;
- case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
- return s->macaddr[offset - 4];
- case 10: /* General Purpose */
- return s->gpr & 0xff;
- case 11:
- return s->gpr >> 8;
- case 12: /* Control */
- return s->ctr & 0xff;
- case 13:
- return s->ctr >> 8;
- }
- break;
-
- case 2:
- switch (offset) {
- case 0: case 1: /* MMUCR Busy bit. */
- return 0;
- case 2: /* Packet Number. */
- return s->packet_num;
- case 3: /* Allocation Result. */
- return s->tx_alloc;
- case 4: /* TX FIFO */
- if (s->tx_fifo_done_len == 0)
- return 0x80;
- else
- return s->tx_fifo_done[0];
- case 5: /* RX FIFO */
- if (s->rx_fifo_len == 0)
- return 0x80;
- else
- return s->rx_fifo[0];
- case 6: /* Pointer */
- return s->ptr & 0xff;
- case 7:
- return (s->ptr >> 8) & 0xf7;
- case 8: case 9: case 10: case 11: /* Data */
- {
- int p;
- int n;
-
- if (s->ptr & 0x8000)
- n = s->rx_fifo[0];
- else
- n = s->packet_num;
- p = s->ptr & 0x07ff;
- if (s->ptr & 0x4000) {
- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x07ff);
- } else {
- p += (offset & 3);
- }
- return s->data[n][p];
- }
- case 12: /* Interrupt status. */
- return s->int_level;
- case 13: /* Interrupt mask. */
- return s->int_mask;
- }
- break;
-
- case 3:
- switch (offset) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* Multicast table. */
- /* Not implemented. */
- return 0;
- case 8: /* Management Interface. */
- /* Not implemented. */
- return 0x30;
- case 9:
- return 0x33;
- case 10: /* Revision. */
- return 0x91;
- case 11:
- return 0x33;
- case 12:
- return s->ercv;
- case 13:
- return 0;
- }
- break;
- }
- cpu_abort (cpu_single_env, "smc91c111_read: Bad reg %d:%x\n",
- s->bank, offset);
- return 0;
-}
-
-static void smc91c111_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_writeb(opaque, offset, value & 0xff);
- smc91c111_writeb(opaque, offset + 1, value >> 8);
-}
-
-static void smc91c111_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
- /* 32-bit writes to offset 0xc only actually write to the bank select
- register (offset 0xe) */
- if (offset != s->base + 0xc)
- smc91c111_writew(opaque, offset, value & 0xffff);
- smc91c111_writew(opaque, offset + 2, value >> 16);
-}
-
-static uint32_t smc91c111_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = smc91c111_readb(opaque, offset);
- val |= smc91c111_readb(opaque, offset + 1) << 8;
- return val;
-}
-
-static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = smc91c111_readw(opaque, offset);
- val |= smc91c111_readw(opaque, offset + 2) << 16;
- return val;
-}
-
-static int smc91c111_can_receive(void *opaque)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
- return 1;
- if (s->allocated == (1 << NUM_PACKETS) - 1)
- return 0;
- return 1;
-}
-
-static void smc91c111_receive(void *opaque, const uint8_t *buf, int size)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
- int status;
- int packetsize;
- uint32_t crc;
- int packetnum;
- uint8_t *p;
-
- if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
- return;
- /* Short packets are padded with zeros. Receiving a packet
- < 64 bytes long is considered an error condition. */
- if (size < 64)
- packetsize = 64;
- else
- packetsize = (size & ~1);
- packetsize += 6;
- crc = (s->rcr & RCR_STRIP_CRC) == 0;
- if (crc)
- packetsize += 4;
- /* TODO: Flag overrun and receive errors. */
- if (packetsize > 2048)
- return;
- packetnum = smc91c111_allocate_packet(s);
- if (packetnum == 0x80)
- return;
- s->rx_fifo[s->rx_fifo_len++] = packetnum;
-
- p = &s->data[packetnum][0];
- /* ??? Multicast packets? */
- status = 0;
- if (size > 1518)
- status |= RS_TOOLONG;
- if (size & 1)
- status |= RS_ODDFRAME;
- *(p++) = status & 0xff;
- *(p++) = status >> 8;
- *(p++) = packetsize & 0xff;
- *(p++) = packetsize >> 8;
- memcpy(p, buf, size & ~1);
- p += (size & ~1);
- /* Pad short packets. */
- if (size < 64) {
- int pad;
-
- if (size & 1)
- *(p++) = buf[size - 1];
- pad = 64 - size;
- memset(p, 0, pad);
- p += pad;
- size = 64;
- }
- /* It's not clear if the CRC should go before or after the last byte in
- odd sized packets. Linux disables the CRC, so that's no help.
- The pictures in the documentation show the CRC aligned on a 16-bit
- boundary before the last odd byte, so that's what we do. */
- if (crc) {
- crc = crc32(~0, buf, size);
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- }
- if (size & 1) {
- *(p++) = buf[size - 1];
- *(p++) = 0x60;
- } else {
- *(p++) = 0;
- *(p++) = 0x40;
- }
- /* TODO: Raise early RX interrupt? */
- s->int_level |= INT_RCV;
- smc91c111_update(s);
-}
-
-static CPUReadMemoryFunc *smc91c111_readfn[] = {
- smc91c111_readb,
- smc91c111_readw,
- smc91c111_readl
-};
-
-static CPUWriteMemoryFunc *smc91c111_writefn[] = {
- smc91c111_writeb,
- smc91c111_writew,
- smc91c111_writel
-};
-
-void smc91c111_init(NICInfo *nd, uint32_t base, void *pic, int irq)
-{
- smc91c111_state *s;
- int iomemtype;
-
- s = (smc91c111_state *)qemu_mallocz(sizeof(smc91c111_state));
- iomemtype = cpu_register_io_memory(0, smc91c111_readfn,
- smc91c111_writefn, s);
- cpu_register_physical_memory(base, 16, iomemtype);
- s->base = base;
- s->pic = pic;
- s->irq = irq;
- memcpy(s->macaddr, nd->macaddr, 6);
-
- smc91c111_reset(s);
-
- s->vc = qemu_new_vlan_client(nd->vlan, smc91c111_receive,
- smc91c111_can_receive, s);
- /* ??? Save/restore. */
-}
diff --git a/tools/ioemu/hw/sparc32_dma.c b/tools/ioemu/hw/sparc32_dma.c
deleted file mode 100644
index b17a12b9e7..0000000000
--- a/tools/ioemu/hw/sparc32_dma.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * QEMU Sparc32 DMA controller emulation
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug DMA */
-//#define DEBUG_DMA
-
-/*
- * This is the DMA controller part of chip STP2000 (Master I/O), also
- * produced as NCR89C100. See
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
- * and
- * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/DMA2.txt
- */
-
-#ifdef DEBUG_DMA
-#define DPRINTF(fmt, args...) \
-do { printf("DMA: " fmt , ##args); } while (0)
-#define pic_set_irq_new(ctl, irq, level) \
- do { printf("DMA: set_irq(%d): %d\n", (irq), (level)); \
- pic_set_irq_new((ctl), (irq),(level));} while (0)
-#else
-#define DPRINTF(fmt, args...)
-#endif
-
-#define DMA_REGS 8
-#define DMA_MAXADDR (DMA_REGS * 4 - 1)
-
-#define DMA_VER 0xa0000000
-#define DMA_INTR 1
-#define DMA_INTREN 0x10
-#define DMA_WRITE_MEM 0x100
-#define DMA_LOADED 0x04000000
-#define DMA_RESET 0x80
-
-typedef struct DMAState DMAState;
-
-struct DMAState {
- uint32_t dmaregs[DMA_REGS];
- int espirq, leirq;
- void *iommu, *esp_opaque, *lance_opaque, *intctl;
-};
-
-void ledma_set_irq(void *opaque, int isr)
-{
- DMAState *s = opaque;
-
- pic_set_irq_new(s->intctl, s->leirq, isr);
-}
-
-/* Note: on sparc, the lance 16 bit bus is swapped */
-void ledma_memory_read(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap)
-{
- DMAState *s = opaque;
- int i;
-
- DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n",
- s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
- addr |= s->dmaregs[7];
- if (do_bswap) {
- sparc_iommu_memory_read(s->iommu, addr, buf, len);
- } else {
- addr &= ~1;
- len &= ~1;
- sparc_iommu_memory_read(s->iommu, addr, buf, len);
- for(i = 0; i < len; i += 2) {
- bswap16s((uint16_t *)(buf + i));
- }
- }
-}
-
-void ledma_memory_write(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap)
-{
- DMAState *s = opaque;
- int l, i;
- uint16_t tmp_buf[32];
-
- DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n",
- s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
- addr |= s->dmaregs[7];
- if (do_bswap) {
- sparc_iommu_memory_write(s->iommu, addr, buf, len);
- } else {
- addr &= ~1;
- len &= ~1;
- while (len > 0) {
- l = len;
- if (l > sizeof(tmp_buf))
- l = sizeof(tmp_buf);
- for(i = 0; i < l; i += 2) {
- tmp_buf[i >> 1] = bswap16(*(uint16_t *)(buf + i));
- }
- sparc_iommu_memory_write(s->iommu, addr, (uint8_t *)tmp_buf, l);
- len -= l;
- buf += l;
- addr += l;
- }
- }
-}
-
-void espdma_raise_irq(void *opaque)
-{
- DMAState *s = opaque;
-
- s->dmaregs[0] |= DMA_INTR;
- pic_set_irq_new(s->intctl, s->espirq, 1);
-}
-
-void espdma_clear_irq(void *opaque)
-{
- DMAState *s = opaque;
-
- s->dmaregs[0] &= ~DMA_INTR;
- pic_set_irq_new(s->intctl, s->espirq, 0);
-}
-
-void espdma_memory_read(void *opaque, uint8_t *buf, int len)
-{
- DMAState *s = opaque;
-
- DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n",
- s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
- sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
- s->dmaregs[0] |= DMA_INTR;
- s->dmaregs[1] += len;
-}
-
-void espdma_memory_write(void *opaque, uint8_t *buf, int len)
-{
- DMAState *s = opaque;
-
- DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n",
- s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
- sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
- s->dmaregs[0] |= DMA_INTR;
- s->dmaregs[1] += len;
-}
-
-static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- DMAState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & DMA_MAXADDR) >> 2;
- DPRINTF("read dmareg[%d]: 0x%8.8x\n", saddr, s->dmaregs[saddr]);
-
- return s->dmaregs[saddr];
-}
-
-static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- DMAState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & DMA_MAXADDR) >> 2;
- DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->dmaregs[saddr], val);
- switch (saddr) {
- case 0:
- if (!(val & DMA_INTREN))
- pic_set_irq_new(s->intctl, s->espirq, 0);
- if (val & DMA_RESET) {
- esp_reset(s->esp_opaque);
- } else if (val & 0x40) {
- val &= ~0x40;
- } else if (val == 0)
- val = 0x40;
- val &= 0x0fffffff;
- val |= DMA_VER;
- break;
- case 1:
- s->dmaregs[0] |= DMA_LOADED;
- break;
- case 4:
- if (!(val & DMA_INTREN))
- pic_set_irq_new(s->intctl, s->leirq, 0);
- if (val & DMA_RESET)
- pcnet_h_reset(s->lance_opaque);
- val &= 0x0fffffff;
- val |= DMA_VER;
- break;
- default:
- break;
- }
- s->dmaregs[saddr] = val;
-}
-
-static CPUReadMemoryFunc *dma_mem_read[3] = {
- dma_mem_readl,
- dma_mem_readl,
- dma_mem_readl,
-};
-
-static CPUWriteMemoryFunc *dma_mem_write[3] = {
- dma_mem_writel,
- dma_mem_writel,
- dma_mem_writel,
-};
-
-static void dma_reset(void *opaque)
-{
- DMAState *s = opaque;
-
- memset(s->dmaregs, 0, DMA_REGS * 4);
- s->dmaregs[0] = DMA_VER;
- s->dmaregs[4] = DMA_VER;
-}
-
-static void dma_save(QEMUFile *f, void *opaque)
-{
- DMAState *s = opaque;
- unsigned int i;
-
- for (i = 0; i < DMA_REGS; i++)
- qemu_put_be32s(f, &s->dmaregs[i]);
-}
-
-static int dma_load(QEMUFile *f, void *opaque, int version_id)
-{
- DMAState *s = opaque;
- unsigned int i;
-
- if (version_id != 1)
- return -EINVAL;
- for (i = 0; i < DMA_REGS; i++)
- qemu_get_be32s(f, &s->dmaregs[i]);
-
- return 0;
-}
-
-void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu, void *intctl)
-{
- DMAState *s;
- int dma_io_memory;
-
- s = qemu_mallocz(sizeof(DMAState));
- if (!s)
- return NULL;
-
- s->espirq = espirq;
- s->leirq = leirq;
- s->iommu = iommu;
- s->intctl = intctl;
-
- dma_io_memory = cpu_register_io_memory(0, dma_mem_read, dma_mem_write, s);
- cpu_register_physical_memory(daddr, 16 * 2, dma_io_memory);
-
- register_savevm("sparc32_dma", daddr, 1, dma_save, dma_load, s);
- qemu_register_reset(dma_reset, s);
-
- return s;
-}
-
-void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque,
- void *lance_opaque)
-{
- DMAState *s = opaque;
-
- s->esp_opaque = esp_opaque;
- s->lance_opaque = lance_opaque;
-}
diff --git a/tools/ioemu/hw/sun4m.c b/tools/ioemu/hw/sun4m.c
deleted file mode 100644
index 9b6aae53c8..0000000000
--- a/tools/ioemu/hw/sun4m.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * QEMU Sun4m System Emulator
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define KERNEL_LOAD_ADDR 0x00004000
-#define CMDLINE_ADDR 0x007ff000
-#define INITRD_LOAD_ADDR 0x00800000
-#define PROM_SIZE_MAX (256 * 1024)
-#define PROM_ADDR 0xffd00000
-#define PROM_FILENAME "openbios-sparc32"
-#define PHYS_JJ_EEPROM 0x71200000 /* m48t08 */
-#define PHYS_JJ_IDPROM_OFF 0x1FD8
-#define PHYS_JJ_EEPROM_SIZE 0x2000
-// IRQs are not PIL ones, but master interrupt controller register
-// bits
-#define PHYS_JJ_IOMMU 0x10000000 /* I/O MMU */
-#define PHYS_JJ_TCX_FB 0x50000000 /* TCX frame buffer */
-#define PHYS_JJ_SLAVIO 0x70000000 /* Slavio base */
-#define PHYS_JJ_DMA 0x78400000 /* DMA controller */
-#define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */
-#define PHYS_JJ_ESP_IRQ 18
-#define PHYS_JJ_LE 0x78C00000 /* Lance ethernet */
-#define PHYS_JJ_LE_IRQ 16
-#define PHYS_JJ_CLOCK 0x71D00000 /* Per-CPU timer/counter, L14 */
-#define PHYS_JJ_CLOCK_IRQ 7
-#define PHYS_JJ_CLOCK1 0x71D10000 /* System timer/counter, L10 */
-#define PHYS_JJ_CLOCK1_IRQ 19
-#define PHYS_JJ_INTR0 0x71E00000 /* Per-CPU interrupt control registers */
-#define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */
-#define PHYS_JJ_MS_KBD 0x71000000 /* Mouse and keyboard */
-#define PHYS_JJ_MS_KBD_IRQ 14
-#define PHYS_JJ_SER 0x71100000 /* Serial */
-#define PHYS_JJ_SER_IRQ 15
-#define PHYS_JJ_FDC 0x71400000 /* Floppy */
-#define PHYS_JJ_FLOPPY_IRQ 22
-#define PHYS_JJ_ME_IRQ 30 /* Module error, power fail */
-#define PHYS_JJ_CS 0x6c000000 /* Crystal CS4231 */
-#define PHYS_JJ_CS_IRQ 5
-
-#define MAX_CPUS 16
-
-/* TSC handling */
-
-uint64_t cpu_get_tsc()
-{
- return qemu_get_clock(vm_clock);
-}
-
-int DMA_get_channel_mode (int nchan)
-{
- return 0;
-}
-int DMA_read_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-int DMA_write_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-void DMA_hold_DREQ (int nchan) {}
-void DMA_release_DREQ (int nchan) {}
-void DMA_schedule(int nchan) {}
-void DMA_run (void) {}
-void DMA_init (int high_page_enable) {}
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
-{
-}
-
-static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
-{
- m48t59_write(nvram, addr++, (value >> 8) & 0xff);
- m48t59_write(nvram, addr++, value & 0xff);
-}
-
-static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
-{
- m48t59_write(nvram, addr++, value >> 24);
- m48t59_write(nvram, addr++, (value >> 16) & 0xff);
- m48t59_write(nvram, addr++, (value >> 8) & 0xff);
- m48t59_write(nvram, addr++, value & 0xff);
-}
-
-static void nvram_set_string (m48t59_t *nvram, uint32_t addr,
- const unsigned char *str, uint32_t max)
-{
- unsigned int i;
-
- for (i = 0; i < max && str[i] != '\0'; i++) {
- m48t59_write(nvram, addr + i, str[i]);
- }
- m48t59_write(nvram, addr + max - 1, '\0');
-}
-
-static m48t59_t *nvram;
-
-extern int nographic;
-
-static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
- int boot_device, uint32_t RAM_size,
- uint32_t kernel_size,
- int width, int height, int depth)
-{
- unsigned char tmp = 0;
- int i, j;
-
- // Try to match PPC NVRAM
- nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
- nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */
- // NVRAM_size, arch not applicable
- m48t59_write(nvram, 0x2D, smp_cpus & 0xff);
- m48t59_write(nvram, 0x2E, 0);
- m48t59_write(nvram, 0x2F, nographic & 0xff);
- nvram_set_lword(nvram, 0x30, RAM_size);
- m48t59_write(nvram, 0x34, boot_device & 0xff);
- nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR);
- nvram_set_lword(nvram, 0x3C, kernel_size);
- if (cmdline) {
- strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
- nvram_set_lword(nvram, 0x40, CMDLINE_ADDR);
- nvram_set_lword(nvram, 0x44, strlen(cmdline));
- }
- // initrd_image, initrd_size passed differently
- nvram_set_word(nvram, 0x54, width);
- nvram_set_word(nvram, 0x56, height);
- nvram_set_word(nvram, 0x58, depth);
-
- // Sun4m specific use
- i = 0x1fd8;
- m48t59_write(nvram, i++, 0x01);
- m48t59_write(nvram, i++, 0x80); /* Sun4m OBP */
- j = 0;
- m48t59_write(nvram, i++, macaddr[j++]);
- m48t59_write(nvram, i++, macaddr[j++]);
- m48t59_write(nvram, i++, macaddr[j++]);
- m48t59_write(nvram, i++, macaddr[j++]);
- m48t59_write(nvram, i++, macaddr[j++]);
- m48t59_write(nvram, i, macaddr[j]);
-
- /* Calculate checksum */
- for (i = 0x1fd8; i < 0x1fe7; i++) {
- tmp ^= m48t59_read(nvram, i);
- }
- m48t59_write(nvram, 0x1fe7, tmp);
-}
-
-static void *slavio_intctl;
-
-void pic_info()
-{
- slavio_pic_info(slavio_intctl);
-}
-
-void irq_info()
-{
- slavio_irq_info(slavio_intctl);
-}
-
-void pic_set_irq(int irq, int level)
-{
- slavio_pic_set_irq(slavio_intctl, irq, level);
-}
-
-void pic_set_irq_new(void *opaque, int irq, int level)
-{
- pic_set_irq(irq, level);
-}
-
-void pic_set_irq_cpu(int irq, int level, unsigned int cpu)
-{
- slavio_pic_set_irq_cpu(slavio_intctl, irq, level, cpu);
-}
-
-static void *slavio_misc;
-
-void qemu_system_powerdown(void)
-{
- slavio_set_power_fail(slavio_misc, 1);
-}
-
-static void main_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
- cpu_reset(env);
-}
-
-/* Sun4m hardware initialisation */
-static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- CPUState *env, *envs[MAX_CPUS];
- char buf[1024];
- int ret, linux_boot;
- unsigned int i;
- long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
- void *iommu, *dma, *main_esp, *main_lance = NULL;
-
- linux_boot = (kernel_filename != NULL);
-
- /* init CPUs */
- for(i = 0; i < smp_cpus; i++) {
- env = cpu_init();
- envs[i] = env;
- if (i != 0)
- env->halted = 1;
- register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
- qemu_register_reset(main_cpu_reset, env);
- }
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, 0);
-
- iommu = iommu_init(PHYS_JJ_IOMMU);
- slavio_intctl = slavio_intctl_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G);
- for(i = 0; i < smp_cpus; i++) {
- slavio_intctl_set_cpu(slavio_intctl, i, envs[i]);
- }
- dma = sparc32_dma_init(PHYS_JJ_DMA, PHYS_JJ_ESP_IRQ, PHYS_JJ_LE_IRQ, iommu, slavio_intctl);
-
- tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height);
- if (nd_table[0].vlan) {
- if (nd_table[0].model == NULL
- || strcmp(nd_table[0].model, "lance") == 0) {
- main_lance = lance_init(&nd_table[0], PHYS_JJ_LE, dma);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
- exit (1);
- }
- }
- nvram = m48t59_init(0, PHYS_JJ_EEPROM, 0, PHYS_JJ_EEPROM_SIZE, 8);
- for (i = 0; i < MAX_CPUS; i++) {
- slavio_timer_init(PHYS_JJ_CLOCK + i * TARGET_PAGE_SIZE, PHYS_JJ_CLOCK_IRQ, 0, i);
- }
- slavio_timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ, 2, (unsigned int)-1);
- slavio_serial_ms_kbd_init(PHYS_JJ_MS_KBD, PHYS_JJ_MS_KBD_IRQ);
- // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
- // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
- slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);
- fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table);
- main_esp = esp_init(bs_table, PHYS_JJ_ESP, dma);
-
- for (i = 0; i < MAX_DISKS; i++) {
- if (bs_table[i]) {
- esp_scsi_attach(main_esp, bs_table[i], i);
- }
- }
-
- slavio_misc = slavio_misc_init(PHYS_JJ_SLAVIO, PHYS_JJ_ME_IRQ);
- cs_init(PHYS_JJ_CS, PHYS_JJ_CS_IRQ, slavio_intctl);
- sparc32_dma_set_reset_data(dma, main_esp, main_lance);
-
- prom_offset = ram_size + vram_size;
- cpu_register_physical_memory(PROM_ADDR,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
- prom_offset | IO_MEM_ROM);
-
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
- ret = load_elf(buf, 0, NULL);
- if (ret < 0) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
- buf);
- exit(1);
- }
-
- kernel_size = 0;
- if (linux_boot) {
- kernel_size = load_elf(kernel_filename, -0xf0000000, NULL);
- if (kernel_size < 0)
- kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
- if (kernel_size < 0)
- kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
-
- /* load initrd */
- initrd_size = 0;
- if (initrd_filename) {
- initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- }
- if (initrd_size > 0) {
- for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
- == 0x48647253) { // HdrS
- stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
- stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
- break;
- }
- }
- }
- }
- nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth);
-}
-
-QEMUMachine sun4m_machine = {
- "sun4m",
- "Sun4m platform",
- sun4m_init,
-};
diff --git a/tools/ioemu/hw/sun4u.c b/tools/ioemu/hw/sun4u.c
deleted file mode 100644
index 61069a6529..0000000000
--- a/tools/ioemu/hw/sun4u.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * QEMU Sun4u System Emulator
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "m48t59.h"
-
-#define KERNEL_LOAD_ADDR 0x00404000
-#define CMDLINE_ADDR 0x003ff000
-#define INITRD_LOAD_ADDR 0x00300000
-#define PROM_SIZE_MAX (512 * 1024)
-#define PROM_ADDR 0x1fff0000000ULL
-#define APB_SPECIAL_BASE 0x1fe00000000ULL
-#define APB_MEM_BASE 0x1ff00000000ULL
-#define VGA_BASE (APB_MEM_BASE + 0x400000ULL)
-#define PROM_FILENAME "openbios-sparc64"
-#define NVRAM_SIZE 0x2000
-
-/* TSC handling */
-
-uint64_t cpu_get_tsc()
-{
- return qemu_get_clock(vm_clock);
-}
-
-int DMA_get_channel_mode (int nchan)
-{
- return 0;
-}
-int DMA_read_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-int DMA_write_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-void DMA_hold_DREQ (int nchan) {}
-void DMA_release_DREQ (int nchan) {}
-void DMA_schedule(int nchan) {}
-void DMA_run (void) {}
-void DMA_init (int high_page_enable) {}
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
-{
-}
-
-/* NVRAM helpers */
-void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
-{
- m48t59_write(nvram, addr, value);
-}
-
-uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
-{
- return m48t59_read(nvram, addr);
-}
-
-void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
-{
- m48t59_write(nvram, addr, value >> 8);
- m48t59_write(nvram, addr + 1, value & 0xFF);
-}
-
-uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
-{
- uint16_t tmp;
-
- tmp = m48t59_read(nvram, addr) << 8;
- tmp |= m48t59_read(nvram, addr + 1);
-
- return tmp;
-}
-
-void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
-{
- m48t59_write(nvram, addr, value >> 24);
- m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);
- m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);
- m48t59_write(nvram, addr + 3, value & 0xFF);
-}
-
-uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
-{
- uint32_t tmp;
-
- tmp = m48t59_read(nvram, addr) << 24;
- tmp |= m48t59_read(nvram, addr + 1) << 16;
- tmp |= m48t59_read(nvram, addr + 2) << 8;
- tmp |= m48t59_read(nvram, addr + 3);
-
- return tmp;
-}
-
-void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
- const unsigned char *str, uint32_t max)
-{
- int i;
-
- for (i = 0; i < max && str[i] != '\0'; i++) {
- m48t59_write(nvram, addr + i, str[i]);
- }
- m48t59_write(nvram, addr + max - 1, '\0');
-}
-
-int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
-{
- int i;
-
- memset(dst, 0, max);
- for (i = 0; i < max; i++) {
- dst[i] = NVRAM_get_byte(nvram, addr + i);
- if (dst[i] == '\0')
- break;
- }
-
- return i;
-}
-
-static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
-{
- uint16_t tmp;
- uint16_t pd, pd1, pd2;
-
- tmp = prev >> 8;
- pd = prev ^ value;
- pd1 = pd & 0x000F;
- pd2 = ((pd >> 4) & 0x000F) ^ pd1;
- tmp ^= (pd1 << 3) | (pd1 << 8);
- tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
-
- return tmp;
-}
-
-uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
-{
- uint32_t i;
- uint16_t crc = 0xFFFF;
- int odd;
-
- odd = count & 1;
- count &= ~1;
- for (i = 0; i != count; i++) {
- crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
- }
- if (odd) {
- crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
- }
-
- return crc;
-}
-
-extern int nographic;
-
-int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
- const unsigned char *arch,
- uint32_t RAM_size, int boot_device,
- uint32_t kernel_image, uint32_t kernel_size,
- const char *cmdline,
- uint32_t initrd_image, uint32_t initrd_size,
- uint32_t NVRAM_image,
- int width, int height, int depth)
-{
- uint16_t crc;
-
- /* Set parameters for Open Hack'Ware BIOS */
- NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
- NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */
- NVRAM_set_word(nvram, 0x14, NVRAM_size);
- NVRAM_set_string(nvram, 0x20, arch, 16);
- NVRAM_set_byte(nvram, 0x2f, nographic & 0xff);
- NVRAM_set_lword(nvram, 0x30, RAM_size);
- NVRAM_set_byte(nvram, 0x34, boot_device);
- NVRAM_set_lword(nvram, 0x38, kernel_image);
- NVRAM_set_lword(nvram, 0x3C, kernel_size);
- if (cmdline) {
- /* XXX: put the cmdline in NVRAM too ? */
- strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
- NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR);
- NVRAM_set_lword(nvram, 0x44, strlen(cmdline));
- } else {
- NVRAM_set_lword(nvram, 0x40, 0);
- NVRAM_set_lword(nvram, 0x44, 0);
- }
- NVRAM_set_lword(nvram, 0x48, initrd_image);
- NVRAM_set_lword(nvram, 0x4C, initrd_size);
- NVRAM_set_lword(nvram, 0x50, NVRAM_image);
-
- NVRAM_set_word(nvram, 0x54, width);
- NVRAM_set_word(nvram, 0x56, height);
- NVRAM_set_word(nvram, 0x58, depth);
- crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
- NVRAM_set_word(nvram, 0xFC, crc);
-
- return 0;
-}
-
-void pic_info()
-{
-}
-
-void irq_info()
-{
-}
-
-void pic_set_irq(int irq, int level)
-{
-}
-
-void pic_set_irq_new(void *opaque, int irq, int level)
-{
-}
-
-void qemu_system_powerdown(void)
-{
-}
-
-static void main_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
- cpu_reset(env);
-}
-
-static const int ide_iobase[2] = { 0x1f0, 0x170 };
-static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 14, 15 };
-
-static const int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static const int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
-static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
-static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
-
-static fdctrl_t *floppy_controller;
-
-/* Sun4u hardware initialisation */
-static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- CPUState *env;
- char buf[1024];
- m48t59_t *nvram;
- int ret, linux_boot;
- unsigned int i;
- long prom_offset, initrd_size, kernel_size;
- PCIBus *pci_bus;
-
- linux_boot = (kernel_filename != NULL);
-
- env = cpu_init();
- register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
- qemu_register_reset(main_cpu_reset, env);
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, 0);
-
- prom_offset = ram_size + vga_ram_size;
- cpu_register_physical_memory(PROM_ADDR,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
- prom_offset | IO_MEM_ROM);
-
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
- ret = load_elf(buf, 0, NULL);
- if (ret < 0) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
- buf);
- exit(1);
- }
-
- kernel_size = 0;
- initrd_size = 0;
- if (linux_boot) {
- /* XXX: put correct offset */
- kernel_size = load_elf(kernel_filename, 0, NULL);
- if (kernel_size < 0)
- kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
- if (kernel_size < 0)
- kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
-
- /* load initrd */
- if (initrd_filename) {
- initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- }
- if (initrd_size > 0) {
- for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
- == 0x48647253) { // HdrS
- stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
- stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
- break;
- }
- }
- }
- }
- pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL);
- isa_mem_base = VGA_BASE;
- pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size, vga_ram_size);
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_hds[i]) {
- serial_init(&pic_set_irq_new, NULL,
- serial_io[i], serial_irq[i], serial_hds[i]);
- }
- }
-
- for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
- if (parallel_hds[i]) {
- parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]);
- }
- }
-
- for(i = 0; i < nb_nics; i++) {
- if (!nd_table[i].model)
- nd_table[i].model = "ne2k_pci";
- pci_nic_init(pci_bus, &nd_table[i], -1);
- }
-
- pci_cmd646_ide_init(pci_bus, bs_table, 1);
- kbd_init();
- floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
- nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE, 59);
- sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device,
- KERNEL_LOAD_ADDR, kernel_size,
- kernel_cmdline,
- INITRD_LOAD_ADDR, initrd_size,
- /* XXX: need an option to load a NVRAM image */
- 0,
- graphic_width, graphic_height, graphic_depth);
-
-}
-
-QEMUMachine sun4u_machine = {
- "sun4u",
- "Sun4u platform",
- sun4u_init,
-};
diff --git a/tools/ioemu/hw/tc58128.c b/tools/ioemu/hw/tc58128.c
deleted file mode 100644
index a8b26f7e8c..0000000000
--- a/tools/ioemu/hw/tc58128.c
+++ /dev/null
@@ -1,181 +0,0 @@
-#include <assert.h>
-#include "vl.h"
-
-#define CE1 0x0100
-#define CE2 0x0200
-#define RE 0x0400
-#define WE 0x0800
-#define ALE 0x1000
-#define CLE 0x2000
-#define RDY1 0x4000
-#define RDY2 0x8000
-#define RDY(n) ((n) == 0 ? RDY1 : RDY2)
-
-typedef enum { WAIT, READ1, READ2, READ3 } state_t;
-
-typedef struct {
- uint8_t *flash_contents;
- state_t state;
- uint32_t address;
- uint8_t address_cycle;
-} tc58128_dev;
-
-static tc58128_dev tc58128_devs[2];
-
-#define FLASH_SIZE (16*1024*1024)
-
-void init_dev(tc58128_dev * dev, char *filename)
-{
- int ret, blocks;
-
- dev->state = WAIT;
- dev->flash_contents = qemu_mallocz(FLASH_SIZE);
- memset(dev->flash_contents, 0xff, FLASH_SIZE);
- if (!dev->flash_contents) {
- fprintf(stderr, "could not alloc memory for flash\n");
- exit(1);
- }
- if (filename) {
- /* Load flash image skipping the first block */
- ret = load_image(filename, dev->flash_contents + 528 * 32);
- if (ret < 0) {
- fprintf(stderr, "ret=%d\n", ret);
- fprintf(stderr, "qemu: could not load flash image %s\n",
- filename);
- exit(1);
- } else {
- /* Build first block with number of blocks */
- blocks = (ret + 528 * 32 - 1) / (528 * 32);
- dev->flash_contents[0] = blocks & 0xff;
- dev->flash_contents[1] = (blocks >> 8) & 0xff;
- dev->flash_contents[2] = (blocks >> 16) & 0xff;
- dev->flash_contents[3] = (blocks >> 24) & 0xff;
- fprintf(stderr, "loaded %d bytes for %s into flash\n", ret,
- filename);
- }
- }
-}
-
-void handle_command(tc58128_dev * dev, uint8_t command)
-{
- switch (command) {
- case 0xff:
- fprintf(stderr, "reset flash device\n");
- dev->state = WAIT;
- break;
- case 0x00:
- fprintf(stderr, "read mode 1\n");
- dev->state = READ1;
- dev->address_cycle = 0;
- break;
- case 0x01:
- fprintf(stderr, "read mode 2\n");
- dev->state = READ2;
- dev->address_cycle = 0;
- break;
- case 0x50:
- fprintf(stderr, "read mode 3\n");
- dev->state = READ3;
- dev->address_cycle = 0;
- break;
- default:
- fprintf(stderr, "unknown flash command 0x%02x\n", command);
- assert(0);
- }
-}
-
-void handle_address(tc58128_dev * dev, uint8_t data)
-{
- switch (dev->state) {
- case READ1:
- case READ2:
- case READ3:
- switch (dev->address_cycle) {
- case 0:
- dev->address = data;
- if (dev->state == READ2)
- dev->address |= 0x100;
- else if (dev->state == READ3)
- dev->address |= 0x200;
- break;
- case 1:
- dev->address += data * 528 * 0x100;
- break;
- case 2:
- dev->address += data * 528;
- fprintf(stderr, "address pointer in flash: 0x%08x\n",
- dev->address);
- break;
- default:
- /* Invalid data */
- assert(0);
- }
- dev->address_cycle++;
- break;
- default:
- assert(0);
- }
-}
-
-uint8_t handle_read(tc58128_dev * dev)
-{
-#if 0
- if (dev->address % 0x100000 == 0)
- fprintf(stderr, "reading flash at address 0x%08x\n", dev->address);
-#endif
- return dev->flash_contents[dev->address++];
-}
-
-/* We never mark the device as busy, so interrupts cannot be triggered
- XXXXX */
-
-int tc58128_cb(uint16_t porta, uint16_t portb,
- uint16_t * periph_pdtra, uint16_t * periph_portadir,
- uint16_t * periph_pdtrb, uint16_t * periph_portbdir)
-{
- int dev;
-
- if ((porta & CE1) == 0)
- dev = 0;
- else if ((porta & CE2) == 0)
- dev = 1;
- else
- return 0; /* No device selected */
-
- if ((porta & RE) && (porta & WE)) {
- /* Nothing to do, assert ready and return to input state */
- *periph_portadir &= 0xff00;
- *periph_portadir |= RDY(dev);
- *periph_pdtra |= RDY(dev);
- return 1;
- }
-
- if (porta & CLE) {
- /* Command */
- assert((porta & WE) == 0);
- handle_command(&tc58128_devs[dev], porta & 0x00ff);
- } else if (porta & ALE) {
- assert((porta & WE) == 0);
- handle_address(&tc58128_devs[dev], porta & 0x00ff);
- } else if ((porta & RE) == 0) {
- *periph_portadir |= 0x00ff;
- *periph_pdtra &= 0xff00;
- *periph_pdtra |= handle_read(&tc58128_devs[dev]);
- } else {
- assert(0);
- }
- return 1;
-}
-
-static sh7750_io_device tc58128 = {
- RE | WE, /* Port A triggers */
- 0, /* Port B triggers */
- tc58128_cb /* Callback */
-};
-
-int tc58128_init(struct SH7750State *s, char *zone1, char *zone2)
-{
- init_dev(&tc58128_devs[0], zone1);
- init_dev(&tc58128_devs[1], zone2);
- return sh7750_register_io_device(s, &tc58128);
-}
diff --git a/tools/ioemu/hw/tcx.c b/tools/ioemu/hw/tcx.c
deleted file mode 100644
index a1a6b68559..0000000000
--- a/tools/ioemu/hw/tcx.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * QEMU TCX Frame buffer
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define MAXX 1024
-#define MAXY 768
-#define TCX_DAC_NREGS 16
-
-typedef struct TCXState {
- uint32_t addr;
- DisplayState *ds;
- uint8_t *vram;
- ram_addr_t vram_offset;
- uint16_t width, height;
- uint8_t r[256], g[256], b[256];
- uint32_t palette[256];
- uint8_t dac_index, dac_state;
-} TCXState;
-
-static void tcx_screen_dump(void *opaque, const char *filename);
-
-/* XXX: unify with vga draw line functions */
-static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-}
-
-static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
-{
- return (r << 16) | (g << 8) | b;
-}
-
-static void update_palette_entries(TCXState *s, int start, int end)
-{
- int i;
- for(i = start; i < end; i++) {
- switch(s->ds->depth) {
- default:
- case 8:
- s->palette[i] = rgb_to_pixel8(s->r[i], s->g[i], s->b[i]);
- break;
- case 15:
- s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]);
- break;
- case 16:
- s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]);
- break;
- case 32:
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
- break;
- }
- }
-}
-
-static void tcx_draw_line32(TCXState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int x;
- uint8_t val;
- uint32_t *p = (uint32_t *)d;
-
- for(x = 0; x < width; x++) {
- val = *s++;
- *p++ = s1->palette[val];
- }
-}
-
-static void tcx_draw_line16(TCXState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int x;
- uint8_t val;
- uint16_t *p = (uint16_t *)d;
-
- for(x = 0; x < width; x++) {
- val = *s++;
- *p++ = s1->palette[val];
- }
-}
-
-static void tcx_draw_line8(TCXState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int x;
- uint8_t val;
-
- for(x = 0; x < width; x++) {
- val = *s++;
- *d++ = s1->palette[val];
- }
-}
-
-/* Fixed line length 1024 allows us to do nice tricks not possible on
- VGA... */
-static void tcx_update_display(void *opaque)
-{
- TCXState *ts = opaque;
- ram_addr_t page, page_min, page_max;
- int y, y_start, dd, ds;
- uint8_t *d, *s;
- void (*f)(TCXState *s1, uint8_t *d, const uint8_t *s, int width);
-
- if (ts->ds->depth == 0)
- return;
- page = ts->vram_offset;
- y_start = -1;
- page_min = 0xffffffff;
- page_max = 0;
- d = ts->ds->data;
- s = ts->vram;
- dd = ts->ds->linesize;
- ds = 1024;
-
- switch (ts->ds->depth) {
- case 32:
- f = tcx_draw_line32;
- break;
- case 15:
- case 16:
- f = tcx_draw_line16;
- break;
- default:
- case 8:
- f = tcx_draw_line8;
- break;
- case 0:
- return;
- }
-
- for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) {
- if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
- if (y_start < 0)
- y_start = y;
- if (page < page_min)
- page_min = page;
- if (page > page_max)
- page_max = page;
- f(ts, d, s, ts->width);
- d += dd;
- s += ds;
- f(ts, d, s, ts->width);
- d += dd;
- s += ds;
- f(ts, d, s, ts->width);
- d += dd;
- s += ds;
- f(ts, d, s, ts->width);
- d += dd;
- s += ds;
- } else {
- if (y_start >= 0) {
- /* flush to display */
- dpy_update(ts->ds, 0, y_start,
- ts->width, y - y_start);
- y_start = -1;
- }
- d += dd * 4;
- s += ds * 4;
- }
- }
- if (y_start >= 0) {
- /* flush to display */
- dpy_update(ts->ds, 0, y_start,
- ts->width, y - y_start);
- }
- /* reset modified pages */
- if (page_min <= page_max) {
- cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
- VGA_DIRTY_FLAG);
- }
-}
-
-static void tcx_invalidate_display(void *opaque)
-{
- TCXState *s = opaque;
- int i;
-
- for (i = 0; i < MAXX*MAXY; i += TARGET_PAGE_SIZE) {
- cpu_physical_memory_set_dirty(s->vram_offset + i);
- }
-}
-
-static void tcx_save(QEMUFile *f, void *opaque)
-{
- TCXState *s = opaque;
-
- qemu_put_be32s(f, (uint32_t *)&s->addr);
- qemu_put_be32s(f, (uint32_t *)&s->vram);
- qemu_put_be16s(f, (uint16_t *)&s->height);
- qemu_put_be16s(f, (uint16_t *)&s->width);
- qemu_put_buffer(f, s->r, 256);
- qemu_put_buffer(f, s->g, 256);
- qemu_put_buffer(f, s->b, 256);
- qemu_put_8s(f, &s->dac_index);
- qemu_put_8s(f, &s->dac_state);
-}
-
-static int tcx_load(QEMUFile *f, void *opaque, int version_id)
-{
- TCXState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, (uint32_t *)&s->addr);
- qemu_get_be32s(f, (uint32_t *)&s->vram);
- qemu_get_be16s(f, (uint16_t *)&s->height);
- qemu_get_be16s(f, (uint16_t *)&s->width);
- qemu_get_buffer(f, s->r, 256);
- qemu_get_buffer(f, s->g, 256);
- qemu_get_buffer(f, s->b, 256);
- qemu_get_8s(f, &s->dac_index);
- qemu_get_8s(f, &s->dac_state);
- update_palette_entries(s, 0, 256);
- return 0;
-}
-
-static void tcx_reset(void *opaque)
-{
- TCXState *s = opaque;
-
- /* Initialize palette */
- memset(s->r, 0, 256);
- memset(s->g, 0, 256);
- memset(s->b, 0, 256);
- s->r[255] = s->g[255] = s->b[255] = 255;
- update_palette_entries(s, 0, 256);
- memset(s->vram, 0, MAXX*MAXY);
- cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,
- VGA_DIRTY_FLAG);
- s->dac_index = 0;
- s->dac_state = 0;
-}
-
-static uint32_t tcx_dac_readl(void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static void tcx_dac_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- TCXState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr & (TCX_DAC_NREGS - 1)) >> 2;
- switch (saddr) {
- case 0:
- s->dac_index = val >> 24;
- s->dac_state = 0;
- break;
- case 1:
- switch (s->dac_state) {
- case 0:
- s->r[s->dac_index] = val >> 24;
- update_palette_entries(s, s->dac_index, s->dac_index + 1);
- s->dac_state++;
- break;
- case 1:
- s->g[s->dac_index] = val >> 24;
- update_palette_entries(s, s->dac_index, s->dac_index + 1);
- s->dac_state++;
- break;
- case 2:
- s->b[s->dac_index] = val >> 24;
- update_palette_entries(s, s->dac_index, s->dac_index + 1);
- default:
- s->dac_state = 0;
- break;
- }
- break;
- default:
- break;
- }
- return;
-}
-
-static CPUReadMemoryFunc *tcx_dac_read[3] = {
- tcx_dac_readl,
- tcx_dac_readl,
- tcx_dac_readl,
-};
-
-static CPUWriteMemoryFunc *tcx_dac_write[3] = {
- tcx_dac_writel,
- tcx_dac_writel,
- tcx_dac_writel,
-};
-
-void tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
- unsigned long vram_offset, int vram_size, int width, int height)
-{
- TCXState *s;
- int io_memory;
-
- s = qemu_mallocz(sizeof(TCXState));
- if (!s)
- return;
- s->ds = ds;
- s->addr = addr;
- s->vram = vram_base;
- s->vram_offset = vram_offset;
- s->width = width;
- s->height = height;
-
- cpu_register_physical_memory(addr + 0x800000, vram_size, vram_offset);
- io_memory = cpu_register_io_memory(0, tcx_dac_read, tcx_dac_write, s);
- cpu_register_physical_memory(addr + 0x200000, TCX_DAC_NREGS, io_memory);
-
- graphic_console_init(s->ds, tcx_update_display, tcx_invalidate_display,
- tcx_screen_dump, s);
- register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
- qemu_register_reset(tcx_reset, s);
- tcx_reset(s);
- dpy_resize(s->ds, width, height);
-}
-
-static void tcx_screen_dump(void *opaque, const char *filename)
-{
- TCXState *s = opaque;
- FILE *f;
- uint8_t *d, *d1, v;
- int y, x;
-
- f = fopen(filename, "wb");
- if (!f)
- return;
- fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
- d1 = s->vram;
- for(y = 0; y < s->height; y++) {
- d = d1;
- for(x = 0; x < s->width; x++) {
- v = *d;
- fputc(s->r[v], f);
- fputc(s->g[v], f);
- fputc(s->b[v], f);
- d++;
- }
- d1 += MAXX;
- }
- fclose(f);
- return;
-}
-
-
-
diff --git a/tools/ioemu/hw/tpm_tis.c b/tools/ioemu/hw/tpm_tis.c
deleted file mode 100644
index a4742e6a4a..0000000000
--- a/tools/ioemu/hw/tpm_tis.c
+++ /dev/null
@@ -1,1149 +0,0 @@
-/*
- * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
- *
- * Copyright (C) 2006 IBM Corporation
- *
- * Author: Stefan Berger <stefanb@us.ibm.com>
- * David Safford <safford@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- *
- *
- * Implementation of the TIS interface according to specs at
- * https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
- *
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "vl.h"
-
-//#define DEBUG_TPM
-
-#define TPM_MAX_PKT 4096
-
-#define VTPM_BAD_INSTANCE (uint32_t)0xffffffff
-
-#define TIS_ADDR_BASE 0xFED40000
-
-/* tis registers */
-#define TPM_REG_ACCESS 0x00
-#define TPM_REG_INT_ENABLE 0x08
-#define TPM_REG_INT_VECTOR 0x0c
-#define TPM_REG_INT_STATUS 0x10
-#define TPM_REG_INTF_CAPABILITY 0x14
-#define TPM_REG_STS 0x18
-#define TPM_REG_DATA_FIFO 0x24
-#define TPM_REG_DID_VID 0xf00
-#define TPM_REG_RID 0xf04
-
-#define STS_VALID (1 << 7)
-#define STS_COMMAND_READY (1 << 6)
-#define STS_TPM_GO (1 << 5)
-#define STS_DATA_AVAILABLE (1 << 4)
-#define STS_EXPECT (1 << 3)
-#define STS_RESPONSE_RETRY (1 << 1)
-
-#define ACCESS_TPM_REG_VALID_STS (1 << 7)
-#define ACCESS_ACTIVE_LOCALITY (1 << 5)
-#define ACCESS_BEEN_SEIZED (1 << 4)
-#define ACCESS_SEIZE (1 << 3)
-#define ACCESS_PENDING_REQUEST (1 << 2)
-#define ACCESS_REQUEST_USE (1 << 1)
-#define ACCESS_TPM_ESTABLISHMENT (1 << 0)
-
-#define INT_ENABLED (1 << 31)
-#define INT_DATA_AVAILABLE (1 << 0)
-#define INT_LOCALITY_CHANGED (1 << 2)
-#define INT_COMMAND_READY (1 << 7)
-
-#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \
- INT_DATA_AVAILABLE | \
- INT_COMMAND_READY)
-#define CAPABILITIES_SUPPORTED ((1 << 4) | \
- INTERRUPTS_SUPPORTED)
-
-enum {
- STATE_IDLE = 0,
- STATE_READY,
- STATE_COMPLETION,
- STATE_EXECUTION,
- STATE_RECEPTION
-};
-
-#define NUM_LOCALITIES 5
-#define NO_LOCALITY 0xff
-
-#define IS_VALID_LOC(x) ((x) < NUM_LOCALITIES)
-
-#define TPM_DID 0x0001
-#define TPM_VID 0x0001
-#define TPM_RID 0x0001
-
-/* if the connection to the vTPM should be closed after a successfully
- received response; set to '0' to allow keeping the connection */
-#define FORCE_CLOSE 0
-
-/* local data structures */
-
-typedef struct TPMTx {
- int fd[2];
-} tpmTx;
-
-typedef struct TPMBuffer {
- uint8_t instance[4]; /* instance number in network byte order */
- uint8_t buf[TPM_MAX_PKT];
-} __attribute__((packed)) tpmBuffer;
-
-/* locality data */
-typedef struct TPMLocal {
- uint32_t state;
- uint8_t access;
- uint8_t sts;
- uint32_t inte;
- uint32_t ints;
-} tpmLoc;
-
-/* overall state of the TPM interface; 's' marks as save upon suspension */
-typedef struct TPMState {
- uint32_t offset; /* s */
- tpmBuffer buffer; /* s */
- uint8_t active_loc; /* s */
- uint8_t aborting_locty;
- uint8_t next_locty;
- uint8_t irq_pending; /* s */
- tpmLoc loc[NUM_LOCALITIES]; /* s */
- QEMUTimer *poll_timer;
- SetIRQFunc *set_irq;
- void *irq_opaque;
- int irq;
- int poll_attempts;
- uint32_t vtpm_instance; /* vtpm inst. number; determined from xenstore*/
- int Transmitlayer;
- tpmTx tpmTx;
-} tpmState;
-
-
-/* local prototypes */
-static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg);
-static int TPM_Receive(tpmState *s, tpmBuffer *buffer);
-static uint32_t vtpm_instance_from_xenstore(void);
-static void tis_poll_timer(void *opaque);
-static void tis_prep_next_interrupt(tpmState *s);
-static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask);
-static void close_vtpm_channel(tpmState *s, int force);
-static void open_vtpm_channel(tpmState *s);
-static void tis_attempt_receive(tpmState *s, uint8_t locty);
-
-/* transport layer functions: local sockets */
-static int create_local_socket(tpmState *s, uint32_t vtpm_instance);
-static int write_local_socket(tpmState *s, const tpmBuffer *);
-static int read_local_socket(tpmState *s, tpmBuffer *);
-static int close_local_socket(tpmState *s, int force);
-static int has_channel_local_socket(tpmState *s);
-#define LOCAL_SOCKET_PATH "/var/vtpm/socks/%d.socket"
-
-
-#define NUM_TRANSPORTS 1
-
-struct vTPM_transmit {
- int (*open_fn) (tpmState *s, uint32_t vtpm_instance);
- int (*write_fn) (tpmState *s, const tpmBuffer *);
- int (*read_fn) (tpmState *s, tpmBuffer *);
- int (*close_fn) (tpmState *s, int);
- int (*has_channel) (tpmState *s);
-} vTPMTransmit[NUM_TRANSPORTS] = {
- { .open_fn = create_local_socket,
- .write_fn = write_local_socket,
- .read_fn = read_local_socket,
- .close_fn = close_local_socket,
- .has_channel = has_channel_local_socket,
- }
-};
-
-
-#define IS_COMM_WITH_VTPM(s) \
- ((s)->Transmitlayer >= 0 && \
- vTPMTransmit[(s)->Transmitlayer].has_channel(s))
-
-
-/**********************************************************************
- helper functions
- *********************************************************************/
-
-static inline uint32_t tpm_get_size_from_buffer(const uint8_t *buffer)
-{
- uint32_t len = (buffer[4] << 8) + buffer[5];
- return len;
-}
-
-static inline void tpm_initialize_instance(tpmState *s, uint32_t instance)
-{
- s->buffer.instance[0] = (instance >> 24) & 0xff;
- s->buffer.instance[1] = (instance >> 16) & 0xff;
- s->buffer.instance[2] = (instance >> 8) & 0xff;
- s->buffer.instance[3] = (instance >> 0) & 0xff;
-}
-
-/*
- * open communication channel with a vTPM
- */
-static void open_vtpm_channel(tpmState *s)
-{
- int idx;
- /* search a usable transmit layer */
- for (idx = 0; idx < NUM_TRANSPORTS; idx++) {
- if (1 == vTPMTransmit[idx].open_fn(s, s->vtpm_instance)) {
- /* found one */
- s->Transmitlayer = idx;
- break;
- }
- }
-}
-
-/*
- * close the communication channel with the vTPM
- */
-static inline void close_vtpm_channel(tpmState *s, int force)
-{
- if (1 == vTPMTransmit[s->Transmitlayer].close_fn(s, force)) {
- s->Transmitlayer = -1;
- }
-}
-
-static inline uint8_t locality_from_addr(target_phys_addr_t addr)
-{
- return (uint8_t)((addr >> 12) & 0x7);
-}
-
-
-/**********************************************************************
- low-level transmission layer methods
- *********************************************************************/
-
-/*
- * the 'open' method that creates the filedescriptor for communicating
- * only one is needed for reading and writing
- */
-static int create_local_socket(tpmState *s, uint32_t vtpm_instance)
-{
- int success = 1;
- if (s->tpmTx.fd[0] < 0) {
- s->tpmTx.fd[0] = socket(PF_LOCAL, SOCK_STREAM, 0);
-
-#ifdef DEBUG_TPM
- fprintf(logfile," SOCKET FD %d errno %d \n", s->tpmTx.fd[0], errno );
-#endif
- if (has_channel_local_socket(s)) {
- int ret;
- struct sockaddr_un addr;
- memset(&addr, 0x0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- snprintf(addr.sun_path, sizeof(addr.sun_path)-1,
- LOCAL_SOCKET_PATH, (uint32_t) vtpm_instance);
-#ifdef DEBUG_TPM
- fprintf(logfile," SOCKET NAME %s \n", addr.sun_path );
-#endif
-
- if ((ret = connect(s->tpmTx.fd[0], (struct sockaddr *)&addr,
- sizeof(addr))) != 0) {
- close_local_socket(s, 1);
-#ifdef DEBUG_TPM
- fprintf(logfile," RET %d errno %d\n", ret, errno );
-#endif
- success = 0;
- } else {
- /* put filedescriptor in non-blocking mode for polling */
-#ifdef DEBUG_TPM
- fprintf(logfile," put filedescriptor in non-blocking mode "
- "for polling \n");
-#endif
- int flags = fcntl(s->tpmTx.fd[0], F_GETFL);
- fcntl(s->tpmTx.fd[0], F_SETFL, flags | O_NONBLOCK);
- }
-#ifdef DEBUG_TPM
- if (success)
- fprintf(logfile," Successfully connected using local socket"
- "%s.\n",addr.sun_path);
- else
- fprintf(logfile," Could not connect to local socket "
- "%s.\n",addr.sun_path);
-#endif
- } else {
- success = 0;
- }
- }
- return success;
-}
-
-/*
- * the 'write' method for sending requests to the vTPM
- * four bytes with the vTPM instance number are prepended to each request
- * the locality in which the command was sent is transmitted in the
- * highest 3 bits
- */
-static int write_local_socket(tpmState *s, const tpmBuffer *buffer)
-{
- uint32_t size = tpm_get_size_from_buffer(buffer->buf);
- int len;
-
- len = write(s->tpmTx.fd[0],
- buffer->instance,
- sizeof(buffer->instance) + size);
- if (len == sizeof(buffer->instance) + size) {
- return len;
- } else {
- return -1;
- }
-}
-
-/*
- * the 'read' method for receiving of responses from the TPM
- * this function expects that four bytes with the instance number
- * are received from the vTPM
- */
-static int read_local_socket(tpmState *s, tpmBuffer *buffer)
-{
- int off;
-#ifdef DEBUG_TPM
- fprintf(logfile, "Reading from fd %d\n", s->tpmTx.fd[0]);
-#endif
- off = read(s->tpmTx.fd[0],
- buffer->instance,
- sizeof(buffer->instance)+TPM_MAX_PKT);
-#ifdef DEBUG_TPM
- fprintf(logfile, "Read %d bytes\n", off);
-#endif
- return off;
-}
-
-/*
- * the 'close' method
- * shut down communication with the vTPM
- * 'force' = 1 indicates that the socket *must* be closed
- * 'force' = 0 indicates that a connection may be maintained
- */
-static int close_local_socket(tpmState *s, int force)
-{
- if (force) {
- close(s->tpmTx.fd[0]);
-#ifdef DEBUG_TPM
- fprintf(logfile,"Closed connection with fd %d\n",s->tpmTx.fd[0]);
-#endif
- s->tpmTx.fd[0] = -1;
- return 1; /* socket was closed */
- }
-#ifdef DEBUG_TPM
- fprintf(logfile,"Keeping connection with fd %d\n",s->tpmTx.fd[0]);
-#endif
- return 0;
-}
-
-/*
- * the 'has_channel' method that checks whether there's a communication
- * channel with the vTPM
- */
-static int has_channel_local_socket(tpmState *s)
-{
- return (s->tpmTx.fd[0] > 0);
-}
-
-/**********************************************************************/
-
-/*
- * read a byte of response data
- */
-static uint32_t tpm_data_read(tpmState *s, uint8_t locty)
-{
- uint32_t ret, len;
-
- /* try to receive data, if none are there it is ok */
- tis_attempt_receive(s, locty);
-
- if (s->loc[locty].state != STATE_COMPLETION) {
- return 0xff;
- }
-
- len = tpm_get_size_from_buffer(s->buffer.buf);
- ret = s->buffer.buf[s->offset++];
- if (s->offset >= len) {
- s->loc[locty].sts = STS_VALID ;
- s->offset = 0;
- }
-#ifdef DEBUG_TPM
- fprintf(logfile,"tpm_data_read byte x%02x [%d]\n",ret,s->offset-1);
-#endif
- return ret;
-}
-
-
-
-/* raise an interrupt if allowed */
-static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask)
-{
- if (!s->irq_pending &&
- (s->loc[locty].inte & INT_ENABLED) &&
- (s->loc[locty].inte & irqmask)) {
- if ((irqmask & s->loc[locty].ints) == 0) {
-#ifdef DEBUG_TPM
- fprintf(logfile,"Raising IRQ for flag %08x\n",irqmask);
-#endif
- s->set_irq(s->irq_opaque, s->irq, 1);
- s->irq_pending = 1;
- s->loc[locty].ints |= irqmask;
- }
- }
-}
-
-/* abort execution of command */
-static void tis_abort(tpmState *s)
-{
- s->offset = 0;
- s->active_loc = s->next_locty;
-
- /*
- * Need to react differently depending on who's aborting now and
- * which locality will become active afterwards.
- */
- if (s->aborting_locty == s->next_locty) {
- s->loc[s->aborting_locty].state = STATE_READY;
- s->loc[s->aborting_locty].sts = STS_COMMAND_READY;
- tis_raise_irq(s, s->aborting_locty, INT_COMMAND_READY);
- }
-
- /* locality after abort is another one than the current one */
- if (s->aborting_locty != s->next_locty && s->next_locty != NO_LOCALITY) {
- s->loc[s->aborting_locty].access &= ~ACCESS_ACTIVE_LOCALITY;
- s->loc[s->next_locty].access |= ACCESS_ACTIVE_LOCALITY;
- tis_raise_irq(s, s->next_locty, INT_LOCALITY_CHANGED);
- }
-
- s->aborting_locty = NO_LOCALITY; /* nobody's aborting a command anymore */
-
- qemu_del_timer(s->poll_timer);
-}
-
-/* abort current command */
-static void tis_prep_abort(tpmState *s, uint8_t locty, uint8_t newlocty)
-{
- s->aborting_locty = locty; /* current locality */
- s->next_locty = newlocty; /* locality after successful abort */
-
- /*
- * only abort a command using an interrupt if currently executing
- * a command AND if there's a valid connection to the vTPM.
- */
- if (s->loc[locty].state == STATE_EXECUTION &&
- IS_COMM_WITH_VTPM(s)) {
- /* start timer and inside the timer wait for the result */
- s->poll_attempts = 0;
- tis_prep_next_interrupt(s);
- } else {
- tis_abort(s);
- }
-}
-
-
-/*
- * Try to receive a response from the vTPM
- */
-static void tis_attempt_receive(tpmState *s, uint8_t locty)
-{
- /*
- * Attempt to read from the vTPM here if
- * - not aborting a command
- * - command has been sent and state is 'EXECUTION' now
- * - no data are already available (data have already been read)
- * - there's a communication path to the vTPM established
- */
- if (!IS_VALID_LOC(s->aborting_locty)) {
- if (s->loc[locty].state == STATE_EXECUTION) {
- if (0 == (s->loc[locty].sts & STS_DATA_AVAILABLE)){
- if (IS_COMM_WITH_VTPM(s)) {
- int n = TPM_Receive(s, &s->buffer);
- if (n > 0) {
- s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
- s->loc[locty].state = STATE_COMPLETION;
- close_vtpm_channel(s, FORCE_CLOSE);
- tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
- }
- }
- }
- }
- }
-}
-
-/*
- * Read a register of the TIS interface
- * See specs pages 33-63 for description of the registers
- */
-static uint32_t tis_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- tpmState *s = (tpmState *)opaque;
- uint16_t offset = addr & 0xffc;
- uint8_t shift = (addr & 0x3) * 8;
- uint32_t val = 0;
- uint8_t locty = locality_from_addr(addr);
-
- if (offset == TPM_REG_ACCESS) {
- if (s->active_loc == locty) {
- s->loc[locty].access |= (1 << 5);
- } else {
- s->loc[locty].access &= ~(1 << 5);
- }
- val = s->loc[locty].access;
- } else
- if (offset == TPM_REG_INT_ENABLE) {
- val = s->loc[locty].inte;
- } else
- if (offset == TPM_REG_INT_VECTOR) {
- val = s->irq;
- } else
- if (offset == TPM_REG_INT_STATUS) {
- tis_attempt_receive(s, locty);
- val = s->loc[locty].ints;
- } else
- if (offset == TPM_REG_INTF_CAPABILITY) {
- val = CAPABILITIES_SUPPORTED;
- } else
- if (offset == TPM_REG_STS) { /* status register */
- tis_attempt_receive(s, locty);
- val = (sizeof(s->buffer.buf) - s->offset) << 8 | s->loc[locty].sts;
- } else
- if (offset == TPM_REG_DATA_FIFO) {
- val = tpm_data_read(s, locty);
- } else
- if (offset == TPM_REG_DID_VID) {
- val = (TPM_DID << 16) | TPM_VID;
- } else
- if (offset == TPM_REG_RID) {
- val = TPM_RID;
- }
-
- if (shift)
- val >>= shift;
-
-#ifdef DEBUG_TPM
- fprintf(logfile," read(%08x) = %08x\n",
- (int)addr,
- val);
-#endif
-
- return val;
-}
-
-/*
- * Write a value to a register of the TIS interface
- * See specs pages 33-63 for description of the registers
- */
-static void tis_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- tpmState* s=(tpmState*)opaque;
- uint16_t off = addr & 0xfff;
- uint8_t locty = locality_from_addr(addr);
- int n, c;
- uint32_t len;
-
-#ifdef DEBUG_TPM
- fprintf(logfile,"write(%08x) = %08x\n",
- (int)addr,
- val);
-#endif
-
- if (off == TPM_REG_ACCESS) {
- if (val & ACCESS_ACTIVE_LOCALITY) {
- /* give up locality if currently owned */
- if (s->active_loc == locty) {
- uint8_t newlocty = NO_LOCALITY;
- s->loc[locty].access &= ~(ACCESS_PENDING_REQUEST);
- /* anybody wants the locality ? */
- for (c = NUM_LOCALITIES - 1; c >= 0; c--) {
- if (s->loc[c].access & ACCESS_REQUEST_USE) {
- s->loc[c].access |= ACCESS_TPM_REG_VALID_STS;
- s->loc[c].access &= ~ACCESS_REQUEST_USE;
- newlocty = c;
- break;
- }
- }
- tis_prep_abort(s, locty, newlocty);
- }
- }
- if (val & ACCESS_BEEN_SEIZED) {
- /* clear the flag */
- s->loc[locty].access &= ~ACCESS_BEEN_SEIZED;
- }
- if (val & ACCESS_SEIZE) {
- if (locty > s->active_loc && IS_VALID_LOC(s->active_loc)) {
- s->loc[s->active_loc].access |= ACCESS_BEEN_SEIZED;
- s->loc[locty].access = ACCESS_TPM_REG_VALID_STS;
- tis_prep_abort(s, s->active_loc, locty);
- }
- }
- if (val & ACCESS_REQUEST_USE) {
- if (IS_VALID_LOC(s->active_loc)) {
- /* locality election */
- s->loc[s->active_loc].access |= ACCESS_PENDING_REQUEST;
- } else {
- /* no locality active -> make this one active now */
- s->loc[locty].access |= ACCESS_ACTIVE_LOCALITY;
- s->active_loc = locty;
- tis_raise_irq(s, locty, INT_LOCALITY_CHANGED);
- }
- }
- } else
- if (off == TPM_REG_INT_ENABLE) {
- s->loc[locty].inte = (val & (INT_ENABLED | (0x3 << 3) |
- INTERRUPTS_SUPPORTED));
- } else
- if (off == TPM_REG_INT_STATUS) {
- /* clearing of interrupt flags */
- if ((val & INTERRUPTS_SUPPORTED) &&
- (s->loc[locty].ints & INTERRUPTS_SUPPORTED)) {
- s->set_irq(s->irq_opaque, s->irq, 0);
- s->irq_pending = 0;
- }
- s->loc[locty].ints &= ~(val & INTERRUPTS_SUPPORTED);
- } else
- if (off == TPM_REG_STS) {
- if (val & STS_COMMAND_READY) {
- if (s->loc[locty].state == STATE_IDLE) {
- s->loc[locty].sts = STS_COMMAND_READY;
- s->loc[locty].state = STATE_READY;
- tis_raise_irq(s, locty, INT_COMMAND_READY);
- } else if (s->loc[locty].state == STATE_COMPLETION ||
- s->loc[locty].state == STATE_EXECUTION ||
- s->loc[locty].state == STATE_RECEPTION) {
- /* abort currently running command */
- tis_prep_abort(s, locty, locty);
- }
- }
- if (val & STS_TPM_GO) {
- n = TPM_Send(s, &s->buffer, locty, "tpm_data_write");
- if (n > 0) {
- /* sending of data was successful */
- s->offset = 0;
- s->loc[locty].state = STATE_EXECUTION;
- if (s->loc[locty].inte & (INT_ENABLED | INT_DATA_AVAILABLE)) {
- s->poll_attempts = 0;
- tis_prep_next_interrupt(s);
- }
- }
- }
- if (val & STS_RESPONSE_RETRY) {
- s->offset = 0;
- }
- } else if (off == TPM_REG_DATA_FIFO) {
- /* data fifo */
- if (s->loc[locty].state == STATE_IDLE ||
- s->loc[locty].state == STATE_EXECUTION ||
- s->loc[locty].state == STATE_COMPLETION) {
- /* drop the byte */
- } else {
-#ifdef TPM_DEBUG
- fprintf(logfile,"Byte to send to TPM: %02x\n", val);
-#endif
- s->loc[locty].state = STATE_RECEPTION;
-
- if (s->offset < sizeof(s->buffer.buf))
- s->buffer.buf[s->offset++] = (uint8_t)val;
-
- if (s->offset > 5) {
- /* we have a packet length - see if we have all of it */
- len = tpm_get_size_from_buffer(s->buffer.buf);
- if (len > s->offset) {
- s->loc[locty].sts = STS_EXPECT | STS_VALID;
- } else {
- s->loc[locty].sts = STS_VALID;
- }
- }
- }
- }
-}
-
-/*
- * Prepare the next interrupt for example after a command has
- * been sent out for the purpose of receiving the response.
- * Depending on how many interrupts (used for polling on the fd) have
- * already been schedule, this function determines the delta in time
- * to the next interrupt. This accomodates for commands that finish
- * quickly.
- */
-static void tis_prep_next_interrupt(tpmState *s)
-{
- int64_t expiration;
- int rate = 5; /* 5 times per second */
-
- /*
- poll often at the beginning for quickly finished commands,
- then back off
- */
- if (s->poll_attempts < 5) {
- rate = 20;
- } else if (s->poll_attempts < 10) {
- rate = 10;
- }
-
- expiration = qemu_get_clock(vm_clock) + (ticks_per_sec / rate);
- qemu_mod_timer(s->poll_timer, expiration);
- s->poll_attempts++;
-}
-
-
-/*
- * The polling routine called when the 'timer interrupt' fires.
- * Tries to receive a command from the vTPM.
- */
-static void tis_poll_timer(void *opaque)
-{
- tpmState* s=(tpmState*)opaque;
- uint8_t locty = s->active_loc;
-
- if (!IS_VALID_LOC(locty) ||
- (!(s->loc[locty].inte & INT_ENABLED) &&
- (s->aborting_locty != NO_LOCALITY)) ||
- !IS_COMM_WITH_VTPM(s)) {
- /* no more interrupts requested, so no more polling needed */
- qemu_del_timer(s->poll_timer);
- }
-
- if (!IS_COMM_WITH_VTPM(s)) {
- if (s->aborting_locty != NO_LOCALITY) {
- tis_abort(s);
- }
- return;
- }
-
- if (s->aborting_locty != NO_LOCALITY) {
- int n = TPM_Receive(s, &s->buffer);
-#ifdef DEBUG_TPM
- fprintf(logfile,"Receiving for abort.\n");
-#endif
- if (n > 0) {
- close_vtpm_channel(s, FORCE_CLOSE);
- tis_abort(s);
-#ifdef DEBUG_TPM
- fprintf(logfile,"Abort is complete.\n");
-#endif
- } else {
- tis_prep_next_interrupt(s);
- }
- } else if (IS_VALID_LOC(locty)) {
- if (s->loc[locty].state == STATE_EXECUTION) {
- /* poll for result */
- int n = TPM_Receive(s, &s->buffer);
- if (n > 0) {
- s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
- s->loc[locty].state = STATE_COMPLETION;
- close_vtpm_channel(s, FORCE_CLOSE);
- tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
- } else {
- /* nothing received */
- tis_prep_next_interrupt(s);
- }
- }
- }
-}
-
-
-static CPUReadMemoryFunc *tis_readfn[3]={
- tis_mem_readl,
- tis_mem_readl,
- tis_mem_readl
-};
-
-static CPUWriteMemoryFunc *tis_writefn[3]={
- tis_mem_writel,
- tis_mem_writel,
- tis_mem_writel
-};
-
-/*
- * Save the internal state of this interface for later resumption.
- * Need to get any outstanding responses from the vTPM back, so
- * this might delay the suspend for a while.
- */
-static void tpm_save(QEMUFile* f,void* opaque)
-{
- tpmState* s=(tpmState*)opaque;
- uint8_t locty = s->active_loc;
- int c;
-
- /* need to wait for outstanding requests to complete */
- if (s->loc[locty].state == STATE_EXECUTION) {
- int repeats = 30; /* 30 seconds; really should be infty */
- while (repeats > 0 &&
- !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) {
- int n = TPM_Receive(s, &s->buffer);
- if (n > 0) {
- if (IS_VALID_LOC(s->active_loc)) {
- s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
- s->loc[s->active_loc].state = STATE_COMPLETION;
- tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
- }
- /* close the connection with the vTPM for good */
- close_vtpm_channel(s, 1);
- break;
- }
- sleep(1);
- }
- }
-
- if (IS_COMM_WITH_VTPM(s)) {
- close_vtpm_channel(s, 1);
- }
-
- qemu_put_be32s(f,&s->offset);
- qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT);
- qemu_put_8s(f, &s->active_loc);
- qemu_put_8s(f, &s->irq_pending);
- for (c = 0; c < NUM_LOCALITIES; c++) {
- qemu_put_be32s(f, &s->loc[c].state);
- qemu_put_8s(f, &s->loc[c].access);
- qemu_put_8s(f, &s->loc[c].sts);
- qemu_put_be32s(f, &s->loc[c].inte);
- qemu_put_be32s(f, &s->loc[c].ints);
- }
-}
-
-/*
- * load TIS interface state
- */
-static int tpm_load(QEMUFile* f,void* opaque,int version_id)
-{
- tpmState* s=(tpmState*)opaque;
- int c;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f,&s->offset);
- qemu_get_buffer(f, s->buffer.buf, TPM_MAX_PKT);
- qemu_get_8s(f, &s->active_loc);
- qemu_get_8s(f, &s->irq_pending);
- for (c = 0; c < NUM_LOCALITIES; c++) {
- qemu_get_be32s(f, &s->loc[c].state);
- qemu_get_8s(f, &s->loc[c].access);
- qemu_get_8s(f, &s->loc[c].sts);
- qemu_get_be32s(f, &s->loc[c].inte);
- qemu_get_be32s(f, &s->loc[c].ints);
- }
-
- /* need to be able to get the instance number from the xenstore */
- s->vtpm_instance = vtpm_instance_from_xenstore();
- if (s->vtpm_instance == VTPM_BAD_INSTANCE)
- return -EINVAL;
- tpm_initialize_instance(s, s->vtpm_instance);
-
- return 0;
-}
-
-
-typedef struct LPCtpmState {
- tpmState tpm;
- int mem;
-} LPCtpmState;
-
-
-/*
- * initialize TIS interface
- */
-void tpm_tis_init(SetIRQFunc *set_irq, void *opaque, int irq)
-{
- LPCtpmState *d;
- tpmState *s;
- int c = 0;
- uint32_t vtpm_in;
-
- vtpm_in = vtpm_instance_from_xenstore();
- /* no valid vtpm instance -> no device */
- if (vtpm_in == VTPM_BAD_INSTANCE)
- return;
-
- d = qemu_mallocz(sizeof(LPCtpmState));
- d->mem = cpu_register_io_memory(0, tis_readfn, tis_writefn, d);
-
- if (d->mem == -1) {
- return;
- }
-
- cpu_register_physical_memory(TIS_ADDR_BASE,
- 0x1000 * NUM_LOCALITIES, d->mem);
-
- /* initialize tpmState */
- s = &d->tpm;
-
- s->offset = 0;
- s->active_loc = NO_LOCALITY;
-
- while (c < NUM_LOCALITIES) {
- s->loc[c].access = (1 << 7);
- s->loc[c].sts = 0;
- s->loc[c].inte = (1 << 3);
- s->loc[c].ints = 0;
- s->loc[c].state = STATE_IDLE;
- c++;
- }
- s->poll_timer = qemu_new_timer(vm_clock, tis_poll_timer, s);
- s->set_irq = set_irq;
- s->irq_opaque = opaque;
- s->irq = irq;
- s->vtpm_instance = vtpm_in;
- s->Transmitlayer = -1;
- s->tpmTx.fd[0] = -1;
- s->tpmTx.fd[1] = -1;
- s->aborting_locty = NO_LOCALITY;
-
- tpm_initialize_instance(s, s->vtpm_instance);
- memset(s->buffer.buf,0,sizeof(s->buffer.buf));
-
- register_savevm("tpm-tis", 0, 1, tpm_save, tpm_load, s);
-
- open_vtpm_channel(s);
- for (c = 0; !IS_COMM_WITH_VTPM(s) && (c < 5); c++) {
- sleep(1);
- open_vtpm_channel(s);
- }
-}
-
-/****************************************************************************/
-/* optional verbose logging of data to/from vtpm */
-/****************************************************************************/
-#ifdef DEBUG_TPM
-static void showBuff(unsigned char *buff, char *string)
-{
- uint32_t i, len;
-
- len = tpm_get_size_from_buffer(buff);
- fprintf(logfile,"%s length = %d\n", string, len);
- for (i = 0; i < len; i++) {
- if (i && !(i % 16)) {
- fprintf(logfile,"\n");
- }
- fprintf(logfile,"%.2X ", buff[i]);
- }
- fprintf(logfile,"\n");
-}
-#endif
-
-/****************************************************************************/
-/* Transmit request to TPM and read Response */
-/****************************************************************************/
-
-const static unsigned char tpm_failure[] = {
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a,
- 0x00, 0x00, 0x00, 0x09
-};
-
-
-/*
- * Send a TPM request.
- */
-static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg)
-{
- int len;
- uint32_t size = tpm_get_size_from_buffer(buffer->buf);
-
- /* try to establish a connection to the vTPM */
- if ( !IS_COMM_WITH_VTPM(s)) {
- open_vtpm_channel(s);
- }
-
- if ( !IS_COMM_WITH_VTPM(s)) {
- unsigned char tag = buffer->buf[1];
-
- /* there's a failure response from the TPM */
- memcpy(buffer->buf, tpm_failure, sizeof(tpm_failure));
- buffer->buf[1] = tag + 3;
- if (IS_VALID_LOC(s->active_loc)) {
- s->loc[s->active_loc].sts = STS_DATA_AVAILABLE | STS_VALID;
- }
-#ifdef DEBUG_TPM
- fprintf(logfile,"No TPM running!\n");
-#endif
- /* the request went out ok. */
- return sizeof(buffer->instance) + size;
- }
-
-#ifdef DEBUG_TPM
- showBuff(buffer->buf, "To TPM");
-#endif
-
- /* transmit the locality in the highest 3 bits */
- buffer->instance[0] &= 0x1f;
- buffer->instance[0] |= (locty << 5);
-
- len = vTPMTransmit[s->Transmitlayer].write_fn(s, buffer);
- if (len < 0) {
- s->Transmitlayer = -1;
- }
- return len;
-}
-
-/*
- * Try to receive data from the file descriptor. Since it is in
- * non-blocking mode it is possible that no data are actually received -
- * whatever calls this function needs to try again later.
- */
-static int TPM_Receive(tpmState *s, tpmBuffer *buffer)
-{
- int off;
-
- off = vTPMTransmit[s->Transmitlayer].read_fn(s, buffer);
-
- if (off < 0) {
- /* EAGAIN is set in errno due to non-blocking mode */
- return -1;
- }
-
- if (off == 0) {
-#ifdef DEBUG_TPM
- fprintf(logfile,"TPM GONE? errno=%d\n",errno);
-#endif
- close_vtpm_channel(s, 1);
- /* pretend that data are available */
- if (IS_VALID_LOC(s->active_loc)) {
- s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
- s->loc[s->active_loc].state = STATE_COMPLETION;
- tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
- }
- return -1;
- }
-
-#ifdef DEBUG_TPM
- if (off > sizeof(buffer->instance ) + 6) {
- uint32_t size = tpm_get_size_from_buffer(buffer->buf);
- if (size + sizeof(buffer->instance) != off) {
- fprintf(logfile,"TPM: Packet size is bad! %d != %d\n",
- (int)(size + sizeof(buffer->instance)),
- off);
- } else {
- uint32_t ret;
- showBuff(buffer->buf, "From TPM");
- ret = (buffer->buf[8])*256 + buffer->buf[9];
- if (ret)
- fprintf(logfile,"Receive failed with error %d\n", ret);
- else
- fprintf(logfile,"Receive succeeded. Got response of length %d (=%d)\n",
- size, off);
- }
- }
-#endif
-
- /* assuming reading in one chunk for now */
- return off;
-}
-
-
-/****************************************************************************
- Helper functions for reading data from the xenstore such as
- reading virtual TPM instance information
- ****************************************************************************/
-int has_tpm_device(void)
-{
- int ret = 0;
- struct xs_handle *handle = xs_daemon_open();
- if (handle) {
- ret = xenstore_domain_has_devtype(handle, "vtpm");
- xs_daemon_close(handle);
- }
- return ret;
-}
-
-
-/*
- * Wait until hotplug scripts have finished then read the vTPM instance
- * number from the xenstore.
- */
-static uint32_t vtpm_instance_from_xenstore(void)
-{
- unsigned int num;
- uint32_t number = VTPM_BAD_INSTANCE;
- int end = 0;
- char *token = "tok";
- int subscribed = 0;
- int ctr = 0;
- fd_set readfds;
-
- struct xs_handle *handle = xs_daemon_open();
-
- FD_ZERO(&readfds);
-
- if (handle) {
- char **e = xenstore_domain_get_devices(handle, "vtpm", &num);
- int fd = xs_fileno(handle);
- FD_SET(fd, &readfds);
- if (e) {
- do {
- struct timeval tv = {
- .tv_sec = 30,
- .tv_usec = 0,
- };
- /* need to make sure that the hotplug scripts have finished */
- char *status = xenstore_read_hotplug_status(handle,
- "vtpm",
- e[0]);
- if (status) {
- if (!strcmp(status, "connected")) {
- char *inst = xenstore_backend_read_variable(handle,
- "vtpm",
- e[0],
- "instance");
- if (1 != (sscanf(inst,"%d",&number)))
- number = VTPM_BAD_INSTANCE;
- free(inst);
- } else {
- fprintf(logfile,
- "bad status '%s' from vtpm hotplug\n",
- status);
- }
- free(status);
- end = 1;
- } else {
- /* no status, yet */
- int rc;
- unsigned int nr;
- char **f;
-
- if (!subscribed) {
- rc = xenstore_subscribe_to_hotplug_status(handle,
- "vtpm",
- e[0],
- token);
- if (rc != 0)
- break;
- subscribed = 1;
- }
- rc = select(fd+1, &readfds, NULL, NULL, &tv);
- /* get what's available -- drain the fd */
- f = xs_read_watch(handle, &nr);
- ctr++;
- free(f);
- if (ctr > 2)
- end = 1;
- }
- } while (end == 0);
- free(e);
- }
- if (subscribed) {
- /* clean up */
- xenstore_unsubscribe_from_hotplug_status(handle,
- "vtpm",
- e[0],
- token);
- }
- xs_daemon_close(handle);
- }
- if (number == VTPM_BAD_INSTANCE)
- fprintf(logfile, "no valid vtpm instance");
- else
- fprintf(logfile,"vtpm instance:%d\n",number);
- return number;
-}
diff --git a/tools/ioemu/hw/unin_pci.c b/tools/ioemu/hw/unin_pci.c
deleted file mode 100644
index 6448a6f250..0000000000
--- a/tools/ioemu/hw/unin_pci.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * QEMU Uninorth PCI host (for all Mac99 and newer machines)
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-typedef target_phys_addr_t pci_addr_t;
-#include "pci_host.h"
-
-typedef PCIHostState UNINState;
-
-static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- UNINState *s = opaque;
- int i;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- for (i = 11; i < 32; i++) {
- if ((val & (1 << i)) != 0)
- break;
- }
-#if 0
- s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
-#else
- s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
-#endif
-}
-
-static uint32_t pci_unin_main_config_readl (void *opaque,
- target_phys_addr_t addr)
-{
- UNINState *s = opaque;
- uint32_t val;
- int devfn;
-
- devfn = (s->config_reg >> 8) & 0xFF;
- val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
- &pci_unin_main_config_writel,
- &pci_unin_main_config_writel,
- &pci_unin_main_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
- &pci_unin_main_config_readl,
- &pci_unin_main_config_readl,
- &pci_unin_main_config_readl,
-};
-
-static CPUWriteMemoryFunc *pci_unin_main_write[] = {
- &pci_host_data_writeb,
- &pci_host_data_writew,
- &pci_host_data_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_main_read[] = {
- &pci_host_data_readb,
- &pci_host_data_readw,
- &pci_host_data_readl,
-};
-
-#if 0
-
-static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- UNINState *s = opaque;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- s->config_reg = 0x80000000 | (val & ~0x00000001);
-}
-
-static uint32_t pci_unin_config_readl (void *opaque,
- target_phys_addr_t addr)
-{
- UNINState *s = opaque;
- uint32_t val;
-
- val = (s->config_reg | 0x00000001) & ~0x80000000;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_unin_config_write[] = {
- &pci_unin_config_writel,
- &pci_unin_config_writel,
- &pci_unin_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_config_read[] = {
- &pci_unin_config_readl,
- &pci_unin_config_readl,
- &pci_unin_config_readl,
-};
-
-static CPUWriteMemoryFunc *pci_unin_write[] = {
- &pci_host_pci_writeb,
- &pci_host_pci_writew,
- &pci_host_pci_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_read[] = {
- &pci_host_pci_readb,
- &pci_host_pci_readw,
- &pci_host_pci_readl,
-};
-#endif
-
-/* Don't know if this matches real hardware, but it agrees with OHW. */
-static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
-{
- return (irq_num + (pci_dev->devfn >> 3)) & 3;
-}
-
-static void pci_unin_set_irq(void *pic, int irq_num, int level)
-{
- openpic_set_irq(pic, irq_num + 8, level);
-}
-
-PCIBus *pci_pmac_init(void *pic)
-{
- UNINState *s;
- PCIDevice *d;
- int pci_mem_config, pci_mem_data;
-
- /* Use values found on a real PowerMac */
- /* Uninorth main bus */
- s = qemu_mallocz(sizeof(UNINState));
- s->bus = pci_register_bus(pci_unin_set_irq, pci_unin_map_irq,
- pic, 11 << 3, 4);
-
- pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
- pci_unin_main_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
- pci_unin_main_write, s);
- cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
- cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
- d = pci_register_device(s->bus, "Uni-north main", sizeof(PCIDevice),
- 11 << 3, NULL, NULL);
- d->config[0x00] = 0x6b; // vendor_id : Apple
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x1F; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x00; // revision
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
- d->config[0x34] = 0x00; // capabilities_pointer
-
-#if 0 // XXX: not activated as PPC BIOS doesn't handle multiple buses properly
- /* pci-to-pci bridge */
- d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
- NULL, NULL);
- d->config[0x00] = 0x11; // vendor_id : TI
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x26; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x05; // revision
- d->config[0x0A] = 0x04; // class_sub = pci2pci
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x20; // latency_timer
- d->config[0x0E] = 0x01; // header_type
-
- d->config[0x18] = 0x01; // primary_bus
- d->config[0x19] = 0x02; // secondary_bus
- d->config[0x1A] = 0x02; // subordinate_bus
- d->config[0x1B] = 0x20; // secondary_latency_timer
- d->config[0x1C] = 0x11; // io_base
- d->config[0x1D] = 0x01; // io_limit
- d->config[0x20] = 0x00; // memory_base
- d->config[0x21] = 0x80;
- d->config[0x22] = 0x00; // memory_limit
- d->config[0x23] = 0x80;
- d->config[0x24] = 0x01; // prefetchable_memory_base
- d->config[0x25] = 0x80;
- d->config[0x26] = 0xF1; // prefectchable_memory_limit
- d->config[0x27] = 0x7F;
- // d->config[0x34] = 0xdc // capabilities_pointer
-#endif
-#if 0 // XXX: not needed for now
- /* Uninorth AGP bus */
- s = &pci_bridge[1];
- pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
- pci_unin_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
- pci_unin_write, s);
- cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
- cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
-
- d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
- NULL, NULL);
- d->config[0x00] = 0x6b; // vendor_id : Apple
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x20; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x00; // revision
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
- // d->config[0x34] = 0x80; // capabilities_pointer
-#endif
-
-#if 0 // XXX: not needed for now
- /* Uninorth internal bus */
- s = &pci_bridge[2];
- pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
- pci_unin_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
- pci_unin_write, s);
- cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
- cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
-
- d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
- 3, 11 << 3, NULL, NULL);
- d->config[0x00] = 0x6b; // vendor_id : Apple
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x1E; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x00; // revision
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
- d->config[0x34] = 0x00; // capabilities_pointer
-#endif
- return s->bus;
-}
-
diff --git a/tools/ioemu/hw/usb-hid.c b/tools/ioemu/hw/usb-hid.c
deleted file mode 100644
index 78b48b8dbb..0000000000
--- a/tools/ioemu/hw/usb-hid.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * QEMU USB HID devices
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* HID interface requests */
-#define GET_REPORT 0xa101
-#define GET_IDLE 0xa102
-#define GET_PROTOCOL 0xa103
-#define SET_IDLE 0x210a
-#define SET_PROTOCOL 0x210b
-
-#define USB_MOUSE 1
-#define USB_TABLET 2
-
-typedef struct USBMouseState {
- USBDevice dev;
- int dx, dy, dz, buttons_state;
- int x, y;
- int kind;
- int mouse_grabbed;
- int status_changed;
- QEMUPutMouseEntry *eh_entry;
-} USBMouseState;
-
-/* mostly the same values as the Bochs USB Mouse device */
-static const uint8_t qemu_mouse_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x00, /* u16 bcdUSB; v1.0 */
-
- 0x00, /* u8 bDeviceClass; */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x27, 0x06, /* u16 idVendor; */
- 0x01, 0x00, /* u16 idProduct; */
- 0x00, 0x00, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-static const uint8_t qemu_mouse_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x05, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 50, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_tablet_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x05, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 74, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x03, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_mouse_hid_report_descriptor[] = {
- 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
- 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
- 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
- 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
- 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
- 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
- 0xC0, 0xC0,
-};
-
-static const uint8_t qemu_tablet_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page Generic Desktop */
- 0x09, 0x01, /* Usage Mouse */
- 0xA1, 0x01, /* Collection Application */
- 0x09, 0x01, /* Usage Pointer */
- 0xA1, 0x00, /* Collection Physical */
- 0x05, 0x09, /* Usage Page Button */
- 0x19, 0x01, /* Usage Minimum Button 1 */
- 0x29, 0x03, /* Usage Maximum Button 3 */
- 0x15, 0x00, /* Logical Minimum 0 */
- 0x25, 0x01, /* Logical Maximum 1 */
- 0x95, 0x03, /* Report Count 3 */
- 0x75, 0x01, /* Report Size 1 */
- 0x81, 0x02, /* Input (Data, Var, Abs) */
- 0x95, 0x01, /* Report Count 1 */
- 0x75, 0x05, /* Report Size 5 */
- 0x81, 0x01, /* Input (Cnst, Var, Abs) */
- 0x05, 0x01, /* Usage Page Generic Desktop */
- 0x09, 0x30, /* Usage X */
- 0x09, 0x31, /* Usage Y */
- 0x15, 0x00, /* Logical Minimum 0 */
- 0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
- 0x35, 0x00, /* Physical Minimum 0 */
- 0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
- 0x75, 0x10, /* Report Size 16 */
- 0x95, 0x02, /* Report Count 2 */
- 0x81, 0x02, /* Input (Data, Var, Abs) */
- 0x05, 0x01, /* Usage Page Generic Desktop */
- 0x09, 0x38, /* Usage Wheel */
- 0x15, 0x81, /* Logical Minimum -127 */
- 0x25, 0x7F, /* Logical Maximum 127 */
- 0x35, 0x00, /* Physical Minimum 0 (same as logical) */
- 0x45, 0x00, /* Physical Maximum 0 (same as logical) */
- 0x75, 0x08, /* Report Size 8 */
- 0x95, 0x01, /* Report Count 1 */
- 0x81, 0x02, /* Input (Data, Var, Rel) */
- 0xC0, /* End Collection */
- 0xC0, /* End Collection */
-};
-
-static int currentbutton = 0;
-typedef struct _mouseclick {
- int button_state;
- struct _mouseclick *next;
-} mouseclick;
-static mouseclick mousequeue[20];
-static mouseclick *head = mousequeue;
-static mouseclick *tail = mousequeue;
-
-static void usb_mouse_event(void *opaque,
- int dx1, int dy1, int dz1, int buttons_state)
-{
- USBMouseState *s = opaque;
-
- if (s->status_changed == 1){
- //A mouse event is lost
- if (buttons_state != currentbutton && tail->next != head) {
- //A left click event is lost: let's add it to the queue
- //counter++;
- tail->button_state = buttons_state;
- tail = tail->next;
- }
- }
- else {
- s->buttons_state = buttons_state;
- }
-
- s->dx += dx1;
- s->dy += dy1;
- s->dz += dz1;
- currentbutton = buttons_state;
- s->status_changed = 1;
-}
-
-static void usb_tablet_event(void *opaque,
- int x, int y, int dz, int buttons_state)
-{
- USBMouseState *s = opaque;
-
- if (s->status_changed == 1){
- //A mouse event is lost
- if (buttons_state != currentbutton && tail->next != head) {
- //A left click event is lost: let's add it to the queue
- //counter++;
- tail->button_state = buttons_state;
- tail = tail->next;
- }
- }
- else {
- s->buttons_state = buttons_state;
- }
-
- s->x = x;
- s->y = y;
- s->dz += dz;
- currentbutton = buttons_state;
- s->status_changed = 1;
-}
-
-static inline int int_clamp(int val, int vmin, int vmax)
-{
- if (val < vmin)
- return vmin;
- else if (val > vmax)
- return vmax;
- else
- return val;
-}
-
-static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
-{
- int dx, dy, dz, b, l;
-
- if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s,
- 0, "QEMU USB Mouse");
- s->mouse_grabbed = 1;
- }
-
- dx = int_clamp(s->dx, -128, 127);
- dy = int_clamp(s->dy, -128, 127);
- dz = int_clamp(s->dz, -128, 127);
-
- s->dx -= dx;
- s->dy -= dy;
- s->dz -= dz;
-
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- buf[0] = b;
- buf[1] = dx;
- buf[2] = dy;
- l = 3;
- if (len >= 4) {
- buf[3] = dz;
- l = 4;
- }
- return l;
-}
-
-static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len)
-{
- int dz, b, l;
-
- if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s,
- 1, "QEMU USB Tablet");
- s->mouse_grabbed = 1;
- }
-
- dz = int_clamp(s->dz, -128, 127);
- s->dz -= dz;
-
- /* Appears we have to invert the wheel direction */
- dz = 0 - dz;
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- buf[0] = b;
- buf[1] = s->x & 0xff;
- buf[2] = s->x >> 8;
- buf[3] = s->y & 0xff;
- buf[4] = s->y >> 8;
- buf[5] = dz;
- l = 6;
-
- return l;
-}
-
-static void usb_mouse_handle_reset(USBDevice *dev)
-{
- USBMouseState *s = (USBMouseState *)dev;
-
- s->dx = 0;
- s->dy = 0;
- s->dz = 0;
- s->x = 0;
- s->y = 0;
- s->buttons_state = 0;
-}
-
-static int usb_mouse_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBMouseState *s = (USBMouseState *)dev;
- int ret = 0;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_mouse_dev_descriptor,
- sizeof(qemu_mouse_dev_descriptor));
- ret = sizeof(qemu_mouse_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_config_descriptor,
- sizeof(qemu_mouse_config_descriptor));
- ret = sizeof(qemu_mouse_config_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_config_descriptor,
- sizeof(qemu_tablet_config_descriptor));
- ret = sizeof(qemu_tablet_config_descriptor);
- }
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "1");
- break;
- case 2:
- /* product description */
- if (s->kind == USB_MOUSE)
- ret = set_usb_string(data, "QEMU USB Mouse");
- else if (s->kind == USB_TABLET)
- ret = set_usb_string(data, "QEMU USB Tablet");
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- case 4:
- ret = set_usb_string(data, "HID Mouse");
- break;
- case 5:
- ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* hid specific requests */
- case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case 0x22:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_hid_report_descriptor,
- sizeof(qemu_mouse_hid_report_descriptor));
- ret = sizeof(qemu_mouse_hid_report_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_hid_report_descriptor,
- sizeof(qemu_tablet_hid_report_descriptor));
- ret = sizeof(qemu_tablet_hid_report_descriptor);
- }
- break;
- default:
- goto fail;
- }
- break;
- case GET_REPORT:
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, data, length);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, data, length);
- break;
- case SET_IDLE:
- ret = 0;
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_mouse_handle_data(USBDevice *dev, USBPacket *p)
-{
- USBMouseState *s = (USBMouseState *)dev;
- int ret = 0;
-
- switch(p->pid) {
- case USB_TOKEN_IN:
- if (p->devep == 1) {
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, p->data, p->len);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, p->data, p->len);
-
- if (!s->status_changed) {
- ret = USB_RET_NAK;
- } else {
- if (head != tail) {
- s->buttons_state = head->button_state;
- head = head->next;
- }
- else {
- s->status_changed = 0;
- }
- }
-
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static void usb_mouse_handle_destroy(USBDevice *dev)
-{
- USBMouseState *s = (USBMouseState *)dev;
-
- qemu_remove_mouse_event_handler(s->eh_entry);
- qemu_free(s);
-}
-
-void usb_mouse_save(QEMUFile *f, void *opaque)
-{
- USBMouseState *s = (USBMouseState*)opaque;
-
- qemu_put_be32s(f, &s->dx);
- qemu_put_be32s(f, &s->dy);
- qemu_put_be32s(f, &s->dz);
- qemu_put_be32s(f, &s->buttons_state);
- qemu_put_be32s(f, &s->x);
- qemu_put_be32s(f, &s->y);
- qemu_put_be32s(f, &s->kind);
- qemu_put_be32s(f, &s->mouse_grabbed);
- qemu_put_be32s(f, &s->status_changed);
-
-}
-
-int usb_mouse_load(QEMUFile *f, void *opaque, int version_id)
-{
- USBMouseState *s = (USBMouseState*)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->dx);
- qemu_get_be32s(f, &s->dy);
- qemu_get_be32s(f, &s->dz);
- qemu_get_be32s(f, &s->buttons_state);
- qemu_get_be32s(f, &s->x);
- qemu_get_be32s(f, &s->y);
- qemu_get_be32s(f, &s->kind);
- qemu_get_be32s(f, &s->mouse_grabbed);
- qemu_get_be32s(f, &s->status_changed);
-
- if ( s->kind == USB_TABLET) {
- fprintf(logfile, "usb_mouse_load:add usb_tablet_event.\n");
- qemu_add_mouse_event_handler(usb_tablet_event, s, 1, "QEMU USB Tablet");
- } else if ( s->kind == USB_MOUSE) {
- fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n");
- qemu_add_mouse_event_handler(usb_mouse_event, s, 0, "QEMU USB MOUSE");
- }
-
- return 0;
-}
-
-
-USBDevice *usb_tablet_init(void)
-{
- USBMouseState *s;
- int i;
-
- for (i = 0; i < 19; i++) {
- mousequeue[i].button_state = 0;
- mousequeue[i].next = &(mousequeue[i + 1]);
- }
- mousequeue[i].button_state = 0;
- mousequeue[i].next = mousequeue;
-
- s = qemu_mallocz(sizeof(USBMouseState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_mouse_handle_control;
- s->dev.handle_data = usb_mouse_handle_data;
- s->dev.handle_destroy = usb_mouse_handle_destroy;
- s->kind = USB_TABLET;
- s->status_changed = 0;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
-
- register_savevm("USB tablet dev", 0, 1, usb_mouse_save, usb_mouse_load, s);
-
- return (USBDevice *)s;
-}
-
-USBDevice *usb_mouse_init(void)
-{
- USBMouseState *s;
- int i;
-
- for (i = 0; i < 19; i++) {
- mousequeue[i].button_state = 0;
- mousequeue[i].next = &(mousequeue[i + 1]);
- }
- mousequeue[i].button_state = 0;
- mousequeue[i].next = mousequeue;
-
- s = qemu_mallocz(sizeof(USBMouseState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_mouse_handle_control;
- s->dev.handle_data = usb_mouse_handle_data;
- s->dev.handle_destroy = usb_mouse_handle_destroy;
- s->kind = USB_MOUSE;
- s->status_changed = 0;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
-
- register_savevm("USB mouse dev", 0, 1, usb_mouse_save, usb_mouse_load, s);
-
- return (USBDevice *)s;
-}
diff --git a/tools/ioemu/hw/usb-hub.c b/tools/ioemu/hw/usb-hub.c
deleted file mode 100644
index 651dac2109..0000000000
--- a/tools/ioemu/hw/usb-hub.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * QEMU USB HUB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG
-
-#define MAX_PORTS 8
-
-typedef struct USBHubPort {
- USBPort port;
- uint16_t wPortStatus;
- uint16_t wPortChange;
-} USBHubPort;
-
-typedef struct USBHubState {
- USBDevice dev;
- int nb_ports;
- USBHubPort ports[MAX_PORTS];
-} USBHubState;
-
-#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
-#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
-#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
-#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
-#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
-#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
-#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
-
-#define PORT_STAT_CONNECTION 0x0001
-#define PORT_STAT_ENABLE 0x0002
-#define PORT_STAT_SUSPEND 0x0004
-#define PORT_STAT_OVERCURRENT 0x0008
-#define PORT_STAT_RESET 0x0010
-#define PORT_STAT_POWER 0x0100
-#define PORT_STAT_LOW_SPEED 0x0200
-#define PORT_STAT_HIGH_SPEED 0x0400
-#define PORT_STAT_TEST 0x0800
-#define PORT_STAT_INDICATOR 0x1000
-
-#define PORT_STAT_C_CONNECTION 0x0001
-#define PORT_STAT_C_ENABLE 0x0002
-#define PORT_STAT_C_SUSPEND 0x0004
-#define PORT_STAT_C_OVERCURRENT 0x0008
-#define PORT_STAT_C_RESET 0x0010
-
-#define PORT_CONNECTION 0
-#define PORT_ENABLE 1
-#define PORT_SUSPEND 2
-#define PORT_OVERCURRENT 3
-#define PORT_RESET 4
-#define PORT_POWER 8
-#define PORT_LOWSPEED 9
-#define PORT_HIGHSPEED 10
-#define PORT_C_CONNECTION 16
-#define PORT_C_ENABLE 17
-#define PORT_C_SUSPEND 18
-#define PORT_C_OVERCURRENT 19
-#define PORT_C_RESET 20
-#define PORT_TEST 21
-#define PORT_INDICATOR 22
-
-/* same as Linux kernel root hubs */
-
-static const uint8_t qemu_hub_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x01, /* u16 bcdUSB; v1.1 */
-
- 0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x01, 0x01, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-/* XXX: patch interrupt size */
-static const uint8_t qemu_hub_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x19, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
- 0x00, /* u8 if_bInterfaceSubClass; */
- 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x00, /* u8 if_iInterface; */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
- 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_hub_hub_descriptor[] =
-{
- 0x00, /* u8 bLength; patched in later */
- 0x29, /* u8 bDescriptorType; Hub-descriptor */
- 0x00, /* u8 bNbrPorts; (patched later) */
- 0x0a, /* u16 wHubCharacteristics; */
- 0x00, /* (per-port OC, no power switching) */
- 0x01, /* u8 bPwrOn2pwrGood; 2ms */
- 0x00 /* u8 bHubContrCurrent; 0 mA */
-
- /* DeviceRemovable and PortPwrCtrlMask patched in later */
-};
-
-static void usb_hub_attach(USBPort *port1, USBDevice *dev)
-{
- USBHubState *s = port1->opaque;
- USBHubPort *port = &s->ports[port1->index];
-
- if (dev) {
- if (port->port.dev)
- usb_attach(port1, NULL);
-
- port->wPortStatus |= PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (dev->speed == USB_SPEED_LOW)
- port->wPortStatus |= PORT_STAT_LOW_SPEED;
- else
- port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
- port->port.dev = dev;
- /* send the attach message */
- usb_send_msg(dev, USB_MSG_ATTACH);
- } else {
- dev = port->port.dev;
- if (dev) {
- port->wPortStatus &= ~PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (port->wPortStatus & PORT_STAT_ENABLE) {
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- port->wPortChange |= PORT_STAT_C_ENABLE;
- }
- /* send the detach message */
- usb_send_msg(dev, USB_MSG_DETACH);
- port->port.dev = NULL;
- }
- }
-}
-
-static void usb_hub_handle_reset(USBDevice *dev)
-{
- /* XXX: do it */
-}
-
-static int usb_hub_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == 0 && index != 0x81) { /* clear ep halt */
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_hub_dev_descriptor,
- sizeof(qemu_hub_dev_descriptor));
- ret = sizeof(qemu_hub_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- memcpy(data, qemu_hub_config_descriptor,
- sizeof(qemu_hub_config_descriptor));
-
- /* status change endpoint size based on number
- * of ports */
- data[22] = (s->nb_ports + 1 + 7) / 8;
-
- ret = sizeof(qemu_hub_config_descriptor);
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "314159");
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, "QEMU USB Hub");
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* usb specific requests */
- case GetHubStatus:
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
- ret = 4;
- break;
- case GetPortStatus:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- data[0] = port->wPortStatus;
- data[1] = port->wPortStatus >> 8;
- data[2] = port->wPortChange;
- data[3] = port->wPortChange >> 8;
- ret = 4;
- }
- break;
- case SetHubFeature:
- case ClearHubFeature:
- if (value == 0 || value == 1) {
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case SetPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_SUSPEND:
- port->wPortStatus |= PORT_STAT_SUSPEND;
- break;
- case PORT_RESET:
- if (dev) {
- usb_send_msg(dev, USB_MSG_RESET);
- port->wPortChange |= PORT_STAT_C_RESET;
- /* set enable bit */
- port->wPortStatus |= PORT_STAT_ENABLE;
- }
- break;
- case PORT_POWER:
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case ClearPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_ENABLE:
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- break;
- case PORT_C_ENABLE:
- port->wPortChange &= ~PORT_STAT_C_ENABLE;
- break;
- case PORT_SUSPEND:
- port->wPortStatus &= ~PORT_STAT_SUSPEND;
- break;
- case PORT_C_SUSPEND:
- port->wPortChange &= ~PORT_STAT_C_SUSPEND;
- break;
- case PORT_C_CONNECTION:
- port->wPortChange &= ~PORT_STAT_C_CONNECTION;
- break;
- case PORT_C_OVERCURRENT:
- port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
- break;
- case PORT_C_RESET:
- port->wPortChange &= ~PORT_STAT_C_RESET;
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case GetHubDescriptor:
- {
- unsigned int n, limit, var_hub_size = 0;
- memcpy(data, qemu_hub_hub_descriptor,
- sizeof(qemu_hub_hub_descriptor));
- data[2] = s->nb_ports;
-
- /* fill DeviceRemovable bits */
- limit = ((s->nb_ports + 1 + 7) / 8) + 7;
- for (n = 7; n < limit; n++) {
- data[n] = 0x00;
- var_hub_size++;
- }
-
- /* fill PortPwrCtrlMask bits */
- limit = limit + ((s->nb_ports + 7) / 8);
- for (;n < limit; n++) {
- data[n] = 0xff;
- var_hub_size++;
- }
-
- ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
- data[0] = ret;
- break;
- }
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(p->pid) {
- case USB_TOKEN_IN:
- if (p->devep == 1) {
- USBHubPort *port;
- unsigned int status;
- int i, n;
- n = (s->nb_ports + 1 + 7) / 8;
- if (p->len == 1) { /* FreeBSD workaround */
- n = 1;
- } else if (n > p->len) {
- return USB_RET_BABBLE;
- }
- status = 0;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- if (port->wPortChange)
- status |= (1 << (i + 1));
- }
- if (status != 0) {
- for(i = 0; i < n; i++) {
- p->data[i] = status >> (8 * i);
- }
- ret = n;
- } else {
- ret = USB_RET_NAK; /* usb11 11.13.1 */
- }
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p)
-{
- USBHubPort *port;
- USBDevice *dev;
- int i, ret;
-
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
- ret = dev->handle_packet(dev, p);
- if (ret != USB_RET_NODEV) {
- return ret;
- }
- }
- }
- return USB_RET_NODEV;
-}
-
-static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p)
-{
- USBHubState *s = (USBHubState *)dev;
-
-#if defined(DEBUG) && 0
- printf("usb_hub: pid=0x%x\n", pid);
-#endif
- if (dev->state == USB_STATE_DEFAULT &&
- dev->addr != 0 &&
- p->devaddr != dev->addr &&
- (p->pid == USB_TOKEN_SETUP ||
- p->pid == USB_TOKEN_OUT ||
- p->pid == USB_TOKEN_IN)) {
- /* broadcast the packet to the devices */
- return usb_hub_broadcast_packet(s, p);
- }
- return usb_generic_handle_packet(dev, p);
-}
-
-static void usb_hub_handle_destroy(USBDevice *dev)
-{
- USBHubState *s = (USBHubState *)dev;
-
- qemu_free(s);
-}
-
-USBDevice *usb_hub_init(int nb_ports)
-{
- USBHubState *s;
- USBHubPort *port;
- int i;
-
- if (nb_ports > MAX_PORTS)
- return NULL;
- s = qemu_mallocz(sizeof(USBHubState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_hub_handle_packet;
-
- /* generic USB device init */
- s->dev.handle_reset = usb_hub_handle_reset;
- s->dev.handle_control = usb_hub_handle_control;
- s->dev.handle_data = usb_hub_handle_data;
- s->dev.handle_destroy = usb_hub_handle_destroy;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Hub");
-
- s->nb_ports = nb_ports;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- qemu_register_usb_port(&port->port, s, i, usb_hub_attach);
- port->wPortStatus = PORT_STAT_POWER;
- port->wPortChange = 0;
- }
- return (USBDevice *)s;
-}
diff --git a/tools/ioemu/hw/usb-msd.c b/tools/ioemu/hw/usb-msd.c
deleted file mode 100644
index 6f22a57969..0000000000
--- a/tools/ioemu/hw/usb-msd.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * USB Mass Storage Device emulation
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- */
-
-#include "vl.h"
-
-//#define DEBUG_MSD
-
-#ifdef DEBUG_MSD
-#define DPRINTF(fmt, args...) \
-do { printf("usb-msd: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-/* USB requests. */
-#define MassStorageReset 0xff
-#define GetMaxLun 0xfe
-
-enum USBMSDMode {
- USB_MSDM_CBW, /* Command Block. */
- USB_MSDM_DATAOUT, /* Tranfer data to device. */
- USB_MSDM_DATAIN, /* Transfer data from device. */
- USB_MSDM_CSW /* Command Status. */
-};
-
-typedef struct {
- USBDevice dev;
- enum USBMSDMode mode;
- uint32_t scsi_len;
- uint8_t *scsi_buf;
- uint32_t usb_len;
- uint8_t *usb_buf;
- uint32_t data_len;
- uint32_t residue;
- uint32_t tag;
- BlockDriverState *bs;
- SCSIDevice *scsi_dev;
- int result;
- /* For async completion. */
- USBPacket *packet;
-} MSDState;
-
-struct usb_msd_cbw {
- uint32_t sig;
- uint32_t tag;
- uint32_t data_len;
- uint8_t flags;
- uint8_t lun;
- uint8_t cmd_len;
- uint8_t cmd[16];
-};
-
-struct usb_msd_csw {
- uint32_t sig;
- uint32_t tag;
- uint32_t residue;
- uint8_t status;
-};
-
-static const uint8_t qemu_msd_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x00, /* u16 bcdUSB; v1.0 */
-
- 0x00, /* u8 bDeviceClass; */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- /* Vendor and product id are arbitrary. */
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x00, 0x00, /* u16 bcdDevice */
-
- 0x01, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x03, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-static const uint8_t qemu_msd_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x20, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x02, /* u8 if_bNumEndpoints; */
- 0x08, /* u8 if_bInterfaceClass; MASS STORAGE */
- 0x06, /* u8 if_bInterfaceSubClass; SCSI */
- 0x50, /* u8 if_bInterfaceProtocol; Bulk Only */
- 0x00, /* u8 if_iInterface; */
-
- /* Bulk-In endpoint */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x02, /* u8 ep_bmAttributes; Bulk */
- 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x00, /* u8 ep_bInterval; */
-
- /* Bulk-Out endpoint */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x02, /* u8 ep_bEndpointAddress; OUT Endpoint 2 */
- 0x02, /* u8 ep_bmAttributes; Bulk */
- 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x00 /* u8 ep_bInterval; */
-};
-
-static void usb_msd_copy_data(MSDState *s)
-{
- uint32_t len;
- len = s->usb_len;
- if (len > s->scsi_len)
- len = s->scsi_len;
- if (s->mode == USB_MSDM_DATAIN) {
- memcpy(s->usb_buf, s->scsi_buf, len);
- } else {
- memcpy(s->scsi_buf, s->usb_buf, len);
- }
- s->usb_len -= len;
- s->scsi_len -= len;
- s->usb_buf += len;
- s->scsi_buf += len;
- s->data_len -= len;
- if (s->scsi_len == 0) {
- if (s->mode == USB_MSDM_DATAIN) {
- scsi_read_data(s->scsi_dev, s->tag);
- } else if (s->mode == USB_MSDM_DATAOUT) {
- scsi_write_data(s->scsi_dev, s->tag);
- }
- }
-}
-
-static void usb_msd_send_status(MSDState *s)
-{
- struct usb_msd_csw csw;
-
- csw.sig = cpu_to_le32(0x53425355);
- csw.tag = cpu_to_le32(s->tag);
- csw.residue = s->residue;
- csw.status = s->result;
- memcpy(s->usb_buf, &csw, 13);
-}
-
-static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag,
- uint32_t arg)
-{
- MSDState *s = (MSDState *)opaque;
- USBPacket *p = s->packet;
-
- if (tag != s->tag) {
- fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag);
- }
- if (reason == SCSI_REASON_DONE) {
- DPRINTF("Command complete %d\n", arg);
- s->residue = s->data_len;
- s->result = arg != 0;
- if (s->packet) {
- if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
- /* A deferred packet with no write data remaining must be
- the status read packet. */
- usb_msd_send_status(s);
- s->mode = USB_MSDM_CBW;
- } else {
- if (s->data_len) {
- s->data_len -= s->usb_len;
- if (s->mode == USB_MSDM_DATAIN)
- memset(s->usb_buf, 0, s->usb_len);
- s->usb_len = 0;
- }
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- }
- s->packet = NULL;
- usb_packet_complete(p);
- } else if (s->data_len == 0) {
- s->mode = USB_MSDM_CSW;
- }
- return;
- }
- s->scsi_len = arg;
- s->scsi_buf = scsi_get_buf(s->scsi_dev, tag);
- if (p) {
- usb_msd_copy_data(s);
- if (s->usb_len == 0) {
- /* Set s->packet to NULL before calling usb_packet_complete
- because annother request may be issued before
- usb_packet_complete returns. */
- DPRINTF("Packet complete %p\n", p);
- s->packet = NULL;
- usb_packet_complete(p);
- }
- }
-}
-
-static void usb_msd_handle_reset(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- DPRINTF("Reset\n");
- s->mode = USB_MSDM_CBW;
-}
-
-static int usb_msd_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- MSDState *s = (MSDState *)dev;
- int ret = 0;
-
- switch (request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_msd_dev_descriptor,
- sizeof(qemu_msd_dev_descriptor));
- ret = sizeof(qemu_msd_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- memcpy(data, qemu_msd_config_descriptor,
- sizeof(qemu_msd_config_descriptor));
- ret = sizeof(qemu_msd_config_descriptor);
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, "QEMU USB HARDDRIVE");
- break;
- case 3:
- /* serial number */
- ret = set_usb_string(data, "1");
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == 0 && index != 0x81) { /* clear ep halt */
- goto fail;
- }
- ret = 0;
- break;
- /* Class specific requests. */
- case MassStorageReset:
- /* Reset state ready for the next CBW. */
- s->mode = USB_MSDM_CBW;
- ret = 0;
- break;
- case GetMaxLun:
- data[0] = 0;
- ret = 1;
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static void usb_msd_cancel_io(USBPacket *p, void *opaque)
-{
- MSDState *s = opaque;
- scsi_cancel_io(s->scsi_dev, s->tag);
- s->packet = NULL;
- s->scsi_len = 0;
-}
-
-static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
-{
- MSDState *s = (MSDState *)dev;
- int ret = 0;
- struct usb_msd_cbw cbw;
- uint8_t devep = p->devep;
- uint8_t *data = p->data;
- int len = p->len;
-
- switch (p->pid) {
- case USB_TOKEN_OUT:
- if (devep != 2)
- goto fail;
-
- switch (s->mode) {
- case USB_MSDM_CBW:
- if (len != 31) {
- fprintf(stderr, "usb-msd: Bad CBW size");
- goto fail;
- }
- memcpy(&cbw, data, 31);
- if (le32_to_cpu(cbw.sig) != 0x43425355) {
- fprintf(stderr, "usb-msd: Bad signature %08x\n",
- le32_to_cpu(cbw.sig));
- goto fail;
- }
- DPRINTF("Command on LUN %d\n", cbw.lun);
- if (cbw.lun != 0) {
- fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
- goto fail;
- }
- s->tag = le32_to_cpu(cbw.tag);
- s->data_len = le32_to_cpu(cbw.data_len);
- if (s->data_len == 0) {
- s->mode = USB_MSDM_CSW;
- } else if (cbw.flags & 0x80) {
- s->mode = USB_MSDM_DATAIN;
- } else {
- s->mode = USB_MSDM_DATAOUT;
- }
- DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
- s->tag, cbw.flags, cbw.cmd_len, s->data_len);
- s->residue = 0;
- scsi_send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
- /* ??? Should check that USB and SCSI data transfer
- directions match. */
- if (s->residue == 0) {
- if (s->mode == USB_MSDM_DATAIN) {
- scsi_read_data(s->scsi_dev, s->tag);
- } else if (s->mode == USB_MSDM_DATAOUT) {
- scsi_write_data(s->scsi_dev, s->tag);
- }
- }
- ret = len;
- break;
-
- case USB_MSDM_DATAOUT:
- DPRINTF("Data out %d/%d\n", len, s->data_len);
- if (len > s->data_len)
- goto fail;
-
- s->usb_buf = data;
- s->usb_len = len;
- if (s->scsi_len) {
- usb_msd_copy_data(s);
- }
- if (s->residue && s->usb_len) {
- s->data_len -= s->usb_len;
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- s->usb_len = 0;
- }
- if (s->usb_len) {
- DPRINTF("Deferring packet %p\n", p);
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- } else {
- ret = len;
- }
- break;
-
- default:
- DPRINTF("Unexpected write (len %d)\n", len);
- goto fail;
- }
- break;
-
- case USB_TOKEN_IN:
- if (devep != 1)
- goto fail;
-
- switch (s->mode) {
- case USB_MSDM_DATAOUT:
- if (s->data_len != 0 || len < 13)
- goto fail;
- /* Waiting for SCSI write to complete. */
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- break;
-
- case USB_MSDM_CSW:
- DPRINTF("Command status %d tag 0x%x, len %d\n",
- s->result, s->tag, len);
- if (len < 13)
- goto fail;
-
- s->usb_len = len;
- s->usb_buf = data;
- usb_msd_send_status(s);
- s->mode = USB_MSDM_CBW;
- ret = 13;
- break;
-
- case USB_MSDM_DATAIN:
- DPRINTF("Data in %d/%d\n", len, s->data_len);
- if (len > s->data_len)
- len = s->data_len;
- s->usb_buf = data;
- s->usb_len = len;
- if (s->scsi_len) {
- usb_msd_copy_data(s);
- }
- if (s->residue && s->usb_len) {
- s->data_len -= s->usb_len;
- memset(s->usb_buf, 0, s->usb_len);
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- s->usb_len = 0;
- }
- if (s->usb_len) {
- DPRINTF("Deferring packet %p\n", p);
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- } else {
- ret = len;
- }
- break;
-
- default:
- DPRINTF("Unexpected read (len %d)\n", len);
- goto fail;
- }
- break;
-
- default:
- DPRINTF("Bad token\n");
- fail:
- ret = USB_RET_STALL;
- break;
- }
-
- return ret;
-}
-
-static void usb_msd_handle_destroy(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- scsi_disk_destroy(s->scsi_dev);
- bdrv_delete(s->bs);
- qemu_free(s);
-}
-
-USBDevice *usb_msd_init(const char *filename, BlockDriver *drv)
-{
- MSDState *s;
- BlockDriverState *bdrv;
-
- s = qemu_mallocz(sizeof(MSDState));
- if (!s)
- return NULL;
-
- bdrv = bdrv_new("usb");
- if (bdrv_open2(bdrv, filename, 0, drv) < 0)
- goto fail;
- s->bs = bdrv;
-
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_msd_handle_reset;
- s->dev.handle_control = usb_msd_handle_control;
- s->dev.handle_data = usb_msd_handle_data;
- s->dev.handle_destroy = usb_msd_handle_destroy;
-
- snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB MSD(%.16s)",
- filename);
-
- s->scsi_dev = scsi_disk_init(bdrv, 0, usb_msd_command_complete, s);
- usb_msd_handle_reset((USBDevice *)s);
- return (USBDevice *)s;
- fail:
- qemu_free(s);
- return NULL;
-}
diff --git a/tools/ioemu/hw/usb-ohci.c b/tools/ioemu/hw/usb-ohci.c
deleted file mode 100644
index e58829fd9a..0000000000
--- a/tools/ioemu/hw/usb-ohci.c
+++ /dev/null
@@ -1,1286 +0,0 @@
-/*
- * QEMU USB OHCI Emulation
- * Copyright (c) 2004 Gianni Tedesco
- * Copyright (c) 2006 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * TODO:
- * o Isochronous transfers
- * o Allocate bandwidth in frames properly
- * o Disable timers when nothing needs to be done, or remove timer usage
- * all together.
- * o Handle unrecoverable errors properly
- * o BIOS work to boot from USB storage
-*/
-
-#include "vl.h"
-
-//#define DEBUG_OHCI
-/* Dump packet contents. */
-//#define DEBUG_PACKET
-/* This causes frames to occur 1000x slower */
-//#define OHCI_TIME_WARP 1
-
-#ifdef DEBUG_OHCI
-#define dprintf printf
-#else
-#define dprintf(...)
-#endif
-
-/* Number of Downstream Ports on the root hub. */
-
-#define OHCI_MAX_PORTS 15
-
-static int64_t usb_frame_time;
-static int64_t usb_bit_time;
-
-typedef struct OHCIPort {
- USBPort port;
- uint32_t ctrl;
-} OHCIPort;
-
-typedef struct {
- struct PCIDevice pci_dev;
- target_phys_addr_t mem_base;
- int mem;
- int num_ports;
-
- QEMUTimer *eof_timer;
- int64_t sof_time;
-
- /* OHCI state */
- /* Control partition */
- uint32_t ctl, status;
- uint32_t intr_status;
- uint32_t intr;
-
- /* memory pointer partition */
- uint32_t hcca;
- uint32_t ctrl_head, ctrl_cur;
- uint32_t bulk_head, bulk_cur;
- uint32_t per_cur;
- uint32_t done;
- int done_count;
-
- /* Frame counter partition */
- uint32_t fsmps:15;
- uint32_t fit:1;
- uint32_t fi:14;
- uint32_t frt:1;
- uint16_t frame_number;
- uint16_t padding;
- uint32_t pstart;
- uint32_t lst;
-
- /* Root Hub partition */
- uint32_t rhdesc_a, rhdesc_b;
- uint32_t rhstatus;
- OHCIPort rhport[OHCI_MAX_PORTS];
-
- /* Active packets. */
- uint32_t old_ctl;
- USBPacket usb_packet;
- uint8_t usb_buf[8192];
- uint32_t async_td;
- int async_complete;
-
-} OHCIState;
-
-/* Host Controller Communications Area */
-struct ohci_hcca {
- uint32_t intr[32];
- uint16_t frame, pad;
- uint32_t done;
-};
-
-/* Bitfields for the first word of an Endpoint Desciptor. */
-#define OHCI_ED_FA_SHIFT 0
-#define OHCI_ED_FA_MASK (0x7f<<OHCI_ED_FA_SHIFT)
-#define OHCI_ED_EN_SHIFT 7
-#define OHCI_ED_EN_MASK (0xf<<OHCI_ED_EN_SHIFT)
-#define OHCI_ED_D_SHIFT 11
-#define OHCI_ED_D_MASK (3<<OHCI_ED_D_SHIFT)
-#define OHCI_ED_S (1<<13)
-#define OHCI_ED_K (1<<14)
-#define OHCI_ED_F (1<<15)
-#define OHCI_ED_MPS_SHIFT 7
-#define OHCI_ED_MPS_MASK (0xf<<OHCI_ED_FA_SHIFT)
-
-/* Flags in the head field of an Endpoint Desciptor. */
-#define OHCI_ED_H 1
-#define OHCI_ED_C 2
-
-/* Bitfields for the first word of a Transfer Desciptor. */
-#define OHCI_TD_R (1<<18)
-#define OHCI_TD_DP_SHIFT 19
-#define OHCI_TD_DP_MASK (3<<OHCI_TD_DP_SHIFT)
-#define OHCI_TD_DI_SHIFT 21
-#define OHCI_TD_DI_MASK (7<<OHCI_TD_DI_SHIFT)
-#define OHCI_TD_T0 (1<<24)
-#define OHCI_TD_T1 (1<<24)
-#define OHCI_TD_EC_SHIFT 26
-#define OHCI_TD_EC_MASK (3<<OHCI_TD_EC_SHIFT)
-#define OHCI_TD_CC_SHIFT 28
-#define OHCI_TD_CC_MASK (0xf<<OHCI_TD_CC_SHIFT)
-
-#define OHCI_DPTR_MASK 0xfffffff0
-
-#define OHCI_BM(val, field) \
- (((val) & OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
-
-#define OHCI_SET_BM(val, field, newval) do { \
- val &= ~OHCI_##field##_MASK; \
- val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \
- } while(0)
-
-/* endpoint descriptor */
-struct ohci_ed {
- uint32_t flags;
- uint32_t tail;
- uint32_t head;
- uint32_t next;
-};
-
-/* General transfer descriptor */
-struct ohci_td {
- uint32_t flags;
- uint32_t cbp;
- uint32_t next;
- uint32_t be;
-};
-
-#define USB_HZ 12000000
-
-/* OHCI Local stuff */
-#define OHCI_CTL_CBSR ((1<<0)|(1<<1))
-#define OHCI_CTL_PLE (1<<2)
-#define OHCI_CTL_IE (1<<3)
-#define OHCI_CTL_CLE (1<<4)
-#define OHCI_CTL_BLE (1<<5)
-#define OHCI_CTL_HCFS ((1<<6)|(1<<7))
-#define OHCI_USB_RESET 0x00
-#define OHCI_USB_RESUME 0x40
-#define OHCI_USB_OPERATIONAL 0x80
-#define OHCI_USB_SUSPEND 0xc0
-#define OHCI_CTL_IR (1<<8)
-#define OHCI_CTL_RWC (1<<9)
-#define OHCI_CTL_RWE (1<<10)
-
-#define OHCI_STATUS_HCR (1<<0)
-#define OHCI_STATUS_CLF (1<<1)
-#define OHCI_STATUS_BLF (1<<2)
-#define OHCI_STATUS_OCR (1<<3)
-#define OHCI_STATUS_SOC ((1<<6)|(1<<7))
-
-#define OHCI_INTR_SO (1<<0) /* Scheduling overrun */
-#define OHCI_INTR_WD (1<<1) /* HcDoneHead writeback */
-#define OHCI_INTR_SF (1<<2) /* Start of frame */
-#define OHCI_INTR_RD (1<<3) /* Resume detect */
-#define OHCI_INTR_UE (1<<4) /* Unrecoverable error */
-#define OHCI_INTR_FNO (1<<5) /* Frame number overflow */
-#define OHCI_INTR_RHSC (1<<6) /* Root hub status change */
-#define OHCI_INTR_OC (1<<30) /* Ownership change */
-#define OHCI_INTR_MIE (1<<31) /* Master Interrupt Enable */
-
-#define OHCI_HCCA_SIZE 0x100
-#define OHCI_HCCA_MASK 0xffffff00
-
-#define OHCI_EDPTR_MASK 0xfffffff0
-
-#define OHCI_FMI_FI 0x00003fff
-#define OHCI_FMI_FSMPS 0xffff0000
-#define OHCI_FMI_FIT 0x80000000
-
-#define OHCI_FR_RT (1<<31)
-
-#define OHCI_LS_THRESH 0x628
-
-#define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */
-#define OHCI_RHA_PSM (1<<8)
-#define OHCI_RHA_NPS (1<<9)
-#define OHCI_RHA_DT (1<<10)
-#define OHCI_RHA_OCPM (1<<11)
-#define OHCI_RHA_NOCP (1<<12)
-#define OHCI_RHA_POTPGT_MASK 0xff000000
-
-#define OHCI_RHS_LPS (1<<0)
-#define OHCI_RHS_OCI (1<<1)
-#define OHCI_RHS_DRWE (1<<15)
-#define OHCI_RHS_LPSC (1<<16)
-#define OHCI_RHS_OCIC (1<<17)
-#define OHCI_RHS_CRWE (1<<31)
-
-#define OHCI_PORT_CCS (1<<0)
-#define OHCI_PORT_PES (1<<1)
-#define OHCI_PORT_PSS (1<<2)
-#define OHCI_PORT_POCI (1<<3)
-#define OHCI_PORT_PRS (1<<4)
-#define OHCI_PORT_PPS (1<<8)
-#define OHCI_PORT_LSDA (1<<9)
-#define OHCI_PORT_CSC (1<<16)
-#define OHCI_PORT_PESC (1<<17)
-#define OHCI_PORT_PSSC (1<<18)
-#define OHCI_PORT_OCIC (1<<19)
-#define OHCI_PORT_PRSC (1<<20)
-#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
- |OHCI_PORT_OCIC|OHCI_PORT_PRSC)
-
-#define OHCI_TD_DIR_SETUP 0x0
-#define OHCI_TD_DIR_OUT 0x1
-#define OHCI_TD_DIR_IN 0x2
-#define OHCI_TD_DIR_RESERVED 0x3
-
-#define OHCI_CC_NOERROR 0x0
-#define OHCI_CC_CRC 0x1
-#define OHCI_CC_BITSTUFFING 0x2
-#define OHCI_CC_DATATOGGLEMISMATCH 0x3
-#define OHCI_CC_STALL 0x4
-#define OHCI_CC_DEVICENOTRESPONDING 0x5
-#define OHCI_CC_PIDCHECKFAILURE 0x6
-#define OHCI_CC_UNDEXPETEDPID 0x7
-#define OHCI_CC_DATAOVERRUN 0x8
-#define OHCI_CC_DATAUNDERRUN 0x9
-#define OHCI_CC_BUFFEROVERRUN 0xc
-#define OHCI_CC_BUFFERUNDERRUN 0xd
-
-/* Update IRQ levels */
-static inline void ohci_intr_update(OHCIState *ohci)
-{
- int level = 0;
-
- if ((ohci->intr & OHCI_INTR_MIE) &&
- (ohci->intr_status & ohci->intr))
- level = 1;
-
- pci_set_irq(&ohci->pci_dev, 0, level);
-}
-
-/* Set an interrupt */
-static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr)
-{
- ohci->intr_status |= intr;
- ohci_intr_update(ohci);
-}
-
-/* Attach or detach a device on a root hub port. */
-static void ohci_attach(USBPort *port1, USBDevice *dev)
-{
- OHCIState *s = port1->opaque;
- OHCIPort *port = &s->rhport[port1->index];
- uint32_t old_state = port->ctrl;
-
- if (dev) {
- if (port->port.dev) {
- usb_attach(port1, NULL);
- }
- /* set connect status */
- port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
-
- /* update speed */
- if (dev->speed == USB_SPEED_LOW)
- port->ctrl |= OHCI_PORT_LSDA;
- else
- port->ctrl &= ~OHCI_PORT_LSDA;
- port->port.dev = dev;
- /* send the attach message */
- usb_send_msg(dev, USB_MSG_ATTACH);
- dprintf("usb-ohci: Attached port %d\n", port1->index);
- } else {
- /* set connect status */
- if (port->ctrl & OHCI_PORT_CCS) {
- port->ctrl &= ~OHCI_PORT_CCS;
- port->ctrl |= OHCI_PORT_CSC;
- }
- /* disable port */
- if (port->ctrl & OHCI_PORT_PES) {
- port->ctrl &= ~OHCI_PORT_PES;
- port->ctrl |= OHCI_PORT_PESC;
- }
- dev = port->port.dev;
- if (dev) {
- /* send the detach message */
- usb_send_msg(dev, USB_MSG_DETACH);
- }
- port->port.dev = NULL;
- dprintf("usb-ohci: Detached port %d\n", port1->index);
- }
-
- if (old_state != port->ctrl)
- ohci_set_interrupt(s, OHCI_INTR_RHSC);
-}
-
-/* Reset the controller */
-static void ohci_reset(OHCIState *ohci)
-{
- OHCIPort *port;
- int i;
-
- ohci->ctl = 0;
- ohci->old_ctl = 0;
- ohci->status = 0;
- ohci->intr_status = 0;
- ohci->intr = OHCI_INTR_MIE;
-
- ohci->hcca = 0;
- ohci->ctrl_head = ohci->ctrl_cur = 0;
- ohci->bulk_head = ohci->bulk_cur = 0;
- ohci->per_cur = 0;
- ohci->done = 0;
- ohci->done_count = 7;
-
- /* FSMPS is marked TBD in OCHI 1.0, what gives ffs?
- * I took the value linux sets ...
- */
- ohci->fsmps = 0x2778;
- ohci->fi = 0x2edf;
- ohci->fit = 0;
- ohci->frt = 0;
- ohci->frame_number = 0;
- ohci->pstart = 0;
- ohci->lst = OHCI_LS_THRESH;
-
- ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports;
- ohci->rhdesc_b = 0x0; /* Impl. specific */
- ohci->rhstatus = 0;
-
- for (i = 0; i < ohci->num_ports; i++)
- {
- port = &ohci->rhport[i];
- port->ctrl = 0;
- if (port->port.dev)
- ohci_attach(&port->port, port->port.dev);
- }
- if (ohci->async_td) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- dprintf("usb-ohci: Reset %s\n", ohci->pci_dev.name);
-}
-
-/* Get an array of dwords from main memory */
-static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
- *buf = le32_to_cpu(*buf);
- }
-
- return 1;
-}
-
-/* Put an array of dwords in to main memory */
-static inline int put_dwords(uint32_t addr, uint32_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- uint32_t tmp = cpu_to_le32(*buf);
- cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
- }
-
- return 1;
-}
-
-static inline int ohci_read_ed(uint32_t addr, struct ohci_ed *ed)
-{
- return get_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
-}
-
-static inline int ohci_read_td(uint32_t addr, struct ohci_td *td)
-{
- return get_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
-}
-
-static inline int ohci_put_ed(uint32_t addr, struct ohci_ed *ed)
-{
- return put_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
-}
-
-static inline int ohci_put_td(uint32_t addr, struct ohci_td *td)
-{
- return put_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
-}
-
-/* Read/Write the contents of a TD from/to main memory. */
-static void ohci_copy_td(struct ohci_td *td, uint8_t *buf, int len, int write)
-{
- uint32_t ptr;
- uint32_t n;
-
- ptr = td->cbp;
- n = 0x1000 - (ptr & 0xfff);
- if (n > len)
- n = len;
- cpu_physical_memory_rw(ptr, buf, n, write);
- if (n == len)
- return;
- ptr = td->be & ~0xfffu;
- buf += n;
- cpu_physical_memory_rw(ptr, buf, len - n, write);
-}
-
-static void ohci_process_lists(OHCIState *ohci);
-
-static void ohci_async_complete_packet(USBPacket * packet, void *opaque)
-{
- OHCIState *ohci = opaque;
-#ifdef DEBUG_PACKET
- dprintf("Async packet complete\n");
-#endif
- ohci->async_complete = 1;
- ohci_process_lists(ohci);
-}
-
-/* Service a transport descriptor.
- Returns nonzero to terminate processing of this endpoint. */
-
-static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
-{
- int dir;
- size_t len = 0;
- char *str = NULL;
- int pid;
- int ret;
- int i;
- USBDevice *dev;
- struct ohci_td td;
- uint32_t addr;
- int flag_r;
- int completion;
-
- addr = ed->head & OHCI_DPTR_MASK;
- /* See if this TD has already been submitted to the device. */
- completion = (addr == ohci->async_td);
- if (completion && !ohci->async_complete) {
-#ifdef DEBUG_PACKET
- dprintf("Skipping async TD\n");
-#endif
- return 1;
- }
- if (!ohci_read_td(addr, &td)) {
- fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
- return 0;
- }
-
- dir = OHCI_BM(ed->flags, ED_D);
- switch (dir) {
- case OHCI_TD_DIR_OUT:
- case OHCI_TD_DIR_IN:
- /* Same value. */
- break;
- default:
- dir = OHCI_BM(td.flags, TD_DP);
- break;
- }
-
- switch (dir) {
- case OHCI_TD_DIR_IN:
- str = "in";
- pid = USB_TOKEN_IN;
- break;
- case OHCI_TD_DIR_OUT:
- str = "out";
- pid = USB_TOKEN_OUT;
- break;
- case OHCI_TD_DIR_SETUP:
- str = "setup";
- pid = USB_TOKEN_SETUP;
- break;
- default:
- fprintf(stderr, "usb-ohci: Bad direction\n");
- return 1;
- }
- if (td.cbp && td.be) {
- if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {
- len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);
- } else {
- len = (td.be - td.cbp) + 1;
- }
-
- if (len && dir != OHCI_TD_DIR_IN && !completion) {
- ohci_copy_td(&td, ohci->usb_buf, len, 0);
- }
- }
-
- flag_r = (td.flags & OHCI_TD_R) != 0;
-#ifdef DEBUG_PACKET
- dprintf(" TD @ 0x%.8x %u bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
- addr, len, str, flag_r, td.cbp, td.be);
-
- if (len >= 0 && dir != OHCI_TD_DIR_IN) {
- dprintf(" data:");
- for (i = 0; i < len; i++)
- printf(" %.2x", ohci->usb_buf[i]);
- dprintf("\n");
- }
-#endif
- if (completion) {
- ret = ohci->usb_packet.len;
- ohci->async_td = 0;
- ohci->async_complete = 0;
- } else {
- ret = USB_RET_NODEV;
- for (i = 0; i < ohci->num_ports; i++) {
- dev = ohci->rhport[i].port.dev;
- if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
- continue;
-
- if (ohci->async_td) {
- /* ??? The hardware should allow one active packet per
- endpoint. We only allow one active packet per controller.
- This should be sufficient as long as devices respond in a
- timely manner.
- */
-#ifdef DEBUG_PACKET
- dprintf("Too many pending packets\n");
-#endif
- return 1;
- }
- ohci->usb_packet.pid = pid;
- ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
- ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
- ohci->usb_packet.data = ohci->usb_buf;
- ohci->usb_packet.len = len;
- ohci->usb_packet.complete_cb = ohci_async_complete_packet;
- ohci->usb_packet.complete_opaque = ohci;
- ret = dev->handle_packet(dev, &ohci->usb_packet);
- if (ret != USB_RET_NODEV)
- break;
- }
-#ifdef DEBUG_PACKET
- dprintf("ret=%d\n", ret);
-#endif
- if (ret == USB_RET_ASYNC) {
- ohci->async_td = addr;
- return 1;
- }
- }
- if (ret >= 0) {
- if (dir == OHCI_TD_DIR_IN) {
- ohci_copy_td(&td, ohci->usb_buf, ret, 1);
-#ifdef DEBUG_PACKET
- dprintf(" data:");
- for (i = 0; i < ret; i++)
- printf(" %.2x", ohci->usb_buf[i]);
- dprintf("\n");
-#endif
- } else {
- ret = len;
- }
- }
-
- /* Writeback */
- if (ret == len || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
- /* Transmission succeeded. */
- if (ret == len) {
- td.cbp = 0;
- } else {
- td.cbp += ret;
- if ((td.cbp & 0xfff) + ret > 0xfff) {
- td.cbp &= 0xfff;
- td.cbp |= td.be & ~0xfff;
- }
- }
- td.flags |= OHCI_TD_T1;
- td.flags ^= OHCI_TD_T0;
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
- OHCI_SET_BM(td.flags, TD_EC, 0);
-
- ed->head &= ~OHCI_ED_C;
- if (td.flags & OHCI_TD_T0)
- ed->head |= OHCI_ED_C;
- } else {
- if (ret >= 0) {
- dprintf("usb-ohci: Underrun\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
- } else {
- switch (ret) {
- case USB_RET_NODEV:
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
- case USB_RET_NAK:
- dprintf("usb-ohci: got NAK\n");
- return 1;
- case USB_RET_STALL:
- dprintf("usb-ohci: got STALL\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);
- break;
- case USB_RET_BABBLE:
- dprintf("usb-ohci: got BABBLE\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
- break;
- default:
- fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);
- OHCI_SET_BM(td.flags, TD_EC, 3);
- break;
- }
- }
- ed->head |= OHCI_ED_H;
- }
-
- /* Retire this TD */
- ed->head &= ~OHCI_DPTR_MASK;
- ed->head |= td.next & OHCI_DPTR_MASK;
- td.next = ohci->done;
- ohci->done = addr;
- i = OHCI_BM(td.flags, TD_DI);
- if (i < ohci->done_count)
- ohci->done_count = i;
- ohci_put_td(addr, &td);
- return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
-}
-
-/* Service an endpoint list. Returns nonzero if active TD were found. */
-static int ohci_service_ed_list(OHCIState *ohci, uint32_t head)
-{
- struct ohci_ed ed;
- uint32_t next_ed;
- uint32_t cur;
- int active;
-
- active = 0;
-
- if (head == 0)
- return 0;
-
- for (cur = head; cur; cur = next_ed) {
- if (!ohci_read_ed(cur, &ed)) {
- fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
- return 0;
- }
-
- next_ed = ed.next & OHCI_DPTR_MASK;
-
- if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
- uint32_t addr;
- /* Cancel pending packets for ED that have been paused. */
- addr = ed.head & OHCI_DPTR_MASK;
- if (ohci->async_td && addr == ohci->async_td) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- continue;
- }
-
- /* Skip isochronous endpoints. */
- if (ed.flags & OHCI_ED_F)
- continue;
-
- while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
-#ifdef DEBUG_PACKET
- dprintf("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
- "h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur,
- OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN),
- OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0,
- (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0,
- OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0,
- (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
- ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
-#endif
- active = 1;
-
- if (ohci_service_td(ohci, &ed))
- break;
- }
-
- ohci_put_ed(cur, &ed);
- }
-
- return active;
-}
-
-/* Generate a SOF event, and set a timer for EOF */
-static void ohci_sof(OHCIState *ohci)
-{
- ohci->sof_time = qemu_get_clock(vm_clock);
- qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
- ohci_set_interrupt(ohci, OHCI_INTR_SF);
-}
-
-/* Process Control and Bulk lists. */
-static void ohci_process_lists(OHCIState *ohci)
-{
- if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
- if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
- dprintf("usb-ohci: head %x, cur %x\n", ohci->ctrl_head, ohci->ctrl_cur);
- if (!ohci_service_ed_list(ohci, ohci->ctrl_head)) {
- ohci->ctrl_cur = 0;
- ohci->status &= ~OHCI_STATUS_CLF;
- }
- }
-
- if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
- if (!ohci_service_ed_list(ohci, ohci->bulk_head)) {
- ohci->bulk_cur = 0;
- ohci->status &= ~OHCI_STATUS_BLF;
- }
- }
-}
-
-/* Do frame processing on frame boundary */
-static void ohci_frame_boundary(void *opaque)
-{
- OHCIState *ohci = opaque;
- struct ohci_hcca hcca;
-
- cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 0);
-
- /* Process all the lists at the end of the frame */
- if (ohci->ctl & OHCI_CTL_PLE) {
- int n;
-
- n = ohci->frame_number & 0x1f;
- ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]));
- }
-
- /* Cancel all pending packets if either of the lists has been disabled. */
- if (ohci->async_td &&
- ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- ohci->old_ctl = ohci->ctl;
- ohci_process_lists(ohci);
-
- /* Frame boundary, so do EOF stuf here */
- ohci->frt = ohci->fit;
-
- /* XXX: endianness */
- ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
- hcca.frame = cpu_to_le32(ohci->frame_number);
-
- if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
- if (!ohci->done)
- abort();
- if (ohci->intr & ohci->intr_status)
- ohci->done |= 1;
- hcca.done = cpu_to_le32(ohci->done);
- ohci->done = 0;
- ohci->done_count = 7;
- ohci_set_interrupt(ohci, OHCI_INTR_WD);
- }
-
- if (ohci->done_count != 7 && ohci->done_count != 0)
- ohci->done_count--;
-
- /* Do SOF stuff here */
- ohci_sof(ohci);
-
- /* Writeback HCCA */
- cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 1);
-}
-
-/* Start sending SOF tokens across the USB bus, lists are processed in
- * next frame
- */
-static int ohci_bus_start(OHCIState *ohci)
-{
- ohci->eof_timer = qemu_new_timer(vm_clock,
- ohci_frame_boundary,
- ohci);
-
- if (ohci->eof_timer == NULL) {
- fprintf(stderr, "usb-ohci: %s: qemu_new_timer failed\n",
- ohci->pci_dev.name);
- /* TODO: Signal unrecoverable error */
- return 0;
- }
-
- dprintf("usb-ohci: %s: USB Operational\n", ohci->pci_dev.name);
-
- ohci_sof(ohci);
-
- return 1;
-}
-
-/* Stop sending SOF tokens on the bus */
-static void ohci_bus_stop(OHCIState *ohci)
-{
- if (ohci->eof_timer)
- qemu_del_timer(ohci->eof_timer);
-}
-
-/* Sets a flag in a port status register but only set it if the port is
- * connected, if not set ConnectStatusChange flag. If flag is enabled
- * return 1.
- */
-static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
-{
- int ret = 1;
-
- /* writing a 0 has no effect */
- if (val == 0)
- return 0;
-
- /* If CurrentConnectStatus is cleared we set
- * ConnectStatusChange
- */
- if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
- ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
- if (ohci->rhstatus & OHCI_RHS_DRWE) {
- /* TODO: CSC is a wakeup event */
- }
- return 0;
- }
-
- if (ohci->rhport[i].ctrl & val)
- ret = 0;
-
- /* set the bit */
- ohci->rhport[i].ctrl |= val;
-
- return ret;
-}
-
-/* Set the frame interval - frame interval toggle is manipulated by the hcd only */
-static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
-{
- val &= OHCI_FMI_FI;
-
- if (val != ohci->fi) {
- dprintf("usb-ohci: %s: FrameInterval = 0x%x (%u)\n",
- ohci->pci_dev.name, ohci->fi, ohci->fi);
- }
-
- ohci->fi = val;
-}
-
-static void ohci_port_power(OHCIState *ohci, int i, int p)
-{
- if (p) {
- ohci->rhport[i].ctrl |= OHCI_PORT_PPS;
- } else {
- ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS|
- OHCI_PORT_CCS|
- OHCI_PORT_PSS|
- OHCI_PORT_PRS);
- }
-}
-
-/* Set HcControlRegister */
-static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
-{
- uint32_t old_state;
- uint32_t new_state;
-
- old_state = ohci->ctl & OHCI_CTL_HCFS;
- ohci->ctl = val;
- new_state = ohci->ctl & OHCI_CTL_HCFS;
-
- /* no state change */
- if (old_state == new_state)
- return;
-
- switch (new_state) {
- case OHCI_USB_OPERATIONAL:
- ohci_bus_start(ohci);
- break;
- case OHCI_USB_SUSPEND:
- ohci_bus_stop(ohci);
- dprintf("usb-ohci: %s: USB Suspended\n", ohci->pci_dev.name);
- break;
- case OHCI_USB_RESUME:
- dprintf("usb-ohci: %s: USB Resume\n", ohci->pci_dev.name);
- break;
- case OHCI_USB_RESET:
- dprintf("usb-ohci: %s: USB Reset\n", ohci->pci_dev.name);
- break;
- }
-}
-
-static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
-{
- uint16_t fr;
- int64_t tks;
-
- if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL)
- return (ohci->frt << 31);
-
- /* Being in USB operational state guarnatees sof_time was
- * set already.
- */
- tks = qemu_get_clock(vm_clock) - ohci->sof_time;
-
- /* avoid muldiv if possible */
- if (tks >= usb_frame_time)
- return (ohci->frt << 31);
-
- tks = muldiv64(1, tks, usb_bit_time);
- fr = (uint16_t)(ohci->fi - tks);
-
- return (ohci->frt << 31) | fr;
-}
-
-
-/* Set root hub status */
-static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
-{
- uint32_t old_state;
-
- old_state = ohci->rhstatus;
-
- /* write 1 to clear OCIC */
- if (val & OHCI_RHS_OCIC)
- ohci->rhstatus &= ~OHCI_RHS_OCIC;
-
- if (val & OHCI_RHS_LPS) {
- int i;
-
- for (i = 0; i < ohci->num_ports; i++)
- ohci_port_power(ohci, i, 0);
- dprintf("usb-ohci: powered down all ports\n");
- }
-
- if (val & OHCI_RHS_LPSC) {
- int i;
-
- for (i = 0; i < ohci->num_ports; i++)
- ohci_port_power(ohci, i, 1);
- dprintf("usb-ohci: powered up all ports\n");
- }
-
- if (val & OHCI_RHS_DRWE)
- ohci->rhstatus |= OHCI_RHS_DRWE;
-
- if (val & OHCI_RHS_CRWE)
- ohci->rhstatus &= ~OHCI_RHS_DRWE;
-
- if (old_state != ohci->rhstatus)
- ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
-}
-
-/* Set root hub port status */
-static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
-{
- uint32_t old_state;
- OHCIPort *port;
-
- port = &ohci->rhport[portnum];
- old_state = port->ctrl;
-
- /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */
- if (val & OHCI_PORT_WTC)
- port->ctrl &= ~(val & OHCI_PORT_WTC);
-
- if (val & OHCI_PORT_CCS)
- port->ctrl &= ~OHCI_PORT_PES;
-
- ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES);
-
- if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS))
- dprintf("usb-ohci: port %d: SUSPEND\n", portnum);
-
- if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
- dprintf("usb-ohci: port %d: RESET\n", portnum);
- usb_send_msg(port->port.dev, USB_MSG_RESET);
- port->ctrl &= ~OHCI_PORT_PRS;
- /* ??? Should this also set OHCI_PORT_PESC. */
- port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
- }
-
- /* Invert order here to ensure in ambiguous case, device is
- * powered up...
- */
- if (val & OHCI_PORT_LSDA)
- ohci_port_power(ohci, portnum, 0);
- if (val & OHCI_PORT_PPS)
- ohci_port_power(ohci, portnum, 1);
-
- if (old_state != port->ctrl)
- ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
-
- return;
-}
-
-static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
-{
- OHCIState *ohci = ptr;
-
- addr -= ohci->mem_base;
-
- /* Only aligned reads are allowed on OHCI */
- if (addr & 3) {
- fprintf(stderr, "usb-ohci: Mis-aligned read\n");
- return 0xffffffff;
- }
-
- if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
- /* HcRhPortStatus */
- return ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS;
- }
-
- switch (addr >> 2) {
- case 0: /* HcRevision */
- return 0x10;
-
- case 1: /* HcControl */
- return ohci->ctl;
-
- case 2: /* HcCommandStatus */
- return ohci->status;
-
- case 3: /* HcInterruptStatus */
- return ohci->intr_status;
-
- case 4: /* HcInterruptEnable */
- case 5: /* HcInterruptDisable */
- return ohci->intr;
-
- case 6: /* HcHCCA */
- return ohci->hcca;
-
- case 7: /* HcPeriodCurrentED */
- return ohci->per_cur;
-
- case 8: /* HcControlHeadED */
- return ohci->ctrl_head;
-
- case 9: /* HcControlCurrentED */
- return ohci->ctrl_cur;
-
- case 10: /* HcBulkHeadED */
- return ohci->bulk_head;
-
- case 11: /* HcBulkCurrentED */
- return ohci->bulk_cur;
-
- case 12: /* HcDoneHead */
- return ohci->done;
-
- case 13: /* HcFmInterval */
- return (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi);
-
- case 14: /* HcFmRemaining */
- return ohci_get_frame_remaining(ohci);
-
- case 15: /* HcFmNumber */
- return ohci->frame_number;
-
- case 16: /* HcPeriodicStart */
- return ohci->pstart;
-
- case 17: /* HcLSThreshold */
- return ohci->lst;
-
- case 18: /* HcRhDescriptorA */
- return ohci->rhdesc_a;
-
- case 19: /* HcRhDescriptorB */
- return ohci->rhdesc_b;
-
- case 20: /* HcRhStatus */
- return ohci->rhstatus;
-
- default:
- fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr);
- return 0xffffffff;
- }
-}
-
-static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
-{
- OHCIState *ohci = ptr;
-
- addr -= ohci->mem_base;
-
- /* Only aligned reads are allowed on OHCI */
- if (addr & 3) {
- fprintf(stderr, "usb-ohci: Mis-aligned write\n");
- return;
- }
-
- if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
- /* HcRhPortStatus */
- ohci_port_set_status(ohci, (addr - 0x54) >> 2, val);
- return;
- }
-
- switch (addr >> 2) {
- case 1: /* HcControl */
- ohci_set_ctl(ohci, val);
- break;
-
- case 2: /* HcCommandStatus */
- /* SOC is read-only */
- val = (val & ~OHCI_STATUS_SOC);
-
- /* Bits written as '0' remain unchanged in the register */
- ohci->status |= val;
-
- if (ohci->status & OHCI_STATUS_HCR)
- ohci_reset(ohci);
- break;
-
- case 3: /* HcInterruptStatus */
- ohci->intr_status &= ~val;
- ohci_intr_update(ohci);
- break;
-
- case 4: /* HcInterruptEnable */
- ohci->intr |= val;
- ohci_intr_update(ohci);
- break;
-
- case 5: /* HcInterruptDisable */
- ohci->intr &= ~val;
- ohci_intr_update(ohci);
- break;
-
- case 6: /* HcHCCA */
- ohci->hcca = val & OHCI_HCCA_MASK;
- break;
-
- case 8: /* HcControlHeadED */
- ohci->ctrl_head = val & OHCI_EDPTR_MASK;
- break;
-
- case 9: /* HcControlCurrentED */
- ohci->ctrl_cur = val & OHCI_EDPTR_MASK;
- break;
-
- case 10: /* HcBulkHeadED */
- ohci->bulk_head = val & OHCI_EDPTR_MASK;
- break;
-
- case 11: /* HcBulkCurrentED */
- ohci->bulk_cur = val & OHCI_EDPTR_MASK;
- break;
-
- case 13: /* HcFmInterval */
- ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16;
- ohci->fit = (val & OHCI_FMI_FIT) >> 31;
- ohci_set_frame_interval(ohci, val);
- break;
-
- case 16: /* HcPeriodicStart */
- ohci->pstart = val & 0xffff;
- break;
-
- case 17: /* HcLSThreshold */
- ohci->lst = val & 0xffff;
- break;
-
- case 18: /* HcRhDescriptorA */
- ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK;
- ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK;
- break;
-
- case 19: /* HcRhDescriptorB */
- break;
-
- case 20: /* HcRhStatus */
- ohci_set_hub_status(ohci, val);
- break;
-
- default:
- fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr);
- break;
- }
-}
-
-/* Only dword reads are defined on OHCI register space */
-static CPUReadMemoryFunc *ohci_readfn[3]={
- ohci_mem_read,
- ohci_mem_read,
- ohci_mem_read
-};
-
-/* Only dword writes are defined on OHCI register space */
-static CPUWriteMemoryFunc *ohci_writefn[3]={
- ohci_mem_write,
- ohci_mem_write,
- ohci_mem_write
-};
-
-static void ohci_mapfunc(PCIDevice *pci_dev, int i,
- uint32_t addr, uint32_t size, int type)
-{
- OHCIState *ohci = (OHCIState *)pci_dev;
- ohci->mem_base = addr;
- cpu_register_physical_memory(addr, size, ohci->mem);
-}
-
-static void ohci_usb_save(QEMUFile *f, void *opaque)
-{
- OHCIState *ohci = opaque;
-
- pci_device_save(&ohci->pci_dev, f);
-}
-
-static int ohci_usb_load(QEMUFile *f, void *opaque, int version_id)
-{
- OHCIState *ohci = opaque;
-
- return pci_device_load(&ohci->pci_dev, f);
-}
-
-void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn)
-{
- OHCIState *ohci;
- int vid = 0x106b;
- int did = 0x003f;
- int i;
-
-
- if (usb_frame_time == 0) {
-#if OHCI_TIME_WARP
- usb_frame_time = ticks_per_sec;
- usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ/1000);
-#else
- usb_frame_time = muldiv64(1, ticks_per_sec, 1000);
- if (ticks_per_sec >= USB_HZ) {
- usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ);
- } else {
- usb_bit_time = 1;
- }
-#endif
- dprintf("usb-ohci: usb_bit_time=%lli usb_frame_time=%lli\n",
- usb_frame_time, usb_bit_time);
- }
-
- ohci = (OHCIState *)pci_register_device(bus, "OHCI USB", sizeof(*ohci),
- devfn, NULL, NULL);
- if (ohci == NULL) {
- fprintf(stderr, "usb-ohci: Failed to register PCI device\n");
- return;
- }
-
- ohci->pci_dev.config[0x00] = vid & 0xff;
- ohci->pci_dev.config[0x01] = (vid >> 8) & 0xff;
- ohci->pci_dev.config[0x02] = did & 0xff;
- ohci->pci_dev.config[0x03] = (did >> 8) & 0xff;
- ohci->pci_dev.config[0x09] = 0x10; /* OHCI */
- ohci->pci_dev.config[0x0a] = 0x3;
- ohci->pci_dev.config[0x0b] = 0xc;
- ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
-
- ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
-
- pci_register_io_region((struct PCIDevice *)ohci, 0, 256,
- PCI_ADDRESS_SPACE_MEM, ohci_mapfunc);
-
- ohci->num_ports = num_ports;
- for (i = 0; i < num_ports; i++) {
- qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
- }
-
- register_savevm("OHCI USB", 0, 1, ohci_usb_save, ohci_usb_load, ohci);
-
- ohci->async_td = 0;
- ohci_reset(ohci);
-}
diff --git a/tools/ioemu/hw/usb-uhci.c b/tools/ioemu/hw/usb-uhci.c
deleted file mode 100644
index 1a59c4b97a..0000000000
--- a/tools/ioemu/hw/usb-uhci.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * USB UHCI controller emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG
-//#define DEBUG_PACKET
-
-#define UHCI_CMD_GRESET (1 << 2)
-#define UHCI_CMD_HCRESET (1 << 1)
-#define UHCI_CMD_RS (1 << 0)
-
-#define UHCI_STS_HCHALTED (1 << 5)
-#define UHCI_STS_HCPERR (1 << 4)
-#define UHCI_STS_HSERR (1 << 3)
-#define UHCI_STS_RD (1 << 2)
-#define UHCI_STS_USBERR (1 << 1)
-#define UHCI_STS_USBINT (1 << 0)
-
-#define TD_CTRL_SPD (1 << 29)
-#define TD_CTRL_ERROR_SHIFT 27
-#define TD_CTRL_IOS (1 << 25)
-#define TD_CTRL_IOC (1 << 24)
-#define TD_CTRL_ACTIVE (1 << 23)
-#define TD_CTRL_STALL (1 << 22)
-#define TD_CTRL_BUFFER (1 << 21)
-#define TD_CTRL_BABBLE (1 << 20)
-#define TD_CTRL_NAK (1 << 19)
-#define TD_CTRL_TIMEOUT (1 << 18)
-#define TD_CTRL_BITSTUFF \
- (1 << 17)
-#define TD_CTRL_MASK \
- (TD_CTRL_BITSTUFF | TD_CTRL_TIMEOUT | TD_CTRL_NAK \
- | TD_CTRL_BABBLE | TD_CTRL_BUFFER | TD_CTRL_STALL)
-
-#define UHCI_PORT_RESET (1 << 9)
-#define UHCI_PORT_LSDA (1 << 8)
-#define UHCI_PORT_ENC (1 << 3)
-#define UHCI_PORT_EN (1 << 2)
-#define UHCI_PORT_CSC (1 << 1)
-#define UHCI_PORT_CCS (1 << 0)
-
-#define FRAME_TIMER_FREQ 1000
-
-#define FRAME_MAX_LOOPS 100
-
-#define NB_PORTS 2
-
-typedef struct UHCIPort {
- USBPort port;
- uint16_t ctrl;
-} UHCIPort;
-
-typedef struct UHCIState {
- PCIDevice dev;
- uint16_t cmd; /* cmd register */
- uint16_t status;
- uint16_t intr; /* interrupt enable register */
- uint16_t frnum; /* frame number */
- uint32_t fl_base_addr; /* frame list base address */
- uint8_t sof_timing;
- uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
- QEMUTimer *frame_timer;
- UHCIPort ports[NB_PORTS];
-
- /* Interrupts that should be raised at the end of the current frame. */
- uint32_t pending_int_mask;
- /* For simplicity of implementation we only allow a single pending USB
- request. This means all usb traffic on this controller is effectively
- suspended until that transfer completes. When the transfer completes
- the next transfer from that queue will be processed. However
- other queues will not be processed until the next frame. The solution
- is to allow multiple pending requests. */
- uint32_t async_qh;
- USBPacket usb_packet;
- uint8_t usb_buf[2048];
-} UHCIState;
-
-typedef struct UHCI_TD {
- uint32_t link;
- uint32_t ctrl; /* see TD_CTRL_xxx */
- uint32_t token;
- uint32_t buffer;
-} UHCI_TD;
-
-typedef struct UHCI_QH {
- uint32_t link;
- uint32_t el_link;
-} UHCI_QH;
-
-static void uhci_attach(USBPort *port1, USBDevice *dev);
-
-static void uhci_update_irq(UHCIState *s)
-{
- int level;
- if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
- ((s->status2 & 2) && (s->intr & (1 << 3))) ||
- ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
- ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
- (s->status & UHCI_STS_HSERR) ||
- (s->status & UHCI_STS_HCPERR)) {
- level = 1;
- } else {
- level = 0;
- }
- pci_set_irq(&s->dev, 3, level);
-}
-
-static void uhci_reset(UHCIState *s)
-{
- uint8_t *pci_conf;
- int i;
- UHCIPort *port;
-
- pci_conf = s->dev.config;
-
- pci_conf[0x6a] = 0x01; /* usb clock */
- pci_conf[0x6b] = 0x00;
- s->cmd = 0;
- s->status = 0;
- s->status2 = 0;
- s->intr = 0;
- s->fl_base_addr = 0;
- s->sof_timing = 64;
- for(i = 0; i < NB_PORTS; i++) {
- port = &s->ports[i];
- port->ctrl = 0x0080;
- if (port->port.dev)
- uhci_attach(&port->port, port->port.dev);
- }
-}
-
-static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x0c:
- s->sof_timing = val;
- break;
- }
-}
-
-static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x0c:
- val = s->sof_timing;
- break;
- default:
- val = 0xff;
- break;
- }
- return val;
-}
-
-static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
-#ifdef DEBUG
- printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
-#endif
- switch(addr) {
- case 0x00:
- if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
- /* start frame processing */
- qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
- s->status &= ~UHCI_STS_HCHALTED;
- } else if (!(val & UHCI_CMD_RS)) {
- s->status |= UHCI_STS_HCHALTED;
- }
- if (val & UHCI_CMD_GRESET) {
- UHCIPort *port;
- USBDevice *dev;
- int i;
-
- /* send reset on the USB bus */
- for(i = 0; i < NB_PORTS; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev) {
- usb_send_msg(dev, USB_MSG_RESET);
- }
- }
- uhci_reset(s);
- return;
- }
- if (val & UHCI_CMD_HCRESET) {
- uhci_reset(s);
- return;
- }
- s->cmd = val;
- break;
- case 0x02:
- s->status &= ~val;
- /* XXX: the chip spec is not coherent, so we add a hidden
- register to distinguish between IOC and SPD */
- if (val & UHCI_STS_USBINT)
- s->status2 = 0;
- uhci_update_irq(s);
- break;
- case 0x04:
- s->intr = val;
- uhci_update_irq(s);
- break;
- case 0x06:
- if (s->status & UHCI_STS_HCHALTED)
- s->frnum = val & 0x7ff;
- break;
- case 0x10 ... 0x1f:
- {
- UHCIPort *port;
- USBDevice *dev;
- int n;
-
- n = (addr >> 1) & 7;
- if (n >= NB_PORTS)
- return;
- port = &s->ports[n];
- dev = port->port.dev;
- if (dev) {
- /* port reset */
- if ( (val & UHCI_PORT_RESET) &&
- !(port->ctrl & UHCI_PORT_RESET) ) {
- usb_send_msg(dev, USB_MSG_RESET);
- }
- }
- port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
- /* some bits are reset when a '1' is written to them */
- port->ctrl &= ~(val & 0x000a);
- }
- break;
- }
-}
-
-static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x00:
- val = s->cmd;
- break;
- case 0x02:
- val = s->status;
- break;
- case 0x04:
- val = s->intr;
- break;
- case 0x06:
- val = s->frnum;
- break;
- case 0x10 ... 0x1f:
- {
- UHCIPort *port;
- int n;
- n = (addr >> 1) & 7;
- if (n >= NB_PORTS)
- goto read_default;
- port = &s->ports[n];
- val = port->ctrl;
- }
- break;
- default:
- read_default:
- val = 0xff7f; /* disabled port */
- break;
- }
-#ifdef DEBUG
- printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
-#endif
- return val;
-}
-
-static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
-#ifdef DEBUG
- printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
-#endif
- switch(addr) {
- case 0x08:
- s->fl_base_addr = val & ~0xfff;
- break;
- }
-}
-
-static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x08:
- val = s->fl_base_addr;
- break;
- default:
- val = 0xffffffff;
- break;
- }
- return val;
-}
-
-static void uhci_attach(USBPort *port1, USBDevice *dev)
-{
- UHCIState *s = port1->opaque;
- UHCIPort *port = &s->ports[port1->index];
-
- if (dev) {
- if (port->port.dev) {
- usb_attach(port1, NULL);
- }
- /* set connect status */
- port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
-
- /* update speed */
- if (dev->speed == USB_SPEED_LOW)
- port->ctrl |= UHCI_PORT_LSDA;
- else
- port->ctrl &= ~UHCI_PORT_LSDA;
- port->port.dev = dev;
- /* send the attach message */
- usb_send_msg(dev, USB_MSG_ATTACH);
- } else {
- /* set connect status */
- if (port->ctrl & UHCI_PORT_CCS) {
- port->ctrl &= ~UHCI_PORT_CCS;
- port->ctrl |= UHCI_PORT_CSC;
- }
- /* disable port */
- if (port->ctrl & UHCI_PORT_EN) {
- port->ctrl &= ~UHCI_PORT_EN;
- port->ctrl |= UHCI_PORT_ENC;
- }
- dev = port->port.dev;
- if (dev) {
- /* send the detach message */
- usb_send_msg(dev, USB_MSG_DETACH);
- }
- port->port.dev = NULL;
- }
-}
-
-static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
-{
- UHCIPort *port;
- USBDevice *dev;
- int i, ret;
-
-#ifdef DEBUG_PACKET
- {
- const char *pidstr;
- switch(p->pid) {
- case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
- case USB_TOKEN_IN: pidstr = "IN"; break;
- case USB_TOKEN_OUT: pidstr = "OUT"; break;
- default: pidstr = "?"; break;
- }
- printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
- s->frnum, pidstr, p->devaddr, p->devep, p->len);
- if (p->pid != USB_TOKEN_IN) {
- printf(" data_out=");
- for(i = 0; i < p->len; i++) {
- printf(" %02x", p->data[i]);
- }
- printf("\n");
- }
- }
-#endif
- for(i = 0; i < NB_PORTS; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev && (port->ctrl & UHCI_PORT_EN)) {
- ret = dev->handle_packet(dev, p);
- if (ret != USB_RET_NODEV) {
-#ifdef DEBUG_PACKET
- if (ret == USB_RET_ASYNC) {
- printf("usb-uhci: Async packet\n");
- } else {
- printf(" ret=%d ", ret);
- if (p->pid == USB_TOKEN_IN && ret > 0) {
- printf("data_in=");
- for(i = 0; i < ret; i++) {
- printf(" %02x", p->data[i]);
- }
- }
- printf("\n");
- }
-#endif
- return ret;
- }
- }
- }
- return USB_RET_NODEV;
-}
-
-static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
-
-/* return -1 if fatal error (frame must be stopped)
- 0 if TD successful
- 1 if TD unsuccessful or inactive
-*/
-static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
-{
- uint8_t pid;
- int len, max_len, err, ret;
-
- if (!(td->ctrl & TD_CTRL_ACTIVE)) {
- ret = 1;
- goto out;
- }
-
- /* Clear TD's status field explicitly */
- td->ctrl = td->ctrl & (~TD_CTRL_MASK);
-
- /* TD is active */
- max_len = ((td->token >> 21) + 1) & 0x7ff;
- pid = td->token & 0xff;
- if (s->async_qh) {
- ret = s->usb_packet.len;
- if (ret >= 0) {
- len = ret;
- if (len > max_len) {
- len = max_len;
- ret = USB_RET_BABBLE;
- }
- if (len > 0) {
- /* write the data back */
- cpu_physical_memory_write(td->buffer, s->usb_buf, len);
- }
- } else {
- len = 0;
- }
- s->async_qh = 0;
- } else {
- s->usb_packet.pid = pid;
- s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
- s->usb_packet.devep = (td->token >> 15) & 0xf;
- s->usb_packet.data = s->usb_buf;
- s->usb_packet.len = max_len;
- s->usb_packet.complete_cb = uhci_async_complete_packet;
- s->usb_packet.complete_opaque = s;
- switch(pid) {
- case USB_TOKEN_OUT:
- case USB_TOKEN_SETUP:
- cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
- ret = uhci_broadcast_packet(s, &s->usb_packet);
- len = max_len;
- break;
- case USB_TOKEN_IN:
- ret = uhci_broadcast_packet(s, &s->usb_packet);
- if (ret >= 0) {
- len = ret;
- if (len > max_len) {
- len = max_len;
- ret = USB_RET_BABBLE;
- }
- if (len > 0) {
- /* write the data back */
- cpu_physical_memory_write(td->buffer, s->usb_buf, len);
- }
- } else {
- len = 0;
- }
- break;
- default:
- /* invalid pid : frame interrupted */
- s->status |= UHCI_STS_HCPERR;
- uhci_update_irq(s);
- ret = -1;
- goto out;
- }
- }
- if (ret == USB_RET_ASYNC) {
- ret = 2;
- goto out;
- }
- if (td->ctrl & TD_CTRL_IOS)
- td->ctrl &= ~TD_CTRL_ACTIVE;
- if (ret >= 0) {
- td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
- td->ctrl &= ~TD_CTRL_ACTIVE;
- if (pid == USB_TOKEN_IN &&
- (td->ctrl & TD_CTRL_SPD) &&
- len < max_len) {
- *int_mask |= 0x02;
- /* short packet: do not update QH */
- ret = 1;
- goto out;
- } else {
- /* success */
- ret = 0;
- goto out;
- }
- } else {
- switch(ret) {
- default:
- case USB_RET_NODEV:
- do_timeout:
- td->ctrl |= TD_CTRL_TIMEOUT;
- err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
- if (err != 0) {
- err--;
- if (err == 0) {
- td->ctrl &= ~TD_CTRL_ACTIVE;
- s->status |= UHCI_STS_USBERR;
- uhci_update_irq(s);
- }
- }
- td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
- (err << TD_CTRL_ERROR_SHIFT);
- ret = 1;
- goto out;
- case USB_RET_NAK:
- td->ctrl |= TD_CTRL_NAK;
- if (pid == USB_TOKEN_SETUP)
- goto do_timeout;
- ret = 1;
- goto out;
- case USB_RET_STALL:
- td->ctrl |= TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
- ret = 1;
- goto out;
- case USB_RET_BABBLE:
- td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
- /* frame interrupted */
- ret = -1;
- goto out;
- }
- }
-
-out:
- /* If TD is inactive and IOC bit set to 1 then update int_mask */
- if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {
- *int_mask |= 0x01;
- }
- return ret;
-}
-
-static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
-{
- UHCIState *s = opaque;
- UHCI_QH qh;
- UHCI_TD td;
- uint32_t link;
- uint32_t old_td_ctrl;
- uint32_t val;
- int ret;
-
- link = s->async_qh;
- if (!link) {
- /* This should never happen. It means a TD somehow got removed
- without cancelling the associated async IO request. */
- return;
- }
- cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
- le32_to_cpus(&qh.link);
- le32_to_cpus(&qh.el_link);
- /* Re-process the queue containing the async packet. */
- while (1) {
- cpu_physical_memory_read(qh.el_link & ~0xf,
- (uint8_t *)&td, sizeof(td));
- le32_to_cpus(&td.link);
- le32_to_cpus(&td.ctrl);
- le32_to_cpus(&td.token);
- le32_to_cpus(&td.buffer);
- old_td_ctrl = td.ctrl;
- ret = uhci_handle_td(s, &td, &s->pending_int_mask);
- /* update the status bits of the TD */
- if (old_td_ctrl != td.ctrl) {
- val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- }
- if (ret < 0)
- break; /* interrupted frame */
- if (ret == 2) {
- s->async_qh = link;
- break;
- } else if (ret == 0) {
- /* update qh element link */
- qh.el_link = td.link;
- val = cpu_to_le32(qh.el_link);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- if (!(qh.el_link & 4))
- break;
- }
- break;
- }
-}
-
-static void uhci_frame_timer(void *opaque)
-{
- UHCIState *s = opaque;
- int64_t expire_time;
- uint32_t frame_addr, link, old_td_ctrl, val;
- int int_mask, cnt, ret;
- UHCI_TD td;
- UHCI_QH qh;
- uint32_t old_async_qh;
-
- if (!(s->cmd & UHCI_CMD_RS)) {
- qemu_del_timer(s->frame_timer);
- /* set hchalted bit in status - UHCI11D 2.1.2 */
- s->status |= UHCI_STS_HCHALTED;
- return;
- }
- /* Complete the previous frame. */
- s->frnum = (s->frnum + 1) & 0x7ff;
- if (s->pending_int_mask) {
- s->status2 |= s->pending_int_mask;
- s->status |= UHCI_STS_USBINT;
- uhci_update_irq(s);
- }
- old_async_qh = s->async_qh;
- frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
- cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
- le32_to_cpus(&link);
- int_mask = 0;
- cnt = FRAME_MAX_LOOPS;
- while ((link & 1) == 0) {
- if (--cnt == 0)
- break;
- /* valid frame */
- if (link & 2) {
- /* QH */
- if (link == s->async_qh) {
- /* We've found a previously issues packet.
- Nothing else to do. */
- old_async_qh = 0;
- break;
- }
- cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
- le32_to_cpus(&qh.link);
- le32_to_cpus(&qh.el_link);
- depth_first:
- if (qh.el_link & 1) {
- /* no element : go to next entry */
- link = qh.link;
- } else if (qh.el_link & 2) {
- /* QH */
- link = qh.el_link;
- } else if (s->async_qh) {
- /* We can only cope with one pending packet. Keep looking
- for the previously issued packet. */
- link = qh.link;
- } else {
- /* TD */
- if (--cnt == 0)
- break;
- cpu_physical_memory_read(qh.el_link & ~0xf,
- (uint8_t *)&td, sizeof(td));
- le32_to_cpus(&td.link);
- le32_to_cpus(&td.ctrl);
- le32_to_cpus(&td.token);
- le32_to_cpus(&td.buffer);
- old_td_ctrl = td.ctrl;
- ret = uhci_handle_td(s, &td, &int_mask);
- /* update the status bits of the TD */
- if (old_td_ctrl != td.ctrl) {
- val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- }
- if (ret < 0)
- break; /* interrupted frame */
- if (ret == 2) {
- s->async_qh = link;
- } else if (ret == 0) {
- /* update qh element link */
- qh.el_link = td.link;
- val = cpu_to_le32(qh.el_link);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- if (qh.el_link & 4) {
- /* depth first */
- goto depth_first;
- }
- }
- /* go to next entry */
- link = qh.link;
- }
- } else {
- /* TD */
- cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
- le32_to_cpus(&td.link);
- le32_to_cpus(&td.ctrl);
- le32_to_cpus(&td.token);
- le32_to_cpus(&td.buffer);
- /* Ignore isochonous transfers while there is an async packet
- pending. This is wrong, but we don't implement isochronous
- transfers anyway. */
- if (s->async_qh == 0) {
- old_td_ctrl = td.ctrl;
- ret = uhci_handle_td(s, &td, &int_mask);
- /* update the status bits of the TD */
- if (old_td_ctrl != td.ctrl) {
- val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- }
- if (ret < 0)
- break; /* interrupted frame */
- if (ret == 2) {
- /* We can't handle async isochronous transfers.
- Cancel The packet. */
- fprintf(stderr, "usb-uhci: Unimplemented async packet\n");
- usb_cancel_packet(&s->usb_packet);
- }
- }
- link = td.link;
- }
- }
- s->pending_int_mask = int_mask;
- if (old_async_qh) {
- /* A previously started transfer has disappeared from the transfer
- list. There's nothing useful we can do with it now, so just
- discard the packet and hope it wasn't too important. */
-#ifdef DEBUG
- printf("Discarding USB packet\n");
-#endif
- usb_cancel_packet(&s->usb_packet);
- s->async_qh = 0;
- }
- /* prepare the timer for the next frame */
- expire_time = qemu_get_clock(vm_clock) +
- (ticks_per_sec / FRAME_TIMER_FREQ);
- qemu_mod_timer(s->frame_timer, expire_time);
-}
-
-static void uhci_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- UHCIState *s = (UHCIState *)pci_dev;
-
- register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
- register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
- register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
- register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
- register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
- register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
-}
-
-void uhci_usb_save(QEMUFile *f, void *opaque)
-{
- int i;
- UHCIState *s = (UHCIState*)opaque;
-
- pci_device_save(&s->dev, f);
-
- qemu_put_be16s(f, &s->cmd);
- qemu_put_be16s(f, &s->status);
- qemu_put_be16s(f, &s->intr);
- qemu_put_be16s(f, &s->frnum);
- qemu_put_be32s(f, &s->fl_base_addr);
- qemu_put_8s(f, &s->sof_timing);
- qemu_put_8s(f, &s->status2);
-
- for(i = 0; i < NB_PORTS; i++) {
- qemu_put_be16s(f, &s->ports[i].ctrl);
- }
-
- qemu_put_timer(f, s->frame_timer);
-}
-
-int uhci_usb_load(QEMUFile *f, void *opaque, int version_id)
-{
- int i;
- UHCIState *s = (UHCIState*)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- i = pci_device_load(&s->dev, f);
- if (i < 0)
- return i;
-
- qemu_get_be16s(f, &s->cmd);
- qemu_get_be16s(f, &s->status);
- qemu_get_be16s(f, &s->intr);
- qemu_get_be16s(f, &s->frnum);
- qemu_get_be32s(f, &s->fl_base_addr);
- qemu_get_8s(f, &s->sof_timing);
- qemu_get_8s(f, &s->status2);
-
- for(i = 0; i < NB_PORTS; i++) {
- qemu_get_be16s(f, &s->ports[i].ctrl);
- }
-
- qemu_get_timer(f, s->frame_timer);
-
- return 0;
-}
-
-void usb_uhci_init(PCIBus *bus, int devfn)
-{
- UHCIState *s;
- uint8_t *pci_conf;
- int i;
-
- s = (UHCIState *)pci_register_device(bus,
- "USB-UHCI", sizeof(UHCIState),
- devfn, NULL, NULL);
- pci_conf = s->dev.config;
- pci_conf[0x00] = 0x86;
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x20;
- pci_conf[0x03] = 0x70;
- pci_conf[0x08] = 0x01; // revision number
- pci_conf[0x09] = 0x00;
- pci_conf[0x0a] = 0x03;
- pci_conf[0x0b] = 0x0c;
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x3d] = 4; // interrupt pin 3
- pci_conf[0x60] = 0x10; // release number
- pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
- pci_conf[0x2d] = pci_conf[0x01];
-
- for(i = 0; i < NB_PORTS; i++) {
- qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
- }
- s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
-
- uhci_reset(s);
-
- /* Use region 4 for consistency with real hardware. BSD guests seem
- to rely on this. */
- pci_register_io_region(&s->dev, 4, 0x20,
- PCI_ADDRESS_SPACE_IO, uhci_map);
-
- register_savevm("UHCI usb controller", 0, 1, uhci_usb_save, uhci_usb_load, s);
-}
diff --git a/tools/ioemu/hw/usb.c b/tools/ioemu/hw/usb.c
deleted file mode 100644
index 4400ee6c34..0000000000
--- a/tools/ioemu/hw/usb.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * QEMU USB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-void usb_attach(USBPort *port, USBDevice *dev)
-{
- port->attach(port, dev);
-}
-
-/**********************/
-/* generic USB device helpers (you are not forced to use them when
- writing your USB device driver, but they help handling the
- protocol)
-*/
-
-#define SETUP_STATE_IDLE 0
-#define SETUP_STATE_DATA 1
-#define SETUP_STATE_ACK 2
-
-int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
-{
- int l, ret = 0;
- int len = p->len;
- uint8_t *data = p->data;
-
- switch(p->pid) {
- case USB_MSG_ATTACH:
- s->state = USB_STATE_ATTACHED;
- break;
- case USB_MSG_DETACH:
- s->state = USB_STATE_NOTATTACHED;
- break;
- case USB_MSG_RESET:
- s->remote_wakeup = 0;
- s->addr = 0;
- s->state = USB_STATE_DEFAULT;
- s->handle_reset(s);
- break;
- case USB_TOKEN_SETUP:
- if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
- return USB_RET_NODEV;
- if (len != 8)
- goto fail;
- memcpy(s->setup_buf, data, 8);
- s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
- s->setup_index = 0;
- if (s->setup_buf[0] & USB_DIR_IN) {
- ret = s->handle_control(s,
- (s->setup_buf[0] << 8) | s->setup_buf[1],
- (s->setup_buf[3] << 8) | s->setup_buf[2],
- (s->setup_buf[5] << 8) | s->setup_buf[4],
- s->setup_len,
- s->data_buf);
- if (ret < 0)
- return ret;
- if (ret < s->setup_len)
- s->setup_len = ret;
- s->setup_state = SETUP_STATE_DATA;
- } else {
- if (s->setup_len == 0)
- s->setup_state = SETUP_STATE_ACK;
- else
- s->setup_state = SETUP_STATE_DATA;
- }
- break;
- case USB_TOKEN_IN:
- if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
- return USB_RET_NODEV;
- switch(p->devep) {
- case 0:
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- s->setup_state = SETUP_STATE_IDLE;
- ret = s->handle_control(s,
- (s->setup_buf[0] << 8) | s->setup_buf[1],
- (s->setup_buf[3] << 8) | s->setup_buf[2],
- (s->setup_buf[5] << 8) | s->setup_buf[4],
- s->setup_len,
- s->data_buf);
- if (ret > 0)
- ret = 0;
- } else {
- /* return 0 byte */
- }
- break;
- case SETUP_STATE_DATA:
- if (s->setup_buf[0] & USB_DIR_IN) {
- l = s->setup_len - s->setup_index;
- if (l > len)
- l = len;
- memcpy(data, s->data_buf + s->setup_index, l);
- s->setup_index += l;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- ret = l;
- } else {
- s->setup_state = SETUP_STATE_IDLE;
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- default:
- ret = s->handle_data(s, p);
- break;
- }
- break;
- case USB_TOKEN_OUT:
- if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
- return USB_RET_NODEV;
- switch(p->devep) {
- case 0:
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (s->setup_buf[0] & USB_DIR_IN) {
- s->setup_state = SETUP_STATE_IDLE;
- /* transfer OK */
- } else {
- /* ignore additionnal output */
- }
- break;
- case SETUP_STATE_DATA:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- l = s->setup_len - s->setup_index;
- if (l > len)
- l = len;
- memcpy(s->data_buf + s->setup_index, data, l);
- s->setup_index += l;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- ret = l;
- } else {
- s->setup_state = SETUP_STATE_IDLE;
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- default:
- ret = s->handle_data(s, p);
- break;
- }
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-/* XXX: fix overflow */
-int set_usb_string(uint8_t *buf, const char *str)
-{
- int len, i;
- uint8_t *q;
-
- q = buf;
- len = strlen(str);
- *q++ = 2 * len + 2;
- *q++ = 3;
- for(i = 0; i < len; i++) {
- *q++ = str[i];
- *q++ = 0;
- }
- return q - buf;
-}
-
-/* Send an internal message to a USB device. */
-void usb_send_msg(USBDevice *dev, int msg)
-{
- USBPacket p;
- memset(&p, 0, sizeof(p));
- p.pid = msg;
- dev->handle_packet(dev, &p);
-}
-
-void generic_usb_save(QEMUFile* f, void *opaque)
-{
- USBDevice *s = (USBDevice*)opaque;
-
- qemu_put_be32s(f, &s->speed);
- qemu_put_8s(f, &s->addr);
- qemu_put_be32s(f, &s->state);
-
- qemu_put_buffer(f, s->setup_buf, 8);
- qemu_put_buffer(f, s->data_buf, 1024);
-
- qemu_put_be32s(f, &s->remote_wakeup);
- qemu_put_be32s(f, &s->setup_state);
- qemu_put_be32s(f, &s->setup_len);
- qemu_put_be32s(f, &s->setup_index);
-
-}
-
-int generic_usb_load(QEMUFile* f, void *opaque, int version_id)
-{
- USBDevice *s = (USBDevice*)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->speed);
- qemu_get_8s(f, &s->addr);
- qemu_get_be32s(f, &s->state);
-
- qemu_get_buffer(f, s->setup_buf, 8);
- qemu_get_buffer(f, s->data_buf, 1024);
-
- qemu_get_be32s(f, &s->remote_wakeup);
- qemu_get_be32s(f, &s->setup_state);
- qemu_get_be32s(f, &s->setup_len);
- qemu_get_be32s(f, &s->setup_index);
-
- return 0;
-}
diff --git a/tools/ioemu/hw/usb.h b/tools/ioemu/hw/usb.h
deleted file mode 100644
index f866e5fa80..0000000000
--- a/tools/ioemu/hw/usb.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * QEMU USB API
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define USB_TOKEN_SETUP 0x2d
-#define USB_TOKEN_IN 0x69 /* device -> host */
-#define USB_TOKEN_OUT 0xe1 /* host -> device */
-
-/* specific usb messages, also sent in the 'pid' parameter */
-#define USB_MSG_ATTACH 0x100
-#define USB_MSG_DETACH 0x101
-#define USB_MSG_RESET 0x102
-
-#define USB_RET_NODEV (-1)
-#define USB_RET_NAK (-2)
-#define USB_RET_STALL (-3)
-#define USB_RET_BABBLE (-4)
-#define USB_RET_ASYNC (-5)
-
-#define USB_SPEED_LOW 0
-#define USB_SPEED_FULL 1
-#define USB_SPEED_HIGH 2
-
-#define USB_STATE_NOTATTACHED 0
-#define USB_STATE_ATTACHED 1
-//#define USB_STATE_POWERED 2
-#define USB_STATE_DEFAULT 3
-//#define USB_STATE_ADDRESS 4
-//#define USB_STATE_CONFIGURED 5
-#define USB_STATE_SUSPENDED 6
-
-#define USB_CLASS_AUDIO 1
-#define USB_CLASS_COMM 2
-#define USB_CLASS_HID 3
-#define USB_CLASS_PHYSICAL 5
-#define USB_CLASS_STILL_IMAGE 6
-#define USB_CLASS_PRINTER 7
-#define USB_CLASS_MASS_STORAGE 8
-#define USB_CLASS_HUB 9
-#define USB_CLASS_CDC_DATA 0x0a
-#define USB_CLASS_CSCID 0x0b
-#define USB_CLASS_CONTENT_SEC 0x0d
-#define USB_CLASS_APP_SPEC 0xfe
-#define USB_CLASS_VENDOR_SPEC 0xff
-
-#define USB_DIR_OUT 0
-#define USB_DIR_IN 0x80
-
-#define USB_TYPE_MASK (0x03 << 5)
-#define USB_TYPE_STANDARD (0x00 << 5)
-#define USB_TYPE_CLASS (0x01 << 5)
-#define USB_TYPE_VENDOR (0x02 << 5)
-#define USB_TYPE_RESERVED (0x03 << 5)
-
-#define USB_RECIP_MASK 0x1f
-#define USB_RECIP_DEVICE 0x00
-#define USB_RECIP_INTERFACE 0x01
-#define USB_RECIP_ENDPOINT 0x02
-#define USB_RECIP_OTHER 0x03
-
-#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define InterfaceRequest \
- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define InterfaceOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-#define EndpointOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-
-#define USB_REQ_GET_STATUS 0x00
-#define USB_REQ_CLEAR_FEATURE 0x01
-#define USB_REQ_SET_FEATURE 0x03
-#define USB_REQ_SET_ADDRESS 0x05
-#define USB_REQ_GET_DESCRIPTOR 0x06
-#define USB_REQ_SET_DESCRIPTOR 0x07
-#define USB_REQ_GET_CONFIGURATION 0x08
-#define USB_REQ_SET_CONFIGURATION 0x09
-#define USB_REQ_GET_INTERFACE 0x0A
-#define USB_REQ_SET_INTERFACE 0x0B
-#define USB_REQ_SYNCH_FRAME 0x0C
-
-#define USB_DEVICE_SELF_POWERED 0
-#define USB_DEVICE_REMOTE_WAKEUP 1
-
-#define USB_DT_DEVICE 0x01
-#define USB_DT_CONFIG 0x02
-#define USB_DT_STRING 0x03
-#define USB_DT_INTERFACE 0x04
-#define USB_DT_ENDPOINT 0x05
-
-typedef struct USBPort USBPort;
-typedef struct USBDevice USBDevice;
-typedef struct USBPacket USBPacket;
-
-/* definition of a USB device */
-struct USBDevice {
- void *opaque;
- int (*handle_packet)(USBDevice *dev, USBPacket *p);
- void (*handle_destroy)(USBDevice *dev);
-
- int speed;
-
- /* The following fields are used by the generic USB device
- layer. They are here just to avoid creating a new structure for
- them. */
- void (*handle_reset)(USBDevice *dev);
- int (*handle_control)(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data);
- int (*handle_data)(USBDevice *dev, USBPacket *p);
- uint8_t addr;
- char devname[32];
-
- int state;
- uint8_t setup_buf[8];
- uint8_t data_buf[1024];
- int remote_wakeup;
- int setup_state;
- int setup_len;
- int setup_index;
-};
-
-typedef void (*usb_attachfn)(USBPort *port, USBDevice *dev);
-
-/* USB port on which a device can be connected */
-struct USBPort {
- USBDevice *dev;
- usb_attachfn attach;
- void *opaque;
- int index; /* internal port index, may be used with the opaque */
- struct USBPort *next; /* Used internally by qemu. */
-};
-
-typedef void USBCallback(USBPacket * packet, void *opaque);
-
-/* Structure used to hold information about an active USB packet. */
-struct USBPacket {
- /* Data fields for use by the driver. */
- int pid;
- uint8_t devaddr;
- uint8_t devep;
- uint8_t *data;
- int len;
- /* Internal use by the USB layer. */
- USBCallback *complete_cb;
- void *complete_opaque;
- USBCallback *cancel_cb;
- void * *cancel_opaque;
-};
-
-/* Defer completion of a USB packet. The hadle_packet routine should then
- return USB_RET_ASYNC. Packets that complete immediately (before
- handle_packet returns) should not call this method. */
-static inline void usb_defer_packet(USBPacket *p, USBCallback *cancel,
- void * opaque)
-{
- p->cancel_cb = cancel;
- p->cancel_opaque = opaque;
-}
-
-/* Notify the controller that an async packet is complete. This should only
- be called for packets previously deferred with usb_defer_packet, and
- should never be called from within handle_packet. */
-static inline void usb_packet_complete(USBPacket *p)
-{
- p->complete_cb(p, p->complete_opaque);
-}
-
-/* Cancel an active packet. The packed must have been deferred with
- usb_defer_packet, and not yet completed. */
-static inline void usb_cancel_packet(USBPacket * p)
-{
- p->cancel_cb(p, p->cancel_opaque);
-}
-
-void usb_attach(USBPort *port, USBDevice *dev);
-int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
-int set_usb_string(uint8_t *buf, const char *str);
-void usb_send_msg(USBDevice *dev, int msg);
-
-void usb_packet_complete(USBPacket *p);
-
-/* usb hub */
-USBDevice *usb_hub_init(int nb_ports);
-
-/* usb-uhci.c */
-void usb_uhci_init(PCIBus *bus, int devfn);
-
-/* usb-ohci.c */
-void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn);
-
-/* usb-linux.c */
-USBDevice *usb_host_device_open(const char *devname);
-void usb_host_info(void);
-
-/* usb-hid.c */
-USBDevice *usb_mouse_init(void);
-USBDevice *usb_tablet_init(void);
-
-/* usb-msd.c */
-USBDevice *usb_msd_init(const char *filename, BlockDriver *drv);
-
-/* usb.c */
-void generic_usb_save(QEMUFile* f, void *opaque);
-int generic_usb_load(QEMUFile* f, void *opaque, int version_id);
-
-
diff --git a/tools/ioemu/hw/versatile_pci.c b/tools/ioemu/hw/versatile_pci.c
deleted file mode 100644
index 32854c2f94..0000000000
--- a/tools/ioemu/hw/versatile_pci.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * ARM Versatile/PB PCI host controller
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- */
-
-#include "vl.h"
-
-static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
-{
- return addr & 0xffffff;
-}
-
-static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1);
-}
-
-static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2);
-}
-
-static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4);
-}
-
-static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
- val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1);
- return val;
-}
-
-static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
- val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr)
-{
- uint32_t val;
- val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_vpb_config_write[] = {
- &pci_vpb_config_writeb,
- &pci_vpb_config_writew,
- &pci_vpb_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_vpb_config_read[] = {
- &pci_vpb_config_readb,
- &pci_vpb_config_readw,
- &pci_vpb_config_readl,
-};
-
-static int pci_vpb_irq;
-
-static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
-{
- return irq_num;
-}
-
-static void pci_vpb_set_irq(void *pic, int irq_num, int level)
-{
- pic_set_irq_new(pic, pci_vpb_irq + irq_num, level);
-}
-
-PCIBus *pci_vpb_init(void *pic, int irq, int realview)
-{
- PCIBus *s;
- PCIDevice *d;
- int mem_config;
- uint32_t base;
- const char * name;
-
- pci_vpb_irq = irq;
- if (realview) {
- base = 0x60000000;
- name = "RealView EB PCI Controller";
- } else {
- base = 0x40000000;
- name = "Versatile/PB PCI Controller";
- }
- s = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, pic, 11 << 3, 4);
- /* ??? Register memory space. */
-
- mem_config = cpu_register_io_memory(0, pci_vpb_config_read,
- pci_vpb_config_write, s);
- /* Selfconfig area. */
- cpu_register_physical_memory(base + 0x01000000, 0x1000000, mem_config);
- /* Normal config area. */
- cpu_register_physical_memory(base + 0x02000000, 0x1000000, mem_config);
-
- d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL);
-
- if (realview) {
- /* IO memory area. */
- isa_mmio_init(base + 0x03000000, 0x00100000);
- }
-
- d->config[0x00] = 0xee; // vendor_id
- d->config[0x01] = 0x10;
- /* Both boards have the same device ID. Oh well. */
- d->config[0x02] = 0x00; // device_id
- d->config[0x03] = 0x03;
- d->config[0x04] = 0x00;
- d->config[0x05] = 0x00;
- d->config[0x06] = 0x20;
- d->config[0x07] = 0x02;
- d->config[0x08] = 0x00; // revision
- d->config[0x09] = 0x00; // programming i/f
- d->config[0x0A] = 0x40; // class_sub = pci host
- d->config[0x0B] = 0x0b; // class_base = PCI_bridge
- d->config[0x0D] = 0x10; // latency_timer
-
- return s;
-}
-
diff --git a/tools/ioemu/hw/versatilepb.c b/tools/ioemu/hw/versatilepb.c
deleted file mode 100644
index bc42472ade..0000000000
--- a/tools/ioemu/hw/versatilepb.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * ARM Versatile Platform/Application Baseboard System emulation.
- *
- * Copyright (c) 2005-2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "vl.h"
-#include "arm_pic.h"
-
-/* Primary interrupt controller. */
-
-typedef struct vpb_sic_state
-{
- arm_pic_handler handler;
- uint32_t base;
- uint32_t level;
- uint32_t mask;
- uint32_t pic_enable;
- void *parent;
- int irq;
-} vpb_sic_state;
-
-static void vpb_sic_update(vpb_sic_state *s)
-{
- uint32_t flags;
-
- flags = s->level & s->mask;
- pic_set_irq_new(s->parent, s->irq, flags != 0);
-}
-
-static void vpb_sic_update_pic(vpb_sic_state *s)
-{
- int i;
- uint32_t mask;
-
- for (i = 21; i <= 30; i++) {
- mask = 1u << i;
- if (!(s->pic_enable & mask))
- continue;
- pic_set_irq_new(s->parent, i, (s->level & mask) != 0);
- }
-}
-
-static void vpb_sic_set_irq(void *opaque, int irq, int level)
-{
- vpb_sic_state *s = (vpb_sic_state *)opaque;
- if (level)
- s->level |= 1u << irq;
- else
- s->level &= ~(1u << irq);
- if (s->pic_enable & (1u << irq))
- pic_set_irq_new(s->parent, irq, level);
- vpb_sic_update(s);
-}
-
-static uint32_t vpb_sic_read(void *opaque, target_phys_addr_t offset)
-{
- vpb_sic_state *s = (vpb_sic_state *)opaque;
-
- offset -= s->base;
- switch (offset >> 2) {
- case 0: /* STATUS */
- return s->level & s->mask;
- case 1: /* RAWSTAT */
- return s->level;
- case 2: /* ENABLE */
- return s->mask;
- case 4: /* SOFTINT */
- return s->level & 1;
- case 8: /* PICENABLE */
- return s->pic_enable;
- default:
- printf ("vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static void vpb_sic_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- vpb_sic_state *s = (vpb_sic_state *)opaque;
- offset -= s->base;
-
- switch (offset >> 2) {
- case 2: /* ENSET */
- s->mask |= value;
- break;
- case 3: /* ENCLR */
- s->mask &= ~value;
- break;
- case 4: /* SOFTINTSET */
- if (value)
- s->mask |= 1;
- break;
- case 5: /* SOFTINTCLR */
- if (value)
- s->mask &= ~1u;
- break;
- case 8: /* PICENSET */
- s->pic_enable |= (value & 0x7fe00000);
- vpb_sic_update_pic(s);
- break;
- case 9: /* PICENCLR */
- s->pic_enable &= ~value;
- vpb_sic_update_pic(s);
- break;
- default:
- printf ("vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
- return;
- }
- vpb_sic_update(s);
-}
-
-static CPUReadMemoryFunc *vpb_sic_readfn[] = {
- vpb_sic_read,
- vpb_sic_read,
- vpb_sic_read
-};
-
-static CPUWriteMemoryFunc *vpb_sic_writefn[] = {
- vpb_sic_write,
- vpb_sic_write,
- vpb_sic_write
-};
-
-static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
-{
- vpb_sic_state *s;
- int iomemtype;
-
- s = (vpb_sic_state *)qemu_mallocz(sizeof(vpb_sic_state));
- if (!s)
- return NULL;
- s->handler = vpb_sic_set_irq;
- s->base = base;
- s->parent = parent;
- s->irq = irq;
- iomemtype = cpu_register_io_memory(0, vpb_sic_readfn,
- vpb_sic_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- /* ??? Save/restore. */
- return s;
-}
-
-/* Board init. */
-
-/* The AB and PB boards both use the same core, just with different
- peripherans and expansion busses. For now we emulate a subset of the
- PB peripherals and just change the board ID. */
-
-static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, int board_id)
-{
- CPUState *env;
- void *pic;
- void *sic;
- void *scsi_hba;
- PCIBus *pci_bus;
- NICInfo *nd;
- int n;
- int done_smc = 0;
-
- env = cpu_init();
- cpu_arm_set_model(env, ARM_CPUID_ARM926);
- /* ??? RAM shoud repeat to fill physical memory space. */
- /* SDRAM at address zero. */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- arm_sysctl_init(0x10000000, 0x41007004);
- pic = arm_pic_init_cpu(env);
- pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
- sic = vpb_sic_init(0x10003000, pic, 31);
- pl050_init(0x10006000, sic, 3, 0);
- pl050_init(0x10007000, sic, 4, 1);
-
- pci_bus = pci_vpb_init(sic, 27, 0);
- /* The Versatile PCI bridge does not provide access to PCI IO space,
- so many of the qemu PCI devices are not useable. */
- for(n = 0; n < nb_nics; n++) {
- nd = &nd_table[n];
- if (!nd->model)
- nd->model = done_smc ? "rtl8139" : "smc91c111";
- if (strcmp(nd->model, "smc91c111") == 0) {
- smc91c111_init(nd, 0x10010000, sic, 25);
- } else {
- pci_nic_init(pci_bus, nd, -1);
- }
- }
- if (usb_enabled) {
- usb_ohci_init(pci_bus, 3, -1);
- }
- scsi_hba = lsi_scsi_init(pci_bus, -1);
- for (n = 0; n < MAX_DISKS; n++) {
- if (bs_table[n]) {
- lsi_scsi_attach(scsi_hba, bs_table[n], n);
- }
- }
-
- pl011_init(0x101f1000, pic, 12, serial_hds[0]);
- pl011_init(0x101f2000, pic, 13, serial_hds[1]);
- pl011_init(0x101f3000, pic, 14, serial_hds[2]);
- pl011_init(0x10009000, sic, 6, serial_hds[3]);
-
- pl080_init(0x10130000, pic, 17, 8);
- sp804_init(0x101e2000, pic, 4);
- sp804_init(0x101e3000, pic, 5);
-
- /* The versatile/PB actually has a modified Color LCD controller
- that includes hardware cursor support from the PL111. */
- pl110_init(ds, 0x10120000, pic, 16, 1);
-
- /* Memory map for Versatile/PB: */
- /* 0x10000000 System registers. */
- /* 0x10001000 PCI controller config registers. */
- /* 0x10002000 Serial bus interface. */
- /* 0x10003000 Secondary interrupt controller. */
- /* 0x10004000 AACI (audio). */
- /* 0x10005000 MMCI0. */
- /* 0x10006000 KMI0 (keyboard). */
- /* 0x10007000 KMI1 (mouse). */
- /* 0x10008000 Character LCD Interface. */
- /* 0x10009000 UART3. */
- /* 0x1000a000 Smart card 1. */
- /* 0x1000b000 MMCI1. */
- /* 0x10010000 Ethernet. */
- /* 0x10020000 USB. */
- /* 0x10100000 SSMC. */
- /* 0x10110000 MPMC. */
- /* 0x10120000 CLCD Controller. */
- /* 0x10130000 DMA Controller. */
- /* 0x10140000 Vectored interrupt controller. */
- /* 0x101d0000 AHB Monitor Interface. */
- /* 0x101e0000 System Controller. */
- /* 0x101e1000 Watchdog Interface. */
- /* 0x101e2000 Timer 0/1. */
- /* 0x101e3000 Timer 2/3. */
- /* 0x101e4000 GPIO port 0. */
- /* 0x101e5000 GPIO port 1. */
- /* 0x101e6000 GPIO port 2. */
- /* 0x101e7000 GPIO port 3. */
- /* 0x101e8000 RTC. */
- /* 0x101f0000 Smart card 0. */
- /* 0x101f1000 UART0. */
- /* 0x101f2000 UART1. */
- /* 0x101f3000 UART2. */
- /* 0x101f4000 SSPI. */
-
- arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
- initrd_filename, board_id);
-}
-
-static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- versatile_init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline,
- initrd_filename, 0x183);
-}
-
-static void vab_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- versatile_init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline,
- initrd_filename, 0x25e);
-}
-
-QEMUMachine versatilepb_machine = {
- "versatilepb",
- "ARM Versatile/PB (ARM926EJ-S)",
- vpb_init,
-};
-
-QEMUMachine versatileab_machine = {
- "versatileab",
- "ARM Versatile/AB (ARM926EJ-S)",
- vab_init,
-};
diff --git a/tools/ioemu/hw/vga.c b/tools/ioemu/hw/vga.c
deleted file mode 100644
index 86fbef858e..0000000000
--- a/tools/ioemu/hw/vga.c
+++ /dev/null
@@ -1,2351 +0,0 @@
-/*
- * QEMU VGA Emulator.
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "vga_int.h"
-#include <sys/mman.h>
-
-//#define DEBUG_VGA
-//#define DEBUG_VGA_MEM
-//#define DEBUG_VGA_REG
-
-//#define DEBUG_BOCHS_VBE
-
-/* force some bits to zero */
-const uint8_t sr_mask[8] = {
- (uint8_t)~0xfc,
- (uint8_t)~0xc2,
- (uint8_t)~0xf0,
- (uint8_t)~0xc0,
- (uint8_t)~0xf1,
- (uint8_t)~0xff,
- (uint8_t)~0xff,
- (uint8_t)~0x00,
-};
-
-const uint8_t gr_mask[16] = {
- (uint8_t)~0xf0, /* 0x00 */
- (uint8_t)~0xf0, /* 0x01 */
- (uint8_t)~0xf0, /* 0x02 */
- (uint8_t)~0xe0, /* 0x03 */
- (uint8_t)~0xfc, /* 0x04 */
- (uint8_t)~0x84, /* 0x05 */
- (uint8_t)~0xf0, /* 0x06 */
- (uint8_t)~0xf0, /* 0x07 */
- (uint8_t)~0x00, /* 0x08 */
- (uint8_t)~0xff, /* 0x09 */
- (uint8_t)~0xff, /* 0x0a */
- (uint8_t)~0xff, /* 0x0b */
- (uint8_t)~0xff, /* 0x0c */
- (uint8_t)~0xff, /* 0x0d */
- (uint8_t)~0xff, /* 0x0e */
- (uint8_t)~0xff, /* 0x0f */
-};
-
-#define cbswap_32(__x) \
-((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef WORDS_BIGENDIAN
-#define PAT(x) cbswap_32(x)
-#else
-#define PAT(x) (x)
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define BIG 1
-#else
-#define BIG 0
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
-#else
-#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
-#endif
-
-static const uint32_t mask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-#undef PAT
-
-#ifdef WORDS_BIGENDIAN
-#define PAT(x) (x)
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static const uint32_t dmask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
- PAT(0x00000000),
- PAT(0x0000ffff),
- PAT(0xffff0000),
- PAT(0xffffffff),
-};
-
-static uint32_t expand4[256];
-static uint16_t expand2[256];
-static uint8_t expand4to8[16];
-
-static void vga_screen_dump(void *opaque, const char *filename);
-
-static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
-{
- VGAState *s = opaque;
- int val, index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
- (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION))) {
- val = 0xff;
- } else {
- switch(addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val = s->ar_index;
- } else {
- val = 0;
- }
- break;
- case 0x3c1:
- index = s->ar_index & 0x1f;
- if (index < 21)
- val = s->ar[index];
- else
- val = 0;
- break;
- case 0x3c2:
- val = s->st00;
- break;
- case 0x3c4:
- val = s->sr_index;
- break;
- case 0x3c5:
- val = s->sr[s->sr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- break;
- case 0x3c7:
- val = s->dac_state;
- break;
- case 0x3c8:
- val = s->dac_write_index;
- break;
- case 0x3c9:
- val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
- }
- break;
- case 0x3ca:
- val = s->fcr;
- break;
- case 0x3cc:
- val = s->msr;
- break;
- case 0x3ce:
- val = s->gr_index;
- break;
- case 0x3cf:
- val = s->gr[s->gr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- break;
- case 0x3b4:
- case 0x3d4:
- val = s->cr_index;
- break;
- case 0x3b5:
- case 0x3d5:
- val = s->cr[s->cr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- break;
- case 0x3ba:
- case 0x3da:
- /* just toggle to fool polling */
- s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
- val = s->st01;
- s->ar_flip_flop = 0;
- break;
- default:
- val = 0x00;
- break;
- }
- }
-#if defined(DEBUG_VGA)
- printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- VGAState *s = opaque;
- int index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
- (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION)))
- return;
-
-#ifdef DEBUG_VGA
- printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
-#endif
-
- switch(addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val &= 0x3f;
- s->ar_index = val;
- } else {
- index = s->ar_index & 0x1f;
- switch(index) {
- case 0x00 ... 0x0f:
- s->ar[index] = val & 0x3f;
- break;
- case 0x10:
- s->ar[index] = val & ~0x10;
- break;
- case 0x11:
- s->ar[index] = val;
- break;
- case 0x12:
- s->ar[index] = val & ~0xc0;
- break;
- case 0x13:
- s->ar[index] = val & ~0xf0;
- break;
- case 0x14:
- s->ar[index] = val & ~0xf0;
- break;
- default:
- break;
- }
- }
- s->ar_flip_flop ^= 1;
- break;
- case 0x3c2:
- s->msr = val & ~0x10;
- break;
- case 0x3c4:
- s->sr_index = val & 7;
- break;
- case 0x3c5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- s->sr[s->sr_index] = val & sr_mask[s->sr_index];
- break;
- case 0x3c7:
- s->dac_read_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 3;
- break;
- case 0x3c8:
- s->dac_write_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 0;
- break;
- case 0x3c9:
- s->dac_cache[s->dac_sub_index] = val;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
- s->dac_sub_index = 0;
- s->dac_write_index++;
- }
- break;
- case 0x3ce:
- s->gr_index = val & 0x0f;
- break;
- case 0x3cf:
-#ifdef DEBUG_VGA_REG
- printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- s->gr[s->gr_index] = val & gr_mask[s->gr_index];
- break;
- case 0x3b4:
- case 0x3d4:
- s->cr_index = val;
- break;
- case 0x3b5:
- case 0x3d5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- /* handle CR0-7 protection */
- if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
- /* can always write bit 4 of CR7 */
- if (s->cr_index == 7)
- s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
- return;
- }
- switch(s->cr_index) {
- case 0x01: /* horizontal display end */
- case 0x07:
- case 0x09:
- case 0x0c:
- case 0x0d:
- case 0x12: /* veritcal display end */
- s->cr[s->cr_index] = val;
- break;
- default:
- s->cr[s->cr_index] = val;
- break;
- }
- break;
- case 0x3ba:
- case 0x3da:
- s->fcr = val & 0x10;
- break;
- }
-}
-
-#ifdef CONFIG_BOCHS_VBE
-static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
-{
- VGAState *s = opaque;
- uint32_t val;
- val = s->vbe_index;
- return val;
-}
-
-static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
-{
- VGAState *s = opaque;
- uint32_t val;
-
- if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
- switch(s->vbe_index) {
- /* XXX: do not hardcode ? */
- case VBE_DISPI_INDEX_XRES:
- val = VBE_DISPI_MAX_XRES;
- break;
- case VBE_DISPI_INDEX_YRES:
- val = VBE_DISPI_MAX_YRES;
- break;
- case VBE_DISPI_INDEX_BPP:
- val = VBE_DISPI_MAX_BPP;
- break;
- default:
- val = s->vbe_regs[s->vbe_index];
- break;
- }
- } else {
- val = s->vbe_regs[s->vbe_index];
- }
- } else {
- val = 0;
- }
-#ifdef DEBUG_BOCHS_VBE
- printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
-#endif
- return val;
-}
-
-static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
-{
- VGAState *s = opaque;
- s->vbe_index = val;
-}
-
-static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
-{
- VGAState *s = opaque;
-
- if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
-#ifdef DEBUG_BOCHS_VBE
- printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
-#endif
- switch(s->vbe_index) {
- case VBE_DISPI_INDEX_ID:
- if (val == VBE_DISPI_ID0 ||
- val == VBE_DISPI_ID1 ||
- val == VBE_DISPI_ID2 ||
- val == VBE_DISPI_ID3 ||
- val == VBE_DISPI_ID4) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_XRES:
- if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_YRES:
- if (val <= VBE_DISPI_MAX_YRES) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_BPP:
- if (val == 0)
- val = 8;
- if (val == 4 || val == 8 || val == 15 ||
- val == 16 || val == 24 || val == 32) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_BANK:
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
- val &= (s->vbe_bank_mask >> 2);
- } else {
- val &= s->vbe_bank_mask;
- }
- s->vbe_regs[s->vbe_index] = val;
- s->bank_offset = (val << 16);
- break;
- case VBE_DISPI_INDEX_ENABLE:
- if ((val & VBE_DISPI_ENABLED) &&
- !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
- int h, shift_control;
-
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
- s->vbe_regs[VBE_DISPI_INDEX_XRES];
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
- s->vbe_regs[VBE_DISPI_INDEX_YRES];
- s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
-
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
- else
- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
- ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
- s->vbe_start_addr = 0;
-
- /* clear the screen (should be done in BIOS) */
- if (!(val & VBE_DISPI_NOCLEARMEM)) {
- memset(s->vram_ptr, 0,
- s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
- }
-
- /* we initialize the VGA graphic mode (should be done
- in BIOS) */
- s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
- s->cr[0x17] |= 3; /* no CGA modes */
- s->cr[0x13] = s->vbe_line_offset >> 3;
- /* width */
- s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
- /* height (only meaningful if < 1024) */
- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
- s->cr[0x12] = h;
- s->cr[0x07] = (s->cr[0x07] & ~0x42) |
- ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
- /* line compare to 1023 */
- s->cr[0x18] = 0xff;
- s->cr[0x07] |= 0x10;
- s->cr[0x09] |= 0x40;
-
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
- shift_control = 0;
- s->sr[0x01] &= ~8; /* no double line */
- } else {
- shift_control = 2;
- s->sr[4] |= 0x08; /* set chain 4 mode */
- s->sr[2] |= 0x0f; /* activate all planes */
- }
- s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
- s->cr[0x09] &= ~0x9f; /* no double scan */
- } else {
- /* XXX: the bios should do that */
- s->bank_offset = 0;
- }
- s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
- s->vbe_regs[s->vbe_index] = val;
- break;
- case VBE_DISPI_INDEX_VIRT_WIDTH:
- {
- int w, h, line_offset;
-
- if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
- return;
- w = val;
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
- line_offset = w >> 1;
- else
- line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
- h = s->vram_size / line_offset;
- /* XXX: support weird bochs semantics ? */
- if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
- return;
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
- s->vbe_line_offset = line_offset;
- }
- break;
- case VBE_DISPI_INDEX_X_OFFSET:
- case VBE_DISPI_INDEX_Y_OFFSET:
- {
- int x;
- s->vbe_regs[s->vbe_index] = val;
- s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
- x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
- s->vbe_start_addr += x >> 1;
- else
- s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
- s->vbe_start_addr >>= 2;
- }
- break;
- default:
- break;
- }
- }
-}
-#endif
-
-/* called for accesses between 0xa0000 and 0xc0000 */
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- VGAState *s = opaque;
- int memory_map_mode, plane;
- uint32_t ret;
-
- /* convert to VGA memory offset */
- memory_map_mode = (s->gr[6] >> 2) & 3;
- addr &= 0x1ffff;
- switch(memory_map_mode) {
- case 0:
- break;
- case 1:
- if (addr >= 0x10000)
- return 0xff;
- addr += s->bank_offset;
- break;
- case 2:
- addr -= 0x10000;
- if (addr >= 0x8000)
- return 0xff;
- break;
- default:
- case 3:
- addr -= 0x18000;
- if (addr >= 0x8000)
- return 0xff;
- break;
- }
-
- if (s->sr[4] & 0x08) {
- /* chain 4 mode : simplest access */
- ret = s->vram_ptr[addr];
- } else if (s->gr[5] & 0x10) {
- /* odd/even mode (aka text mode mapping) */
- plane = (s->gr[4] & 2) | (addr & 1);
- ret = s->vram_ptr[((addr & ~1) << 1) | plane];
- } else {
- /* standard VGA latched access */
- s->latch = ((uint32_t *)s->vram_ptr)[addr];
-
- if (!(s->gr[5] & 0x08)) {
- /* read mode 0 */
- plane = s->gr[4];
- ret = GET_PLANE(s->latch, plane);
- } else {
- /* read mode 1 */
- ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
- ret |= ret >> 16;
- ret |= ret >> 8;
- ret = (~ret) & 0xff;
- }
- }
- return ret;
-}
-
-static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = vga_mem_readb(opaque, addr) << 8;
- v |= vga_mem_readb(opaque, addr + 1);
-#else
- v = vga_mem_readb(opaque, addr);
- v |= vga_mem_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = vga_mem_readb(opaque, addr) << 24;
- v |= vga_mem_readb(opaque, addr + 1) << 16;
- v |= vga_mem_readb(opaque, addr + 2) << 8;
- v |= vga_mem_readb(opaque, addr + 3);
-#else
- v = vga_mem_readb(opaque, addr);
- v |= vga_mem_readb(opaque, addr + 1) << 8;
- v |= vga_mem_readb(opaque, addr + 2) << 16;
- v |= vga_mem_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-/* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- VGAState *s = opaque;
- int memory_map_mode, plane, write_mode, b, func_select, mask;
- uint32_t write_mask, bit_mask, set_mask;
-
-#ifdef DEBUG_VGA_MEM
- printf("vga: [0x%x] = 0x%02x\n", addr, val);
-#endif
- /* convert to VGA memory offset */
- memory_map_mode = (s->gr[6] >> 2) & 3;
- addr &= 0x1ffff;
- switch(memory_map_mode) {
- case 0:
- break;
- case 1:
- if (addr >= 0x10000)
- return;
- addr += s->bank_offset;
- break;
- case 2:
- addr -= 0x10000;
- if (addr >= 0x8000)
- return;
- break;
- default:
- case 3:
- addr -= 0x18000;
- if (addr >= 0x8000)
- return;
- break;
- }
-
- if (s->sr[4] & 0x08) {
- /* chain 4 mode : simplest access */
- plane = addr & 3;
- mask = (1 << plane);
- if (s->sr[2] & mask) {
- s->vram_ptr[addr] = val;
-#ifdef DEBUG_VGA_MEM
- printf("vga: chain4: [0x%x]\n", addr);
-#endif
- s->plane_updated |= mask; /* only used to detect font change */
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
- }
- } else if (s->gr[5] & 0x10) {
- /* odd/even mode (aka text mode mapping) */
- plane = (s->gr[4] & 2) | (addr & 1);
- mask = (1 << plane);
- if (s->sr[2] & mask) {
- addr = ((addr & ~1) << 1) | plane;
- s->vram_ptr[addr] = val;
-#ifdef DEBUG_VGA_MEM
- printf("vga: odd/even: [0x%x]\n", addr);
-#endif
- s->plane_updated |= mask; /* only used to detect font change */
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
- }
- } else {
- /* standard VGA latched access */
- write_mode = s->gr[5] & 3;
- switch(write_mode) {
- default:
- case 0:
- /* rotate */
- b = s->gr[3] & 7;
- val = ((val >> b) | (val << (8 - b))) & 0xff;
- val |= val << 8;
- val |= val << 16;
-
- /* apply set/reset mask */
- set_mask = mask16[s->gr[1]];
- val = (val & ~set_mask) | (mask16[s->gr[0]] & set_mask);
- bit_mask = s->gr[8];
- break;
- case 1:
- val = s->latch;
- goto do_write;
- case 2:
- val = mask16[val & 0x0f];
- bit_mask = s->gr[8];
- break;
- case 3:
- /* rotate */
- b = s->gr[3] & 7;
- val = (val >> b) | (val << (8 - b));
-
- bit_mask = s->gr[8] & val;
- val = mask16[s->gr[0]];
- break;
- }
-
- /* apply logical operation */
- func_select = s->gr[3] >> 3;
- switch(func_select) {
- case 0:
- default:
- /* nothing to do */
- break;
- case 1:
- /* and */
- val &= s->latch;
- break;
- case 2:
- /* or */
- val |= s->latch;
- break;
- case 3:
- /* xor */
- val ^= s->latch;
- break;
- }
-
- /* apply bit mask */
- bit_mask |= bit_mask << 8;
- bit_mask |= bit_mask << 16;
- val = (val & bit_mask) | (s->latch & ~bit_mask);
-
- do_write:
- /* mask data according to sr[2] */
- mask = s->sr[2];
- s->plane_updated |= mask; /* only used to detect font change */
- write_mask = mask16[mask];
- ((uint32_t *)s->vram_ptr)[addr] =
- (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
- (val & write_mask);
-#ifdef DEBUG_VGA_MEM
- printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
- addr * 4, write_mask, val);
-#endif
- cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
- }
-}
-
-static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
- vga_mem_writeb(opaque, addr + 1, val & 0xff);
-#else
- vga_mem_writeb(opaque, addr, val & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- vga_mem_writeb(opaque, addr + 3, val & 0xff);
-#else
- vga_mem_writeb(opaque, addr, val & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol);
-typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol, int dup9);
-typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width);
-
-static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-}
-
-static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
-{
- return (r << 16) | (g << 8) | b;
-}
-
-static inline unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g, unsigned b)
-{
- return (b << 16) | (g << 8) | r;
-}
-
-#define DEPTH 8
-#include "vga_template.h"
-
-#define DEPTH 15
-#include "vga_template.h"
-
-#define DEPTH 16
-#include "vga_template.h"
-
-#define DEPTH 32
-#include "vga_template.h"
-
-#define BGR_FORMAT
-#define DEPTH 32
-#include "vga_template.h"
-
-static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel8(r, g, b);
- col |= col << 8;
- col |= col << 16;
- return col;
-}
-
-static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel15(r, g, b);
- col |= col << 16;
- return col;
-}
-
-static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel16(r, g, b);
- col |= col << 16;
- return col;
-}
-
-static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel32(r, g, b);
- return col;
-}
-
-static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel32bgr(r, g, b);
- return col;
-}
-
-/* return true if the palette was modified */
-static int update_palette16(VGAState *s)
-{
- int full_update, i;
- uint32_t v, col, *palette;
-
- full_update = 0;
- palette = s->last_palette;
- for(i = 0; i < 16; i++) {
- v = s->ar[i];
- if (s->ar[0x10] & 0x80)
- v = ((s->ar[0x14] & 0xf) << 4) | (v & 0xf);
- else
- v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);
- v = v * 3;
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
- if (col != palette[i]) {
- full_update = 1;
- palette[i] = col;
- }
- }
- return full_update;
-}
-
-/* return true if the palette was modified */
-static int update_palette256(VGAState *s)
-{
- int full_update, i;
- uint32_t v, col, *palette;
-
- full_update = 0;
- palette = s->last_palette;
- v = 0;
- for(i = 0; i < 256; i++) {
- if (s->dac_8bit) {
- col = s->rgb_to_pixel(s->palette[v],
- s->palette[v + 1],
- s->palette[v + 2]);
- } else {
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
- }
- if (col != palette[i]) {
- full_update = 1;
- palette[i] = col;
- }
- v += 3;
- }
- return full_update;
-}
-
-static void vga_get_offsets(VGAState *s,
- uint32_t *pline_offset,
- uint32_t *pstart_addr,
- uint32_t *pline_compare)
-{
- uint32_t start_addr, line_offset, line_compare;
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- line_offset = s->vbe_line_offset;
- start_addr = s->vbe_start_addr;
- line_compare = 65535;
- } else
-#endif
- {
- /* compute line_offset in bytes */
- line_offset = s->cr[0x13];
- line_offset <<= 3;
-
- /* starting address */
- start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
-
- /* line compare */
- line_compare = s->cr[0x18] |
- ((s->cr[0x07] & 0x10) << 4) |
- ((s->cr[0x09] & 0x40) << 3);
- }
- *pline_offset = line_offset;
- *pstart_addr = start_addr;
- *pline_compare = line_compare;
-}
-
-/* update start_addr and line_offset. Return TRUE if modified */
-static int update_basic_params(VGAState *s)
-{
- int full_update;
- uint32_t start_addr, line_offset, line_compare;
-
- full_update = 0;
-
- s->get_offsets(s, &line_offset, &start_addr, &line_compare);
-
- if (line_offset != s->line_offset ||
- start_addr != s->start_addr ||
- line_compare != s->line_compare) {
- s->line_offset = line_offset;
- s->start_addr = start_addr;
- s->line_compare = line_compare;
- full_update = 1;
- }
- return full_update;
-}
-
-#define NB_DEPTHS 5
-
-static inline int get_depth_index(DisplayState *s)
-{
- switch(s->depth) {
- default:
- case 8:
- return 0;
- case 15:
- return 1;
- case 16:
- return 2;
- case 32:
- if (s->bgr)
- return 4;
- else
- return 3;
- }
-}
-
-static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = {
- vga_draw_glyph8_8,
- vga_draw_glyph8_16,
- vga_draw_glyph8_16,
- vga_draw_glyph8_32,
- vga_draw_glyph8_32,
-};
-
-static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {
- vga_draw_glyph16_8,
- vga_draw_glyph16_16,
- vga_draw_glyph16_16,
- vga_draw_glyph16_32,
- vga_draw_glyph16_32,
-};
-
-static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = {
- vga_draw_glyph9_8,
- vga_draw_glyph9_16,
- vga_draw_glyph9_16,
- vga_draw_glyph9_32,
- vga_draw_glyph9_32,
-};
-
-static const uint8_t cursor_glyph[32 * 4] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
-
-static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS];
-
-/*
- * Text mode update
- * Missing:
- * - double scan
- * - double width
- * - underline
- * - flashing
- */
-static void vga_draw_text(VGAState *s, int full_update)
-{
- int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
- int cx_min, cx_max, linesize, x_incr;
- uint32_t offset, fgcol, bgcol, v, cursor_offset;
- uint8_t *d1, *d, *src, *s1, *dest, *cursor_ptr;
- const uint8_t *font_ptr, *font_base[2];
- int dup9, line_offset, depth_index;
- uint32_t *palette;
- uint32_t *ch_attr_ptr;
- vga_draw_glyph8_func *vga_draw_glyph8;
- vga_draw_glyph9_func *vga_draw_glyph9;
-
- /* Disable dirty bit tracking */
- xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
-
- /* total width & height */
- cheight = (s->cr[9] & 0x1f) + 1;
- cw = 8;
- if (!(s->sr[1] & 0x01))
- cw = 9;
- if (s->sr[1] & 0x08)
- cw = 16; /* NOTE: no 18 pixel wide */
- width = (s->cr[0x01] + 1);
- if (s->cr[0x06] == 100) {
- /* ugly hack for CGA 160x100x16 - explain me the logic */
- height = 100;
- } else {
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
- height = (height + 1) / cheight;
- }
- if ((height * width) > CH_ATTR_SIZE) {
- /* better than nothing: exit if transient size is too big */
- return;
- }
-
- s->last_scr_width = width * cw;
- s->last_scr_height = height * cheight;
- if (width != s->last_width || height != s->last_height ||
- cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
- dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
- s->last_depth = 0;
- full_update = 1;
- }
- s->last_width = width;
- s->last_height = height;
- s->last_ch = cheight;
- s->last_cw = cw;
-
- s->rgb_to_pixel =
- rgb_to_pixel_dup_table[get_depth_index(s->ds)];
-
- full_update |= update_palette16(s);
- palette = s->last_palette;
-
- x_incr = cw * ((s->ds->depth + 7) >> 3);
- /* compute font data address (in plane 2) */
- v = s->sr[3];
- offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
- if (offset != s->font_offsets[0]) {
- s->font_offsets[0] = offset;
- full_update = 1;
- }
- font_base[0] = s->vram_ptr + offset;
-
- offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
- font_base[1] = s->vram_ptr + offset;
- if (offset != s->font_offsets[1]) {
- s->font_offsets[1] = offset;
- full_update = 1;
- }
- if (s->plane_updated & (1 << 2)) {
- /* if the plane 2 was modified since the last display, it
- indicates the font may have been modified */
- s->plane_updated = 0;
- full_update = 1;
- }
- full_update |= update_basic_params(s);
-
- line_offset = s->line_offset;
- s1 = s->vram_ptr + (s->start_addr * 4);
-
- cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
- if (cursor_offset != s->cursor_offset ||
- s->cr[0xa] != s->cursor_start ||
- s->cr[0xb] != s->cursor_end) {
- /* if the cursor position changed, we update the old and new
- chars */
- if (s->cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[s->cursor_offset] = -1;
- if (cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[cursor_offset] = -1;
- s->cursor_offset = cursor_offset;
- s->cursor_start = s->cr[0xa];
- s->cursor_end = s->cr[0xb];
- }
- cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
-
- depth_index = get_depth_index(s->ds);
- if (cw == 16)
- vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
- else
- vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
- vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
-
- dest = s->ds->data;
- linesize = s->ds->linesize;
- ch_attr_ptr = s->last_ch_attr;
- for(cy = 0; cy < height; cy++) {
- d1 = dest;
- src = s1;
- cx_min = width;
- cx_max = -1;
- for(cx = 0; cx < width; cx++) {
- ch_attr = *(uint16_t *)src;
- if (full_update || ch_attr != *ch_attr_ptr) {
- if (cx < cx_min)
- cx_min = cx;
- if (cx > cx_max)
- cx_max = cx;
- *ch_attr_ptr = ch_attr;
-#ifdef WORDS_BIGENDIAN
- ch = ch_attr >> 8;
- cattr = ch_attr & 0xff;
-#else
- ch = ch_attr & 0xff;
- cattr = ch_attr >> 8;
-#endif
- font_ptr = font_base[(cattr >> 3) & 1];
- font_ptr += 32 * 4 * ch;
- bgcol = palette[cattr >> 4];
- fgcol = palette[cattr & 0x0f];
- if (cw != 9) {
- vga_draw_glyph8(d1, linesize,
- font_ptr, cheight, fgcol, bgcol);
- } else {
- dup9 = 0;
- if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))
- dup9 = 1;
- vga_draw_glyph9(d1, linesize,
- font_ptr, cheight, fgcol, bgcol, dup9);
- }
- if (src == cursor_ptr &&
- !(s->cr[0x0a] & 0x20)) {
- int line_start, line_last, h;
- /* draw the cursor */
- line_start = s->cr[0x0a] & 0x1f;
- line_last = s->cr[0x0b] & 0x1f;
- /* XXX: check that */
- if (line_last > cheight - 1)
- line_last = cheight - 1;
- if (line_last >= line_start && line_start < cheight) {
- h = line_last - line_start + 1;
- d = d1 + linesize * line_start;
- if (cw != 9) {
- vga_draw_glyph8(d, linesize,
- cursor_glyph, h, fgcol, bgcol);
- } else {
- vga_draw_glyph9(d, linesize,
- cursor_glyph, h, fgcol, bgcol, 1);
- }
- }
- }
- }
- d1 += x_incr;
- src += 4;
- ch_attr_ptr++;
- }
- if (cx_max != -1) {
- dpy_update(s->ds, cx_min * cw, cy * cheight,
- (cx_max - cx_min + 1) * cw, cheight);
- }
- dest += linesize * cheight;
- s1 += line_offset;
- }
-}
-
-enum {
- VGA_DRAW_LINE2,
- VGA_DRAW_LINE2D2,
- VGA_DRAW_LINE4,
- VGA_DRAW_LINE4D2,
- VGA_DRAW_LINE8D2,
- VGA_DRAW_LINE8,
- VGA_DRAW_LINE15,
- VGA_DRAW_LINE16,
- VGA_DRAW_LINE24,
- VGA_DRAW_LINE32,
- VGA_DRAW_LINE_NB,
-};
-
-static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
- vga_draw_line2_8,
- vga_draw_line2_16,
- vga_draw_line2_16,
- vga_draw_line2_32,
- vga_draw_line2_32,
-
- vga_draw_line2d2_8,
- vga_draw_line2d2_16,
- vga_draw_line2d2_16,
- vga_draw_line2d2_32,
- vga_draw_line2d2_32,
-
- vga_draw_line4_8,
- vga_draw_line4_16,
- vga_draw_line4_16,
- vga_draw_line4_32,
- vga_draw_line4_32,
-
- vga_draw_line4d2_8,
- vga_draw_line4d2_16,
- vga_draw_line4d2_16,
- vga_draw_line4d2_32,
- vga_draw_line4d2_32,
-
- vga_draw_line8d2_8,
- vga_draw_line8d2_16,
- vga_draw_line8d2_16,
- vga_draw_line8d2_32,
- vga_draw_line8d2_32,
-
- vga_draw_line8_8,
- vga_draw_line8_16,
- vga_draw_line8_16,
- vga_draw_line8_32,
- vga_draw_line8_32,
-
- vga_draw_line15_8,
- vga_draw_line15_15,
- vga_draw_line15_16,
- vga_draw_line15_32,
- vga_draw_line15_32bgr,
-
- vga_draw_line16_8,
- vga_draw_line16_15,
- vga_draw_line16_16,
- vga_draw_line16_32,
- vga_draw_line16_32bgr,
-
- vga_draw_line24_8,
- vga_draw_line24_15,
- vga_draw_line24_16,
- vga_draw_line24_32,
- vga_draw_line24_32bgr,
-
- vga_draw_line32_8,
- vga_draw_line32_15,
- vga_draw_line32_16,
- vga_draw_line32_32,
- vga_draw_line32_32bgr,
-};
-
-static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
- rgb_to_pixel8_dup,
- rgb_to_pixel15_dup,
- rgb_to_pixel16_dup,
- rgb_to_pixel32_dup,
- rgb_to_pixel32bgr_dup,
-};
-
-static int vga_get_bpp(VGAState *s)
-{
- int ret;
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
- } else
-#endif
- {
- ret = 0;
- }
- return ret;
-}
-
-static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
-{
- int width, height;
-
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
- height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
- } else
-#endif
- {
- width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
- height = (height + 1);
- }
- *pwidth = width;
- *pheight = height;
-}
-
-void vga_invalidate_scanlines(VGAState *s, int y1, int y2)
-{
- int y;
- if (y1 >= VGA_MAX_HEIGHT)
- return;
- if (y2 >= VGA_MAX_HEIGHT)
- y2 = VGA_MAX_HEIGHT;
- for(y = y1; y < y2; y++) {
- s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
- }
-}
-
-/*
- * graphic modes
- */
-static void vga_draw_graphic(VGAState *s, int full_update)
-{
- int y1, y, update, linesize, y_start, double_scan, mask, depth;
- int width, height, shift_control, line_offset, bwidth, ds_depth, bits;
- ram_addr_t page0, page1;
- int disp_width, multi_scan, multi_run;
- uint8_t *d;
- uint32_t v, addr1, addr;
- vga_draw_line_func *vga_draw_line;
- ram_addr_t page_min, page_max;
- unsigned long start, end;
-
- full_update |= update_basic_params(s);
-
- s->get_resolution(s, &width, &height);
- disp_width = width;
-
- shift_control = (s->gr[0x05] >> 5) & 3;
- double_scan = (s->cr[0x09] >> 7);
- if (shift_control != 1) {
- multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
- } else {
- /* in CGA modes, multi_scan is ignored */
- /* XXX: is it correct ? */
- multi_scan = double_scan;
- }
- multi_run = multi_scan;
- if (shift_control != s->shift_control ||
- double_scan != s->double_scan) {
- full_update = 1;
- s->shift_control = shift_control;
- s->double_scan = double_scan;
- }
- if (shift_control == 1 && (s->sr[0x01] & 8)) {
- disp_width <<= 1;
- }
-
- ds_depth = s->ds->depth;
- depth = s->get_bpp(s);
- if (s->ds->dpy_resize_shared) {
- if (s->line_offset != s->last_line_offset ||
- disp_width != s->last_width ||
- height != s->last_height ||
- s->last_depth != depth) {
- dpy_resize_shared(s->ds, disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4));
- s->last_scr_width = disp_width;
- s->last_scr_height = height;
- s->last_width = disp_width;
- s->last_height = height;
- s->last_line_offset = s->line_offset;
- s->last_depth = depth;
- full_update = 1;
- } else if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
- s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
- } else if (disp_width != s->last_width ||
- height != s->last_height) {
- dpy_resize(s->ds, disp_width, height);
- s->last_scr_width = disp_width;
- s->last_scr_height = height;
- s->last_width = disp_width;
- s->last_height = height;
- full_update = 1;
- }
-
- s->rgb_to_pixel =
- rgb_to_pixel_dup_table[get_depth_index(s->ds)];
-
- if (shift_control == 0) {
- full_update |= update_palette16(s);
- if (s->sr[0x01] & 8) {
- v = VGA_DRAW_LINE4D2;
- } else {
- v = VGA_DRAW_LINE4;
- }
- bits = 4;
- } else if (shift_control == 1) {
- full_update |= update_palette16(s);
- if (s->sr[0x01] & 8) {
- v = VGA_DRAW_LINE2D2;
- } else {
- v = VGA_DRAW_LINE2;
- }
- bits = 4;
- } else {
- switch(s->get_bpp(s)) {
- default:
- case 0:
- full_update |= update_palette256(s);
- v = VGA_DRAW_LINE8D2;
- bits = 4;
- break;
- case 8:
- full_update |= update_palette256(s);
- v = VGA_DRAW_LINE8;
- bits = 8;
- break;
- case 15:
- v = VGA_DRAW_LINE15;
- bits = 16;
- break;
- case 16:
- v = VGA_DRAW_LINE16;
- bits = 16;
- break;
- case 24:
- v = VGA_DRAW_LINE24;
- bits = 24;
- break;
- case 32:
- v = VGA_DRAW_LINE32;
- bits = 32;
- break;
- }
- }
-
- vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
- if (!s->ds->shared_buf && s->cursor_invalidate)
- s->cursor_invalidate(s);
-
- line_offset = s->line_offset;
-#if 0
- printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
- width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
-#endif
-
- if (s->lfb_addr) {
- if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3) {
- /* Tricky things happen, just track all video memory */
- start = 0;
- end = s->vram_size;
- } else {
- /* Tricky things won't have any effect, i.e. we are in the very simple
- * (and very usual) case of a linear buffer. */
- /* use page table dirty bit tracking for the LFB plus border */
- start = (s->start_addr * 4) & TARGET_PAGE_MASK;
- end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
- }
-
- for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
- /* We will not read that anyway. */
- cpu_physical_memory_set_dirty(s->vram_offset + y);
-
- {
- unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
- const int width = sizeof(unsigned long) * 8;
- unsigned long bitmap[(npages + width - 1) / width];
- int err;
-
- if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
- (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
- int i, j;
- for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
- unsigned long map = bitmap[i];
- for (j = i * width; map && j < npages; map >>= 1, j++)
- if (map & 1)
- cpu_physical_memory_set_dirty(s->vram_offset + y
- + j * TARGET_PAGE_SIZE);
- }
- y += npages * TARGET_PAGE_SIZE;
- } else {
- /* ENODATA just means we have changed mode and will succeed
- * next time */
- if (errno != ENODATA)
- fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d, %d)\n", s->lfb_addr + y, npages, err, errno);
- }
- }
-
- for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
- /* We will not read that anyway. */
- cpu_physical_memory_set_dirty(s->vram_offset + y);
- }
-
- addr1 = (s->start_addr * 4);
- bwidth = (width * bits + 7) / 8;
- y_start = -1;
- page_min = 0;
- page_max = 0;
- d = s->ds->data;
- linesize = s->ds->linesize;
- y1 = 0;
- for(y = 0; y < height; y++) {
- addr = addr1;
- if (!(s->cr[0x17] & 1)) {
- int shift;
- /* CGA compatibility handling */
- shift = 14 + ((s->cr[0x17] >> 6) & 1);
- addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
- }
- if (!(s->cr[0x17] & 2)) {
- addr = (addr & ~0x8000) | ((y1 & 2) << 14);
- }
- page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
- page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
- update = full_update |
- cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
- cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
- if ((page1 - page0) > TARGET_PAGE_SIZE) {
- /* if wide line, can use another page */
- update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
- VGA_DIRTY_FLAG);
- }
- /* explicit invalidation for the hardware cursor */
- update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
- if (update) {
- if (y_start < 0)
- y_start = y;
- if (page_min == 0 || page0 < page_min)
- page_min = page0;
- if (page_max == 0 || page1 > page_max)
- page_max = page1;
- if (!s->ds->shared_buf) {
- vga_draw_line(s, d, s->vram_ptr + addr, width);
- if (s->cursor_draw_line)
- s->cursor_draw_line(s, d, y);
- }
- } else {
- if (y_start >= 0) {
- /* flush to display */
- dpy_update(s->ds, 0, y_start,
- disp_width, y - y_start);
- y_start = -1;
- }
- }
- if (!multi_run) {
- mask = (s->cr[0x17] & 3) ^ 3;
- if ((y1 & mask) == mask)
- addr1 += line_offset;
- y1++;
- multi_run = multi_scan;
- } else {
- multi_run--;
- }
- /* line compare acts on the displayed lines */
- if (y == s->line_compare)
- addr1 = 0;
- d += linesize;
- }
- if (y_start >= 0) {
- /* flush to display */
- dpy_update(s->ds, 0, y_start,
- disp_width, y - y_start);
- }
- /* reset modified pages */
- if (page_max != -1) {
- cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
- VGA_DIRTY_FLAG);
- }
- memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
-}
-
-static void vga_draw_blank(VGAState *s, int full_update)
-{
- int i, w, val;
- uint8_t *d;
-
- if (!full_update)
- return;
- if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
- return;
-
- /* Disable dirty bit tracking */
- xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
-
- s->rgb_to_pixel =
- rgb_to_pixel_dup_table[get_depth_index(s->ds)];
- if (s->ds->depth == 8)
- val = s->rgb_to_pixel(0, 0, 0);
- else
- val = 0;
- w = s->last_scr_width * ((s->ds->depth + 7) >> 3);
- d = s->ds->data;
- for(i = 0; i < s->last_scr_height; i++) {
- memset(d, val, w);
- d += s->ds->linesize;
- }
- dpy_update(s->ds, 0, 0,
- s->last_scr_width, s->last_scr_height);
-}
-
-#define GMODE_TEXT 0
-#define GMODE_GRAPH 1
-#define GMODE_BLANK 2
-
-static void vga_update_display(void *opaque)
-{
- VGAState *s = (VGAState *)opaque;
- int full_update, graphic_mode;
-
- if (s->ds->depth == 0) {
- /* nothing to do */
- } else {
- full_update = 0;
- if (!(s->ar_index & 0x20)) {
- graphic_mode = GMODE_BLANK;
- } else {
- graphic_mode = s->gr[6] & 1;
- }
- if (graphic_mode != s->graphic_mode) {
- s->graphic_mode = graphic_mode;
- full_update = 1;
- }
- switch(graphic_mode) {
- case GMODE_TEXT:
- vga_draw_text(s, full_update);
- break;
- case GMODE_GRAPH:
- vga_draw_graphic(s, full_update);
- break;
- case GMODE_BLANK:
- default:
- vga_draw_blank(s, full_update);
- break;
- }
- }
-}
-
-/* force a full display refresh */
-static void vga_invalidate_display(void *opaque)
-{
- VGAState *s = (VGAState *)opaque;
-
- s->last_width = -1;
- s->last_height = -1;
-}
-
-static void vga_reset(VGAState *s)
-{
- memset(s, 0, sizeof(VGAState));
- s->graphic_mode = -1; /* force full update */
-}
-
-static CPUReadMemoryFunc *vga_mem_read[3] = {
- vga_mem_readb,
- vga_mem_readw,
- vga_mem_readl,
-};
-
-static CPUWriteMemoryFunc *vga_mem_write[3] = {
- vga_mem_writeb,
- vga_mem_writew,
- vga_mem_writel,
-};
-
-static void vga_save(QEMUFile *f, void *opaque)
-{
- VGAState *s = opaque;
- uint32_t vram_size;
-#ifdef CONFIG_BOCHS_VBE
- int i;
-#endif
-
- if (s->pci_dev)
- pci_device_save(s->pci_dev, f);
-
- qemu_put_be32s(f, &s->latch);
- qemu_put_8s(f, &s->sr_index);
- qemu_put_buffer(f, s->sr, 8);
- qemu_put_8s(f, &s->gr_index);
- qemu_put_buffer(f, s->gr, 16);
- qemu_put_8s(f, &s->ar_index);
- qemu_put_buffer(f, s->ar, 21);
- qemu_put_be32s(f, &s->ar_flip_flop);
- qemu_put_8s(f, &s->cr_index);
- qemu_put_buffer(f, s->cr, 256);
- qemu_put_8s(f, &s->msr);
- qemu_put_8s(f, &s->fcr);
- qemu_put_8s(f, &s->st00);
- qemu_put_8s(f, &s->st01);
-
- qemu_put_8s(f, &s->dac_state);
- qemu_put_8s(f, &s->dac_sub_index);
- qemu_put_8s(f, &s->dac_read_index);
- qemu_put_8s(f, &s->dac_write_index);
- qemu_put_buffer(f, s->dac_cache, 3);
- qemu_put_buffer(f, s->palette, 768);
-
- qemu_put_be32s(f, &s->bank_offset);
-#ifdef CONFIG_BOCHS_VBE
- qemu_put_byte(f, 1);
- qemu_put_be16s(f, &s->vbe_index);
- for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
- qemu_put_be16s(f, &s->vbe_regs[i]);
- qemu_put_be32s(f, &s->vbe_start_addr);
- qemu_put_be32s(f, &s->vbe_line_offset);
- qemu_put_be32s(f, &s->vbe_bank_mask);
-#else
- qemu_put_byte(f, 0);
-#endif
- vram_size = s->vram_size;
- qemu_put_be32s(f, &vram_size);
- qemu_put_be64s(f, &s->stolen_vram_addr);
- if (!s->stolen_vram_addr)
- /* Old guest: VRAM is not mapped, we have to save it ourselves */
- qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
-}
-
-static int vga_load(QEMUFile *f, void *opaque, int version_id)
-{
- VGAState *s = opaque;
- int is_vbe, ret;
- uint32_t vram_size;
-#ifdef CONFIG_BOCHS_VBE
- int i;
-#endif
-
- if (version_id > 4)
- return -EINVAL;
-
- if (s->pci_dev && version_id >= 2) {
- ret = pci_device_load(s->pci_dev, f);
- if (ret < 0)
- return ret;
- }
-
- qemu_get_be32s(f, &s->latch);
- qemu_get_8s(f, &s->sr_index);
- qemu_get_buffer(f, s->sr, 8);
- qemu_get_8s(f, &s->gr_index);
- qemu_get_buffer(f, s->gr, 16);
- qemu_get_8s(f, &s->ar_index);
- qemu_get_buffer(f, s->ar, 21);
- qemu_get_be32s(f, &s->ar_flip_flop);
- qemu_get_8s(f, &s->cr_index);
- qemu_get_buffer(f, s->cr, 256);
- qemu_get_8s(f, &s->msr);
- qemu_get_8s(f, &s->fcr);
- qemu_get_8s(f, &s->st00);
- qemu_get_8s(f, &s->st01);
-
- qemu_get_8s(f, &s->dac_state);
- qemu_get_8s(f, &s->dac_sub_index);
- qemu_get_8s(f, &s->dac_read_index);
- qemu_get_8s(f, &s->dac_write_index);
- qemu_get_buffer(f, s->dac_cache, 3);
- qemu_get_buffer(f, s->palette, 768);
-
- qemu_get_be32s(f, &s->bank_offset);
- is_vbe = qemu_get_byte(f);
-#ifdef CONFIG_BOCHS_VBE
- if (!is_vbe)
- return -EINVAL;
- qemu_get_be16s(f, &s->vbe_index);
- for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
- qemu_get_be16s(f, &s->vbe_regs[i]);
- qemu_get_be32s(f, &s->vbe_start_addr);
- qemu_get_be32s(f, &s->vbe_line_offset);
- qemu_get_be32s(f, &s->vbe_bank_mask);
-#else
- if (is_vbe)
- return -EINVAL;
-#endif
- if (version_id >= 3) {
- /* people who restore old images may be lucky ... */
- qemu_get_be32s(f, &vram_size);
- if (vram_size != s->vram_size)
- return -EINVAL;
- if (version_id >= 4) {
- qemu_get_be64s(f, &s->stolen_vram_addr);
- if (s->stolen_vram_addr)
- xen_vga_vram_map(s->stolen_vram_addr, 0);
- }
- /* Old guest, VRAM is not mapped, we have to restore it ourselves */
- if (!s->stolen_vram_addr)
- qemu_get_buffer(f, s->vram_ptr, s->vram_size);
- }
-
- /* force refresh */
- s->graphic_mode = -1;
- return 0;
-}
-
-typedef struct PCIVGAState {
- PCIDevice dev;
- VGAState vga_state;
-} PCIVGAState;
-
-static void vga_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIVGAState *d = (PCIVGAState *)pci_dev;
- VGAState *s = &d->vga_state;
- if (region_num == PCI_ROM_SLOT) {
- cpu_register_physical_memory(addr, s->bios_size, s->bios_offset);
- } else {
- cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
- }
-}
-
-/* do the same job as vgabios before vgabios get ready - yeah */
-void vga_bios_init(VGAState *s)
-{
- uint8_t palette_model[192] = {
- 0, 0, 0, 0, 0, 170, 0, 170,
- 0, 0, 170, 170, 170, 0, 0, 170,
- 0, 170, 170, 85, 0, 170, 170, 170,
- 85, 85, 85, 85, 85, 255, 85, 255,
- 85, 85, 255, 255, 255, 85, 85, 255,
- 85, 255, 255, 255, 85, 255, 255, 255,
- 0, 21, 0, 0, 21, 42, 0, 63,
- 0, 0, 63, 42, 42, 21, 0, 42,
- 21, 42, 42, 63, 0, 42, 63, 42,
- 0, 21, 21, 0, 21, 63, 0, 63,
- 21, 0, 63, 63, 42, 21, 21, 42,
- 21, 63, 42, 63, 21, 42, 63, 63,
- 21, 0, 0, 21, 0, 42, 21, 42,
- 0, 21, 42, 42, 63, 0, 0, 63,
- 0, 42, 63, 42, 0, 63, 42, 42,
- 21, 0, 21, 21, 0, 63, 21, 42,
- 21, 21, 42, 63, 63, 0, 21, 63,
- 0, 63, 63, 42, 21, 63, 42, 63,
- 21, 21, 0, 21, 21, 42, 21, 63,
- 0, 21, 63, 42, 63, 21, 0, 63,
- 21, 42, 63, 63, 0, 63, 63, 42,
- 21, 21, 21, 21, 21, 63, 21, 63,
- 21, 21, 63, 63, 63, 21, 21, 63,
- 21, 63, 63, 63, 21, 63, 63, 63
- };
-
- s->latch = 0;
-
- s->sr_index = 3;
- s->sr[0] = 3;
- s->sr[1] = 0;
- s->sr[2] = 3;
- s->sr[3] = 0;
- s->sr[4] = 2;
- s->sr[5] = 0;
- s->sr[6] = 0;
- s->sr[7] = 0;
-
- s->gr_index = 5;
- s->gr[0] = 0;
- s->gr[1] = 0;
- s->gr[2] = 0;
- s->gr[3] = 0;
- s->gr[4] = 0;
- s->gr[5] = 16;
- s->gr[6] = 14;
- s->gr[7] = 15;
- s->gr[8] = 255;
-
- /* changed by out 0x03c0 */
- s->ar_index = 32;
- s->ar[0] = 0;
- s->ar[1] = 1;
- s->ar[2] = 2;
- s->ar[3] = 3;
- s->ar[4] = 4;
- s->ar[5] = 5;
- s->ar[6] = 6;
- s->ar[7] = 7;
- s->ar[8] = 8;
- s->ar[9] = 9;
- s->ar[10] = 10;
- s->ar[11] = 11;
- s->ar[12] = 12;
- s->ar[13] = 13;
- s->ar[14] = 14;
- s->ar[15] = 15;
- s->ar[16] = 12;
- s->ar[17] = 0;
- s->ar[18] = 15;
- s->ar[19] = 8;
- s->ar[20] = 0;
-
- s->ar_flip_flop = 1;
-
- s->cr_index = 15;
- s->cr[0] = 95;
- s->cr[1] = 79;
- s->cr[2] = 80;
- s->cr[3] = 130;
- s->cr[4] = 85;
- s->cr[5] = 129;
- s->cr[6] = 191;
- s->cr[7] = 31;
- s->cr[8] = 0;
- s->cr[9] = 79;
- s->cr[10] = 14;
- s->cr[11] = 15;
- s->cr[12] = 0;
- s->cr[13] = 0;
- s->cr[14] = 5;
- s->cr[15] = 160;
- s->cr[16] = 156;
- s->cr[17] = 142;
- s->cr[18] = 143;
- s->cr[19] = 40;
- s->cr[20] = 31;
- s->cr[21] = 150;
- s->cr[22] = 185;
- s->cr[23] = 163;
- s->cr[24] = 255;
-
- s->msr = 103;
- s->fcr = 0;
- s->st00 = 0;
- s->st01 = 0;
-
- /* dac_* & palette will be initialized by os through out 0x03c8 &
- * out 0c03c9(1:3) */
- s->dac_state = 0;
- s->dac_sub_index = 0;
- s->dac_read_index = 0;
- s->dac_write_index = 16;
- s->dac_cache[0] = 255;
- s->dac_cache[1] = 255;
- s->dac_cache[2] = 255;
-
- /* palette */
- memcpy(s->palette, palette_model, 192);
-
- s->bank_offset = 0;
- s->graphic_mode = -1;
-
- /* TODO: add vbe support if enabled */
-}
-
-
-static VGAState *xen_vga_state;
-
-/* When loading old images we have to populate the video ram ourselves */
-void xen_vga_populate_vram(uint64_t vram_addr)
-{
- unsigned long nr_pfn;
- struct xen_remove_from_physmap xrfp;
- xen_pfn_t *pfn_list;
- int i;
- int rc;
-
- fprintf(logfile, "populating video RAM at %lx\n", vram_addr);
-
- nr_pfn = VGA_RAM_SIZE >> TARGET_PAGE_BITS;
-
- pfn_list = malloc(sizeof(*pfn_list) * nr_pfn);
-
- for (i = 0; i < nr_pfn; i++)
- pfn_list[i] = (vram_addr >> TARGET_PAGE_BITS) + i;
-
- if (xc_domain_memory_populate_physmap(xc_handle, domid, nr_pfn, 0, 0, pfn_list)) {
- fprintf(stderr, "Failed to populate video ram\n");
- exit(1);
- }
- free(pfn_list);
-
- xen_vga_vram_map(vram_addr, 0);
-
- /* Unmap them from the guest for now. */
- xrfp.domid = domid;
- for (i = 0; i < nr_pfn; i++) {
- xrfp.gpfn = (vram_addr >> TARGET_PAGE_BITS) + i;
- rc = xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp);
- if (rc) {
- fprintf(stderr, "remove_from_physmap PFN %"PRI_xen_pfn" failed: %d\n", xrfp.gpfn, rc);
- break;
- }
- }
-}
-
-/* Called once video memory has been allocated in the GPFN space */
-void xen_vga_vram_map(uint64_t vram_addr, int copy)
-{
- unsigned long nr_pfn;
- xen_pfn_t *pfn_list;
- int i;
- void *vram;
-
- fprintf(logfile, "mapping video RAM from %lx\n", vram_addr);
-
- nr_pfn = VGA_RAM_SIZE >> TARGET_PAGE_BITS;
-
- pfn_list = malloc(sizeof(*pfn_list) * nr_pfn);
-
- for (i = 0; i < nr_pfn; i++)
- pfn_list[i] = (vram_addr >> TARGET_PAGE_BITS) + i;
-
- vram = xc_map_foreign_pages(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- pfn_list, nr_pfn);
-
- if (!vram) {
- fprintf(stderr, "Failed to map vram\n");
- exit(1);
- }
-
- if (xc_domain_memory_translate_gpfn_list(xc_handle, domid, nr_pfn,
- pfn_list, pfn_list)) {
- fprintf(stderr, "Failed translation in xen_vga_vram_addr\n");
- exit(1);
- }
-
- if (copy)
- memcpy(vram, xen_vga_state->vram_ptr, VGA_RAM_SIZE);
- if (xen_vga_state->vram_mfns) {
- /* In case this function is called more than once */
- free(xen_vga_state->vram_mfns);
- munmap(xen_vga_state->vram_ptr, VGA_RAM_SIZE);
- } else {
- qemu_free(xen_vga_state->vram_ptr);
- }
- xen_vga_state->vram_ptr = vram;
- xen_vga_state->vram_mfns = pfn_list;
-#ifdef CONFIG_STUBDOM
- xenfb_pv_display_start(vram);
-#endif
-}
-
-/* Called at boot time when the BIOS has allocated video RAM */
-void xen_vga_stolen_vram_addr(uint64_t stolen_vram_addr)
-{
- fprintf(logfile, "stolen video RAM at %lx\n", stolen_vram_addr);
-
- xen_vga_state->stolen_vram_addr = stolen_vram_addr;
-
- /* And copy from the initialization value */
- xen_vga_vram_map(stolen_vram_addr, 1);
-}
-
-/* when used on xen environment, the vga_ram_base is not used */
-void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- int i, j, v, b;
-
- for(i = 0;i < 256; i++) {
- v = 0;
- for(j = 0; j < 8; j++) {
- v |= ((i >> j) & 1) << (j * 4);
- }
- expand4[i] = v;
-
- v = 0;
- for(j = 0; j < 4; j++) {
- v |= ((i >> (2 * j)) & 3) << (j * 4);
- }
- expand2[i] = v;
- }
- for(i = 0; i < 16; i++) {
- v = 0;
- for(j = 0; j < 4; j++) {
- b = ((i >> j) & 1);
- v |= b << (2 * j);
- v |= b << (2 * j + 1);
- }
- expand4to8[i] = v;
- }
-
- vga_reset(s);
-
- s->vram_ptr = qemu_malloc(vga_ram_size);
- s->vram_mfns = NULL;
- xen_vga_state = s;
-
- s->vram_offset = vga_ram_offset;
- s->vram_size = vga_ram_size;
- s->ds = ds;
- ds->palette = s->last_palette;
- s->get_bpp = vga_get_bpp;
- s->get_offsets = vga_get_offsets;
- s->get_resolution = vga_get_resolution;
- graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
- vga_screen_dump, s);
-
- vga_bios_init(s);
-}
-
-/* used by both ISA and PCI */
-static void vga_init(VGAState *s)
-{
- int vga_io_memory;
-
- register_savevm("vga", 0, 4, vga_save, vga_load, s);
-
- register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
-
- register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
- register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
- register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
- register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
- register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
- s->bank_offset = 0;
-
-#ifdef CONFIG_BOCHS_VBE
- s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
- s->vbe_bank_mask = ((s->vram_size >> 16) - 1);
-#if defined (TARGET_I386)
- register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s);
-
- register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s);
-
- /* old Bochs IO ports */
- register_ioport_read(0xff80, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
-
- register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
-#else
- register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
-
- register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s);
-#endif
-#endif /* CONFIG_BOCHS_VBE */
-
- vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- vga_io_memory);
-}
-
-int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- VGAState *s;
-
- s = qemu_mallocz(sizeof(VGAState));
- if (!s)
- return -1;
-
- vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
- vga_init(s);
-
-#ifdef CONFIG_BOCHS_VBE
- /* XXX: use optimized standard vga accesses */
- cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
- vga_ram_size, vga_ram_offset);
-#endif
- return 0;
-}
-
-int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size,
- unsigned long vga_bios_offset, int vga_bios_size)
-{
- PCIVGAState *d;
- VGAState *s;
- uint8_t *pci_conf;
-
- d = (PCIVGAState *)pci_register_device(bus, "VGA",
- sizeof(PCIVGAState),
- -1, NULL, NULL);
- if (!d)
- return -1;
- s = &d->vga_state;
-
- vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
- vga_init(s);
- s->pci_dev = &d->dev;
-
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
- pci_conf[0x01] = 0x12;
- pci_conf[0x02] = 0x11;
- pci_conf[0x03] = 0x11;
- pci_conf[0x0a] = 0x00; // VGA controller
- pci_conf[0x0b] = 0x03;
- pci_conf[0x0e] = 0x00; // header_type
-
- /* XXX: vga_ram_size must be a power of two */
- pci_register_io_region(&d->dev, 0, vga_ram_size,
- PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
- if (vga_bios_size != 0) {
- unsigned int bios_total_size;
- s->bios_offset = vga_bios_offset;
- s->bios_size = vga_bios_size;
- /* must be a power of two */
- bios_total_size = 1;
- while (bios_total_size < vga_bios_size)
- bios_total_size <<= 1;
- pci_register_io_region(&d->dev, PCI_ROM_SLOT, bios_total_size,
- PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
- }
- return 0;
-}
-
-/********************************************************/
-/* vga screen dump */
-
-static int vga_save_w, vga_save_h;
-
-static void vga_save_dpy_update(DisplayState *s,
- int x, int y, int w, int h)
-{
-}
-
-static void vga_save_dpy_resize(DisplayState *s, int w, int h)
-{
- s->linesize = w * 4;
- s->data = qemu_malloc(h * s->linesize);
- vga_save_w = w;
- vga_save_h = h;
-}
-
-static void vga_save_dpy_refresh(DisplayState *s)
-{
-}
-
-static int ppm_save(const char *filename, uint8_t *data,
- int w, int h, int linesize)
-{
- FILE *f;
- uint8_t *d, *d1;
- unsigned int v;
- int y, x;
-
- f = fopen(filename, "wb");
- if (!f)
- return -1;
- fprintf(f, "P6\n%d %d\n%d\n",
- w, h, 255);
- d1 = data;
- for(y = 0; y < h; y++) {
- d = d1;
- for(x = 0; x < w; x++) {
- v = *(uint32_t *)d;
- fputc((v >> 16) & 0xff, f);
- fputc((v >> 8) & 0xff, f);
- fputc((v) & 0xff, f);
- d += 4;
- }
- d1 += linesize;
- }
- fclose(f);
- return 0;
-}
-
-/* save the vga display in a PPM image even if no display is
- available */
-static void vga_screen_dump(void *opaque, const char *filename)
-{
- VGAState *s = (VGAState *)opaque;
- DisplayState *saved_ds, ds1, *ds = &ds1;
-
- /* XXX: this is a little hackish */
- vga_invalidate_display(s);
- saved_ds = s->ds;
-
- memset(ds, 0, sizeof(DisplayState));
- ds->dpy_update = vga_save_dpy_update;
- ds->dpy_resize = vga_save_dpy_resize;
- ds->dpy_refresh = vga_save_dpy_refresh;
- ds->depth = 32;
-
- s->ds = ds;
- s->graphic_mode = -1;
- vga_update_display(s);
-
- if (ds->data) {
- ppm_save(filename, ds->data, vga_save_w, vga_save_h,
- s->ds->linesize);
- qemu_free(ds->data);
- }
- s->ds = saved_ds;
-}
diff --git a/tools/ioemu/hw/vga_int.h b/tools/ioemu/hw/vga_int.h
deleted file mode 100644
index 7b2f33f067..0000000000
--- a/tools/ioemu/hw/vga_int.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * QEMU internal VGA defines.
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define MSR_COLOR_EMULATION 0x01
-#define MSR_PAGE_SELECT 0x20
-
-#define ST01_V_RETRACE 0x08
-#define ST01_DISP_ENABLE 0x01
-
-/* bochs VBE support */
-//#define CONFIG_BOCHS_VBE
-
-#define VBE_DISPI_MAX_XRES 1600
-#define VBE_DISPI_MAX_YRES 1200
-#define VBE_DISPI_MAX_BPP 32
-
-#define VBE_DISPI_INDEX_ID 0x0
-#define VBE_DISPI_INDEX_XRES 0x1
-#define VBE_DISPI_INDEX_YRES 0x2
-#define VBE_DISPI_INDEX_BPP 0x3
-#define VBE_DISPI_INDEX_ENABLE 0x4
-#define VBE_DISPI_INDEX_BANK 0x5
-#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
-#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
-#define VBE_DISPI_INDEX_X_OFFSET 0x8
-#define VBE_DISPI_INDEX_Y_OFFSET 0x9
-#define VBE_DISPI_INDEX_NB 0xa
-
-#define VBE_DISPI_ID0 0xB0C0
-#define VBE_DISPI_ID1 0xB0C1
-#define VBE_DISPI_ID2 0xB0C2
-#define VBE_DISPI_ID3 0xB0C3
-#define VBE_DISPI_ID4 0xB0C4
-
-#define VBE_DISPI_DISABLED 0x00
-#define VBE_DISPI_ENABLED 0x01
-#define VBE_DISPI_GETCAPS 0x02
-#define VBE_DISPI_8BIT_DAC 0x20
-#define VBE_DISPI_LFB_ENABLED 0x40
-#define VBE_DISPI_NOCLEARMEM 0x80
-
-#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
-
-#ifdef CONFIG_BOCHS_VBE
-
-#define VGA_STATE_COMMON_BOCHS_VBE \
- uint16_t vbe_index; \
- uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; \
- uint32_t vbe_start_addr; \
- uint32_t vbe_line_offset; \
- uint32_t vbe_bank_mask;
-
-#else
-
-#define VGA_STATE_COMMON_BOCHS_VBE
-
-#endif /* !CONFIG_BOCHS_VBE */
-
-#define CH_ATTR_SIZE (160 * 100)
-#define VGA_MAX_HEIGHT 2048
-
-#define VGA_STATE_COMMON \
- uint8_t *vram_ptr; \
- xen_pfn_t *vram_mfns; \
- uint64_t stolen_vram_addr; /* Address of stolen RAM */ \
- unsigned long vram_offset; \
- unsigned int vram_size; \
- unsigned long bios_offset; \
- unsigned int bios_size; \
- unsigned long lfb_addr; \
- unsigned long lfb_end; \
- PCIDevice *pci_dev; \
- uint32_t latch; \
- uint8_t sr_index; \
- uint8_t sr[256]; \
- uint8_t gr_index; \
- uint8_t gr[256]; \
- uint8_t ar_index; \
- uint8_t ar[21]; \
- int ar_flip_flop; \
- uint8_t cr_index; \
- uint8_t cr[256]; /* CRT registers */ \
- uint8_t msr; /* Misc Output Register */ \
- uint8_t fcr; /* Feature Control Register */ \
- uint8_t st00; /* status 0 */ \
- uint8_t st01; /* status 1 */ \
- uint8_t dac_state; \
- uint8_t dac_sub_index; \
- uint8_t dac_read_index; \
- uint8_t dac_write_index; \
- uint8_t dac_cache[3]; /* used when writing */ \
- int dac_8bit; \
- uint8_t palette[768]; \
- int32_t bank_offset; \
- int (*get_bpp)(struct VGAState *s); \
- void (*get_offsets)(struct VGAState *s, \
- uint32_t *pline_offset, \
- uint32_t *pstart_addr, \
- uint32_t *pline_compare); \
- void (*get_resolution)(struct VGAState *s, \
- int *pwidth, \
- int *pheight); \
- VGA_STATE_COMMON_BOCHS_VBE \
- /* display refresh support */ \
- DisplayState *ds; \
- uint32_t font_offsets[2]; \
- int graphic_mode; \
- uint8_t shift_control; \
- uint8_t double_scan; \
- uint32_t line_offset; \
- uint32_t line_compare; \
- uint32_t start_addr; \
- uint32_t plane_updated; \
- uint32_t last_line_offset; \
- uint8_t last_cw, last_ch; \
- uint32_t last_width, last_height; /* in chars or pixels */ \
- uint32_t last_scr_width, last_scr_height; /* in pixels */ \
- uint32_t last_depth; /* in bits */ \
- uint8_t cursor_start, cursor_end; \
- uint32_t cursor_offset; \
- unsigned int (*rgb_to_pixel)(unsigned int r, \
- unsigned int g, unsigned b); \
- /* hardware mouse cursor support */ \
- uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; \
- void (*cursor_invalidate)(struct VGAState *s); \
- void (*cursor_draw_line)(struct VGAState *s, uint8_t *d, int y); \
- /* tell for each page if it has been updated since the last time */ \
- uint32_t last_palette[256]; \
- uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */
-
-
-typedef struct VGAState {
- VGA_STATE_COMMON
-} VGAState;
-
-static inline int c6_to_8(int v)
-{
- int b;
- v &= 0x3f;
- b = v & 1;
- return (v << 2) | (b << 1) | b;
-}
-
-void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
-void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
-
-void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
- unsigned int color0, unsigned int color1,
- unsigned int color_xor);
-void vga_draw_cursor_line_16(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
- unsigned int color0, unsigned int color1,
- unsigned int color_xor);
-void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
- unsigned int color0, unsigned int color1,
- unsigned int color_xor);
-
-void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
-extern const uint8_t sr_mask[8];
-extern const uint8_t gr_mask[16];
diff --git a/tools/ioemu/hw/vga_template.h b/tools/ioemu/hw/vga_template.h
deleted file mode 100644
index e7e8cb853e..0000000000
--- a/tools/ioemu/hw/vga_template.h
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * QEMU VGA Emulator templates
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if DEPTH == 8
-#define BPP 1
-#define PIXEL_TYPE uint8_t
-#elif DEPTH == 15 || DEPTH == 16
-#define BPP 2
-#define PIXEL_TYPE uint16_t
-#elif DEPTH == 32
-#define BPP 4
-#define PIXEL_TYPE uint32_t
-#else
-#error unsupport depth
-#endif
-
-#ifdef BGR_FORMAT
-#define PIXEL_NAME glue(DEPTH, bgr)
-#else
-#define PIXEL_NAME DEPTH
-#endif /* BGR_FORMAT */
-
-#if DEPTH != 15 && !defined(BGR_FORMAT)
-
-static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
- uint32_t font_data,
- uint32_t xorcol,
- uint32_t bgcol)
-{
-#if BPP == 1
- ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
-#elif BPP == 2
- ((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;
- ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
-#else
- ((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;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
-#endif
-}
-
-static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
-{
- uint32_t font_data, xorcol;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
-{
- uint32_t font_data, xorcol;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- glue(vga_draw_glyph_line_, DEPTH)(d,
- expand4to8[font_data >> 4],
- xorcol, bgcol);
- glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
- expand4to8[font_data & 0x0f],
- xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol, int dup9)
-{
- uint32_t font_data, xorcol, v;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
-#if BPP == 1
- cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
- v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
- cpu_to_32wu(((uint32_t *)d)+1, v);
- if (dup9)
- ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
- else
- ((uint8_t *)d)[8] = bgcol;
-
-#elif BPP == 2
- cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
- cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
- cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
- v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
- cpu_to_32wu(((uint32_t *)d)+3, v);
- if (dup9)
- ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
- else
- ((uint16_t *)d)[8] = bgcol;
-#else
- ((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;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = v;
- if (dup9)
- ((uint32_t *)d)[8] = v;
- else
- ((uint32_t *)d)[8] = bgcol;
-#endif
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-/*
- * 4 color mode
- */
-static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, *palette, data, v;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
- ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
- ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
- ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
-
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
- ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
- ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
- ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
- d += BPP * 8;
- s += 4;
- }
-}
-
-#if BPP == 1
-#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
-#elif BPP == 2
-#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
-#else
-#define PUT_PIXEL2(d, n, v) \
-((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
-#endif
-
-/*
- * 4 color mode, dup2 horizontal
- */
-static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, *palette, data, v;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- PUT_PIXEL2(d, 0, palette[v >> 12]);
- PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
-
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- PUT_PIXEL2(d, 4, palette[v >> 12]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += BPP * 16;
- s += 4;
- }
-}
-
-/*
- * 16 color mode
- */
-static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, data, v, *palette;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
- ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
- ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
- ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
- ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
- ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
- ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
- ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
- d += BPP * 8;
- s += 4;
- }
-}
-
-/*
- * 16 color mode, dup2 horizontal
- */
-static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, data, v, *palette;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- PUT_PIXEL2(d, 0, palette[v >> 28]);
- PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
- PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += BPP * 16;
- s += 4;
- }
-}
-
-/*
- * 256 color mode, double pixels
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
-static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t *palette;
- int x;
-
- palette = s1->last_palette;
- width >>= 3;
- for(x = 0; x < width; x++) {
- PUT_PIXEL2(d, 0, palette[s[0]]);
- PUT_PIXEL2(d, 1, palette[s[1]]);
- PUT_PIXEL2(d, 2, palette[s[2]]);
- PUT_PIXEL2(d, 3, palette[s[3]]);
- d += BPP * 8;
- s += 4;
- }
-}
-
-/*
- * standard 256 color mode
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
-static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t *palette;
- int x;
-
- palette = s1->last_palette;
- width >>= 3;
- for(x = 0; x < width; x++) {
- ((PIXEL_TYPE *)d)[0] = palette[s[0]];
- ((PIXEL_TYPE *)d)[1] = palette[s[1]];
- ((PIXEL_TYPE *)d)[2] = palette[s[2]];
- ((PIXEL_TYPE *)d)[3] = palette[s[3]];
- ((PIXEL_TYPE *)d)[4] = palette[s[4]];
- ((PIXEL_TYPE *)d)[5] = palette[s[5]];
- ((PIXEL_TYPE *)d)[6] = palette[s[6]];
- ((PIXEL_TYPE *)d)[7] = palette[s[7]];
- d += BPP * 8;
- s += 8;
- }
-}
-
-void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
- const uint8_t *src1,
- int poffset, int w,
- unsigned int color0,
- unsigned int color1,
- unsigned int color_xor)
-{
- const uint8_t *plane0, *plane1;
- int x, b0, b1;
- uint8_t *d;
-
- d = d1;
- plane0 = src1;
- plane1 = src1 + poffset;
- for(x = 0; x < w; x++) {
- b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
- b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
-#if DEPTH == 8
- switch(b0 | (b1 << 1)) {
- case 0:
- break;
- case 1:
- d[0] ^= color_xor;
- break;
- case 2:
- d[0] = color0;
- break;
- case 3:
- d[0] = color1;
- break;
- }
-#elif DEPTH == 16
- switch(b0 | (b1 << 1)) {
- case 0:
- break;
- case 1:
- ((uint16_t *)d)[0] ^= color_xor;
- break;
- case 2:
- ((uint16_t *)d)[0] = color0;
- break;
- case 3:
- ((uint16_t *)d)[0] = color1;
- break;
- }
-#elif DEPTH == 32
- switch(b0 | (b1 << 1)) {
- case 0:
- break;
- case 1:
- ((uint32_t *)d)[0] ^= color_xor;
- break;
- case 2:
- ((uint32_t *)d)[0] = color0;
- break;
- case 3:
- ((uint32_t *)d)[0] = color1;
- break;
- }
-#else
-#error unsupported depth
-#endif
- d += BPP;
- }
-}
-
-#endif /* DEPTH != 15 */
-
-
-/* XXX: optimize */
-
-/*
- * 15 bit color
- */
-static void glue(vga_draw_line15_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
- memcpy(d, s, width * 2);
-#else
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_raw((void *)s);
- r = (v >> 7) & 0xf8;
- g = (v >> 2) & 0xf8;
- b = (v << 3) & 0xf8;
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- s += 2;
- d += BPP;
- } while (--w != 0);
-#endif
-}
-
-/*
- * 16 bit color
- */
-static void glue(vga_draw_line16_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
- memcpy(d, s, width * 2);
-#else
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_raw((void *)s);
- r = (v >> 8) & 0xf8;
- g = (v >> 3) & 0xfc;
- b = (v << 3) & 0xf8;
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- s += 2;
- d += BPP;
- } while (--w != 0);
-#endif
-}
-
-/*
- * 24 bit color
- */
-static void glue(vga_draw_line24_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
-#if defined(TARGET_WORDS_BIGENDIAN)
- r = s[0];
- g = s[1];
- b = s[2];
-#else
- b = s[0];
- g = s[1];
- r = s[2];
-#endif
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- s += 3;
- d += BPP;
- } while (--w != 0);
-}
-
-/*
- * 32 bit color
- */
-static void glue(vga_draw_line32_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
- memcpy(d, s, width * 4);
-#else
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
-#if defined(TARGET_WORDS_BIGENDIAN)
- r = s[1];
- g = s[2];
- b = s[3];
-#else
- b = s[0];
- g = s[1];
- r = s[2];
-#endif
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- s += 4;
- d += BPP;
- } while (--w != 0);
-#endif
-}
-
-#undef PUT_PIXEL2
-#undef DEPTH
-#undef BPP
-#undef PIXEL_TYPE
-#undef PIXEL_NAME
-#undef BGR_FORMAT
diff --git a/tools/ioemu/hw/xen_blktap.c b/tools/ioemu/hw/xen_blktap.c
deleted file mode 100644
index 996d492bc5..0000000000
--- a/tools/ioemu/hw/xen_blktap.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/* xen_blktap.c
- *
- * Interface to blktapctrl to allow use of qemu block drivers with blktap.
- * This file is based on tools/blktap/drivers/tapdisk.c
- *
- * Copyright (c) 2005 Julian Chesterfield and Andrew Warfield.
- * Copyright (c) 2008 Kevin Wolf
- */
-
-/*
- * There are several communication channels which are used by this interface:
- *
- * - A pair of pipes for receiving and sending general control messages
- * (qemu-read-N and qemu-writeN in /var/run/tap, where N is the domain ID).
- * These control messages are handled by handle_blktap_ctrlmsg().
- *
- * - One file descriptor per attached disk (/dev/xen/blktapN) for disk
- * specific control messages. A callback is triggered on this fd if there
- * is a new IO request. The callback function is handle_blktap_iomsg().
- *
- * - A shared ring for each attached disk containing the actual IO requests
- * and responses. Whenever handle_blktap_iomsg() is triggered it processes
- * the requests on this ring.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include "vl.h"
-#include "blktaplib.h"
-#include "xen_blktap.h"
-#include "block_int.h"
-
-#define MSG_SIZE 4096
-
-#define BLKTAP_CTRL_DIR "/var/run/tap"
-
-/* If enabled, print debug messages to stderr */
-#if 1
-#define DPRINTF(_f, _a...) fprintf(stderr, __FILE__ ":%d: " _f, __LINE__, ##_a)
-#else
-#define DPRINTF(_f, _a...) ((void)0)
-#endif
-
-#if 1
-#define ASSERT(_p) \
- if ( !(_p) ) { DPRINTF("Assertion '%s' failed, line %d, file %s\n", #_p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p) ((void)0)
-#endif
-
-
-extern int domid;
-
-int read_fd;
-int write_fd;
-
-static pid_t process;
-fd_list_entry_t *fd_start = NULL;
-
-static void handle_blktap_iomsg(void* private);
-
-struct aiocb_info {
- struct td_state *s;
- uint64_t sector;
- int nr_secs;
- int idx;
- long i;
-};
-
-static void unmap_disk(struct td_state *s)
-{
- tapdev_info_t *info = s->ring_info;
- fd_list_entry_t *entry;
-
- bdrv_close(s->bs);
-
- if (info != NULL && info->mem > 0)
- munmap(info->mem, getpagesize() * BLKTAP_MMAP_REGION_SIZE);
-
- entry = s->fd_entry;
- *entry->pprev = entry->next;
- if (entry->next)
- entry->next->pprev = entry->pprev;
-
- qemu_set_fd_handler2(info->fd, NULL, NULL, NULL, NULL);
- close(info->fd);
-
- free(s->fd_entry);
- free(s->blkif);
- free(s->ring_info);
- free(s);
-
- return;
-}
-
-static inline fd_list_entry_t *add_fd_entry(int tap_fd, struct td_state *s)
-{
- fd_list_entry_t **pprev, *entry;
-
- DPRINTF("Adding fd_list_entry\n");
-
- /*Add to linked list*/
- s->fd_entry = entry = malloc(sizeof(fd_list_entry_t));
- entry->tap_fd = tap_fd;
- entry->s = s;
- entry->next = NULL;
-
- pprev = &fd_start;
- while (*pprev != NULL)
- pprev = &(*pprev)->next;
-
- *pprev = entry;
- entry->pprev = pprev;
-
- return entry;
-}
-
-static inline struct td_state *get_state(int cookie)
-{
- fd_list_entry_t *ptr;
-
- ptr = fd_start;
- while (ptr != NULL) {
- if (ptr->cookie == cookie) return ptr->s;
- ptr = ptr->next;
- }
- return NULL;
-}
-
-static struct td_state *state_init(void)
-{
- int i;
- struct td_state *s;
- blkif_t *blkif;
-
- s = malloc(sizeof(struct td_state));
- blkif = s->blkif = malloc(sizeof(blkif_t));
- s->ring_info = calloc(1, sizeof(tapdev_info_t));
-
- for (i = 0; i < MAX_REQUESTS; i++) {
- blkif->pending_list[i].secs_pending = 0;
- blkif->pending_list[i].submitting = 0;
- }
-
- return s;
-}
-
-static int map_new_dev(struct td_state *s, int minor)
-{
- int tap_fd;
- tapdev_info_t *info = s->ring_info;
- char *devname;
- fd_list_entry_t *ptr;
- int page_size;
-
- if (asprintf(&devname,"%s/%s%d", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, minor) == -1)
- return -1;
- tap_fd = open(devname, O_RDWR);
- if (tap_fd == -1)
- {
- DPRINTF("open failed on dev %s!\n",devname);
- goto fail;
- }
- info->fd = tap_fd;
-
- /*Map the shared memory*/
- page_size = getpagesize();
- info->mem = mmap(0, page_size * BLKTAP_MMAP_REGION_SIZE,
- PROT_READ | PROT_WRITE, MAP_SHARED, info->fd, 0);
- if ((long int)info->mem == -1)
- {
- DPRINTF("mmap failed on dev %s!\n",devname);
- goto fail;
- }
-
- /* assign the rings to the mapped memory */
- info->sring = (blkif_sring_t *)((unsigned long)info->mem);
- BACK_RING_INIT(&info->fe_ring, info->sring, page_size);
-
- info->vstart =
- (unsigned long)info->mem + (BLKTAP_RING_PAGES * page_size);
-
- ioctl(info->fd, BLKTAP_IOCTL_SENDPID, process );
- ioctl(info->fd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
- free(devname);
-
- /*Update the fd entry*/
- ptr = fd_start;
- while (ptr != NULL) {
- if (s == ptr->s) {
- ptr->tap_fd = tap_fd;
-
- /* Setup fd_handler for qemu main loop */
- DPRINTF("set tap_fd = %d\n", tap_fd);
- qemu_set_fd_handler2(tap_fd, NULL, &handle_blktap_iomsg, NULL, s);
-
- break;
- }
- ptr = ptr->next;
- }
-
-
- DPRINTF("map_new_dev = %d\n", minor);
- return minor;
-
- fail:
- free(devname);
- return -1;
-}
-
-static int open_disk(struct td_state *s, char *path, int readonly)
-{
- struct disk_id id;
- BlockDriverState* bs;
-
- DPRINTF("Opening %s\n", path);
- bs = calloc(1, sizeof(*bs));
-
- memset(&id, 0, sizeof(struct disk_id));
-
- if (bdrv_open(bs, path, 0) != 0) {
- fprintf(stderr, "Could not open image file %s\n", path);
- return -ENOMEM;
- }
-
- s->bs = bs;
- s->flags = readonly ? TD_RDONLY : 0;
- s->size = bs->total_sectors;
- s->sector_size = 512;
-
- s->info = ((s->flags & TD_RDONLY) ? VDISK_READONLY : 0);
-
- return 0;
-}
-
-static inline void write_rsp_to_ring(struct td_state *s, blkif_response_t *rsp)
-{
- tapdev_info_t *info = s->ring_info;
- blkif_response_t *rsp_d;
-
- rsp_d = RING_GET_RESPONSE(&info->fe_ring, info->fe_ring.rsp_prod_pvt);
- memcpy(rsp_d, rsp, sizeof(blkif_response_t));
- info->fe_ring.rsp_prod_pvt++;
-}
-
-static inline void kick_responses(struct td_state *s)
-{
- tapdev_info_t *info = s->ring_info;
-
- if (info->fe_ring.rsp_prod_pvt != info->fe_ring.sring->rsp_prod)
- {
- RING_PUSH_RESPONSES(&info->fe_ring);
- ioctl(info->fd, BLKTAP_IOCTL_KICK_FE);
- }
-}
-
-static int send_responses(struct td_state *s, int res,
- uint64_t sector, int nr_secs, int idx, void *private)
-{
- pending_req_t *preq;
- blkif_request_t *req;
- int responses_queued = 0;
- blkif_t *blkif = s->blkif;
- int secs_done = nr_secs;
-
- if ( (idx > MAX_REQUESTS-1) )
- {
- DPRINTF("invalid index returned(%u)!\n", idx);
- return 0;
- }
- preq = &blkif->pending_list[idx];
- req = &preq->req;
-
- preq->secs_pending -= secs_done;
-
- if (res == -EBUSY && preq->submitting)
- return -EBUSY; /* propagate -EBUSY back to higher layers */
- if (res)
- preq->status = BLKIF_RSP_ERROR;
-
- if (!preq->submitting && preq->secs_pending == 0)
- {
- blkif_request_t tmp;
- blkif_response_t *rsp;
-
- tmp = preq->req;
- rsp = (blkif_response_t *)req;
-
- rsp->id = tmp.id;
- rsp->operation = tmp.operation;
- rsp->status = preq->status;
-
- write_rsp_to_ring(s, rsp);
- responses_queued++;
-
- kick_responses(s);
- }
-
- return responses_queued;
-}
-
-static void qemu_send_responses(void* opaque, int ret)
-{
- struct aiocb_info* info = opaque;
-
- if (ret != 0) {
- DPRINTF("ERROR: ret = %d (%s)\n", ret, strerror(-ret));
- }
-
- send_responses(info->s, ret, info->sector, info->nr_secs,
- info->idx, (void*) info->i);
- free(info);
-}
-
-/**
- * Callback function for the IO message pipe. Reads requests from the ring
- * and processes them (call qemu read/write functions).
- *
- * The private parameter points to the struct td_state representing the
- * disk the request is targeted at.
- */
-static void handle_blktap_iomsg(void* private)
-{
- struct td_state* s = private;
-
- RING_IDX rp, j, i;
- blkif_request_t *req;
- int idx, nsects, ret;
- uint64_t sector_nr;
- uint8_t *page;
- blkif_t *blkif = s->blkif;
- tapdev_info_t *info = s->ring_info;
- int page_size = getpagesize();
-
- struct aiocb_info *aiocb_info;
-
- if (info->fe_ring.sring == NULL) {
- DPRINTF(" sring == NULL, ignoring IO request\n");
- return;
- }
-
- rp = info->fe_ring.sring->req_prod;
- xen_rmb();
-
- for (j = info->fe_ring.req_cons; j != rp; j++)
- {
- int start_seg = 0;
-
- req = NULL;
- req = RING_GET_REQUEST(&info->fe_ring, j);
- ++info->fe_ring.req_cons;
-
- if (req == NULL)
- continue;
-
- idx = req->id;
-
- ASSERT(blkif->pending_list[idx].secs_pending == 0);
- memcpy(&blkif->pending_list[idx].req, req, sizeof(*req));
- blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
- blkif->pending_list[idx].submitting = 1;
- sector_nr = req->sector_number;
-
- /* Don't allow writes on readonly devices */
- if ((s->flags & TD_RDONLY) &&
- (req->operation == BLKIF_OP_WRITE)) {
- blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
- goto send_response;
- }
-
- for (i = start_seg; i < req->nr_segments; i++) {
- nsects = req->seg[i].last_sect -
- req->seg[i].first_sect + 1;
-
- if ((req->seg[i].last_sect >= page_size >> 9) ||
- (nsects <= 0))
- continue;
-
- page = (uint8_t*) MMAP_VADDR(info->vstart,
- (unsigned long)req->id, i);
- page += (req->seg[i].first_sect << SECTOR_SHIFT);
-
- if (sector_nr >= s->size) {
- DPRINTF("Sector request failed:\n");
- DPRINTF("%s request, idx [%d,%d] size [%llu], "
- "sector [%llu,%llu]\n",
- (req->operation == BLKIF_OP_WRITE ?
- "WRITE" : "READ"),
- idx,i,
- (long long unsigned)
- nsects<<SECTOR_SHIFT,
- (long long unsigned)
- sector_nr<<SECTOR_SHIFT,
- (long long unsigned) sector_nr);
- continue;
- }
-
- blkif->pending_list[idx].secs_pending += nsects;
-
- switch (req->operation)
- {
- case BLKIF_OP_WRITE:
- aiocb_info = malloc(sizeof(*aiocb_info));
-
- aiocb_info->s = s;
- aiocb_info->sector = sector_nr;
- aiocb_info->nr_secs = nsects;
- aiocb_info->idx = idx;
- aiocb_info->i = i;
-
- ret = (NULL == bdrv_aio_write(s->bs, sector_nr,
- page, nsects,
- qemu_send_responses,
- aiocb_info));
-
- if (ret) {
- blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
- DPRINTF("ERROR: bdrv_write() == NULL\n");
- goto send_response;
- }
- break;
-
- case BLKIF_OP_READ:
- aiocb_info = malloc(sizeof(*aiocb_info));
-
- aiocb_info->s = s;
- aiocb_info->sector = sector_nr;
- aiocb_info->nr_secs = nsects;
- aiocb_info->idx = idx;
- aiocb_info->i = i;
-
- ret = (NULL == bdrv_aio_read(s->bs, sector_nr,
- page, nsects,
- qemu_send_responses,
- aiocb_info));
-
- if (ret) {
- blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
- DPRINTF("ERROR: bdrv_read() == NULL\n");
- goto send_response;
- }
- break;
-
- default:
- DPRINTF("Unknown block operation\n");
- break;
- }
- sector_nr += nsects;
- }
- send_response:
- blkif->pending_list[idx].submitting = 0;
-
- /* force write_rsp_to_ring for synchronous case */
- if (blkif->pending_list[idx].secs_pending == 0)
- send_responses(s, 0, 0, 0, idx, (void *)(long)0);
- }
-}
-
-/**
- * Callback function for the qemu-read pipe. Reads and processes control
- * message from the pipe.
- *
- * The parameter private is unused.
- */
-static void handle_blktap_ctrlmsg(void* private)
-{
- int length, len, msglen;
- char *ptr, *path;
- image_t *img;
- msg_hdr_t *msg;
- msg_newdev_t *msg_dev;
- msg_pid_t *msg_pid;
- int ret = -1;
- struct td_state *s = NULL;
- fd_list_entry_t *entry;
-
- char buf[MSG_SIZE];
-
- length = read(read_fd, buf, MSG_SIZE);
-
- if (length > 0 && length >= sizeof(msg_hdr_t))
- {
- msg = (msg_hdr_t *)buf;
- DPRINTF("blktap: Received msg, len %d, type %d, UID %d\n",
- length,msg->type,msg->cookie);
-
- switch (msg->type) {
- case CTLMSG_PARAMS:
- ptr = buf + sizeof(msg_hdr_t);
- len = (length - sizeof(msg_hdr_t));
- path = calloc(1, len + 1);
-
- memcpy(path, ptr, len);
- DPRINTF("Received CTLMSG_PARAMS: [%s]\n", path);
-
- /* Allocate the disk structs */
- s = state_init();
-
- /*Open file*/
- if (s == NULL || open_disk(s, path, msg->readonly)) {
- msglen = sizeof(msg_hdr_t);
- msg->type = CTLMSG_IMG_FAIL;
- msg->len = msglen;
- } else {
- entry = add_fd_entry(0, s);
- entry->cookie = msg->cookie;
- DPRINTF("Entered cookie %d\n", entry->cookie);
-
- memset(buf, 0x00, MSG_SIZE);
-
- msglen = sizeof(msg_hdr_t) + sizeof(image_t);
- msg->type = CTLMSG_IMG;
- img = (image_t *)(buf + sizeof(msg_hdr_t));
- img->size = s->size;
- img->secsize = s->sector_size;
- img->info = s->info;
- DPRINTF("Writing (size, secsize, info) = "
- "(%#" PRIx64 ", %#" PRIx64 ", %d)\n",
- s->size, s->sector_size, s->info);
- }
- len = write(write_fd, buf, msglen);
- free(path);
- break;
-
- case CTLMSG_NEWDEV:
- msg_dev = (msg_newdev_t *)(buf + sizeof(msg_hdr_t));
-
- s = get_state(msg->cookie);
- DPRINTF("Retrieving state, cookie %d.....[%s]\n",
- msg->cookie, (s == NULL ? "FAIL":"OK"));
- if (s != NULL) {
- ret = ((map_new_dev(s, msg_dev->devnum)
- == msg_dev->devnum ? 0: -1));
- }
-
- memset(buf, 0x00, MSG_SIZE);
- msglen = sizeof(msg_hdr_t);
- msg->type = (ret == 0 ? CTLMSG_NEWDEV_RSP
- : CTLMSG_NEWDEV_FAIL);
- msg->len = msglen;
-
- len = write(write_fd, buf, msglen);
- break;
-
- case CTLMSG_CLOSE:
- s = get_state(msg->cookie);
- if (s) unmap_disk(s);
- break;
-
- case CTLMSG_PID:
- memset(buf, 0x00, MSG_SIZE);
- msglen = sizeof(msg_hdr_t) + sizeof(msg_pid_t);
- msg->type = CTLMSG_PID_RSP;
- msg->len = msglen;
-
- msg_pid = (msg_pid_t *)(buf + sizeof(msg_hdr_t));
- process = getpid();
- msg_pid->pid = process;
-
- len = write(write_fd, buf, msglen);
- break;
-
- default:
- break;
- }
- }
-}
-
-/**
- * Opens a control socket, i.e. a pipe to communicate with blktapctrl.
- *
- * Returns the file descriptor number for the pipe; -1 in error case
- */
-static int open_ctrl_socket(char *devname)
-{
- int ipc_fd;
-
- if (mkdir(BLKTAP_CTRL_DIR, 0755) == 0)
- DPRINTF("Created %s directory\n", BLKTAP_CTRL_DIR);
-
- if (access(devname, R_OK | W_OK))
- return -1;
-
- ipc_fd = open(devname,O_RDWR|O_NONBLOCK);
-
- if (ipc_fd < 0) {
- DPRINTF("FD open failed\n");
- return -1;
- }
-
- return ipc_fd;
-}
-
-/**
- * Initialize the blktap interface, i.e. open a pair of pipes in /var/run/tap
- * and register a fd handler.
- *
- * Returns 0 on success.
- */
-int init_blktap(void)
-{
- char* devname;
-
- DPRINTF("Init blktap pipes\n");
-
- /* Open the read pipe */
- if (asprintf(&devname, BLKTAP_CTRL_DIR "/qemu-read-%d", domid) >= 0) {
- read_fd = open_ctrl_socket(devname);
- free(devname);
-
- if (read_fd == -1) {
- fprintf(stderr, "Could not open %s/qemu-read-%d\n",
- BLKTAP_CTRL_DIR, domid);
- return -1;
- }
- }
-
- /* Open the write pipe */
- if (asprintf(&devname, BLKTAP_CTRL_DIR "/qemu-write-%d", domid) >= 0) {
- write_fd = open_ctrl_socket(devname);
- free(devname);
-
- if (write_fd == -1) {
- fprintf(stderr, "Could not open %s/qemu-write-%d\n",
- BLKTAP_CTRL_DIR, domid);
- close(read_fd);
- return -1;
- }
- }
-
- /* Attach a handler to the read pipe (called from qemu main loop) */
- qemu_set_fd_handler2(read_fd, NULL, &handle_blktap_ctrlmsg, NULL, NULL);
-
- return 0;
-}
diff --git a/tools/ioemu/hw/xen_blktap.h b/tools/ioemu/hw/xen_blktap.h
deleted file mode 100644
index 0fb4bb3f6f..0000000000
--- a/tools/ioemu/hw/xen_blktap.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* xen_blktap.h
- *
- * Generic disk interface for blktap-based image adapters.
- *
- * (c) 2006 Andrew Warfield and Julian Chesterfield
- */
-
-#ifndef XEN_BLKTAP_H_
-#define XEN_BLKTAP_H_
-
-#include <stdint.h>
-#include <syslog.h>
-#include <stdio.h>
-
-#include "block_int.h"
-
-/* Things disks need to know about, these should probably be in a higher-level
- * header. */
-#define MAX_SEGMENTS_PER_REQ 11
-#define SECTOR_SHIFT 9
-#define DEFAULT_SECTOR_SIZE 512
-
-#define MAX_IOFD 2
-
-#define BLK_NOT_ALLOCATED 99
-#define TD_NO_PARENT 1
-
-typedef uint32_t td_flag_t;
-
-#define TD_RDONLY 1
-
-struct disk_id {
- char *name;
- int drivertype;
-};
-
-/* This structure represents the state of an active virtual disk. */
-struct td_state {
- BlockDriverState* bs;
- td_flag_t flags;
- void *blkif;
- void *image;
- void *ring_info;
- void *fd_entry;
- uint64_t sector_size;
- uint64_t size;
- unsigned int info;
-};
-
-typedef struct fd_list_entry {
- int cookie;
- int tap_fd;
- struct td_state *s;
- struct fd_list_entry **pprev, *next;
-} fd_list_entry_t;
-
-#endif /*XEN_BLKTAP_H_*/
diff --git a/tools/ioemu/hw/xen_console.c b/tools/ioemu/hw/xen_console.c
deleted file mode 100644
index 92c424740a..0000000000
--- a/tools/ioemu/hw/xen_console.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) International Business Machines Corp., 2005
- * Author(s): Anthony Liguori <aliguori@us.ibm.com>
- *
- * Copyright (C) Red Hat 2007
- *
- * Xen Console
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <malloc.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <termios.h>
-#include <stdarg.h>
-#include <sys/mman.h>
-#include <xs.h>
-#include <xen/io/console.h>
-#include <xenctrl.h>
-
-#include "vl.h"
-
-#include "xen_console.h"
-
-#define dolog(val, fmt, ...) fprintf(stderr, fmt "\n", ## __VA_ARGS__)
-
-struct buffer
-{
- uint8_t *data;
- size_t consumed;
- size_t size;
- size_t capacity;
- size_t max_capacity;
-};
-
-struct domain
-{
- int domid;
- struct buffer buffer;
-
- char *conspath;
- char *serialpath;
- int use_consolepath;
- int ring_ref;
- evtchn_port_t local_port;
- evtchn_port_t remote_port;
- int xce_handle;
- struct xs_handle *xsh;
- struct xencons_interface *interface;
- CharDriverState *chr;
-};
-
-
-static void buffer_append(struct domain *dom)
-{
- struct buffer *buffer = &dom->buffer;
- XENCONS_RING_IDX cons, prod, size;
- struct xencons_interface *intf = dom->interface;
-
- cons = intf->out_cons;
- prod = intf->out_prod;
- xen_mb();
-
- size = prod - cons;
- if ((size == 0) || (size > sizeof(intf->out)))
- return;
-
- if ((buffer->capacity - buffer->size) < size) {
- buffer->capacity += (size + 1024);
- buffer->data = realloc(buffer->data, buffer->capacity);
- if (buffer->data == NULL) {
- dolog(LOG_ERR, "Memory allocation failed");
- exit(ENOMEM);
- }
- }
-
- while (cons != prod)
- buffer->data[buffer->size++] = intf->out[
- MASK_XENCONS_IDX(cons++, intf->out)];
-
- xen_mb();
- intf->out_cons = cons;
- xc_evtchn_notify(dom->xce_handle, dom->local_port);
-
- if (buffer->max_capacity &&
- buffer->size > buffer->max_capacity) {
- /* Discard the middle of the data. */
-
- size_t over = buffer->size - buffer->max_capacity;
- uint8_t *maxpos = buffer->data + buffer->max_capacity;
-
- memmove(maxpos - over, maxpos, over);
- buffer->data = realloc(buffer->data, buffer->max_capacity);
- buffer->size = buffer->capacity = buffer->max_capacity;
-
- if (buffer->consumed > buffer->max_capacity - over)
- buffer->consumed = buffer->max_capacity - over;
- }
-}
-
-static void buffer_advance(struct buffer *buffer, size_t len)
-{
- buffer->consumed += len;
- if (buffer->consumed == buffer->size) {
- buffer->consumed = 0;
- buffer->size = 0;
- }
-}
-
-/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xs_gather(struct xs_handle *xs, const char *dir, ...)
-{
- va_list ap;
- const char *name;
- char *path;
- int ret = 0;
-
- va_start(ap, dir);
- while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
- const char *fmt = va_arg(ap, char *);
- void *result = va_arg(ap, void *);
- char *p;
-
- if (asprintf(&path, "%s/%s", dir, name) == -1) {
- ret = ENOMEM;
- break;
- }
- p = xs_read(xs, XBT_NULL, path, NULL);
- free(path);
- if (p == NULL) {
- ret = ENOENT;
- break;
- }
- if (fmt) {
- if (sscanf(p, fmt, result) == 0)
- ret = EINVAL;
- free(p);
- } else
- *(char **)result = p;
- }
- va_end(ap);
- return ret;
-}
-
-static int domain_create_ring(struct domain *dom)
-{
- int err, remote_port, ring_ref, limit, rc;
-
- err = xs_gather(dom->xsh, dom->serialpath,
- "ring-ref", "%u", &ring_ref,
- "port", "%i", &remote_port,
- "limit", "%i", &limit,
- NULL);
- if (err) {
- err = xs_gather(dom->xsh, dom->conspath,
- "ring-ref", "%u", &ring_ref,
- "port", "%i", &remote_port,
- "limit", "%i", &limit,
- NULL);
- if (err) {
- fprintf(stderr, "Console: failed to find ring-ref/port yet\n");
- goto out;
- }
- dom->use_consolepath = 1;
- } else
- dom->use_consolepath = 0;
- dom->buffer.max_capacity = limit;
- fprintf(stderr, "Console: got ring-ref %d port %d limit %d\n",
- ring_ref, remote_port, limit);
-
- if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
- goto out;
-
- if (ring_ref != dom->ring_ref) {
- if (dom->interface != NULL)
- munmap(dom->interface, getpagesize());
- dom->interface = xc_map_foreign_range(
- xc_handle, dom->domid, getpagesize(),
- PROT_READ|PROT_WRITE,
- (unsigned long)ring_ref);
- if (dom->interface == NULL) {
- err = errno;
- goto out;
- }
- dom->ring_ref = ring_ref;
- }
-
- dom->local_port = -1;
- dom->remote_port = -1;
-
- dom->xce_handle = xc_evtchn_open();
- if (dom->xce_handle == -1) {
- err = errno;
- goto out;
- }
-
- rc = xc_evtchn_bind_interdomain(dom->xce_handle,
- dom->domid, remote_port);
-
- if (rc == -1) {
- err = errno;
- xc_evtchn_close(dom->xce_handle);
- dom->xce_handle = -1;
- goto out;
- }
- dom->local_port = rc;
- dom->remote_port = remote_port;
-
- out:
- return err;
-}
-
-
-static struct domain *create_domain(int domid, CharDriverState *chr)
-{
- struct domain *dom;
- char *s;
-
- dom = (struct domain *)malloc(sizeof(struct domain));
- if (dom == NULL) {
- dolog(LOG_ERR, "Out of memory %s:%s():L%d",
- __FILE__, __FUNCTION__, __LINE__);
- exit(ENOMEM);
- }
-
- dom->domid = domid;
- dom->chr = chr;
-
- dom->xsh = xs_daemon_open();
- if (dom->xsh == NULL) {
- fprintf(logfile, "Could not contact xenstore for console watch\n");
- goto out;
- }
-
- dom->serialpath = xs_get_domain_path(dom->xsh, dom->domid);
- s = realloc(dom->serialpath, strlen(dom->serialpath) +
- strlen("/serial/0") + 1);
- if (s == NULL)
- goto out;
- dom->serialpath = s;
- strcat(dom->serialpath, "/serial/0");
-
- dom->conspath = xs_get_domain_path(dom->xsh, dom->domid);
- s = realloc(dom->conspath, strlen(dom->conspath) +
- strlen("/console") + 1);
- if (s == NULL)
- goto out;
- dom->conspath = s;
- strcat(dom->conspath, "/console");
-
- dom->buffer.data = 0;
- dom->buffer.consumed = 0;
- dom->buffer.size = 0;
- dom->buffer.capacity = 0;
- dom->buffer.max_capacity = 0;
-
- dom->ring_ref = -1;
- dom->local_port = -1;
- dom->remote_port = -1;
- dom->interface = NULL;
- dom->xce_handle = -1;
-
-
- return dom;
- out:
- free(dom->serialpath);
- free(dom->conspath);
- free(dom);
- return NULL;
-}
-
-
-static int ring_free_bytes(struct domain *dom)
-{
- struct xencons_interface *intf = dom->interface;
- XENCONS_RING_IDX cons, prod, space;
-
- cons = intf->in_cons;
- prod = intf->in_prod;
- xen_mb();
-
- space = prod - cons;
- if (space > sizeof(intf->in))
- return 0; /* ring is screwed: ignore it */
-
- return (sizeof(intf->in) - space);
-}
-
-static int xencons_can_receive(void *opaque)
-{
- struct domain *dom = (struct domain *)opaque;
-
- return ring_free_bytes(dom);
-}
-
-static void xencons_receive(void *opaque, const uint8_t *buf, int len)
-{
- struct domain *dom = (struct domain *)opaque;
- int i, max;
- struct xencons_interface *intf = dom->interface;
- XENCONS_RING_IDX prod;
-
- max = ring_free_bytes(dom);
- /* The can_receive() func limits this, but check again anyway */
- if (max < len)
- len = max;
-
- prod = intf->in_prod;
- for (i = 0; i < len; i++) {
- intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
- buf[i];
- }
- xen_wmb();
- intf->in_prod = prod;
- xc_evtchn_notify(dom->xce_handle, dom->local_port);
-}
-
-static void xencons_send(struct domain *dom)
-{
- ssize_t len;
- len = qemu_chr_write(dom->chr, dom->buffer.data + dom->buffer.consumed,
- dom->buffer.size - dom->buffer.consumed);
- if (len < 1) {
- /*
- * Disable log because if we're redirecting to /dev/pts/N we
- * don't want to flood logs when no client has the PTY open
- */
- /*
- dolog(LOG_DEBUG, "Write failed on domain %d: %zd, %d\n",
- dom->domid, len, errno);
- */
- } else {
- buffer_advance(&dom->buffer, len);
- }
-}
-
-static void xencons_ring_read(void *opaque)
-{
- evtchn_port_t port;
- struct domain *dom = (struct domain *)opaque;
-
- if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
- return;
-
- buffer_append(dom);
-
- (void)xc_evtchn_unmask(dom->xce_handle, port);
-
- if (dom->buffer.size - dom->buffer.consumed)
- xencons_send(dom);
-}
-
-static void xencons_startup(void *opaque)
-{
- struct domain *dom = (struct domain *)opaque;
- unsigned dummy;
- char **vec;
- int err;
- vec = xs_read_watch(dom->xsh, &dummy);
- if (vec)
- free(vec);
- fprintf(stderr, "Console: got watch\n");
- err = domain_create_ring(dom);
- if (err)
- return;
-
- xs_unwatch(dom->xsh, dom->conspath, "");
- xs_unwatch(dom->xsh, dom->serialpath, "");
- qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, NULL, NULL, NULL);
-
- fprintf(stderr, "Console: connected to guest frontend\n");
- if (qemu_set_fd_handler2(xc_evtchn_fd(dom->xce_handle), NULL, xencons_ring_read, NULL, dom) < 0)
- return;
-
- qemu_chr_add_handlers(dom->chr, xencons_can_receive, xencons_receive,
- NULL, dom);
-}
-
-
-int xencons_init(int domid, CharDriverState *chr)
-{
- struct domain *dom = create_domain(domid, chr);
-
- if (!dom)
- return -1;
-
- /* Setup watches so we asynchronously connect to serial console */
- if (!(xs_watch(dom->xsh, dom->conspath, ""))) {
- fprintf(stderr, "Unable to watch console %s\n", dom->conspath);
- goto fail;
- }
- if (!(xs_watch(dom->xsh, dom->serialpath, ""))) {
- fprintf(stderr, "Unable to watch console %s\n", dom->conspath);
- xs_unwatch(dom->xsh, dom->conspath, "");
- goto fail;
- }
- qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, xencons_startup, NULL, dom);
- fprintf(stderr, "Console: prepared domain, waiting for ringref at %s or %s\n",
- dom->conspath, dom->serialpath);
-
- return 0;
-
-fail:
- xs_daemon_close(dom->xsh);
- free(dom->serialpath);
- free(dom->conspath);
- free(dom);
- return -1;
-}
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/tools/ioemu/hw/xen_console.h b/tools/ioemu/hw/xen_console.h
deleted file mode 100644
index ece35776df..0000000000
--- a/tools/ioemu/hw/xen_console.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) International Business Machines Corp., 2005
- * Author(s): Anthony Liguori <aliguori@us.ibm.com>
- *
- * Copyright (C) Red Hat 2007
- *
- * Xen Console
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "vl.h"
-
-extern int xencons_init(int domid, CharDriverState *chr);
diff --git a/tools/ioemu/hw/xen_machine_fv.c b/tools/ioemu/hw/xen_machine_fv.c
deleted file mode 100644
index 036fbc4e99..0000000000
--- a/tools/ioemu/hw/xen_machine_fv.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * QEMU Xen FV Machine
- *
- * Copyright (c) 2003-2007 Fabrice Bellard
- * Copyright (c) 2007 Red Hat
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-#include <xen/hvm/params.h>
-#include <sys/mman.h>
-
-#if defined(MAPCACHE)
-
-#if defined(__i386__)
-#define MAX_MCACHE_SIZE 0x40000000 /* 1GB max for x86 */
-#define MCACHE_BUCKET_SHIFT 16
-#elif defined(__x86_64__)
-#define MAX_MCACHE_SIZE 0x1000000000 /* 64GB max for x86_64 */
-#define MCACHE_BUCKET_SHIFT 20
-#endif
-
-#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
-
-#define BITS_PER_LONG (sizeof(long)*8)
-#define BITS_TO_LONGS(bits) \
- (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#define DECLARE_BITMAP(name,bits) \
- unsigned long name[BITS_TO_LONGS(bits)]
-#define test_bit(bit,map) \
- (!!((map)[(bit)/BITS_PER_LONG] & (1UL << ((bit)%BITS_PER_LONG))))
-
-struct map_cache {
- unsigned long paddr_index;
- uint8_t *vaddr_base;
- DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>XC_PAGE_SHIFT);
-};
-
-static struct map_cache *mapcache_entry;
-static unsigned long nr_buckets;
-
-/* For most cases (>99.9%), the page address is the same. */
-static unsigned long last_address_index = ~0UL;
-static uint8_t *last_address_vaddr;
-
-static int qemu_map_cache_init(void)
-{
- unsigned long size;
-
- nr_buckets = (((MAX_MCACHE_SIZE >> XC_PAGE_SHIFT) +
- (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
-
- /*
- * Use mmap() directly: lets us allocate a big hash table with no up-front
- * cost in storage space. The OS will allocate memory only for the buckets
- * that we actually use. All others will contain all zeroes.
- */
- size = nr_buckets * sizeof(struct map_cache);
- size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
- fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx size %lu\n", nr_buckets, size);
- mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
- MAP_SHARED|MAP_ANON, -1, 0);
- if (mapcache_entry == MAP_FAILED) {
- errno = ENOMEM;
- return -1;
- }
-
- return 0;
-}
-
-static void qemu_remap_bucket(struct map_cache *entry,
- unsigned long address_index)
-{
- uint8_t *vaddr_base;
- unsigned long pfns[MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT];
- unsigned int i, j;
-
- if (entry->vaddr_base != NULL) {
- errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
- if (errno) {
- fprintf(logfile, "unmap fails %d\n", errno);
- exit(-1);
- }
- }
-
- for (i = 0; i < MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT; i++)
- pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
-
- vaddr_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE,
- pfns, MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT);
- if (vaddr_base == NULL) {
- fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
- exit(-1);
- }
-
- entry->vaddr_base = vaddr_base;
- entry->paddr_index = address_index;
-
- for (i = 0; i < MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT; i += BITS_PER_LONG) {
- unsigned long word = 0;
- j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT)) ?
- (MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
- while (j > 0)
- word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
- entry->valid_mapping[i / BITS_PER_LONG] = word;
- }
-}
-
-uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
-{
- struct map_cache *entry;
- unsigned long address_index = phys_addr >> MCACHE_BUCKET_SHIFT;
- unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
-
- if (address_index == last_address_index)
- return last_address_vaddr + address_offset;
-
- entry = &mapcache_entry[address_index % nr_buckets];
-
- if (entry->vaddr_base == NULL || entry->paddr_index != address_index ||
- !test_bit(address_offset>>XC_PAGE_SHIFT, entry->valid_mapping))
- qemu_remap_bucket(entry, address_index);
-
- if (!test_bit(address_offset>>XC_PAGE_SHIFT, entry->valid_mapping)) {
- last_address_index = ~0UL;
- return NULL;
- }
-
- last_address_index = address_index;
- last_address_vaddr = entry->vaddr_base;
-
- return last_address_vaddr + address_offset;
-}
-
-void qemu_invalidate_map_cache(void)
-{
- unsigned long i;
-
- mapcache_lock();
-
- for (i = 0; i < nr_buckets; i++) {
- struct map_cache *entry = &mapcache_entry[i];
-
- if (entry->vaddr_base == NULL)
- continue;
-
- errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
- if (errno) {
- fprintf(logfile, "unmap fails %d\n", errno);
- exit(-1);
- }
-
- entry->paddr_index = 0;
- entry->vaddr_base = NULL;
- }
-
- last_address_index = ~0UL;
- last_address_vaddr = NULL;
-
- mapcache_unlock();
-}
-
-#endif /* defined(MAPCACHE) */
-
-
-static void xen_init_fv(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *direct_pci)
-{
- unsigned long ioreq_pfn;
- extern void *shared_page;
- extern void *buffered_io_page;
-#ifdef __ia64__
- unsigned long nr_pages;
- xen_pfn_t *page_array;
- extern void *buffered_pio_page;
- int i;
-#endif
-
-#if defined(__i386__) || defined(__x86_64__)
-
- if (qemu_map_cache_init()) {
- fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
- exit(-1);
- }
-#endif
-
- xc_set_hvm_param(xc_handle, domid, HVM_PARAM_DM_DOMAIN, DOMID_SELF);
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
- fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
- shared_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
- PROT_READ|PROT_WRITE, ioreq_pfn);
- if (shared_page == NULL) {
- fprintf(logfile, "map shared IO page returned error %d\n", errno);
- exit(-1);
- }
-
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
- fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
- buffered_io_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
- PROT_READ|PROT_WRITE, ioreq_pfn);
- if (buffered_io_page == NULL) {
- fprintf(logfile, "map buffered IO page returned error %d\n", errno);
- exit(-1);
- }
-
-#if defined(__ia64__)
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFPIOREQ_PFN, &ioreq_pfn);
- fprintf(logfile, "buffered pio page at pfn %lx\n", ioreq_pfn);
- buffered_pio_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
- PROT_READ|PROT_WRITE, ioreq_pfn);
- if (buffered_pio_page == NULL) {
- fprintf(logfile, "map buffered PIO page returned error %d\n", errno);
- exit(-1);
- }
-
- nr_pages = ram_size / XC_PAGE_SIZE;
-
- page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
- if (page_array == NULL) {
- fprintf(logfile, "malloc returned error %d\n", errno);
- exit(-1);
- }
-
- for (i = 0; i < nr_pages; i++)
- page_array[i] = i;
-
- /* VTI will not use memory between 3G~4G, so we just pass a legal pfn
- to make QEMU map continuous virtual memory space */
- if (ram_size > MMIO_START) {
- for (i = 0 ; i < (MEM_G >> XC_PAGE_SHIFT); i++)
- page_array[(MMIO_START >> XC_PAGE_SHIFT) + i] =
- (STORE_PAGE_START >> XC_PAGE_SHIFT);
- }
- /* skipping VGA hole, same as above */
- if (ram_size > VGA_IO_START) {
- for (i = 0 ; i < (VGA_IO_SIZE >> XC_PAGE_SHIFT); i++)
- page_array[(VGA_IO_START >> XC_PAGE_SHIFT) + i] =
- (STORE_PAGE_START >> XC_PAGE_SHIFT);
- }
-
- phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- page_array, nr_pages);
- if (phys_ram_base == 0) {
- fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
- exit(-1);
- }
- free(page_array);
-#endif
-
- timeoffset_get();
-
-
- pc_machine.init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
- snapshot, kernel_filename, kernel_cmdline, initrd_filename,
- direct_pci);
-}
-
-QEMUMachine xenfv_machine = {
- "xenfv",
- "Xen Fully-virtualized PC",
- xen_init_fv,
-};
-
-/*
- * Local variables:
- * indent-tabs-mode: nil
- * c-indent-level: 4
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
diff --git a/tools/ioemu/hw/xen_machine_pv.c b/tools/ioemu/hw/xen_machine_pv.c
deleted file mode 100644
index 5cf5a695d4..0000000000
--- a/tools/ioemu/hw/xen_machine_pv.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * QEMU Xen PV Machine
- *
- * Copyright (c) 2007 Red Hat
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-#include "xen_console.h"
-#include "xenfb.h"
-
-extern void init_blktap(void);
-
-
-/* The Xen PV machine currently provides
- * - a virtual framebuffer
- * - ....
- */
-static void xen_init_pv(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *direct_pci)
-{
- struct xenfb *xenfb;
- extern int domid;
-
-
-#ifndef CONFIG_STUBDOM
- /* Initialize tapdisk client */
- init_blktap();
-#endif
-
- /* Connect to text console */
- if (serial_hds[0]) {
- if (xencons_init(domid, serial_hds[0]) < 0) {
- fprintf(stderr, "Could not connect to domain console\n");
- exit(1);
- }
- }
-
- /* Prepare PVFB state */
- xenfb = xenfb_new(domid, ds);
- if (xenfb == NULL) {
- fprintf(stderr, "Could not create framebuffer (%s)\n",
- strerror(errno));
- exit(1);
- }
-}
-
-QEMUMachine xenpv_machine = {
- "xenpv",
- "Xen Para-virtualized PC",
- xen_init_pv,
-};
-
-/*
- * Local variables:
- * indent-tabs-mode: nil
- * c-indent-level: 4
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
diff --git a/tools/ioemu/hw/xen_platform.c b/tools/ioemu/hw/xen_platform.c
deleted file mode 100644
index cb34d63f7c..0000000000
--- a/tools/ioemu/hw/xen_platform.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * XEN platform fake pci device, formerly known as the event channel device
- *
- * Copyright (c) 2003-2004 Intel Corp.
- * Copyright (c) 2006 XenSource
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#include <xenguest.h>
-
-extern FILE *logfile;
-
-#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
-
-typedef struct PCIXenPlatformState
-{
- PCIDevice pci_dev;
- uint8_t platform_flags;
- uint64_t vga_stolen_ram;
-} PCIXenPlatformState;
-
-static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
-{
- PCIXenPlatformState *s = opaque;
-
- addr &= 0xff;
-
- return (addr == 0) ? s->platform_flags : ~0u;
-}
-
-static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIXenPlatformState *d = opaque;
-
- addr &= 0xff;
- val &= 0xff;
-
- switch (addr) {
- case 0: /* Platform flags */ {
- hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
- HVMMEM_ram_ro : HVMMEM_ram_rw;
- if (xc_hvm_set_mem_type(xc_handle, domid, mem_type, 0xc0, 0x40))
- fprintf(logfile,"xen_platform: unable to change ro/rw "
- "state of ROM memory area!\n");
- else
- d->platform_flags = val & PFFLAG_ROM_LOCK;
- break;
- }
- default:
- break;
- }
-}
-
-
-static uint32_t xen_platform_ioport_readl(void *opaque, uint32_t addr)
-{
- PCIXenPlatformState *d = opaque;
-
- addr &= 0xff;
-
- switch (addr) {
- case 4: /* VGA stolen memory address */
- return d->vga_stolen_ram;
- default:
- return ~0u;
- }
-}
-
-static void xen_platform_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIXenPlatformState *d = opaque;
-
- addr &= 0xff;
- val &= 0xffffffff;
-
- switch (addr) {
- case 4: /* VGA stolen memory address */
- d->vga_stolen_ram = val;
- xen_vga_stolen_vram_addr(val);
- break;
- default:
- break;
- }
-}
-
-
-
-static void platform_ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type)
-{
- PCIXenPlatformState *d = (PCIXenPlatformState *)pci_dev;
- register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
- register_ioport_write(addr, size, 4, xen_platform_ioport_writel, d);
- register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
- register_ioport_read(addr, size, 4, xen_platform_ioport_readl, d);
-}
-
-static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
-{
- static int warnings = 0;
- if (warnings < 5) {
- fprintf(logfile, "Warning: attempted read from physical address "
- "0x%"PRIx64" in xen platform mmio space\n", (uint64_t)addr);
- warnings++;
- }
- return 0;
-}
-
-static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- static int warnings = 0;
- if (warnings < 5) {
- fprintf(logfile, "Warning: attempted write of 0x%x to physical "
- "address 0x%"PRIx64" in xen platform mmio space\n",
- val, (uint64_t)addr);
- warnings++;
- }
- return;
-}
-
-static CPUReadMemoryFunc *platform_mmio_read_funcs[3] = {
- platform_mmio_read,
- platform_mmio_read,
- platform_mmio_read,
-};
-
-static CPUWriteMemoryFunc *platform_mmio_write_funcs[3] = {
- platform_mmio_write,
- platform_mmio_write,
- platform_mmio_write,
-};
-
-static void platform_mmio_map(PCIDevice *d, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- int mmio_io_addr;
-
- mmio_io_addr = cpu_register_io_memory(0, platform_mmio_read_funcs,
- platform_mmio_write_funcs, NULL);
-
- cpu_register_physical_memory(addr, 0x1000000, mmio_io_addr);
-}
-
-struct pci_config_header {
- uint16_t vendor_id;
- uint16_t device_id;
- uint16_t command;
- uint16_t status;
- uint8_t revision;
- uint8_t api;
- uint8_t subclass;
- uint8_t class;
- uint8_t cache_line_size; /* Units of 32 bit words */
- uint8_t latency_timer; /* In units of bus cycles */
- uint8_t header_type; /* Should be 0 */
- uint8_t bist; /* Built in self test */
- uint32_t base_address_regs[6];
- uint32_t reserved1;
- uint16_t subsystem_vendor_id;
- uint16_t subsystem_id;
- uint32_t rom_addr;
- uint32_t reserved3;
- uint32_t reserved4;
- uint8_t interrupt_line;
- uint8_t interrupt_pin;
- uint8_t min_gnt;
- uint8_t max_lat;
-};
-
-void xen_pci_save(QEMUFile *f, void *opaque)
-{
- PCIXenPlatformState *d = opaque;
-
- pci_device_save(&d->pci_dev, f);
- qemu_put_8s(f, &d->platform_flags);
- qemu_put_be64s(f, &d->vga_stolen_ram);
-}
-
-int xen_pci_load(QEMUFile *f, void *opaque, int version_id)
-{
- PCIXenPlatformState *d = opaque;
- int ret;
-
- if (version_id > 2)
- return -EINVAL;
-
- ret = pci_device_load(&d->pci_dev, f);
- if (ret < 0)
- return ret;
-
- if (version_id >= 2) {
- uint8_t flags;
- qemu_get_8s(f, &flags);
- xen_platform_ioport_writeb(d, 0, flags);
- qemu_get_be64s(f, &d->vga_stolen_ram);
- }
-
- return 0;
-}
-
-void pci_xen_platform_init(PCIBus *bus)
-{
- PCIXenPlatformState *d;
- struct pci_config_header *pch;
-
- printf("Register xen platform.\n");
- d = (PCIXenPlatformState *)pci_register_device(
- bus, "xen-platform", sizeof(PCIXenPlatformState), -1, NULL, NULL);
- pch = (struct pci_config_header *)d->pci_dev.config;
- pch->vendor_id = 0x5853;
- pch->device_id = 0x0001;
- pch->command = 3; /* IO and memory access */
- pch->revision = 1;
- pch->api = 0;
- pch->subclass = 0x80; /* Other */
- pch->class = 0xff; /* Unclassified device class */
- pch->header_type = 0;
- pch->interrupt_pin = 1;
-
- /* Microsoft WHQL requires non-zero subsystem IDs. */
- /* http://www.pcisig.com/reflector/msg02205.html. */
- pch->subsystem_vendor_id = pch->vendor_id; /* Duplicate vendor id. */
- pch->subsystem_id = 0x0001; /* Hardcode sub-id as 1. */
-
- pci_register_io_region(&d->pci_dev, 0, 0x100,
- PCI_ADDRESS_SPACE_IO, platform_ioport_map);
-
- /* reserve 16MB mmio address for share memory*/
- pci_register_io_region(&d->pci_dev, 1, 0x1000000,
- PCI_ADDRESS_SPACE_MEM_PREFETCH, platform_mmio_map);
-
- xen_platform_ioport_writeb(d, 0, 0);
-
- register_savevm("platform", 0, 2, xen_pci_save, xen_pci_load, d);
- printf("Done register platform.\n");
-}
diff --git a/tools/ioemu/hw/xenfb.c b/tools/ioemu/hw/xenfb.c
deleted file mode 100644
index 1e8a1e998f..0000000000
--- a/tools/ioemu/hw/xenfb.c
+++ /dev/null
@@ -1,1341 +0,0 @@
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <xenctrl.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/fbif.h>
-#include <xen/io/kbdif.h>
-#include <xen/io/protocols.h>
-#include <stdbool.h>
-#include <xen/event_channel.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <xs.h>
-
-#include "xenfb.h"
-
-#ifndef BTN_LEFT
-#define BTN_LEFT 0x110 /* from <linux/input.h> */
-#endif
-
-struct xenfb;
-
-struct xenfb_device {
- const char *devicetype;
- char nodename[64]; /* backend xenstore dir */
- char otherend[64]; /* frontend xenstore dir */
- int otherend_id; /* frontend domid */
- enum xenbus_state state; /* backend state */
- void *page; /* shared page */
- evtchn_port_t port;
- struct xenfb *xenfb;
-};
-
-struct xenfb {
- DisplayState *ds; /* QEMU graphical console state */
- int evt_xch; /* event channel driver handle */
- int xc; /* hypervisor interface handle */
- struct xs_handle *xsh; /* xs daemon handle */
- struct xenfb_device fb, kbd;
- void *pixels; /* guest framebuffer data */
- size_t fb_len; /* size of framebuffer */
- int row_stride; /* width of one row in framebuffer */
- int depth; /* colour depth of guest framebuffer */
- int width; /* pixel width of guest framebuffer */
- int height; /* pixel height of guest framebuffer */
- int offset; /* offset of the framebuffer */
- int abs_pointer_wanted; /* Whether guest supports absolute pointer */
- int button_state; /* Last seen pointer button state */
- int refresh_period; /* The refresh period we have advised */
- char protocol[64]; /* frontend protocol */
-};
-
-/* Functions for frontend/backend state machine*/
-static int xenfb_wait_for_frontend(struct xenfb_device *dev, IOHandler *handler);
-static int xenfb_wait_for_backend(struct xenfb_device *dev, IOHandler *handler);
-static void xenfb_backend_created_kbd(void *opaque);
-static void xenfb_backend_created_fb(void *opaque);
-static void xenfb_frontend_initialized_kbd(void *opaque);
-static void xenfb_frontend_initialized_fb(void *opaque);
-static void xenfb_frontend_connected_kbd(void *opaque);
-
-/* Helper functions for checking state of frontend/backend devices */
-static int xenfb_frontend_connected(struct xenfb_device *dev);
-static int xenfb_frontend_initialized(struct xenfb_device *dev);
-static int xenfb_backend_created(struct xenfb_device *dev);
-
-/* Functions which tie the PVFB into the QEMU device model */
-static void xenfb_key_event(void *opaque, int keycode);
-static void xenfb_mouse_event(void *opaque,
- int dx, int dy, int dz, int button_state);
-static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h);
-static void xenfb_update(void *opaque);
-static void xenfb_invalidate(void *opaque);
-static void xenfb_screen_dump(void *opaque, const char *name);
-static int xenfb_register_console(struct xenfb *xenfb);
-
-/*
- * Tables to map from scancode to Linux input layer keycode.
- * Scancodes are hardware-specific. These maps assumes a
- * standard AT or PS/2 keyboard which is what QEMU feeds us.
- */
-const unsigned char atkbd_set2_keycode[512] = {
-
- 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117,
- 0, 56, 42, 93, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0,
- 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
- 0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185,
- 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
- 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85,
- 0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0,
- 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125,
- 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127,
- 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142,
- 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0,
- 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112,
- 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0,
-
-};
-
-const unsigned char atkbd_unxlate_table[128] = {
-
- 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
- 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
- 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
- 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
- 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
- 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
- 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
- 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
-
-};
-
-static unsigned char scancode2linux[512];
-
-static int xenfb_xs_scanf1(struct xs_handle *xsh,
- const char *dir, const char *node,
- const char *fmt, void *dest)
-{
- char buf[1024];
- char *p;
- int ret;
-
- if (snprintf(buf, sizeof(buf), "%s/%s", dir, node) >= sizeof(buf)) {
- errno = ENOENT;
- return -1;
- }
- p = xs_read(xsh, XBT_NULL, buf, NULL);
- if (!p) {
- errno = ENOENT;
- return -1;
- }
- ret = sscanf(p, fmt, dest);
- free(p);
- if (ret != 1) {
- errno = EDOM;
- return -1;
- }
- return ret;
-}
-
-static int xenfb_xs_printf(struct xs_handle *xsh,
- const char *dir, const char *node, char *fmt, ...)
-{
- va_list ap;
- char key[1024];
- char val[1024];
- int n;
-
- if (snprintf(key, sizeof(key), "%s/%s", dir, node) >= sizeof(key)) {
- errno = ENOENT;
- return -1;
- }
-
- va_start(ap, fmt);
- n = vsnprintf(val, sizeof(val), fmt, ap);
- va_end(ap);
- if (n >= sizeof(val)) {
- errno = ENOSPC; /* close enough */
- return -1;
- }
-
- if (!xs_write(xsh, XBT_NULL, key, val, n))
- return -1;
- return 0;
-}
-
-static void xenfb_device_init(struct xenfb_device *dev,
- const char *type,
- struct xenfb *xenfb)
-{
- dev->devicetype = type;
- dev->otherend_id = -1;
- dev->port = -1;
- dev->xenfb = xenfb;
-}
-
-static char *xenfb_path_in_dom(struct xs_handle *xsh,
- char *buf, size_t size,
- unsigned domid, const char *fmt, ...)
-{
- va_list ap;
- char *domp = xs_get_domain_path(xsh, domid);
- int n;
-
- if (domp == NULL)
- return NULL;
-
- n = snprintf(buf, size, "%s/", domp);
- free(domp);
- if (n >= size)
- return NULL;
-
- va_start(ap, fmt);
- n += vsnprintf(buf + n, size - n, fmt, ap);
- va_end(ap);
- if (n >= size)
- return NULL;
-
- return buf;
-}
-
-static int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
-{
- dev->otherend_id = domid;
-
- if (!xenfb_path_in_dom(dev->xenfb->xsh,
- dev->otherend, sizeof(dev->otherend),
- domid, "device/%s/0", dev->devicetype)) {
- errno = ENOENT;
- return -1;
- }
- if (!xenfb_path_in_dom(dev->xenfb->xsh,
- dev->nodename, sizeof(dev->nodename),
- 0, "backend/%s/%d/0", dev->devicetype, domid)) {
- errno = ENOENT;
- return -1;
- }
-
- return 0;
-}
-
-struct xenfb *xenfb_new(int domid, DisplayState *ds)
-{
- struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
- int serrno;
- int i;
-
- if (xenfb == NULL)
- return NULL;
-
- /* Prepare scancode mapping table */
- for (i = 0; i < 128; i++) {
- scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
- scancode2linux[i | 0x80] =
- atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
- }
-
- memset(xenfb, 0, sizeof(*xenfb));
- xenfb->evt_xch = xenfb->xc = -1;
- xenfb_device_init(&xenfb->fb, "vfb", xenfb);
- xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
-
- xenfb->evt_xch = xc_evtchn_open();
- if (xenfb->evt_xch == -1)
- goto fail;
-
- xenfb->xc = xc_interface_open();
- if (xenfb->xc == -1)
- goto fail;
-
- xenfb->xsh = xs_daemon_open();
- if (!xenfb->xsh)
- goto fail;
-
- xenfb->ds = ds;
- xenfb_device_set_domain(&xenfb->fb, domid);
- xenfb_device_set_domain(&xenfb->kbd, domid);
-
- fprintf(stderr, "FB: Waiting for KBD backend creation\n");
- xenfb_wait_for_backend(&xenfb->kbd, xenfb_backend_created_kbd);
-
- return xenfb;
-
- fail:
- serrno = errno;
- xenfb_shutdown(xenfb);
- errno = serrno;
- return NULL;
-}
-
-
-static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
- const char *dir)
-{
- int ret, state;
-
- ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
- if (ret < 0)
- return XenbusStateUnknown;
-
- if ((unsigned)state > XenbusStateClosed)
- state = XenbusStateUnknown;
- return state;
-}
-
-static int xenfb_switch_state(struct xenfb_device *dev,
- enum xenbus_state state)
-{
- struct xs_handle *xsh = dev->xenfb->xsh;
-
- if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
- return -1;
- dev->state = state;
- return 0;
-}
-
-
-static int xenfb_hotplug(struct xenfb_device *dev)
-{
- if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename,
- "hotplug-status", "connected"))
- return -1;
- return 0;
-}
-
-static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
-{
- uint32_t *src32 = src;
- uint64_t *src64 = src;
- int i;
-
- for (i = 0; i < count; i++)
- dst[i] = (mode == 32) ? src32[i] : src64[i];
-}
-
-static int xenfb_map_fb(struct xenfb *xenfb, int domid)
-{
- struct xenfb_page *page = xenfb->fb.page;
- int n_fbmfns;
- int n_fbdirs;
- unsigned long *pgmfns = NULL;
- unsigned long *fbmfns = NULL;
- void *map, *pd;
- int mode, ret = -1;
-
- /* default to native */
- pd = page->pd;
- mode = sizeof(unsigned long) * 8;
-
- if (0 == strlen(xenfb->protocol)) {
- /*
- * Undefined protocol, some guesswork needed.
- *
- * Old frontends which don't set the protocol use
- * one page directory only, thus pd[1] must be zero.
- * pd[1] of the 32bit struct layout and the lower
- * 32 bits of pd[0] of the 64bit struct layout have
- * the same location, so we can check that ...
- */
- uint32_t *ptr32 = NULL;
- uint32_t *ptr64 = NULL;
-#if defined(__i386__)
- ptr32 = (void*)page->pd;
- ptr64 = ((void*)page->pd) + 4;
-#elif defined(__x86_64__)
- ptr32 = ((void*)page->pd) - 4;
- ptr64 = (void*)page->pd;
-#endif
- if (ptr32) {
- if (0 == ptr32[1]) {
- mode = 32;
- pd = ptr32;
- } else {
- mode = 64;
- pd = ptr64;
- }
- }
-#if defined(__x86_64__)
- } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
- /* 64bit dom0, 32bit domU */
- mode = 32;
- pd = ((void*)page->pd) - 4;
-#elif defined(__i386__)
- } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
- /* 32bit dom0, 64bit domU */
- mode = 64;
- pd = ((void*)page->pd) + 4;
-#endif
- }
-
- n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
- n_fbdirs = n_fbmfns * mode / 8;
- n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
-
- pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
- fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
- if (!pgmfns || !fbmfns)
- goto out;
-
- xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
- map = xc_map_foreign_pages(xenfb->xc, domid,
- PROT_READ, pgmfns, n_fbdirs);
- if (map == NULL)
- goto out;
- xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
- munmap(map, n_fbdirs * XC_PAGE_SIZE);
-
- xenfb->pixels = xc_map_foreign_pages(xenfb->xc, domid,
- PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
- if (xenfb->pixels == NULL)
- goto out;
-
- ret = 0; /* all is fine */
-
- out:
- if (pgmfns)
- free(pgmfns);
- if (fbmfns)
- free(fbmfns);
- return ret;
-}
-
-static int xenfb_bind(struct xenfb_device *dev)
-{
- struct xenfb *xenfb = dev->xenfb;
- unsigned long mfn;
- evtchn_port_t evtchn;
-
- if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu",
- &mfn) < 0)
- return -1;
- if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u",
- &evtchn) < 0)
- return -1;
-
- dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch,
- dev->otherend_id, evtchn);
- if (dev->port == -1)
- return -1;
-
- dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id,
- XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
- if (dev->page == NULL)
- return -1;
-
- return 0;
-}
-
-static void xenfb_unbind(struct xenfb_device *dev)
-{
- if (dev->page) {
- munmap(dev->page, XC_PAGE_SIZE);
- dev->page = NULL;
- }
- if (dev->port >= 0) {
- xc_evtchn_unbind(dev->xenfb->evt_xch, dev->port);
- dev->port = -1;
- }
-}
-
-
-static void xenfb_detach_dom(struct xenfb *xenfb)
-{
- xenfb_unbind(&xenfb->fb);
- xenfb_unbind(&xenfb->kbd);
- if (xenfb->pixels) {
- munmap(xenfb->pixels, xenfb->fb_len);
- xenfb->pixels = NULL;
- }
-}
-
-/* Remove the backend area in xenbus since the framebuffer really is
- going away. */
-void xenfb_shutdown(struct xenfb *xenfb)
-{
- fprintf(stderr, "FB: Shutting down backend\n");
- xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
- xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
-
- xenfb_detach_dom(xenfb);
- if (xenfb->xc >= 0)
- xc_interface_close(xenfb->xc);
- if (xenfb->evt_xch >= 0)
- xc_evtchn_close(xenfb->evt_xch);
- if (xenfb->xsh)
- xs_daemon_close(xenfb->xsh);
- free(xenfb);
-}
-
-static int xenfb_configure_fb(struct xenfb *xenfb, size_t fb_len_lim,
- int width, int height, int depth,
- size_t fb_len, int offset, int row_stride)
-{
- size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
- size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
- size_t fb_pages = pd_len * XC_PAGE_SIZE / mfn_sz;
- size_t fb_len_max = fb_pages * XC_PAGE_SIZE;
- int max_width, max_height;
-
- if (fb_len_lim > fb_len_max) {
- fprintf(stderr,
- "FB: fb size limit %zu exceeds %zu, corrected\n",
- fb_len_lim, fb_len_max);
- fb_len_lim = fb_len_max;
- }
- if (fb_len_lim && fb_len > fb_len_lim) {
- fprintf(stderr,
- "FB: frontend fb size %zu limited to %zu\n",
- fb_len, fb_len_lim);
- fb_len = fb_len_lim;
- }
- if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
- fprintf(stderr,
- "FB: can't handle frontend fb depth %d\n",
- depth);
- return -1;
- }
- if (row_stride < 0 || row_stride > fb_len) {
- fprintf(stderr,
- "FB: invalid frontend stride %d\n", row_stride);
- return -1;
- }
- max_width = row_stride / (depth / 8);
- if (width < 0 || width > max_width) {
- fprintf(stderr,
- "FB: invalid frontend width %d limited to %d\n",
- width, max_width);
- width = max_width;
- }
- if (offset < 0 || offset >= fb_len) {
- fprintf(stderr,
- "FB: invalid frontend offset %d (max %zu)\n",
- offset, fb_len - 1);
- return -1;
- }
- max_height = (fb_len - offset) / row_stride;
- if (height < 0 || height > max_height) {
- fprintf(stderr,
- "FB: invalid frontend height %d limited to %d\n",
- height, max_height);
- height = max_height;
- }
- xenfb->fb_len = fb_len;
- xenfb->row_stride = row_stride;
- xenfb->depth = depth;
- xenfb->width = width;
- xenfb->height = height;
- xenfb->offset = offset;
- fprintf(stderr, "Framebuffer %dx%dx%d offset %d stride %d\n",
- width, height, depth, offset, row_stride);
- return 0;
-}
-
-static void xenfb_on_fb_event(struct xenfb *xenfb)
-{
- uint32_t prod, cons;
- struct xenfb_page *page = xenfb->fb.page;
-
- prod = page->out_prod;
- if (prod == page->out_cons)
- return;
- xen_rmb(); /* ensure we see ring contents up to prod */
- for (cons = page->out_cons; cons != prod; cons++) {
- union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
- int x, y, w, h;
-
- switch (event->type) {
- case XENFB_TYPE_UPDATE:
- x = MAX(event->update.x, 0);
- y = MAX(event->update.y, 0);
- w = MIN(event->update.width, xenfb->width - x);
- h = MIN(event->update.height, xenfb->height - y);
- if (w < 0 || h < 0) {
- fprintf(stderr, "%s bogus update ignored\n",
- xenfb->fb.nodename);
- break;
- }
- if (x != event->update.x || y != event->update.y
- || w != event->update.width
- || h != event->update.height) {
- fprintf(stderr, "%s bogus update clipped\n",
- xenfb->fb.nodename);
- }
- xenfb_guest_copy(xenfb, x, y, w, h);
- break;
- case XENFB_TYPE_RESIZE:
- if (xenfb_configure_fb(xenfb, xenfb->fb_len,
- event->resize.width,
- event->resize.height,
- event->resize.depth,
- xenfb->fb_len,
- event->resize.offset,
- event->resize.stride) < 0)
- break;
- if (xenfb->ds->dpy_resize_shared)
- dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
- else
- dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
- xenfb_invalidate(xenfb);
- break;
- }
- }
- xen_mb(); /* ensure we're done with ring contents */
- page->out_cons = cons;
- xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
-}
-
-static int xenfb_queue_full(struct xenfb *xenfb)
-{
- struct xenfb_page *page = xenfb->fb.page;
- uint32_t cons, prod;
-
- prod = page->in_prod;
- cons = page->in_cons;
- return prod - cons == XENFB_IN_RING_LEN;
-}
-
-static void xenfb_send_event(struct xenfb *xenfb, union xenfb_in_event *event)
-{
- uint32_t prod;
- struct xenfb_page *page = xenfb->fb.page;
-
- prod = page->in_prod;
- /* caller ensures !xenfb_queue_full() */
- xen_mb(); /* ensure ring space available */
- XENFB_IN_RING_REF(page, prod) = *event;
- xen_wmb(); /* ensure ring contents visible */
- page->in_prod = prod + 1;
-
- xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
-}
-
-static void xenfb_send_refresh_period(struct xenfb *xenfb, int period)
-{
- union xenfb_in_event event;
-
- memset(&event, 0, sizeof(event));
- event.type = XENFB_TYPE_REFRESH_PERIOD;
- event.refresh_period.period = period;
- xenfb_send_event(xenfb, &event);
-}
-
-static void xenfb_on_kbd_event(struct xenfb *xenfb)
-{
- struct xenkbd_page *page = xenfb->kbd.page;
-
- /* We don't understand any keyboard events, so just ignore them. */
- if (page->out_prod == page->out_cons)
- return;
- page->out_cons = page->out_prod;
- xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-static int xenfb_on_state_change(struct xenfb_device *dev)
-{
- enum xenbus_state state;
-
- state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
-
- switch (state) {
- case XenbusStateUnknown:
- /* There was an error reading the frontend state. The
- domain has probably gone away; in any case, there's
- not much point in us continuing. */
- return -1;
- case XenbusStateInitialising:
- case XenbusStateInitWait:
- case XenbusStateInitialised:
- case XenbusStateConnected:
- break;
- case XenbusStateClosing:
- xenfb_unbind(dev);
- xenfb_switch_state(dev, state);
- break;
- case XenbusStateClosed:
- xenfb_switch_state(dev, state);
- }
- return 0;
-}
-
-/* Send an event to the keyboard frontend driver */
-static int xenfb_kbd_event(struct xenfb *xenfb,
- union xenkbd_in_event *event)
-{
- uint32_t prod;
- struct xenkbd_page *page = xenfb->kbd.page;
-
- if (xenfb->kbd.state != XenbusStateConnected)
- return 0;
-
- prod = page->in_prod;
- if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
- errno = EAGAIN;
- return -1;
- }
-
- xen_mb(); /* ensure ring space available */
- XENKBD_IN_RING_REF(page, prod) = *event;
- xen_wmb(); /* ensure ring contents visible */
- page->in_prod = prod + 1;
- return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-/* Send a keyboard (or mouse button) event */
-static int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode)
-{
- union xenkbd_in_event event;
-
- memset(&event, 0, XENKBD_IN_EVENT_SIZE);
- event.type = XENKBD_TYPE_KEY;
- event.key.pressed = down ? 1 : 0;
- event.key.keycode = keycode;
-
- return xenfb_kbd_event(xenfb, &event);
-}
-
-/* Send a relative mouse movement event */
-static int xenfb_send_motion(struct xenfb *xenfb,
- int rel_x, int rel_y, int rel_z)
-{
- union xenkbd_in_event event;
-
- memset(&event, 0, XENKBD_IN_EVENT_SIZE);
- event.type = XENKBD_TYPE_MOTION;
- event.motion.rel_x = rel_x;
- event.motion.rel_y = rel_y;
- event.motion.rel_z = rel_z;
-
- return xenfb_kbd_event(xenfb, &event);
-}
-
-/* Send an absolute mouse movement event */
-static int xenfb_send_position(struct xenfb *xenfb,
- int abs_x, int abs_y, int rel_z)
-{
- union xenkbd_in_event event;
-
- memset(&event, 0, XENKBD_IN_EVENT_SIZE);
- event.type = XENKBD_TYPE_POS;
- event.pos.abs_x = abs_x;
- event.pos.abs_y = abs_y;
- event.pos.rel_z = rel_z;
-
- return xenfb_kbd_event(xenfb, &event);
-}
-
-/* Process events from the frontend event channel */
-static void xenfb_dispatch_channel(void *opaque)
-{
- struct xenfb *xenfb = (struct xenfb *)opaque;
- evtchn_port_t port;
- port = xc_evtchn_pending(xenfb->evt_xch);
- if (port == -1) {
- xenfb_shutdown(xenfb);
- exit(1);
- }
-
- if (port == xenfb->fb.port)
- xenfb_on_fb_event(xenfb);
- else if (port == xenfb->kbd.port)
- xenfb_on_kbd_event(xenfb);
-
- if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1) {
- xenfb_shutdown(xenfb);
- exit(1);
- }
-}
-
-/* Process ongoing events from the frontend devices */
-static void xenfb_dispatch_store(void *opaque)
-{
- struct xenfb *xenfb = (struct xenfb *)opaque;
- unsigned dummy;
- char **vec;
- int r;
-
- vec = xs_read_watch(xenfb->xsh, &dummy);
- free(vec);
- r = xenfb_on_state_change(&xenfb->fb);
- if (r == 0)
- r = xenfb_on_state_change(&xenfb->kbd);
- if (r < 0) {
- xenfb_shutdown(xenfb);
- exit(1);
- }
-}
-
-
-/****************************************************************
- *
- * Functions for processing frontend config
- *
- ****************************************************************/
-
-
-/* Process the frontend framebuffer config */
-static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) {
- struct xenfb_page *fb_page;
- int val;
- int videoram;
-
- if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update",
- "%d", &val) < 0)
- val = 0;
- if (!val) {
- fprintf(stderr, "feature-update not supported\n");
- errno = ENOTSUP;
- return -1;
- }
- if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "protocol", "%63s",
- xenfb->protocol) < 0)
- xenfb->protocol[0] = '\0';
- xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1");
- xenfb->refresh_period = -1;
-
- if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.nodename, "videoram", "%d",
- &videoram) < 0)
- videoram = 0;
- fb_page = xenfb->fb.page;
- if (xenfb_configure_fb(xenfb, videoram * 1024 * 1024U,
- fb_page->width, fb_page->height, fb_page->depth,
- fb_page->mem_length, 0, fb_page->line_length)
- < 0) {
- errno = EINVAL;
- return -1;
- }
-
- if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0)
- return -1;
-
- /* Indicate we have the frame buffer resize feature */
- xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "feature-resize", "1");
-
- /* Tell kbd pointer the screen geometry */
- xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "width", "%d", xenfb->width);
- xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "height", "%d", xenfb->height);
-
- if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
- return -1;
- if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
- return -1;
-
- return 0;
-}
-
-/* Process the frontend keyboard config */
-static int xenfb_read_frontend_kbd_config(struct xenfb *xenfb)
-{
- int val;
-
- if (xenfb_xs_scanf1(xenfb->xsh, xenfb->kbd.otherend, "request-abs-pointer",
- "%d", &val) < 0)
- val = 0;
- xenfb->abs_pointer_wanted = val;
-
- return 0;
-}
-
-
-/****************************************************************
- *
- * Functions for frontend/backend state machine
- *
- ****************************************************************/
-
-/* Register a watch against a frontend device, and setup
- * QEMU event loop to poll the xenstore FD for notification */
-static int xenfb_wait_for_frontend(struct xenfb_device *dev, IOHandler *handler)
-{
- fprintf(stderr, "Doing frontend watch on %s\n", dev->otherend);
- if (!xs_watch(dev->xenfb->xsh, dev->otherend, "")) {
- fprintf(stderr, "Watch for dev failed\n");
- return -1;
- }
-
- if (qemu_set_fd_handler2(xs_fileno(dev->xenfb->xsh), NULL, handler, NULL, dev) < 0)
- return -1;
-
- return 0;
-}
-
-/* Register a watch against a backend device, and setup
- * QEMU event loop to poll the xenstore FD for notification */
-static int xenfb_wait_for_backend(struct xenfb_device *dev, IOHandler *handler)
-{
- fprintf(stderr, "Doing backend watch on %s\n", dev->nodename);
- if (!xs_watch(dev->xenfb->xsh, dev->nodename, "")) {
- fprintf(stderr, "Watch for dev failed\n");
- return -1;
- }
-
- if (qemu_set_fd_handler2(xs_fileno(dev->xenfb->xsh), NULL, handler, NULL, dev) < 0)
- return -1;
-
- return 0;
-}
-
-/* Callback invoked while waiting for KBD backend to change
- * to the created state */
-static void xenfb_backend_created_kbd(void *opaque)
-{
- struct xenfb_device *dev = (struct xenfb_device *)opaque;
- int ret = xenfb_backend_created(dev);
- if (ret < 0) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
- if (ret)
- return; /* Still waiting */
-
- if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename, "feature-abs-pointer", "1")) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
-
- fprintf(stderr, "FB: Waiting for FB backend creation\n");
- xenfb_wait_for_backend(&dev->xenfb->fb, xenfb_backend_created_fb);
-}
-
-/* Callback invoked while waiting for FB backend to change
- * to the created state */
-static void xenfb_backend_created_fb(void *opaque)
-{
- struct xenfb_device *dev = (struct xenfb_device *)opaque;
- int ret = xenfb_backend_created(dev);
- if (ret < 0) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
- if (ret)
- return; /* Still waiting */
-
- fprintf(stderr, "FB: Waiting for KBD frontend initialization\n");
- xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_initialized_kbd);
-}
-
-/* Callback invoked while waiting for KBD frontend to change
- * to the initialized state */
-static void xenfb_frontend_initialized_kbd(void *opaque)
-{
- struct xenfb_device *dev = (struct xenfb_device *)opaque;
- int ret = xenfb_frontend_initialized(dev);
- if (ret < 0) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
- if (ret)
- return; /* Still waiting */
-
-
- fprintf(stderr, "FB: Waiting for FB frontend initialization\n");
- xenfb_wait_for_frontend(&dev->xenfb->fb, xenfb_frontend_initialized_fb);
-}
-
-/* Callback invoked while waiting for FB frontend to change
- * to the initialized state */
-static void xenfb_frontend_initialized_fb(void *opaque)
-{
- struct xenfb_device *dev = (struct xenfb_device *)opaque;
- int ret = xenfb_frontend_initialized(dev);
- if (ret < 0) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
- if (ret)
- return; /* Still waiting */
-
-
- if (xenfb_read_frontend_fb_config(dev->xenfb)) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
-
- fprintf(stderr, "FB: Waiting for KBD frontend connection\n");
- xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_connected_kbd);
-}
-
-/* Callback invoked while waiting for KBD frontend to change
- * to the connected state */
-static void xenfb_frontend_connected_kbd(void *opaque)
-{
- struct xenfb_device *dev = (struct xenfb_device *)opaque;
- int ret = xenfb_frontend_connected(dev);
- if (ret < 0) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
- if (ret)
- return; /* Still waiting */
-
- if (xenfb_read_frontend_kbd_config(dev->xenfb) < 0) {
- xenfb_shutdown(dev->xenfb);
- exit(1);
- }
-
- xenfb_register_console(dev->xenfb);
-}
-
-
-/****************************************************************
- *
- * Helper functions for checking state of frontend/backend devices
- *
- ****************************************************************/
-
-/* Helper to determine if a frontend device is in Connected state */
-static int xenfb_frontend_connected(struct xenfb_device *dev)
-{
- unsigned int state;
- unsigned int dummy;
- char **vec;
- vec = xs_read_watch(dev->xenfb->xsh, &dummy);
- if (!vec)
- return -1;
- free(vec);
-
- state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
- if (!((1 <<state) & ((1 << XenbusStateUnknown) |
- (1 << XenbusStateConnected)))) {
- fprintf(stderr, "FB: Carry on waiting\n");
- return 1;
- }
-
- /* Don't unwatch frontend - we need to detect shutdown */
- /*xs_unwatch(dev->xenfb->xsh, dev->otherend, "");*/
-
- switch (state) {
- case XenbusStateConnected:
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-
-/* Helper to determine if a frontend device is in Initialized state */
-static int xenfb_frontend_initialized(struct xenfb_device *dev)
-{
- unsigned int state;
- unsigned int dummy;
- char **vec;
- vec = xs_read_watch(dev->xenfb->xsh, &dummy);
- if (!vec)
- return -1;
- free(vec);
-
- state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
-
- if (!((1 << state) & ((1 << XenbusStateUnknown)
- | (1 << XenbusStateInitialised)
-#if 1 /* TODO fudging state to permit restarting; to be removed */
- | (1 << XenbusStateConnected)
-#endif
- ))) {
- fprintf(stderr, "FB: Carry on waiting\n");
- return 1;
- }
-
- xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
-
- switch (state) {
-#if 1
- case XenbusStateConnected:
- printf("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */
-#endif
- case XenbusStateInitialised:
- break;
- default:
- return -1;
- }
-
- if (xenfb_bind(dev) < 0)
- return -1;
-
- return 0;
-}
-
-/* Helper to determine if a backend device is in Created state */
-static int xenfb_backend_created(struct xenfb_device *dev)
-{
- unsigned int state;
- unsigned int dummy;
- char **vec;
- vec = xs_read_watch(dev->xenfb->xsh, &dummy);
- if (!vec)
- return -1;
- free(vec);
-
- state = xenfb_read_state(dev->xenfb->xsh, dev->nodename);
-
- if (!((1 <<state) & ((1 << XenbusStateUnknown)
- | (1 << XenbusStateInitialising)
- | (1 << XenbusStateClosed)
-#if 1 /* TODO fudging state to permit restarting; to be removed */
- | (1 << XenbusStateInitWait)
- | (1 << XenbusStateConnected)
- | (1 << XenbusStateClosing)
-#endif
- ))) {
- fprintf(stderr, "FB: Carry on waiting\n");
- return 1;
- }
-
- xs_unwatch(dev->xenfb->xsh, dev->nodename, "");
-
- switch (state) {
-#if 1
- case XenbusStateInitWait:
- case XenbusStateConnected:
- printf("Fudging state to %d\n", XenbusStateInitialising); /* FIXME */
-#endif
- case XenbusStateInitialising:
- case XenbusStateClosing:
- case XenbusStateClosed:
- break;
- default:
- fprintf(stderr, "Wrong state %d\n", state);
- return -1;
- }
- xenfb_switch_state(dev, XenbusStateInitWait);
- if (xenfb_hotplug(dev) < 0)
- return -1;
-
- return 0;
-}
-
-
-/****************************************************************
- *
- * QEMU device model integration functions
- *
- ****************************************************************/
-
-/*
- * Send a key event from the client to the guest OS
- * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
- * We have to turn this into a Linux Input layer keycode.
- *
- * Extra complexity from the fact that with extended scancodes
- * (like those produced by arrow keys) this method gets called
- * twice, but we only want to send a single event. So we have to
- * track the '0xe0' scancode state & collapse the extended keys
- * as needed.
- *
- * Wish we could just send scancodes straight to the guest which
- * already has code for dealing with this...
- */
-static void xenfb_key_event(void *opaque, int scancode)
-{
- static int extended = 0;
- int down = 1;
- if (scancode == 0xe0) {
- extended = 1;
- return;
- } else if (scancode & 0x80) {
- scancode &= 0x7f;
- down = 0;
- }
- if (extended) {
- scancode |= 0x80;
- extended = 0;
- }
- xenfb_send_key(opaque, down, scancode2linux[scancode]);
-}
-
-/*
- * Send a mouse event from the client to the guest OS
- *
- * The QEMU mouse can be in either relative, or absolute mode.
- * Movement is sent separately from button state, which has to
- * be encoded as virtual key events. We also don't actually get
- * given any button up/down events, so have to track changes in
- * the button state.
- */
-static void xenfb_mouse_event(void *opaque,
- int dx, int dy, int dz, int button_state)
-{
- int i;
- struct xenfb *xenfb = opaque;
- if (xenfb->abs_pointer_wanted)
- xenfb_send_position(xenfb,
- dx * (xenfb->ds->width - 1) / 0x7fff,
- dy * (xenfb->ds->height - 1) / 0x7fff,
- dz);
- else
- xenfb_send_motion(xenfb, dx, dy, dz);
-
- for (i = 0 ; i < 8 ; i++) {
- int lastDown = xenfb->button_state & (1 << i);
- int down = button_state & (1 << i);
- if (down == lastDown)
- continue;
-
- if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
- return;
- }
- xenfb->button_state = button_state;
-}
-
-/* A convenient function for munging pixels between different depths */
-#define BLT(SRC_T,DST_T,RSB,GSB,BSB,RDB,GDB,BDB) \
- for (line = y ; line < (y+h) ; line++) { \
- SRC_T *src = (SRC_T *)(xenfb->pixels \
- + xenfb->offset \
- + (line * xenfb->row_stride) \
- + (x * xenfb->depth / 8)); \
- DST_T *dst = (DST_T *)(xenfb->ds->data \
- + (line * xenfb->ds->linesize) \
- + (x * xenfb->ds->depth / 8)); \
- int col; \
- const int RSS = 32 - (RSB + GSB + BSB); \
- const int GSS = 32 - (GSB + BSB); \
- const int BSS = 32 - (BSB); \
- const uint32_t RSM = (~0U) << (32 - RSB); \
- const uint32_t GSM = (~0U) << (32 - GSB); \
- const uint32_t BSM = (~0U) << (32 - BSB); \
- const int RDS = 32 - (RDB + GDB + BDB); \
- const int GDS = 32 - (GDB + BDB); \
- const int BDS = 32 - (BDB); \
- const uint32_t RDM = (~0U) << (32 - RDB); \
- const uint32_t GDM = (~0U) << (32 - GDB); \
- const uint32_t BDM = (~0U) << (32 - BDB); \
- for (col = x ; col < (x+w) ; col++) { \
- uint32_t spix = *src; \
- *dst = (((spix << RSS) & RSM & RDM) >> RDS) | \
- (((spix << GSS) & GSM & GDM) >> GDS) | \
- (((spix << BSS) & BSM & BDM) >> BDS); \
- src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8); \
- dst = (DST_T *) ((unsigned long) dst + xenfb->ds->depth / 8); \
- } \
- }
-
-
-/* This copies data from the guest framebuffer region, into QEMU's copy
- * NB. QEMU's copy is stored in the pixel format of a) the local X
- * server (SDL case) or b) the current VNC client pixel format.
- * When shifting between colour depths we preserve the MSB.
- */
-static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
-{
- int line;
-
- if (!xenfb->ds->shared_buf) {
- if (xenfb->depth == xenfb->ds->depth) { /* Perfect match can use fast path */
- for (line = y ; line < (y+h) ; line++) {
- memcpy(xenfb->ds->data + (line * xenfb->ds->linesize) + (x * xenfb->ds->depth / 8),
- xenfb->pixels + xenfb->offset + (line * xenfb->row_stride) + (x * xenfb->depth / 8),
- w * xenfb->depth / 8);
- }
- } else { /* Mismatch requires slow pixel munging */
- /* 8 bit == r:3 g:3 b:2 */
- /* 16 bit == r:5 g:6 b:5 */
- /* 24 bit == r:8 g:8 b:8 */
- /* 32 bit == r:8 g:8 b:8 (padding:8) */
- if (xenfb->depth == 8) {
- if (xenfb->ds->depth == 16) {
- BLT(uint8_t, uint16_t, 3, 3, 2, 5, 6, 5);
- } else if (xenfb->ds->depth == 32) {
- BLT(uint8_t, uint32_t, 3, 3, 2, 8, 8, 8);
- }
- } else if (xenfb->depth == 16) {
- if (xenfb->ds->depth == 8) {
- BLT(uint16_t, uint8_t, 5, 6, 5, 3, 3, 2);
- } else if (xenfb->ds->depth == 32) {
- BLT(uint16_t, uint32_t, 5, 6, 5, 8, 8, 8);
- }
- } else if (xenfb->depth == 24 || xenfb->depth == 32) {
- if (xenfb->ds->depth == 8) {
- BLT(uint32_t, uint8_t, 8, 8, 8, 3, 3, 2);
- } else if (xenfb->ds->depth == 16) {
- BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5);
- } else if (xenfb->ds->depth == 32) {
- BLT(uint32_t, uint32_t, 8, 8, 8, 8, 8, 8);
- }
- }
- }
- }
- dpy_update(xenfb->ds, x, y, w, h);
-}
-
-/* Periodic update of display, transmit the refresh interval to the frontend */
-static void xenfb_update(void *opaque)
-{
- struct xenfb *xenfb = opaque;
- int period;
-
- if (xenfb_queue_full(xenfb))
- return;
-
- if (xenfb->ds->idle)
- period = XENFB_NO_REFRESH;
- else {
- period = xenfb->ds->gui_timer_interval;
- if (!period)
- period = GUI_REFRESH_INTERVAL;
- }
-
- /* Will have to be disabled for frontends without feature-update */
- if (xenfb->refresh_period != period) {
- xenfb_send_refresh_period(xenfb, period);
- xenfb->refresh_period = period;
- }
-}
-
-/* QEMU display state changed, so refresh the framebuffer copy */
-static void xenfb_invalidate(void *opaque)
-{
- struct xenfb *xenfb = opaque;
- xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
-}
-
-/* Screen dump is not used in Xen, so no need to impl this....yet */
-static void xenfb_screen_dump(void *opaque, const char *name) { }
-
-
-/* Register a QEMU graphical console, and key/mouse handler,
- * connecting up their events to the frontend */
-static int xenfb_register_console(struct xenfb *xenfb) {
- /* Register our keyboard & mouse handlers */
- qemu_add_kbd_event_handler(xenfb_key_event, xenfb);
- qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
- xenfb->abs_pointer_wanted,
- "Xen PVFB Mouse");
-
- /* Tell QEMU to allocate a graphical console */
- graphic_console_init(xenfb->ds,
- xenfb_update,
- xenfb_invalidate,
- xenfb_screen_dump,
- xenfb);
- if (xenfb->ds->dpy_resize_shared)
- dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
- else
- dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
-
- if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
- return -1;
- if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0)
- return -1;
-
- fprintf(stderr, "Xen Framebuffer registered\n");
- return 0;
-}
-
-/*
- * Local variables:
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/tools/ioemu/hw/xenfb.h b/tools/ioemu/hw/xenfb.h
deleted file mode 100644
index 545b6de38b..0000000000
--- a/tools/ioemu/hw/xenfb.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _XENFB_H_
-#define _XENFB_H_
-
-#include "vl.h"
-#include <stdbool.h>
-#include <sys/types.h>
-
-struct xenfb;
-
-struct xenfb *xenfb_new(int domid, DisplayState *ds);
-void xenfb_shutdown(struct xenfb *xenfb);
-extern const unsigned char atkbd_set2_keycode[512];
-extern const unsigned char atkbd_unxlate_table[128];
-
-#endif
diff --git a/tools/ioemu/i386-dis.c b/tools/ioemu/i386-dis.c
deleted file mode 100644
index 0496e141d4..0000000000
--- a/tools/ioemu/i386-dis.c
+++ /dev/null
@@ -1,4143 +0,0 @@
-/* Print i386 instructions for GDB, the GNU debugger.
- Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2001
- Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/*
- * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
- * July 1988
- * modified by John Hassey (hassey@dg-rtp.dg.com)
- * x86-64 support added by Jan Hubicka (jh@suse.cz)
- */
-
-/*
- * The main tables describing the instructions is essentially a copy
- * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
- * Programmers Manual. Usually, there is a capital letter, followed
- * by a small letter. The capital letter tell the addressing mode,
- * and the small letter tells about the operand size. Refer to
- * the Intel manual for details.
- */
-
-#include <stdlib.h>
-#include "dis-asm.h"
-
-#define MAXLEN 20
-
-#include <setjmp.h>
-
-#ifndef UNIXWARE_COMPAT
-/* Set non-zero for broken, compatible instructions. Set to zero for
- non-broken opcodes. */
-#define UNIXWARE_COMPAT 1
-#endif
-
-static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
-static void ckprefix PARAMS ((void));
-static const char *prefix_name PARAMS ((int, int));
-static int print_insn PARAMS ((bfd_vma, disassemble_info *));
-static void dofloat PARAMS ((int));
-static void OP_ST PARAMS ((int, int));
-static void OP_STi PARAMS ((int, int));
-static int putop PARAMS ((const char *, int));
-static void oappend PARAMS ((const char *));
-static void append_seg PARAMS ((void));
-static void OP_indirE PARAMS ((int, int));
-static void print_operand_value PARAMS ((char *, int, bfd_vma));
-static void OP_E PARAMS ((int, int));
-static void OP_G PARAMS ((int, int));
-static bfd_vma get64 PARAMS ((void));
-static bfd_signed_vma get32 PARAMS ((void));
-static bfd_signed_vma get32s PARAMS ((void));
-static int get16 PARAMS ((void));
-static void set_op PARAMS ((bfd_vma, int));
-static void OP_REG PARAMS ((int, int));
-static void OP_IMREG PARAMS ((int, int));
-static void OP_I PARAMS ((int, int));
-static void OP_I64 PARAMS ((int, int));
-static void OP_sI PARAMS ((int, int));
-static void OP_J PARAMS ((int, int));
-static void OP_SEG PARAMS ((int, int));
-static void OP_DIR PARAMS ((int, int));
-static void OP_OFF PARAMS ((int, int));
-static void OP_OFF64 PARAMS ((int, int));
-static void ptr_reg PARAMS ((int, int));
-static void OP_ESreg PARAMS ((int, int));
-static void OP_DSreg PARAMS ((int, int));
-static void OP_C PARAMS ((int, int));
-static void OP_D PARAMS ((int, int));
-static void OP_T PARAMS ((int, int));
-static void OP_Rd PARAMS ((int, int));
-static void OP_MMX PARAMS ((int, int));
-static void OP_XMM PARAMS ((int, int));
-static void OP_EM PARAMS ((int, int));
-static void OP_EX PARAMS ((int, int));
-static void OP_MS PARAMS ((int, int));
-static void OP_XS PARAMS ((int, int));
-static void OP_3DNowSuffix PARAMS ((int, int));
-static void OP_SIMD_Suffix PARAMS ((int, int));
-static void SIMD_Fixup PARAMS ((int, int));
-static void BadOp PARAMS ((void));
-
-struct dis_private {
- /* Points to first byte not fetched. */
- bfd_byte *max_fetched;
- bfd_byte the_buffer[MAXLEN];
- bfd_vma insn_start;
- int orig_sizeflag;
- jmp_buf bailout;
-};
-
-/* The opcode for the fwait instruction, which we treat as a prefix
- when we can. */
-#define FWAIT_OPCODE (0x9b)
-
-/* Set to 1 for 64bit mode disassembly. */
-static int mode_64bit;
-
-/* Flags for the prefixes for the current instruction. See below. */
-static int prefixes;
-
-/* REX prefix the current instruction. See below. */
-static int rex;
-/* Bits of REX we've already used. */
-static int rex_used;
-#define REX_MODE64 8
-#define REX_EXTX 4
-#define REX_EXTY 2
-#define REX_EXTZ 1
-/* Mark parts used in the REX prefix. When we are testing for
- empty prefix (for 8bit register REX extension), just mask it
- out. Otherwise test for REX bit is excuse for existence of REX
- only in case value is nonzero. */
-#define USED_REX(value) \
- { \
- if (value) \
- rex_used |= (rex & value) ? (value) | 0x40 : 0; \
- else \
- rex_used |= 0x40; \
- }
-
-/* Flags for prefixes which we somehow handled when printing the
- current instruction. */
-static int used_prefixes;
-
-/* Flags stored in PREFIXES. */
-#define PREFIX_REPZ 1
-#define PREFIX_REPNZ 2
-#define PREFIX_LOCK 4
-#define PREFIX_CS 8
-#define PREFIX_SS 0x10
-#define PREFIX_DS 0x20
-#define PREFIX_ES 0x40
-#define PREFIX_FS 0x80
-#define PREFIX_GS 0x100
-#define PREFIX_DATA 0x200
-#define PREFIX_ADDR 0x400
-#define PREFIX_FWAIT 0x800
-
-/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
- to ADDR (exclusive) are valid. Returns 1 for success, longjmps
- on error. */
-#define FETCH_DATA(info, addr) \
- ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
- ? 1 : fetch_data ((info), (addr)))
-
-static int
-fetch_data (info, addr)
- struct disassemble_info *info;
- bfd_byte *addr;
-{
- int status;
- struct dis_private *priv = (struct dis_private *) info->private_data;
- bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
-
- status = (*info->read_memory_func) (start,
- priv->max_fetched,
- addr - priv->max_fetched,
- info);
- if (status != 0)
- {
- /* If we did manage to read at least one byte, then
- print_insn_i386 will do something sensible. Otherwise, print
- an error. We do that here because this is where we know
- STATUS. */
- if (priv->max_fetched == priv->the_buffer)
- (*info->memory_error_func) (status, start, info);
- longjmp (priv->bailout, 1);
- }
- else
- priv->max_fetched = addr;
- return 1;
-}
-
-#define XX NULL, 0
-
-#define Eb OP_E, b_mode
-#define Ev OP_E, v_mode
-#define Ed OP_E, d_mode
-#define indirEb OP_indirE, b_mode
-#define indirEv OP_indirE, v_mode
-#define Ew OP_E, w_mode
-#define Ma OP_E, v_mode
-#define M OP_E, 0 /* lea, lgdt, etc. */
-#define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
-#define Gb OP_G, b_mode
-#define Gv OP_G, v_mode
-#define Gd OP_G, d_mode
-#define Gw OP_G, w_mode
-#define Rd OP_Rd, d_mode
-#define Rm OP_Rd, m_mode
-#define Ib OP_I, b_mode
-#define sIb OP_sI, b_mode /* sign extened byte */
-#define Iv OP_I, v_mode
-#define Iq OP_I, q_mode
-#define Iv64 OP_I64, v_mode
-#define Iw OP_I, w_mode
-#define Jb OP_J, b_mode
-#define Jv OP_J, v_mode
-#define Cm OP_C, m_mode
-#define Dm OP_D, m_mode
-#define Td OP_T, d_mode
-
-#define RMeAX OP_REG, eAX_reg
-#define RMeBX OP_REG, eBX_reg
-#define RMeCX OP_REG, eCX_reg
-#define RMeDX OP_REG, eDX_reg
-#define RMeSP OP_REG, eSP_reg
-#define RMeBP OP_REG, eBP_reg
-#define RMeSI OP_REG, eSI_reg
-#define RMeDI OP_REG, eDI_reg
-#define RMrAX OP_REG, rAX_reg
-#define RMrBX OP_REG, rBX_reg
-#define RMrCX OP_REG, rCX_reg
-#define RMrDX OP_REG, rDX_reg
-#define RMrSP OP_REG, rSP_reg
-#define RMrBP OP_REG, rBP_reg
-#define RMrSI OP_REG, rSI_reg
-#define RMrDI OP_REG, rDI_reg
-#define RMAL OP_REG, al_reg
-#define RMAL OP_REG, al_reg
-#define RMCL OP_REG, cl_reg
-#define RMDL OP_REG, dl_reg
-#define RMBL OP_REG, bl_reg
-#define RMAH OP_REG, ah_reg
-#define RMCH OP_REG, ch_reg
-#define RMDH OP_REG, dh_reg
-#define RMBH OP_REG, bh_reg
-#define RMAX OP_REG, ax_reg
-#define RMDX OP_REG, dx_reg
-
-#define eAX OP_IMREG, eAX_reg
-#define eBX OP_IMREG, eBX_reg
-#define eCX OP_IMREG, eCX_reg
-#define eDX OP_IMREG, eDX_reg
-#define eSP OP_IMREG, eSP_reg
-#define eBP OP_IMREG, eBP_reg
-#define eSI OP_IMREG, eSI_reg
-#define eDI OP_IMREG, eDI_reg
-#define AL OP_IMREG, al_reg
-#define AL OP_IMREG, al_reg
-#define CL OP_IMREG, cl_reg
-#define DL OP_IMREG, dl_reg
-#define BL OP_IMREG, bl_reg
-#define AH OP_IMREG, ah_reg
-#define CH OP_IMREG, ch_reg
-#define DH OP_IMREG, dh_reg
-#define BH OP_IMREG, bh_reg
-#define AX OP_IMREG, ax_reg
-#define DX OP_IMREG, dx_reg
-#define indirDX OP_IMREG, indir_dx_reg
-
-#define Sw OP_SEG, w_mode
-#define Ap OP_DIR, 0
-#define Ob OP_OFF, b_mode
-#define Ob64 OP_OFF64, b_mode
-#define Ov OP_OFF, v_mode
-#define Ov64 OP_OFF64, v_mode
-#define Xb OP_DSreg, eSI_reg
-#define Xv OP_DSreg, eSI_reg
-#define Yb OP_ESreg, eDI_reg
-#define Yv OP_ESreg, eDI_reg
-#define DSBX OP_DSreg, eBX_reg
-
-#define es OP_REG, es_reg
-#define ss OP_REG, ss_reg
-#define cs OP_REG, cs_reg
-#define ds OP_REG, ds_reg
-#define fs OP_REG, fs_reg
-#define gs OP_REG, gs_reg
-
-#define MX OP_MMX, 0
-#define XM OP_XMM, 0
-#define EM OP_EM, v_mode
-#define EX OP_EX, v_mode
-#define MS OP_MS, v_mode
-#define XS OP_XS, v_mode
-#define None OP_E, 0
-#define OPSUF OP_3DNowSuffix, 0
-#define OPSIMD OP_SIMD_Suffix, 0
-
-#define cond_jump_flag NULL, cond_jump_mode
-#define loop_jcxz_flag NULL, loop_jcxz_mode
-
-/* bits in sizeflag */
-#define SUFFIX_ALWAYS 4
-#define AFLAG 2
-#define DFLAG 1
-
-#define b_mode 1 /* byte operand */
-#define v_mode 2 /* operand size depends on prefixes */
-#define w_mode 3 /* word operand */
-#define d_mode 4 /* double word operand */
-#define q_mode 5 /* quad word operand */
-#define x_mode 6
-#define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
-#define cond_jump_mode 8
-#define loop_jcxz_mode 9
-
-#define es_reg 100
-#define cs_reg 101
-#define ss_reg 102
-#define ds_reg 103
-#define fs_reg 104
-#define gs_reg 105
-
-#define eAX_reg 108
-#define eCX_reg 109
-#define eDX_reg 110
-#define eBX_reg 111
-#define eSP_reg 112
-#define eBP_reg 113
-#define eSI_reg 114
-#define eDI_reg 115
-
-#define al_reg 116
-#define cl_reg 117
-#define dl_reg 118
-#define bl_reg 119
-#define ah_reg 120
-#define ch_reg 121
-#define dh_reg 122
-#define bh_reg 123
-
-#define ax_reg 124
-#define cx_reg 125
-#define dx_reg 126
-#define bx_reg 127
-#define sp_reg 128
-#define bp_reg 129
-#define si_reg 130
-#define di_reg 131
-
-#define rAX_reg 132
-#define rCX_reg 133
-#define rDX_reg 134
-#define rBX_reg 135
-#define rSP_reg 136
-#define rBP_reg 137
-#define rSI_reg 138
-#define rDI_reg 139
-
-#define indir_dx_reg 150
-
-#define FLOATCODE 1
-#define USE_GROUPS 2
-#define USE_PREFIX_USER_TABLE 3
-#define X86_64_SPECIAL 4
-
-#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
-
-#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
-#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
-#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
-#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
-#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
-#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
-#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
-#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
-#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
-#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
-#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
-#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
-#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
-#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
-#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
-#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
-#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
-#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
-#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
-#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
-#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
-#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
-#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
-
-#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
-#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
-#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
-#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
-#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
-#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
-#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
-#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
-#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
-#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
-#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
-#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
-#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
-#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
-#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
-#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
-#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
-#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
-#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
-#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
-#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
-#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
-#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
-#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
-#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
-#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
-#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
-
-#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
-
-typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
-
-struct dis386 {
- const char *name;
- op_rtn op1;
- int bytemode1;
- op_rtn op2;
- int bytemode2;
- op_rtn op3;
- int bytemode3;
-};
-
-/* Upper case letters in the instruction names here are macros.
- 'A' => print 'b' if no register operands or suffix_always is true
- 'B' => print 'b' if suffix_always is true
- 'E' => print 'e' if 32-bit form of jcxz
- 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
- 'H' => print ",pt" or ",pn" branch hint
- 'L' => print 'l' if suffix_always is true
- 'N' => print 'n' if instruction has no wait "prefix"
- 'O' => print 'd', or 'o'
- 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
- . or suffix_always is true. print 'q' if rex prefix is present.
- 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
- . is true
- 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
- 'S' => print 'w', 'l' or 'q' if suffix_always is true
- 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
- 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
- 'X' => print 's', 'd' depending on data16 prefix (for XMM)
- 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
- 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
-
- Many of the above letters print nothing in Intel mode. See "putop"
- for the details.
-
- Braces '{' and '}', and vertical bars '|', indicate alternative
- mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
- modes. In cases where there are only two alternatives, the X86_64
- instruction is reserved, and "(bad)" is printed.
-*/
-
-static const struct dis386 dis386[] = {
- /* 00 */
- { "addB", Eb, Gb, XX },
- { "addS", Ev, Gv, XX },
- { "addB", Gb, Eb, XX },
- { "addS", Gv, Ev, XX },
- { "addB", AL, Ib, XX },
- { "addS", eAX, Iv, XX },
- { "push{T|}", es, XX, XX },
- { "pop{T|}", es, XX, XX },
- /* 08 */
- { "orB", Eb, Gb, XX },
- { "orS", Ev, Gv, XX },
- { "orB", Gb, Eb, XX },
- { "orS", Gv, Ev, XX },
- { "orB", AL, Ib, XX },
- { "orS", eAX, Iv, XX },
- { "push{T|}", cs, XX, XX },
- { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
- /* 10 */
- { "adcB", Eb, Gb, XX },
- { "adcS", Ev, Gv, XX },
- { "adcB", Gb, Eb, XX },
- { "adcS", Gv, Ev, XX },
- { "adcB", AL, Ib, XX },
- { "adcS", eAX, Iv, XX },
- { "push{T|}", ss, XX, XX },
- { "popT|}", ss, XX, XX },
- /* 18 */
- { "sbbB", Eb, Gb, XX },
- { "sbbS", Ev, Gv, XX },
- { "sbbB", Gb, Eb, XX },
- { "sbbS", Gv, Ev, XX },
- { "sbbB", AL, Ib, XX },
- { "sbbS", eAX, Iv, XX },
- { "push{T|}", ds, XX, XX },
- { "pop{T|}", ds, XX, XX },
- /* 20 */
- { "andB", Eb, Gb, XX },
- { "andS", Ev, Gv, XX },
- { "andB", Gb, Eb, XX },
- { "andS", Gv, Ev, XX },
- { "andB", AL, Ib, XX },
- { "andS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG ES prefix */
- { "daa{|}", XX, XX, XX },
- /* 28 */
- { "subB", Eb, Gb, XX },
- { "subS", Ev, Gv, XX },
- { "subB", Gb, Eb, XX },
- { "subS", Gv, Ev, XX },
- { "subB", AL, Ib, XX },
- { "subS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG CS prefix */
- { "das{|}", XX, XX, XX },
- /* 30 */
- { "xorB", Eb, Gb, XX },
- { "xorS", Ev, Gv, XX },
- { "xorB", Gb, Eb, XX },
- { "xorS", Gv, Ev, XX },
- { "xorB", AL, Ib, XX },
- { "xorS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG SS prefix */
- { "aaa{|}", XX, XX, XX },
- /* 38 */
- { "cmpB", Eb, Gb, XX },
- { "cmpS", Ev, Gv, XX },
- { "cmpB", Gb, Eb, XX },
- { "cmpS", Gv, Ev, XX },
- { "cmpB", AL, Ib, XX },
- { "cmpS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG DS prefix */
- { "aas{|}", XX, XX, XX },
- /* 40 */
- { "inc{S|}", RMeAX, XX, XX },
- { "inc{S|}", RMeCX, XX, XX },
- { "inc{S|}", RMeDX, XX, XX },
- { "inc{S|}", RMeBX, XX, XX },
- { "inc{S|}", RMeSP, XX, XX },
- { "inc{S|}", RMeBP, XX, XX },
- { "inc{S|}", RMeSI, XX, XX },
- { "inc{S|}", RMeDI, XX, XX },
- /* 48 */
- { "dec{S|}", RMeAX, XX, XX },
- { "dec{S|}", RMeCX, XX, XX },
- { "dec{S|}", RMeDX, XX, XX },
- { "dec{S|}", RMeBX, XX, XX },
- { "dec{S|}", RMeSP, XX, XX },
- { "dec{S|}", RMeBP, XX, XX },
- { "dec{S|}", RMeSI, XX, XX },
- { "dec{S|}", RMeDI, XX, XX },
- /* 50 */
- { "pushS", RMrAX, XX, XX },
- { "pushS", RMrCX, XX, XX },
- { "pushS", RMrDX, XX, XX },
- { "pushS", RMrBX, XX, XX },
- { "pushS", RMrSP, XX, XX },
- { "pushS", RMrBP, XX, XX },
- { "pushS", RMrSI, XX, XX },
- { "pushS", RMrDI, XX, XX },
- /* 58 */
- { "popS", RMrAX, XX, XX },
- { "popS", RMrCX, XX, XX },
- { "popS", RMrDX, XX, XX },
- { "popS", RMrBX, XX, XX },
- { "popS", RMrSP, XX, XX },
- { "popS", RMrBP, XX, XX },
- { "popS", RMrSI, XX, XX },
- { "popS", RMrDI, XX, XX },
- /* 60 */
- { "pusha{P|}", XX, XX, XX },
- { "popa{P|}", XX, XX, XX },
- { "bound{S|}", Gv, Ma, XX },
- { X86_64_0 },
- { "(bad)", XX, XX, XX }, /* seg fs */
- { "(bad)", XX, XX, XX }, /* seg gs */
- { "(bad)", XX, XX, XX }, /* op size prefix */
- { "(bad)", XX, XX, XX }, /* adr size prefix */
- /* 68 */
- { "pushT", Iq, XX, XX },
- { "imulS", Gv, Ev, Iv },
- { "pushT", sIb, XX, XX },
- { "imulS", Gv, Ev, sIb },
- { "ins{b||b|}", Yb, indirDX, XX },
- { "ins{R||R|}", Yv, indirDX, XX },
- { "outs{b||b|}", indirDX, Xb, XX },
- { "outs{R||R|}", indirDX, Xv, XX },
- /* 70 */
- { "joH", Jb, XX, cond_jump_flag },
- { "jnoH", Jb, XX, cond_jump_flag },
- { "jbH", Jb, XX, cond_jump_flag },
- { "jaeH", Jb, XX, cond_jump_flag },
- { "jeH", Jb, XX, cond_jump_flag },
- { "jneH", Jb, XX, cond_jump_flag },
- { "jbeH", Jb, XX, cond_jump_flag },
- { "jaH", Jb, XX, cond_jump_flag },
- /* 78 */
- { "jsH", Jb, XX, cond_jump_flag },
- { "jnsH", Jb, XX, cond_jump_flag },
- { "jpH", Jb, XX, cond_jump_flag },
- { "jnpH", Jb, XX, cond_jump_flag },
- { "jlH", Jb, XX, cond_jump_flag },
- { "jgeH", Jb, XX, cond_jump_flag },
- { "jleH", Jb, XX, cond_jump_flag },
- { "jgH", Jb, XX, cond_jump_flag },
- /* 80 */
- { GRP1b },
- { GRP1S },
- { "(bad)", XX, XX, XX },
- { GRP1Ss },
- { "testB", Eb, Gb, XX },
- { "testS", Ev, Gv, XX },
- { "xchgB", Eb, Gb, XX },
- { "xchgS", Ev, Gv, XX },
- /* 88 */
- { "movB", Eb, Gb, XX },
- { "movS", Ev, Gv, XX },
- { "movB", Gb, Eb, XX },
- { "movS", Gv, Ev, XX },
- { "movQ", Ev, Sw, XX },
- { "leaS", Gv, M, XX },
- { "movQ", Sw, Ev, XX },
- { "popU", Ev, XX, XX },
- /* 90 */
- { "nop", XX, XX, XX },
- /* FIXME: NOP with REPz prefix is called PAUSE. */
- { "xchgS", RMeCX, eAX, XX },
- { "xchgS", RMeDX, eAX, XX },
- { "xchgS", RMeBX, eAX, XX },
- { "xchgS", RMeSP, eAX, XX },
- { "xchgS", RMeBP, eAX, XX },
- { "xchgS", RMeSI, eAX, XX },
- { "xchgS", RMeDI, eAX, XX },
- /* 98 */
- { "cW{tR||tR|}", XX, XX, XX },
- { "cR{tO||tO|}", XX, XX, XX },
- { "lcall{T|}", Ap, XX, XX },
- { "(bad)", XX, XX, XX }, /* fwait */
- { "pushfT", XX, XX, XX },
- { "popfT", XX, XX, XX },
- { "sahf{|}", XX, XX, XX },
- { "lahf{|}", XX, XX, XX },
- /* a0 */
- { "movB", AL, Ob64, XX },
- { "movS", eAX, Ov64, XX },
- { "movB", Ob64, AL, XX },
- { "movS", Ov64, eAX, XX },
- { "movs{b||b|}", Yb, Xb, XX },
- { "movs{R||R|}", Yv, Xv, XX },
- { "cmps{b||b|}", Xb, Yb, XX },
- { "cmps{R||R|}", Xv, Yv, XX },
- /* a8 */
- { "testB", AL, Ib, XX },
- { "testS", eAX, Iv, XX },
- { "stosB", Yb, AL, XX },
- { "stosS", Yv, eAX, XX },
- { "lodsB", AL, Xb, XX },
- { "lodsS", eAX, Xv, XX },
- { "scasB", AL, Yb, XX },
- { "scasS", eAX, Yv, XX },
- /* b0 */
- { "movB", RMAL, Ib, XX },
- { "movB", RMCL, Ib, XX },
- { "movB", RMDL, Ib, XX },
- { "movB", RMBL, Ib, XX },
- { "movB", RMAH, Ib, XX },
- { "movB", RMCH, Ib, XX },
- { "movB", RMDH, Ib, XX },
- { "movB", RMBH, Ib, XX },
- /* b8 */
- { "movS", RMeAX, Iv64, XX },
- { "movS", RMeCX, Iv64, XX },
- { "movS", RMeDX, Iv64, XX },
- { "movS", RMeBX, Iv64, XX },
- { "movS", RMeSP, Iv64, XX },
- { "movS", RMeBP, Iv64, XX },
- { "movS", RMeSI, Iv64, XX },
- { "movS", RMeDI, Iv64, XX },
- /* c0 */
- { GRP2b },
- { GRP2S },
- { "retT", Iw, XX, XX },
- { "retT", XX, XX, XX },
- { "les{S|}", Gv, Mp, XX },
- { "ldsS", Gv, Mp, XX },
- { "movA", Eb, Ib, XX },
- { "movQ", Ev, Iv, XX },
- /* c8 */
- { "enterT", Iw, Ib, XX },
- { "leaveT", XX, XX, XX },
- { "lretP", Iw, XX, XX },
- { "lretP", XX, XX, XX },
- { "int3", XX, XX, XX },
- { "int", Ib, XX, XX },
- { "into{|}", XX, XX, XX },
- { "iretP", XX, XX, XX },
- /* d0 */
- { GRP2b_one },
- { GRP2S_one },
- { GRP2b_cl },
- { GRP2S_cl },
- { "aam{|}", sIb, XX, XX },
- { "aad{|}", sIb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "xlat", DSBX, XX, XX },
- /* d8 */
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- /* e0 */
- { "loopneFH", Jb, XX, loop_jcxz_flag },
- { "loopeFH", Jb, XX, loop_jcxz_flag },
- { "loopFH", Jb, XX, loop_jcxz_flag },
- { "jEcxzH", Jb, XX, loop_jcxz_flag },
- { "inB", AL, Ib, XX },
- { "inS", eAX, Ib, XX },
- { "outB", Ib, AL, XX },
- { "outS", Ib, eAX, XX },
- /* e8 */
- { "callT", Jv, XX, XX },
- { "jmpT", Jv, XX, XX },
- { "ljmp{T|}", Ap, XX, XX },
- { "jmp", Jb, XX, XX },
- { "inB", AL, indirDX, XX },
- { "inS", eAX, indirDX, XX },
- { "outB", indirDX, AL, XX },
- { "outS", indirDX, eAX, XX },
- /* f0 */
- { "(bad)", XX, XX, XX }, /* lock prefix */
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX }, /* repne */
- { "(bad)", XX, XX, XX }, /* repz */
- { "hlt", XX, XX, XX },
- { "cmc", XX, XX, XX },
- { GRP3b },
- { GRP3S },
- /* f8 */
- { "clc", XX, XX, XX },
- { "stc", XX, XX, XX },
- { "cli", XX, XX, XX },
- { "sti", XX, XX, XX },
- { "cld", XX, XX, XX },
- { "std", XX, XX, XX },
- { GRP4 },
- { GRP5 },
-};
-
-static const struct dis386 dis386_twobyte[] = {
- /* 00 */
- { GRP6 },
- { GRP7 },
- { "larS", Gv, Ew, XX },
- { "lslS", Gv, Ew, XX },
- { "(bad)", XX, XX, XX },
- { "syscall", XX, XX, XX },
- { "clts", XX, XX, XX },
- { "sysretP", XX, XX, XX },
- /* 08 */
- { "invd", XX, XX, XX },
- { "wbinvd", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "ud2a", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { GRPAMD },
- { "femms", XX, XX, XX },
- { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
- /* 10 */
- { PREGRP8 },
- { PREGRP9 },
- { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
- { "movlpX", EX, XM, SIMD_Fixup, 'h' },
- { "unpcklpX", XM, EX, XX },
- { "unpckhpX", XM, EX, XX },
- { "movhpX", XM, EX, SIMD_Fixup, 'l' },
- { "movhpX", EX, XM, SIMD_Fixup, 'l' },
- /* 18 */
- { GRP14 },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* 20 */
- { "movL", Rm, Cm, XX },
- { "movL", Rm, Dm, XX },
- { "movL", Cm, Rm, XX },
- { "movL", Dm, Rm, XX },
- { "movL", Rd, Td, XX },
- { "(bad)", XX, XX, XX },
- { "movL", Td, Rd, XX },
- { "(bad)", XX, XX, XX },
- /* 28 */
- { "movapX", XM, EX, XX },
- { "movapX", EX, XM, XX },
- { PREGRP2 },
- { "movntpX", Ev, XM, XX },
- { PREGRP4 },
- { PREGRP3 },
- { "ucomisX", XM,EX, XX },
- { "comisX", XM,EX, XX },
- /* 30 */
- { "wrmsr", XX, XX, XX },
- { "rdtsc", XX, XX, XX },
- { "rdmsr", XX, XX, XX },
- { "rdpmc", XX, XX, XX },
- { "sysenter", XX, XX, XX },
- { "sysexit", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* 38 */
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* 40 */
- { "cmovo", Gv, Ev, XX },
- { "cmovno", Gv, Ev, XX },
- { "cmovb", Gv, Ev, XX },
- { "cmovae", Gv, Ev, XX },
- { "cmove", Gv, Ev, XX },
- { "cmovne", Gv, Ev, XX },
- { "cmovbe", Gv, Ev, XX },
- { "cmova", Gv, Ev, XX },
- /* 48 */
- { "cmovs", Gv, Ev, XX },
- { "cmovns", Gv, Ev, XX },
- { "cmovp", Gv, Ev, XX },
- { "cmovnp", Gv, Ev, XX },
- { "cmovl", Gv, Ev, XX },
- { "cmovge", Gv, Ev, XX },
- { "cmovle", Gv, Ev, XX },
- { "cmovg", Gv, Ev, XX },
- /* 50 */
- { "movmskpX", Gd, XS, XX },
- { PREGRP13 },
- { PREGRP12 },
- { PREGRP11 },
- { "andpX", XM, EX, XX },
- { "andnpX", XM, EX, XX },
- { "orpX", XM, EX, XX },
- { "xorpX", XM, EX, XX },
- /* 58 */
- { PREGRP0 },
- { PREGRP10 },
- { PREGRP17 },
- { PREGRP16 },
- { PREGRP14 },
- { PREGRP7 },
- { PREGRP5 },
- { PREGRP6 },
- /* 60 */
- { "punpcklbw", MX, EM, XX },
- { "punpcklwd", MX, EM, XX },
- { "punpckldq", MX, EM, XX },
- { "packsswb", MX, EM, XX },
- { "pcmpgtb", MX, EM, XX },
- { "pcmpgtw", MX, EM, XX },
- { "pcmpgtd", MX, EM, XX },
- { "packuswb", MX, EM, XX },
- /* 68 */
- { "punpckhbw", MX, EM, XX },
- { "punpckhwd", MX, EM, XX },
- { "punpckhdq", MX, EM, XX },
- { "packssdw", MX, EM, XX },
- { PREGRP26 },
- { PREGRP24 },
- { "movd", MX, Ed, XX },
- { PREGRP19 },
- /* 70 */
- { PREGRP22 },
- { GRP10 },
- { GRP11 },
- { GRP12 },
- { "pcmpeqb", MX, EM, XX },
- { "pcmpeqw", MX, EM, XX },
- { "pcmpeqd", MX, EM, XX },
- { "emms", XX, XX, XX },
- /* 78 */
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { PREGRP23 },
- { PREGRP20 },
- /* 80 */
- { "joH", Jv, XX, cond_jump_flag },
- { "jnoH", Jv, XX, cond_jump_flag },
- { "jbH", Jv, XX, cond_jump_flag },
- { "jaeH", Jv, XX, cond_jump_flag },
- { "jeH", Jv, XX, cond_jump_flag },
- { "jneH", Jv, XX, cond_jump_flag },
- { "jbeH", Jv, XX, cond_jump_flag },
- { "jaH", Jv, XX, cond_jump_flag },
- /* 88 */
- { "jsH", Jv, XX, cond_jump_flag },
- { "jnsH", Jv, XX, cond_jump_flag },
- { "jpH", Jv, XX, cond_jump_flag },
- { "jnpH", Jv, XX, cond_jump_flag },
- { "jlH", Jv, XX, cond_jump_flag },
- { "jgeH", Jv, XX, cond_jump_flag },
- { "jleH", Jv, XX, cond_jump_flag },
- { "jgH", Jv, XX, cond_jump_flag },
- /* 90 */
- { "seto", Eb, XX, XX },
- { "setno", Eb, XX, XX },
- { "setb", Eb, XX, XX },
- { "setae", Eb, XX, XX },
- { "sete", Eb, XX, XX },
- { "setne", Eb, XX, XX },
- { "setbe", Eb, XX, XX },
- { "seta", Eb, XX, XX },
- /* 98 */
- { "sets", Eb, XX, XX },
- { "setns", Eb, XX, XX },
- { "setp", Eb, XX, XX },
- { "setnp", Eb, XX, XX },
- { "setl", Eb, XX, XX },
- { "setge", Eb, XX, XX },
- { "setle", Eb, XX, XX },
- { "setg", Eb, XX, XX },
- /* a0 */
- { "pushT", fs, XX, XX },
- { "popT", fs, XX, XX },
- { "cpuid", XX, XX, XX },
- { "btS", Ev, Gv, XX },
- { "shldS", Ev, Gv, Ib },
- { "shldS", Ev, Gv, CL },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* a8 */
- { "pushT", gs, XX, XX },
- { "popT", gs, XX, XX },
- { "rsm", XX, XX, XX },
- { "btsS", Ev, Gv, XX },
- { "shrdS", Ev, Gv, Ib },
- { "shrdS", Ev, Gv, CL },
- { GRP13 },
- { "imulS", Gv, Ev, XX },
- /* b0 */
- { "cmpxchgB", Eb, Gb, XX },
- { "cmpxchgS", Ev, Gv, XX },
- { "lssS", Gv, Mp, XX },
- { "btrS", Ev, Gv, XX },
- { "lfsS", Gv, Mp, XX },
- { "lgsS", Gv, Mp, XX },
- { "movz{bR|x|bR|x}", Gv, Eb, XX },
- { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
- /* b8 */
- { "(bad)", XX, XX, XX },
- { "ud2b", XX, XX, XX },
- { GRP8 },
- { "btcS", Ev, Gv, XX },
- { "bsfS", Gv, Ev, XX },
- { "bsrS", Gv, Ev, XX },
- { "movs{bR|x|bR|x}", Gv, Eb, XX },
- { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
- /* c0 */
- { "xaddB", Eb, Gb, XX },
- { "xaddS", Ev, Gv, XX },
- { PREGRP1 },
- { "movntiS", Ev, Gv, XX },
- { "pinsrw", MX, Ed, Ib },
- { "pextrw", Gd, MS, Ib },
- { "shufpX", XM, EX, Ib },
- { GRP9 },
- /* c8 */
- { "bswap", RMeAX, XX, XX },
- { "bswap", RMeCX, XX, XX },
- { "bswap", RMeDX, XX, XX },
- { "bswap", RMeBX, XX, XX },
- { "bswap", RMeSP, XX, XX },
- { "bswap", RMeBP, XX, XX },
- { "bswap", RMeSI, XX, XX },
- { "bswap", RMeDI, XX, XX },
- /* d0 */
- { "(bad)", XX, XX, XX },
- { "psrlw", MX, EM, XX },
- { "psrld", MX, EM, XX },
- { "psrlq", MX, EM, XX },
- { "paddq", MX, EM, XX },
- { "pmullw", MX, EM, XX },
- { PREGRP21 },
- { "pmovmskb", Gd, MS, XX },
- /* d8 */
- { "psubusb", MX, EM, XX },
- { "psubusw", MX, EM, XX },
- { "pminub", MX, EM, XX },
- { "pand", MX, EM, XX },
- { "paddusb", MX, EM, XX },
- { "paddusw", MX, EM, XX },
- { "pmaxub", MX, EM, XX },
- { "pandn", MX, EM, XX },
- /* e0 */
- { "pavgb", MX, EM, XX },
- { "psraw", MX, EM, XX },
- { "psrad", MX, EM, XX },
- { "pavgw", MX, EM, XX },
- { "pmulhuw", MX, EM, XX },
- { "pmulhw", MX, EM, XX },
- { PREGRP15 },
- { PREGRP25 },
- /* e8 */
- { "psubsb", MX, EM, XX },
- { "psubsw", MX, EM, XX },
- { "pminsw", MX, EM, XX },
- { "por", MX, EM, XX },
- { "paddsb", MX, EM, XX },
- { "paddsw", MX, EM, XX },
- { "pmaxsw", MX, EM, XX },
- { "pxor", MX, EM, XX },
- /* f0 */
- { "(bad)", XX, XX, XX },
- { "psllw", MX, EM, XX },
- { "pslld", MX, EM, XX },
- { "psllq", MX, EM, XX },
- { "pmuludq", MX, EM, XX },
- { "pmaddwd", MX, EM, XX },
- { "psadbw", MX, EM, XX },
- { PREGRP18 },
- /* f8 */
- { "psubb", MX, EM, XX },
- { "psubw", MX, EM, XX },
- { "psubd", MX, EM, XX },
- { "psubq", MX, EM, XX },
- { "paddb", MX, EM, XX },
- { "paddw", MX, EM, XX },
- { "paddd", MX, EM, XX },
- { "(bad)", XX, XX, XX }
-};
-
-static const unsigned char onebyte_has_modrm[256] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ------------------------------- */
- /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
- /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
- /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
- /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
- /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
- /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
- /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
- /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
- /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
- /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
- /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
- /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
- /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
- /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
- /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
- /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
- /* ------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
-
-static const unsigned char twobyte_has_modrm[256] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ------------------------------- */
- /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
- /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
- /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
- /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
- /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
- /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
- /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
- /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
- /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
- /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
- /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
- /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
- /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
- /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
- /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
- /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
- /* ------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
-
-static const unsigned char twobyte_uses_SSE_prefix[256] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ------------------------------- */
- /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
- /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
- /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
- /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
- /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
- /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
- /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
- /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
- /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
- /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
- /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
- /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
- /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
- /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
- /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
- /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
- /* ------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
-
-static char obuf[100];
-static char *obufp;
-static char scratchbuf[100];
-static unsigned char *start_codep;
-static unsigned char *insn_codep;
-static unsigned char *codep;
-static disassemble_info *the_info;
-static int mod;
-static int rm;
-static int reg;
-static unsigned char need_modrm;
-
-/* If we are accessing mod/rm/reg without need_modrm set, then the
- values are stale. Hitting this abort likely indicates that you
- need to update onebyte_has_modrm or twobyte_has_modrm. */
-#define MODRM_CHECK if (!need_modrm) abort ()
-
-static const char **names64;
-static const char **names32;
-static const char **names16;
-static const char **names8;
-static const char **names8rex;
-static const char **names_seg;
-static const char **index16;
-
-static const char *intel_names64[] = {
- "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
-};
-static const char *intel_names32[] = {
- "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
- "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
-};
-static const char *intel_names16[] = {
- "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
- "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
-};
-static const char *intel_names8[] = {
- "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
-};
-static const char *intel_names8rex[] = {
- "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
- "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
-};
-static const char *intel_names_seg[] = {
- "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
-};
-static const char *intel_index16[] = {
- "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
-};
-
-static const char *att_names64[] = {
- "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
- "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
-};
-static const char *att_names32[] = {
- "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
- "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
-};
-static const char *att_names16[] = {
- "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
- "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
-};
-static const char *att_names8[] = {
- "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
-};
-static const char *att_names8rex[] = {
- "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
- "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
-};
-static const char *att_names_seg[] = {
- "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
-};
-static const char *att_index16[] = {
- "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
-};
-
-static const struct dis386 grps[][8] = {
- /* GRP1b */
- {
- { "addA", Eb, Ib, XX },
- { "orA", Eb, Ib, XX },
- { "adcA", Eb, Ib, XX },
- { "sbbA", Eb, Ib, XX },
- { "andA", Eb, Ib, XX },
- { "subA", Eb, Ib, XX },
- { "xorA", Eb, Ib, XX },
- { "cmpA", Eb, Ib, XX }
- },
- /* GRP1S */
- {
- { "addQ", Ev, Iv, XX },
- { "orQ", Ev, Iv, XX },
- { "adcQ", Ev, Iv, XX },
- { "sbbQ", Ev, Iv, XX },
- { "andQ", Ev, Iv, XX },
- { "subQ", Ev, Iv, XX },
- { "xorQ", Ev, Iv, XX },
- { "cmpQ", Ev, Iv, XX }
- },
- /* GRP1Ss */
- {
- { "addQ", Ev, sIb, XX },
- { "orQ", Ev, sIb, XX },
- { "adcQ", Ev, sIb, XX },
- { "sbbQ", Ev, sIb, XX },
- { "andQ", Ev, sIb, XX },
- { "subQ", Ev, sIb, XX },
- { "xorQ", Ev, sIb, XX },
- { "cmpQ", Ev, sIb, XX }
- },
- /* GRP2b */
- {
- { "rolA", Eb, Ib, XX },
- { "rorA", Eb, Ib, XX },
- { "rclA", Eb, Ib, XX },
- { "rcrA", Eb, Ib, XX },
- { "shlA", Eb, Ib, XX },
- { "shrA", Eb, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "sarA", Eb, Ib, XX },
- },
- /* GRP2S */
- {
- { "rolQ", Ev, Ib, XX },
- { "rorQ", Ev, Ib, XX },
- { "rclQ", Ev, Ib, XX },
- { "rcrQ", Ev, Ib, XX },
- { "shlQ", Ev, Ib, XX },
- { "shrQ", Ev, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "sarQ", Ev, Ib, XX },
- },
- /* GRP2b_one */
- {
- { "rolA", Eb, XX, XX },
- { "rorA", Eb, XX, XX },
- { "rclA", Eb, XX, XX },
- { "rcrA", Eb, XX, XX },
- { "shlA", Eb, XX, XX },
- { "shrA", Eb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "sarA", Eb, XX, XX },
- },
- /* GRP2S_one */
- {
- { "rolQ", Ev, XX, XX },
- { "rorQ", Ev, XX, XX },
- { "rclQ", Ev, XX, XX },
- { "rcrQ", Ev, XX, XX },
- { "shlQ", Ev, XX, XX },
- { "shrQ", Ev, XX, XX },
- { "(bad)", XX, XX, XX},
- { "sarQ", Ev, XX, XX },
- },
- /* GRP2b_cl */
- {
- { "rolA", Eb, CL, XX },
- { "rorA", Eb, CL, XX },
- { "rclA", Eb, CL, XX },
- { "rcrA", Eb, CL, XX },
- { "shlA", Eb, CL, XX },
- { "shrA", Eb, CL, XX },
- { "(bad)", XX, XX, XX },
- { "sarA", Eb, CL, XX },
- },
- /* GRP2S_cl */
- {
- { "rolQ", Ev, CL, XX },
- { "rorQ", Ev, CL, XX },
- { "rclQ", Ev, CL, XX },
- { "rcrQ", Ev, CL, XX },
- { "shlQ", Ev, CL, XX },
- { "shrQ", Ev, CL, XX },
- { "(bad)", XX, XX, XX },
- { "sarQ", Ev, CL, XX }
- },
- /* GRP3b */
- {
- { "testA", Eb, Ib, XX },
- { "(bad)", Eb, XX, XX },
- { "notA", Eb, XX, XX },
- { "negA", Eb, XX, XX },
- { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
- { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
- { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
- { "idivA", Eb, XX, XX } /* and idiv for consistency. */
- },
- /* GRP3S */
- {
- { "testQ", Ev, Iv, XX },
- { "(bad)", XX, XX, XX },
- { "notQ", Ev, XX, XX },
- { "negQ", Ev, XX, XX },
- { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
- { "imulQ", Ev, XX, XX },
- { "divQ", Ev, XX, XX },
- { "idivQ", Ev, XX, XX },
- },
- /* GRP4 */
- {
- { "incA", Eb, XX, XX },
- { "decA", Eb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP5 */
- {
- { "incQ", Ev, XX, XX },
- { "decQ", Ev, XX, XX },
- { "callT", indirEv, XX, XX },
- { "lcallT", indirEv, XX, XX },
- { "jmpT", indirEv, XX, XX },
- { "ljmpT", indirEv, XX, XX },
- { "pushU", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP6 */
- {
- { "sldtQ", Ev, XX, XX },
- { "strQ", Ev, XX, XX },
- { "lldt", Ew, XX, XX },
- { "ltr", Ew, XX, XX },
- { "verr", Ew, XX, XX },
- { "verw", Ew, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX }
- },
- /* GRP7 */
- {
- { "sgdtQ", M, XX, XX },
- { "sidtQ", M, XX, XX },
- { "lgdtQ", M, XX, XX },
- { "lidtQ", M, XX, XX },
- { "smswQ", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "lmsw", Ew, XX, XX },
- { "invlpg", Ew, XX, XX },
- },
- /* GRP8 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "btQ", Ev, Ib, XX },
- { "btsQ", Ev, Ib, XX },
- { "btrQ", Ev, Ib, XX },
- { "btcQ", Ev, Ib, XX },
- },
- /* GRP9 */
- {
- { "(bad)", XX, XX, XX },
- { "cmpxchg8b", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP10 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psrlw", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "psraw", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "psllw", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP11 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psrld", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "psrad", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "pslld", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP12 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psrlq", MS, Ib, XX },
- { "psrldq", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psllq", MS, Ib, XX },
- { "pslldq", MS, Ib, XX },
- },
- /* GRP13 */
- {
- { "fxsave", Ev, XX, XX },
- { "fxrstor", Ev, XX, XX },
- { "ldmxcsr", Ev, XX, XX },
- { "stmxcsr", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "lfence", None, XX, XX },
- { "mfence", None, XX, XX },
- { "sfence", None, XX, XX },
- /* FIXME: the sfence with memory operand is clflush! */
- },
- /* GRP14 */
- {
- { "prefetchnta", Ev, XX, XX },
- { "prefetcht0", Ev, XX, XX },
- { "prefetcht1", Ev, XX, XX },
- { "prefetcht2", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRPAMD */
- {
- { "prefetch", Eb, XX, XX },
- { "prefetchw", Eb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- }
-};
-
-static const struct dis386 prefix_user_table[][4] = {
- /* PREGRP0 */
- {
- { "addps", XM, EX, XX },
- { "addss", XM, EX, XX },
- { "addpd", XM, EX, XX },
- { "addsd", XM, EX, XX },
- },
- /* PREGRP1 */
- {
- { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
- { "", XM, EX, OPSIMD },
- { "", XM, EX, OPSIMD },
- { "", XM, EX, OPSIMD },
- },
- /* PREGRP2 */
- {
- { "cvtpi2ps", XM, EM, XX },
- { "cvtsi2ssY", XM, Ev, XX },
- { "cvtpi2pd", XM, EM, XX },
- { "cvtsi2sdY", XM, Ev, XX },
- },
- /* PREGRP3 */
- {
- { "cvtps2pi", MX, EX, XX },
- { "cvtss2siY", Gv, EX, XX },
- { "cvtpd2pi", MX, EX, XX },
- { "cvtsd2siY", Gv, EX, XX },
- },
- /* PREGRP4 */
- {
- { "cvttps2pi", MX, EX, XX },
- { "cvttss2siY", Gv, EX, XX },
- { "cvttpd2pi", MX, EX, XX },
- { "cvttsd2siY", Gv, EX, XX },
- },
- /* PREGRP5 */
- {
- { "divps", XM, EX, XX },
- { "divss", XM, EX, XX },
- { "divpd", XM, EX, XX },
- { "divsd", XM, EX, XX },
- },
- /* PREGRP6 */
- {
- { "maxps", XM, EX, XX },
- { "maxss", XM, EX, XX },
- { "maxpd", XM, EX, XX },
- { "maxsd", XM, EX, XX },
- },
- /* PREGRP7 */
- {
- { "minps", XM, EX, XX },
- { "minss", XM, EX, XX },
- { "minpd", XM, EX, XX },
- { "minsd", XM, EX, XX },
- },
- /* PREGRP8 */
- {
- { "movups", XM, EX, XX },
- { "movss", XM, EX, XX },
- { "movupd", XM, EX, XX },
- { "movsd", XM, EX, XX },
- },
- /* PREGRP9 */
- {
- { "movups", EX, XM, XX },
- { "movss", EX, XM, XX },
- { "movupd", EX, XM, XX },
- { "movsd", EX, XM, XX },
- },
- /* PREGRP10 */
- {
- { "mulps", XM, EX, XX },
- { "mulss", XM, EX, XX },
- { "mulpd", XM, EX, XX },
- { "mulsd", XM, EX, XX },
- },
- /* PREGRP11 */
- {
- { "rcpps", XM, EX, XX },
- { "rcpss", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP12 */
- {
- { "rsqrtps", XM, EX, XX },
- { "rsqrtss", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP13 */
- {
- { "sqrtps", XM, EX, XX },
- { "sqrtss", XM, EX, XX },
- { "sqrtpd", XM, EX, XX },
- { "sqrtsd", XM, EX, XX },
- },
- /* PREGRP14 */
- {
- { "subps", XM, EX, XX },
- { "subss", XM, EX, XX },
- { "subpd", XM, EX, XX },
- { "subsd", XM, EX, XX },
- },
- /* PREGRP15 */
- {
- { "(bad)", XM, EX, XX },
- { "cvtdq2pd", XM, EX, XX },
- { "cvttpd2dq", XM, EX, XX },
- { "cvtpd2dq", XM, EX, XX },
- },
- /* PREGRP16 */
- {
- { "cvtdq2ps", XM, EX, XX },
- { "cvttps2dq",XM, EX, XX },
- { "cvtps2dq",XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP17 */
- {
- { "cvtps2pd", XM, EX, XX },
- { "cvtss2sd", XM, EX, XX },
- { "cvtpd2ps", XM, EX, XX },
- { "cvtsd2ss", XM, EX, XX },
- },
- /* PREGRP18 */
- {
- { "maskmovq", MX, MS, XX },
- { "(bad)", XM, EX, XX },
- { "maskmovdqu", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP19 */
- {
- { "movq", MX, EM, XX },
- { "movdqu", XM, EX, XX },
- { "movdqa", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP20 */
- {
- { "movq", EM, MX, XX },
- { "movdqu", EX, XM, XX },
- { "movdqa", EX, XM, XX },
- { "(bad)", EX, XM, XX },
- },
- /* PREGRP21 */
- {
- { "(bad)", EX, XM, XX },
- { "movq2dq", XM, MS, XX },
- { "movq", EX, XM, XX },
- { "movdq2q", MX, XS, XX },
- },
- /* PREGRP22 */
- {
- { "pshufw", MX, EM, Ib },
- { "pshufhw", XM, EX, Ib },
- { "pshufd", XM, EX, Ib },
- { "pshuflw", XM, EX, Ib },
- },
- /* PREGRP23 */
- {
- { "movd", Ed, MX, XX },
- { "movq", XM, EX, XX },
- { "movd", Ed, XM, XX },
- { "(bad)", Ed, XM, XX },
- },
- /* PREGRP24 */
- {
- { "(bad)", MX, EX, XX },
- { "(bad)", XM, EX, XX },
- { "punpckhqdq", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP25 */
- {
- { "movntq", Ev, MX, XX },
- { "(bad)", Ev, XM, XX },
- { "movntdq", Ev, XM, XX },
- { "(bad)", Ev, XM, XX },
- },
- /* PREGRP26 */
- {
- { "(bad)", MX, EX, XX },
- { "(bad)", XM, EX, XX },
- { "punpcklqdq", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
-};
-
-static const struct dis386 x86_64_table[][2] = {
- {
- { "arpl", Ew, Gw, XX },
- { "movs{||lq|xd}", Gv, Ed, XX },
- },
-};
-
-#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
-
-static void
-ckprefix ()
-{
- int newrex;
- rex = 0;
- prefixes = 0;
- used_prefixes = 0;
- rex_used = 0;
- while (1)
- {
- FETCH_DATA (the_info, codep + 1);
- newrex = 0;
- switch (*codep)
- {
- /* REX prefixes family. */
- case 0x40:
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x45:
- case 0x46:
- case 0x47:
- case 0x48:
- case 0x49:
- case 0x4a:
- case 0x4b:
- case 0x4c:
- case 0x4d:
- case 0x4e:
- case 0x4f:
- if (mode_64bit)
- newrex = *codep;
- else
- return;
- break;
- case 0xf3:
- prefixes |= PREFIX_REPZ;
- break;
- case 0xf2:
- prefixes |= PREFIX_REPNZ;
- break;
- case 0xf0:
- prefixes |= PREFIX_LOCK;
- break;
- case 0x2e:
- prefixes |= PREFIX_CS;
- break;
- case 0x36:
- prefixes |= PREFIX_SS;
- break;
- case 0x3e:
- prefixes |= PREFIX_DS;
- break;
- case 0x26:
- prefixes |= PREFIX_ES;
- break;
- case 0x64:
- prefixes |= PREFIX_FS;
- break;
- case 0x65:
- prefixes |= PREFIX_GS;
- break;
- case 0x66:
- prefixes |= PREFIX_DATA;
- break;
- case 0x67:
- prefixes |= PREFIX_ADDR;
- break;
- case FWAIT_OPCODE:
- /* fwait is really an instruction. If there are prefixes
- before the fwait, they belong to the fwait, *not* to the
- following instruction. */
- if (prefixes)
- {
- prefixes |= PREFIX_FWAIT;
- codep++;
- return;
- }
- prefixes = PREFIX_FWAIT;
- break;
- default:
- return;
- }
- /* Rex is ignored when followed by another prefix. */
- if (rex)
- {
- oappend (prefix_name (rex, 0));
- oappend (" ");
- }
- rex = newrex;
- codep++;
- }
-}
-
-/* Return the name of the prefix byte PREF, or NULL if PREF is not a
- prefix byte. */
-
-static const char *
-prefix_name (pref, sizeflag)
- int pref;
- int sizeflag;
-{
- switch (pref)
- {
- /* REX prefixes family. */
- case 0x40:
- return "rex";
- case 0x41:
- return "rexZ";
- case 0x42:
- return "rexY";
- case 0x43:
- return "rexYZ";
- case 0x44:
- return "rexX";
- case 0x45:
- return "rexXZ";
- case 0x46:
- return "rexXY";
- case 0x47:
- return "rexXYZ";
- case 0x48:
- return "rex64";
- case 0x49:
- return "rex64Z";
- case 0x4a:
- return "rex64Y";
- case 0x4b:
- return "rex64YZ";
- case 0x4c:
- return "rex64X";
- case 0x4d:
- return "rex64XZ";
- case 0x4e:
- return "rex64XY";
- case 0x4f:
- return "rex64XYZ";
- case 0xf3:
- return "repz";
- case 0xf2:
- return "repnz";
- case 0xf0:
- return "lock";
- case 0x2e:
- return "cs";
- case 0x36:
- return "ss";
- case 0x3e:
- return "ds";
- case 0x26:
- return "es";
- case 0x64:
- return "fs";
- case 0x65:
- return "gs";
- case 0x66:
- return (sizeflag & DFLAG) ? "data16" : "data32";
- case 0x67:
- if (mode_64bit)
- return (sizeflag & AFLAG) ? "addr32" : "addr64";
- else
- return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
- case FWAIT_OPCODE:
- return "fwait";
- default:
- return NULL;
- }
-}
-
-static char op1out[100], op2out[100], op3out[100];
-static int op_ad, op_index[3];
-static bfd_vma op_address[3];
-static bfd_vma op_riprel[3];
-static bfd_vma start_pc;
-
-/*
- * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
- * (see topic "Redundant prefixes" in the "Differences from 8086"
- * section of the "Virtual 8086 Mode" chapter.)
- * 'pc' should be the address of this instruction, it will
- * be used to print the target address if this is a relative jump or call
- * The function returns the length of this instruction in bytes.
- */
-
-static int8_t intel_syntax;
-static char open_char;
-static char close_char;
-static char separator_char;
-static char scale_char;
-
-/* Here for backwards compatibility. When gdb stops using
- print_insn_i386_att and print_insn_i386_intel these functions can
- disappear, and print_insn_i386 be merged into print_insn. */
-int
-print_insn_i386_att (pc, info)
- bfd_vma pc;
- disassemble_info *info;
-{
- intel_syntax = 0;
-
- return print_insn (pc, info);
-}
-
-int
-print_insn_i386_intel (pc, info)
- bfd_vma pc;
- disassemble_info *info;
-{
- intel_syntax = 1;
-
- return print_insn (pc, info);
-}
-
-int
-print_insn_i386 (pc, info)
- bfd_vma pc;
- disassemble_info *info;
-{
- intel_syntax = -1;
-
- return print_insn (pc, info);
-}
-
-static int
-print_insn (pc, info)
- bfd_vma pc;
- disassemble_info *info;
-{
- const struct dis386 *dp;
- int i;
- int two_source_ops;
- char *first, *second, *third;
- int needcomma;
- unsigned char uses_SSE_prefix;
- int sizeflag;
- const char *p;
- struct dis_private priv;
-
- mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
- || info->mach == bfd_mach_x86_64);
-
- if (intel_syntax == -1)
- intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
- || info->mach == bfd_mach_x86_64_intel_syntax);
-
- if (info->mach == bfd_mach_i386_i386
- || info->mach == bfd_mach_x86_64
- || info->mach == bfd_mach_i386_i386_intel_syntax
- || info->mach == bfd_mach_x86_64_intel_syntax)
- priv.orig_sizeflag = AFLAG | DFLAG;
- else if (info->mach == bfd_mach_i386_i8086)
- priv.orig_sizeflag = 0;
- else
- abort ();
-
- for (p = info->disassembler_options; p != NULL; )
- {
- if (strncmp (p, "x86-64", 6) == 0)
- {
- mode_64bit = 1;
- priv.orig_sizeflag = AFLAG | DFLAG;
- }
- else if (strncmp (p, "i386", 4) == 0)
- {
- mode_64bit = 0;
- priv.orig_sizeflag = AFLAG | DFLAG;
- }
- else if (strncmp (p, "i8086", 5) == 0)
- {
- mode_64bit = 0;
- priv.orig_sizeflag = 0;
- }
- else if (strncmp (p, "intel", 5) == 0)
- {
- intel_syntax = 1;
- }
- else if (strncmp (p, "att", 3) == 0)
- {
- intel_syntax = 0;
- }
- else if (strncmp (p, "addr", 4) == 0)
- {
- if (p[4] == '1' && p[5] == '6')
- priv.orig_sizeflag &= ~AFLAG;
- else if (p[4] == '3' && p[5] == '2')
- priv.orig_sizeflag |= AFLAG;
- }
- else if (strncmp (p, "data", 4) == 0)
- {
- if (p[4] == '1' && p[5] == '6')
- priv.orig_sizeflag &= ~DFLAG;
- else if (p[4] == '3' && p[5] == '2')
- priv.orig_sizeflag |= DFLAG;
- }
- else if (strncmp (p, "suffix", 6) == 0)
- priv.orig_sizeflag |= SUFFIX_ALWAYS;
-
- p = strchr (p, ',');
- if (p != NULL)
- p++;
- }
-
- if (intel_syntax)
- {
- names64 = intel_names64;
- names32 = intel_names32;
- names16 = intel_names16;
- names8 = intel_names8;
- names8rex = intel_names8rex;
- names_seg = intel_names_seg;
- index16 = intel_index16;
- open_char = '[';
- close_char = ']';
- separator_char = '+';
- scale_char = '*';
- }
- else
- {
- names64 = att_names64;
- names32 = att_names32;
- names16 = att_names16;
- names8 = att_names8;
- names8rex = att_names8rex;
- names_seg = att_names_seg;
- index16 = att_index16;
- open_char = '(';
- close_char = ')';
- separator_char = ',';
- scale_char = ',';
- }
-
- /* The output looks better if we put 7 bytes on a line, since that
- puts most long word instructions on a single line. */
- info->bytes_per_line = 7;
-
- info->private_data = (PTR) &priv;
- priv.max_fetched = priv.the_buffer;
- priv.insn_start = pc;
-
- obuf[0] = 0;
- op1out[0] = 0;
- op2out[0] = 0;
- op3out[0] = 0;
-
- op_index[0] = op_index[1] = op_index[2] = -1;
-
- the_info = info;
- start_pc = pc;
- start_codep = priv.the_buffer;
- codep = priv.the_buffer;
-
- if (setjmp (priv.bailout) != 0)
- {
- const char *name;
-
- /* Getting here means we tried for data but didn't get it. That
- means we have an incomplete instruction of some sort. Just
- print the first byte as a prefix or a .byte pseudo-op. */
- if (codep > priv.the_buffer)
- {
- name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
- if (name != NULL)
- (*info->fprintf_func) (info->stream, "%s", name);
- else
- {
- /* Just print the first byte as a .byte instruction. */
- (*info->fprintf_func) (info->stream, ".byte 0x%x",
- (unsigned int) priv.the_buffer[0]);
- }
-
- return 1;
- }
-
- return -1;
- }
-
- obufp = obuf;
- ckprefix ();
-
- insn_codep = codep;
- sizeflag = priv.orig_sizeflag;
-
- FETCH_DATA (info, codep + 1);
- two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
-
- if ((prefixes & PREFIX_FWAIT)
- && ((*codep < 0xd8) || (*codep > 0xdf)))
- {
- const char *name;
-
- /* fwait not followed by floating point instruction. Print the
- first prefix, which is probably fwait itself. */
- name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
- (*info->fprintf_func) (info->stream, "%s", name);
- return 1;
- }
-
- if (*codep == 0x0f)
- {
- FETCH_DATA (info, codep + 2);
- dp = &dis386_twobyte[*++codep];
- need_modrm = twobyte_has_modrm[*codep];
- uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
- }
- else
- {
- dp = &dis386[*codep];
- need_modrm = onebyte_has_modrm[*codep];
- uses_SSE_prefix = 0;
- }
- codep++;
-
- if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
- {
- oappend ("repz ");
- used_prefixes |= PREFIX_REPZ;
- }
- if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
- {
- oappend ("repnz ");
- used_prefixes |= PREFIX_REPNZ;
- }
- if (prefixes & PREFIX_LOCK)
- {
- oappend ("lock ");
- used_prefixes |= PREFIX_LOCK;
- }
-
- if (prefixes & PREFIX_ADDR)
- {
- sizeflag ^= AFLAG;
- if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
- {
- if ((sizeflag & AFLAG) || mode_64bit)
- oappend ("addr32 ");
- else
- oappend ("addr16 ");
- used_prefixes |= PREFIX_ADDR;
- }
- }
-
- if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
- {
- sizeflag ^= DFLAG;
- if (dp->bytemode3 == cond_jump_mode
- && dp->bytemode1 == v_mode
- && !intel_syntax)
- {
- if (sizeflag & DFLAG)
- oappend ("data32 ");
- else
- oappend ("data16 ");
- used_prefixes |= PREFIX_DATA;
- }
- }
-
- if (need_modrm)
- {
- FETCH_DATA (info, codep + 1);
- mod = (*codep >> 6) & 3;
- reg = (*codep >> 3) & 7;
- rm = *codep & 7;
- }
-
- if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
- {
- dofloat (sizeflag);
- }
- else
- {
- int index;
- if (dp->name == NULL)
- {
- switch (dp->bytemode1)
- {
- case USE_GROUPS:
- dp = &grps[dp->bytemode2][reg];
- break;
-
- case USE_PREFIX_USER_TABLE:
- index = 0;
- used_prefixes |= (prefixes & PREFIX_REPZ);
- if (prefixes & PREFIX_REPZ)
- index = 1;
- else
- {
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- index = 2;
- else
- {
- used_prefixes |= (prefixes & PREFIX_REPNZ);
- if (prefixes & PREFIX_REPNZ)
- index = 3;
- }
- }
- dp = &prefix_user_table[dp->bytemode2][index];
- break;
-
- case X86_64_SPECIAL:
- dp = &x86_64_table[dp->bytemode2][mode_64bit];
- break;
-
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- break;
- }
- }
-
- if (putop (dp->name, sizeflag) == 0)
- {
- obufp = op1out;
- op_ad = 2;
- if (dp->op1)
- (*dp->op1) (dp->bytemode1, sizeflag);
-
- obufp = op2out;
- op_ad = 1;
- if (dp->op2)
- (*dp->op2) (dp->bytemode2, sizeflag);
-
- obufp = op3out;
- op_ad = 0;
- if (dp->op3)
- (*dp->op3) (dp->bytemode3, sizeflag);
- }
- }
-
- /* See if any prefixes were not used. If so, print the first one
- separately. If we don't do this, we'll wind up printing an
- instruction stream which does not precisely correspond to the
- bytes we are disassembling. */
- if ((prefixes & ~used_prefixes) != 0)
- {
- const char *name;
-
- name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
- (*info->fprintf_func) (info->stream, "%s", name);
- return 1;
- }
- if (rex & ~rex_used)
- {
- const char *name;
- name = prefix_name (rex | 0x40, priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
- (*info->fprintf_func) (info->stream, "%s ", name);
- }
-
- obufp = obuf + strlen (obuf);
- for (i = strlen (obuf); i < 6; i++)
- oappend (" ");
- oappend (" ");
- (*info->fprintf_func) (info->stream, "%s", obuf);
-
- /* The enter and bound instructions are printed with operands in the same
- order as the intel book; everything else is printed in reverse order. */
- if (intel_syntax || two_source_ops)
- {
- first = op1out;
- second = op2out;
- third = op3out;
- op_ad = op_index[0];
- op_index[0] = op_index[2];
- op_index[2] = op_ad;
- }
- else
- {
- first = op3out;
- second = op2out;
- third = op1out;
- }
- needcomma = 0;
- if (*first)
- {
- if (op_index[0] != -1 && !op_riprel[0])
- (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
- else
- (*info->fprintf_func) (info->stream, "%s", first);
- needcomma = 1;
- }
- if (*second)
- {
- if (needcomma)
- (*info->fprintf_func) (info->stream, ",");
- if (op_index[1] != -1 && !op_riprel[1])
- (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
- else
- (*info->fprintf_func) (info->stream, "%s", second);
- needcomma = 1;
- }
- if (*third)
- {
- if (needcomma)
- (*info->fprintf_func) (info->stream, ",");
- if (op_index[2] != -1 && !op_riprel[2])
- (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
- else
- (*info->fprintf_func) (info->stream, "%s", third);
- }
- for (i = 0; i < 3; i++)
- if (op_index[i] != -1 && op_riprel[i])
- {
- (*info->fprintf_func) (info->stream, " # ");
- (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
- + op_address[op_index[i]]), info);
- }
- return codep - priv.the_buffer;
-}
-
-static const char *float_mem[] = {
- /* d8 */
- "fadd{s||s|}",
- "fmul{s||s|}",
- "fcom{s||s|}",
- "fcomp{s||s|}",
- "fsub{s||s|}",
- "fsubr{s||s|}",
- "fdiv{s||s|}",
- "fdivr{s||s|}",
- /* d9 */
- "fld{s||s|}",
- "(bad)",
- "fst{s||s|}",
- "fstp{s||s|}",
- "fldenv",
- "fldcw",
- "fNstenv",
- "fNstcw",
- /* da */
- "fiadd{l||l|}",
- "fimul{l||l|}",
- "ficom{l||l|}",
- "ficomp{l||l|}",
- "fisub{l||l|}",
- "fisubr{l||l|}",
- "fidiv{l||l|}",
- "fidivr{l||l|}",
- /* db */
- "fild{l||l|}",
- "(bad)",
- "fist{l||l|}",
- "fistp{l||l|}",
- "(bad)",
- "fld{t||t|}",
- "(bad)",
- "fstp{t||t|}",
- /* dc */
- "fadd{l||l|}",
- "fmul{l||l|}",
- "fcom{l||l|}",
- "fcomp{l||l|}",
- "fsub{l||l|}",
- "fsubr{l||l|}",
- "fdiv{l||l|}",
- "fdivr{l||l|}",
- /* dd */
- "fld{l||l|}",
- "(bad)",
- "fst{l||l|}",
- "fstp{l||l|}",
- "frstor",
- "(bad)",
- "fNsave",
- "fNstsw",
- /* de */
- "fiadd",
- "fimul",
- "ficom",
- "ficomp",
- "fisub",
- "fisubr",
- "fidiv",
- "fidivr",
- /* df */
- "fild",
- "(bad)",
- "fist",
- "fistp",
- "fbld",
- "fild{ll||ll|}",
- "fbstp",
- "fistpll",
-};
-
-#define ST OP_ST, 0
-#define STi OP_STi, 0
-
-#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
-#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
-#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
-#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
-#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
-#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
-#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
-#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
-#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
-
-static const struct dis386 float_reg[][8] = {
- /* d8 */
- {
- { "fadd", ST, STi, XX },
- { "fmul", ST, STi, XX },
- { "fcom", STi, XX, XX },
- { "fcomp", STi, XX, XX },
- { "fsub", ST, STi, XX },
- { "fsubr", ST, STi, XX },
- { "fdiv", ST, STi, XX },
- { "fdivr", ST, STi, XX },
- },
- /* d9 */
- {
- { "fld", STi, XX, XX },
- { "fxch", STi, XX, XX },
- { FGRPd9_2 },
- { "(bad)", XX, XX, XX },
- { FGRPd9_4 },
- { FGRPd9_5 },
- { FGRPd9_6 },
- { FGRPd9_7 },
- },
- /* da */
- {
- { "fcmovb", ST, STi, XX },
- { "fcmove", ST, STi, XX },
- { "fcmovbe",ST, STi, XX },
- { "fcmovu", ST, STi, XX },
- { "(bad)", XX, XX, XX },
- { FGRPda_5 },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* db */
- {
- { "fcmovnb",ST, STi, XX },
- { "fcmovne",ST, STi, XX },
- { "fcmovnbe",ST, STi, XX },
- { "fcmovnu",ST, STi, XX },
- { FGRPdb_4 },
- { "fucomi", ST, STi, XX },
- { "fcomi", ST, STi, XX },
- { "(bad)", XX, XX, XX },
- },
- /* dc */
- {
- { "fadd", STi, ST, XX },
- { "fmul", STi, ST, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
-#if UNIXWARE_COMPAT
- { "fsub", STi, ST, XX },
- { "fsubr", STi, ST, XX },
- { "fdiv", STi, ST, XX },
- { "fdivr", STi, ST, XX },
-#else
- { "fsubr", STi, ST, XX },
- { "fsub", STi, ST, XX },
- { "fdivr", STi, ST, XX },
- { "fdiv", STi, ST, XX },
-#endif
- },
- /* dd */
- {
- { "ffree", STi, XX, XX },
- { "(bad)", XX, XX, XX },
- { "fst", STi, XX, XX },
- { "fstp", STi, XX, XX },
- { "fucom", STi, XX, XX },
- { "fucomp", STi, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* de */
- {
- { "faddp", STi, ST, XX },
- { "fmulp", STi, ST, XX },
- { "(bad)", XX, XX, XX },
- { FGRPde_3 },
-#if UNIXWARE_COMPAT
- { "fsubp", STi, ST, XX },
- { "fsubrp", STi, ST, XX },
- { "fdivp", STi, ST, XX },
- { "fdivrp", STi, ST, XX },
-#else
- { "fsubrp", STi, ST, XX },
- { "fsubp", STi, ST, XX },
- { "fdivrp", STi, ST, XX },
- { "fdivp", STi, ST, XX },
-#endif
- },
- /* df */
- {
- { "ffreep", STi, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { FGRPdf_4 },
- { "fucomip",ST, STi, XX },
- { "fcomip", ST, STi, XX },
- { "(bad)", XX, XX, XX },
- },
-};
-
-static char *fgrps[][8] = {
- /* d9_2 0 */
- {
- "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-
- /* d9_4 1 */
- {
- "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
- },
-
- /* d9_5 2 */
- {
- "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
- },
-
- /* d9_6 3 */
- {
- "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
- },
-
- /* d9_7 4 */
- {
- "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
- },
-
- /* da_5 5 */
- {
- "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-
- /* db_4 6 */
- {
- "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
- "fNsetpm(287 only)","(bad)","(bad)","(bad)",
- },
-
- /* de_3 7 */
- {
- "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-
- /* df_4 8 */
- {
- "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-};
-
-static void
-dofloat (sizeflag)
- int sizeflag;
-{
- const struct dis386 *dp;
- unsigned char floatop;
-
- floatop = codep[-1];
-
- if (mod != 3)
- {
- putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
- obufp = op1out;
- if (floatop == 0xdb)
- OP_E (x_mode, sizeflag);
- else if (floatop == 0xdd)
- OP_E (d_mode, sizeflag);
- else
- OP_E (v_mode, sizeflag);
- return;
- }
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
-
- dp = &float_reg[floatop - 0xd8][reg];
- if (dp->name == NULL)
- {
- putop (fgrps[dp->bytemode1][rm], sizeflag);
-
- /* Instruction fnstsw is only one with strange arg. */
- if (floatop == 0xdf && codep[-1] == 0xe0)
- strcpy (op1out, names16[0]);
- }
- else
- {
- putop (dp->name, sizeflag);
-
- obufp = op1out;
- if (dp->op1)
- (*dp->op1) (dp->bytemode1, sizeflag);
- obufp = op2out;
- if (dp->op2)
- (*dp->op2) (dp->bytemode2, sizeflag);
- }
-}
-
-static void
-OP_ST (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- oappend ("%st");
-}
-
-static void
-OP_STi (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- sprintf (scratchbuf, "%%st(%d)", rm);
- oappend (scratchbuf + intel_syntax);
-}
-
-/* Capital letters in template are macros. */
-static int
-putop (template, sizeflag)
- const char *template;
- int sizeflag;
-{
- const char *p;
- int alt;
-
- for (p = template; *p; p++)
- {
- switch (*p)
- {
- default:
- *obufp++ = *p;
- break;
- case '{':
- alt = 0;
- if (intel_syntax)
- alt += 1;
- if (mode_64bit)
- alt += 2;
- while (alt != 0)
- {
- while (*++p != '|')
- {
- if (*p == '}')
- {
- /* Alternative not valid. */
- strcpy (obuf, "(bad)");
- obufp = obuf + 5;
- return 1;
- }
- else if (*p == '\0')
- abort ();
- }
- alt--;
- }
- break;
- case '|':
- while (*++p != '}')
- {
- if (*p == '\0')
- abort ();
- }
- break;
- case '}':
- break;
- case 'A':
- if (intel_syntax)
- break;
- if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
- *obufp++ = 'b';
- break;
- case 'B':
- if (intel_syntax)
- break;
- if (sizeflag & SUFFIX_ALWAYS)
- *obufp++ = 'b';
- break;
- case 'E': /* For jcxz/jecxz */
- if (mode_64bit)
- {
- if (sizeflag & AFLAG)
- *obufp++ = 'r';
- else
- *obufp++ = 'e';
- }
- else
- if (sizeflag & AFLAG)
- *obufp++ = 'e';
- used_prefixes |= (prefixes & PREFIX_ADDR);
- break;
- case 'F':
- if (intel_syntax)
- break;
- if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
- {
- if (sizeflag & AFLAG)
- *obufp++ = mode_64bit ? 'q' : 'l';
- else
- *obufp++ = mode_64bit ? 'l' : 'w';
- used_prefixes |= (prefixes & PREFIX_ADDR);
- }
- break;
- case 'H':
- if (intel_syntax)
- break;
- if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
- || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
- {
- used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
- *obufp++ = ',';
- *obufp++ = 'p';
- if (prefixes & PREFIX_DS)
- *obufp++ = 't';
- else
- *obufp++ = 'n';
- }
- break;
- case 'L':
- if (intel_syntax)
- break;
- if (sizeflag & SUFFIX_ALWAYS)
- *obufp++ = 'l';
- break;
- case 'N':
- if ((prefixes & PREFIX_FWAIT) == 0)
- *obufp++ = 'n';
- else
- used_prefixes |= PREFIX_FWAIT;
- break;
- case 'O':
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- *obufp++ = 'o';
- else
- *obufp++ = 'd';
- break;
- case 'T':
- if (intel_syntax)
- break;
- if (mode_64bit)
- {
- *obufp++ = 'q';
- break;
- }
- /* Fall through. */
- case 'P':
- if (intel_syntax)
- break;
- if ((prefixes & PREFIX_DATA)
- || (rex & REX_MODE64)
- || (sizeflag & SUFFIX_ALWAYS))
- {
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else
- {
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
- }
- break;
- case 'U':
- if (intel_syntax)
- break;
- if (mode_64bit)
- {
- *obufp++ = 'q';
- break;
- }
- /* Fall through. */
- case 'Q':
- if (intel_syntax)
- break;
- USED_REX (REX_MODE64);
- if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
- {
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else
- {
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
- }
- break;
- case 'R':
- USED_REX (REX_MODE64);
- if (intel_syntax)
- {
- if (rex & REX_MODE64)
- {
- *obufp++ = 'q';
- *obufp++ = 't';
- }
- else if (sizeflag & DFLAG)
- {
- *obufp++ = 'd';
- *obufp++ = 'q';
- }
- else
- {
- *obufp++ = 'w';
- *obufp++ = 'd';
- }
- }
- else
- {
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- }
- if (!(rex & REX_MODE64))
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case 'S':
- if (intel_syntax)
- break;
- if (sizeflag & SUFFIX_ALWAYS)
- {
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else
- {
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
- }
- break;
- case 'X':
- if (prefixes & PREFIX_DATA)
- *obufp++ = 'd';
- else
- *obufp++ = 's';
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case 'Y':
- if (intel_syntax)
- break;
- if (rex & REX_MODE64)
- {
- USED_REX (REX_MODE64);
- *obufp++ = 'q';
- }
- break;
- /* implicit operand size 'l' for i386 or 'q' for x86-64 */
- case 'W':
- /* operand size flag for cwtl, cbtw */
- USED_REX (0);
- if (rex)
- *obufp++ = 'l';
- else if (sizeflag & DFLAG)
- *obufp++ = 'w';
- else
- *obufp++ = 'b';
- if (intel_syntax)
- {
- if (rex)
- {
- *obufp++ = 'q';
- *obufp++ = 'e';
- }
- if (sizeflag & DFLAG)
- {
- *obufp++ = 'd';
- *obufp++ = 'e';
- }
- else
- {
- *obufp++ = 'w';
- }
- }
- if (!rex)
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- }
- }
- *obufp = 0;
- return 0;
-}
-
-static void
-oappend (s)
- const char *s;
-{
- strcpy (obufp, s);
- obufp += strlen (s);
-}
-
-static void
-append_seg ()
-{
- if (prefixes & PREFIX_CS)
- {
- used_prefixes |= PREFIX_CS;
- oappend ("%cs:" + intel_syntax);
- }
- if (prefixes & PREFIX_DS)
- {
- used_prefixes |= PREFIX_DS;
- oappend ("%ds:" + intel_syntax);
- }
- if (prefixes & PREFIX_SS)
- {
- used_prefixes |= PREFIX_SS;
- oappend ("%ss:" + intel_syntax);
- }
- if (prefixes & PREFIX_ES)
- {
- used_prefixes |= PREFIX_ES;
- oappend ("%es:" + intel_syntax);
- }
- if (prefixes & PREFIX_FS)
- {
- used_prefixes |= PREFIX_FS;
- oappend ("%fs:" + intel_syntax);
- }
- if (prefixes & PREFIX_GS)
- {
- used_prefixes |= PREFIX_GS;
- oappend ("%gs:" + intel_syntax);
- }
-}
-
-static void
-OP_indirE (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (!intel_syntax)
- oappend ("*");
- OP_E (bytemode, sizeflag);
-}
-
-static void
-print_operand_value (buf, hex, disp)
- char *buf;
- int hex;
- bfd_vma disp;
-{
- if (mode_64bit)
- {
- if (hex)
- {
- char tmp[30];
- int i;
- buf[0] = '0';
- buf[1] = 'x';
- sprintf_vma (tmp, disp);
- for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
- strcpy (buf + 2, tmp + i);
- }
- else
- {
- bfd_signed_vma v = disp;
- char tmp[30];
- int i;
- if (v < 0)
- {
- *(buf++) = '-';
- v = -disp;
- /* Check for possible overflow on 0x8000000000000000. */
- if (v < 0)
- {
- strcpy (buf, "9223372036854775808");
- return;
- }
- }
- if (!v)
- {
- strcpy (buf, "0");
- return;
- }
-
- i = 0;
- tmp[29] = 0;
- while (v)
- {
- tmp[28 - i] = (v % 10) + '0';
- v /= 10;
- i++;
- }
- strcpy (buf, tmp + 29 - i);
- }
- }
- else
- {
- if (hex)
- sprintf (buf, "0x%x", (unsigned int) disp);
- else
- sprintf (buf, "%d", (int) disp);
- }
-}
-
-static void
-OP_E (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma disp;
- int add = 0;
- int riprel = 0;
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add += 8;
-
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
-
- if (mod == 3)
- {
- switch (bytemode)
- {
- case b_mode:
- USED_REX (0);
- if (rex)
- oappend (names8rex[rm + add]);
- else
- oappend (names8[rm + add]);
- break;
- case w_mode:
- oappend (names16[rm + add]);
- break;
- case d_mode:
- oappend (names32[rm + add]);
- break;
- case q_mode:
- oappend (names64[rm + add]);
- break;
- case m_mode:
- if (mode_64bit)
- oappend (names64[rm + add]);
- else
- oappend (names32[rm + add]);
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- oappend (names64[rm + add]);
- else if (sizeflag & DFLAG)
- oappend (names32[rm + add]);
- else
- oappend (names16[rm + add]);
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case 0:
- if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
- && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
- && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
- BadOp (); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- break;
- }
- return;
- }
-
- disp = 0;
- append_seg ();
-
- if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
- {
- int havesib;
- int havebase;
- int base;
- int index = 0;
- int scale = 0;
-
- havesib = 0;
- havebase = 1;
- base = rm;
-
- if (base == 4)
- {
- havesib = 1;
- FETCH_DATA (the_info, codep + 1);
- scale = (*codep >> 6) & 3;
- index = (*codep >> 3) & 7;
- base = *codep & 7;
- USED_REX (REX_EXTY);
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTY)
- index += 8;
- if (rex & REX_EXTZ)
- base += 8;
- codep++;
- }
-
- switch (mod)
- {
- case 0:
- if ((base & 7) == 5)
- {
- havebase = 0;
- if (mode_64bit && !havesib && (sizeflag & AFLAG))
- riprel = 1;
- disp = get32s ();
- }
- break;
- case 1:
- FETCH_DATA (the_info, codep + 1);
- disp = *codep++;
- if ((disp & 0x80) != 0)
- disp -= 0x100;
- break;
- case 2:
- disp = get32s ();
- break;
- }
-
- if (!intel_syntax)
- if (mod != 0 || (base & 7) == 5)
- {
- print_operand_value (scratchbuf, !riprel, disp);
- oappend (scratchbuf);
- if (riprel)
- {
- set_op (disp, 1);
- oappend ("(%rip)");
- }
- }
-
- if (havebase || (havesib && (index != 4 || scale != 0)))
- {
- if (intel_syntax)
- {
- switch (bytemode)
- {
- case b_mode:
- oappend ("BYTE PTR ");
- break;
- case w_mode:
- oappend ("WORD PTR ");
- break;
- case v_mode:
- oappend ("DWORD PTR ");
- break;
- case d_mode:
- oappend ("QWORD PTR ");
- break;
- case m_mode:
- if (mode_64bit)
- oappend ("DWORD PTR ");
- else
- oappend ("QWORD PTR ");
- break;
- case x_mode:
- oappend ("XWORD PTR ");
- break;
- default:
- break;
- }
- }
- *obufp++ = open_char;
- if (intel_syntax && riprel)
- oappend ("rip + ");
- *obufp = '\0';
- USED_REX (REX_EXTZ);
- if (!havesib && (rex & REX_EXTZ))
- base += 8;
- if (havebase)
- oappend (mode_64bit && (sizeflag & AFLAG)
- ? names64[base] : names32[base]);
- if (havesib)
- {
- if (index != 4)
- {
- if (intel_syntax)
- {
- if (havebase)
- {
- *obufp++ = separator_char;
- *obufp = '\0';
- }
- sprintf (scratchbuf, "%s",
- mode_64bit && (sizeflag & AFLAG)
- ? names64[index] : names32[index]);
- }
- else
- sprintf (scratchbuf, ",%s",
- mode_64bit && (sizeflag & AFLAG)
- ? names64[index] : names32[index]);
- oappend (scratchbuf);
- }
- if (!intel_syntax
- || (intel_syntax
- && bytemode != b_mode
- && bytemode != w_mode
- && bytemode != v_mode))
- {
- *obufp++ = scale_char;
- *obufp = '\0';
- sprintf (scratchbuf, "%d", 1 << scale);
- oappend (scratchbuf);
- }
- }
- if (intel_syntax)
- if (mod != 0 || (base & 7) == 5)
- {
- /* Don't print zero displacements. */
- if (disp != 0)
- {
- if ((bfd_signed_vma) disp > 0)
- {
- *obufp++ = '+';
- *obufp = '\0';
- }
-
- print_operand_value (scratchbuf, 0, disp);
- oappend (scratchbuf);
- }
- }
-
- *obufp++ = close_char;
- *obufp = '\0';
- }
- else if (intel_syntax)
- {
- if (mod != 0 || (base & 7) == 5)
- {
- if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS))
- ;
- else
- {
- oappend (names_seg[ds_reg - es_reg]);
- oappend (":");
- }
- print_operand_value (scratchbuf, 1, disp);
- oappend (scratchbuf);
- }
- }
- }
- else
- { /* 16 bit address mode */
- switch (mod)
- {
- case 0:
- if ((rm & 7) == 6)
- {
- disp = get16 ();
- if ((disp & 0x8000) != 0)
- disp -= 0x10000;
- }
- break;
- case 1:
- FETCH_DATA (the_info, codep + 1);
- disp = *codep++;
- if ((disp & 0x80) != 0)
- disp -= 0x100;
- break;
- case 2:
- disp = get16 ();
- if ((disp & 0x8000) != 0)
- disp -= 0x10000;
- break;
- }
-
- if (!intel_syntax)
- if (mod != 0 || (rm & 7) == 6)
- {
- print_operand_value (scratchbuf, 0, disp);
- oappend (scratchbuf);
- }
-
- if (mod != 0 || (rm & 7) != 6)
- {
- *obufp++ = open_char;
- *obufp = '\0';
- oappend (index16[rm + add]);
- *obufp++ = close_char;
- *obufp = '\0';
- }
- }
-}
-
-static void
-OP_G (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add += 8;
- switch (bytemode)
- {
- case b_mode:
- USED_REX (0);
- if (rex)
- oappend (names8rex[reg + add]);
- else
- oappend (names8[reg + add]);
- break;
- case w_mode:
- oappend (names16[reg + add]);
- break;
- case d_mode:
- oappend (names32[reg + add]);
- break;
- case q_mode:
- oappend (names64[reg + add]);
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- oappend (names64[reg + add]);
- else if (sizeflag & DFLAG)
- oappend (names32[reg + add]);
- else
- oappend (names16[reg + add]);
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- break;
- }
-}
-
-static bfd_vma
-get64 ()
-{
- bfd_vma x;
-#ifdef BFD64
- unsigned int a;
- unsigned int b;
-
- FETCH_DATA (the_info, codep + 8);
- a = *codep++ & 0xff;
- a |= (*codep++ & 0xff) << 8;
- a |= (*codep++ & 0xff) << 16;
- a |= (*codep++ & 0xff) << 24;
- b = *codep++ & 0xff;
- b |= (*codep++ & 0xff) << 8;
- b |= (*codep++ & 0xff) << 16;
- b |= (*codep++ & 0xff) << 24;
- x = a + ((bfd_vma) b << 32);
-#else
- abort ();
- x = 0;
-#endif
- return x;
-}
-
-static bfd_signed_vma
-get32 ()
-{
- bfd_signed_vma x = 0;
-
- FETCH_DATA (the_info, codep + 4);
- x = *codep++ & (bfd_signed_vma) 0xff;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
- return x;
-}
-
-static bfd_signed_vma
-get32s ()
-{
- bfd_signed_vma x = 0;
-
- FETCH_DATA (the_info, codep + 4);
- x = *codep++ & (bfd_signed_vma) 0xff;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
-
- x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
-
- return x;
-}
-
-static int
-get16 ()
-{
- int x = 0;
-
- FETCH_DATA (the_info, codep + 2);
- x = *codep++ & 0xff;
- x |= (*codep++ & 0xff) << 8;
- return x;
-}
-
-static void
-set_op (op, riprel)
- bfd_vma op;
- int riprel;
-{
- op_index[op_ad] = op_ad;
- if (mode_64bit)
- {
- op_address[op_ad] = op;
- op_riprel[op_ad] = riprel;
- }
- else
- {
- /* Mask to get a 32-bit address. */
- op_address[op_ad] = op & 0xffffffff;
- op_riprel[op_ad] = riprel & 0xffffffff;
- }
-}
-
-static void
-OP_REG (code, sizeflag)
- int code;
- int sizeflag;
-{
- const char *s;
- int add = 0;
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add = 8;
-
- switch (code)
- {
- case indir_dx_reg:
- if (intel_syntax)
- s = "[dx]";
- else
- s = "(%dx)";
- break;
- case ax_reg: case cx_reg: case dx_reg: case bx_reg:
- case sp_reg: case bp_reg: case si_reg: case di_reg:
- s = names16[code - ax_reg + add];
- break;
- case es_reg: case ss_reg: case cs_reg:
- case ds_reg: case fs_reg: case gs_reg:
- s = names_seg[code - es_reg + add];
- break;
- case al_reg: case ah_reg: case cl_reg: case ch_reg:
- case dl_reg: case dh_reg: case bl_reg: case bh_reg:
- USED_REX (0);
- if (rex)
- s = names8rex[code - al_reg + add];
- else
- s = names8[code - al_reg];
- break;
- case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
- case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
- if (mode_64bit)
- {
- s = names64[code - rAX_reg + add];
- break;
- }
- code += eAX_reg - rAX_reg;
- /* Fall through. */
- case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
- case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- s = names64[code - eAX_reg + add];
- else if (sizeflag & DFLAG)
- s = names32[code - eAX_reg + add];
- else
- s = names16[code - eAX_reg + add];
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- default:
- s = INTERNAL_DISASSEMBLER_ERROR;
- break;
- }
- oappend (s);
-}
-
-static void
-OP_IMREG (code, sizeflag)
- int code;
- int sizeflag;
-{
- const char *s;
-
- switch (code)
- {
- case indir_dx_reg:
- if (intel_syntax)
- s = "[dx]";
- else
- s = "(%dx)";
- break;
- case ax_reg: case cx_reg: case dx_reg: case bx_reg:
- case sp_reg: case bp_reg: case si_reg: case di_reg:
- s = names16[code - ax_reg];
- break;
- case es_reg: case ss_reg: case cs_reg:
- case ds_reg: case fs_reg: case gs_reg:
- s = names_seg[code - es_reg];
- break;
- case al_reg: case ah_reg: case cl_reg: case ch_reg:
- case dl_reg: case dh_reg: case bl_reg: case bh_reg:
- USED_REX (0);
- if (rex)
- s = names8rex[code - al_reg];
- else
- s = names8[code - al_reg];
- break;
- case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
- case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- s = names64[code - eAX_reg];
- else if (sizeflag & DFLAG)
- s = names32[code - eAX_reg];
- else
- s = names16[code - eAX_reg];
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- default:
- s = INTERNAL_DISASSEMBLER_ERROR;
- break;
- }
- oappend (s);
-}
-
-static void
-OP_I (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_signed_vma op;
- bfd_signed_vma mask = -1;
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- op = *codep++;
- mask = 0xff;
- break;
- case q_mode:
- if (mode_64bit)
- {
- op = get32s ();
- break;
- }
- /* Fall through. */
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- op = get32s ();
- else if (sizeflag & DFLAG)
- {
- op = get32 ();
- mask = 0xffffffff;
- }
- else
- {
- op = get16 ();
- mask = 0xfffff;
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case w_mode:
- mask = 0xfffff;
- op = get16 ();
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
-
- op &= mask;
- scratchbuf[0] = '$';
- print_operand_value (scratchbuf + 1, 1, op);
- oappend (scratchbuf + intel_syntax);
- scratchbuf[0] = '\0';
-}
-
-static void
-OP_I64 (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_signed_vma op;
- bfd_signed_vma mask = -1;
-
- if (!mode_64bit)
- {
- OP_I (bytemode, sizeflag);
- return;
- }
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- op = *codep++;
- mask = 0xff;
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- op = get64 ();
- else if (sizeflag & DFLAG)
- {
- op = get32 ();
- mask = 0xffffffff;
- }
- else
- {
- op = get16 ();
- mask = 0xfffff;
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case w_mode:
- mask = 0xfffff;
- op = get16 ();
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
-
- op &= mask;
- scratchbuf[0] = '$';
- print_operand_value (scratchbuf + 1, 1, op);
- oappend (scratchbuf + intel_syntax);
- scratchbuf[0] = '\0';
-}
-
-static void
-OP_sI (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_signed_vma op;
- bfd_signed_vma mask = -1;
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- op = *codep++;
- if ((op & 0x80) != 0)
- op -= 0x100;
- mask = 0xffffffff;
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- op = get32s ();
- else if (sizeflag & DFLAG)
- {
- op = get32s ();
- mask = 0xffffffff;
- }
- else
- {
- mask = 0xffffffff;
- op = get16 ();
- if ((op & 0x8000) != 0)
- op -= 0x10000;
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case w_mode:
- op = get16 ();
- mask = 0xffffffff;
- if ((op & 0x8000) != 0)
- op -= 0x10000;
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
-
- scratchbuf[0] = '$';
- print_operand_value (scratchbuf + 1, 1, op);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_J (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma disp;
- bfd_vma mask = -1;
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- disp = *codep++;
- if ((disp & 0x80) != 0)
- disp -= 0x100;
- break;
- case v_mode:
- if (sizeflag & DFLAG)
- disp = get32s ();
- else
- {
- disp = get16 ();
- /* For some reason, a data16 prefix on a jump instruction
- means that the pc is masked to 16 bits after the
- displacement is added! */
- mask = 0xffff;
- }
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
- disp = (start_pc + codep - start_codep + disp) & mask;
- set_op (disp, 0);
- print_operand_value (scratchbuf, 1, disp);
- oappend (scratchbuf);
-}
-
-static void
-OP_SEG (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- oappend (names_seg[reg]);
-}
-
-static void
-OP_DIR (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- int seg, offset;
-
- if (sizeflag & DFLAG)
- {
- offset = get32 ();
- seg = get16 ();
- }
- else
- {
- offset = get16 ();
- seg = get16 ();
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (intel_syntax)
- sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
- else
- sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
- oappend (scratchbuf);
-}
-
-static void
-OP_OFF (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma off;
-
- append_seg ();
-
- if ((sizeflag & AFLAG) || mode_64bit)
- off = get32 ();
- else
- off = get16 ();
-
- if (intel_syntax)
- {
- if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
- {
- oappend (names_seg[ds_reg - es_reg]);
- oappend (":");
- }
- }
- print_operand_value (scratchbuf, 1, off);
- oappend (scratchbuf);
-}
-
-static void
-OP_OFF64 (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma off;
-
- if (!mode_64bit)
- {
- OP_OFF (bytemode, sizeflag);
- return;
- }
-
- append_seg ();
-
- off = get64 ();
-
- if (intel_syntax)
- {
- if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
- {
- oappend (names_seg[ds_reg - es_reg]);
- oappend (":");
- }
- }
- print_operand_value (scratchbuf, 1, off);
- oappend (scratchbuf);
-}
-
-static void
-ptr_reg (code, sizeflag)
- int code;
- int sizeflag;
-{
- const char *s;
- if (intel_syntax)
- oappend ("[");
- else
- oappend ("(");
-
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- {
- if (!(sizeflag & AFLAG))
- s = names32[code - eAX_reg];
- else
- s = names64[code - eAX_reg];
- }
- else if (sizeflag & AFLAG)
- s = names32[code - eAX_reg];
- else
- s = names16[code - eAX_reg];
- oappend (s);
- if (intel_syntax)
- oappend ("]");
- else
- oappend (")");
-}
-
-static void
-OP_ESreg (code, sizeflag)
- int code;
- int sizeflag;
-{
- oappend ("%es:" + intel_syntax);
- ptr_reg (code, sizeflag);
-}
-
-static void
-OP_DSreg (code, sizeflag)
- int code;
- int sizeflag;
-{
- if ((prefixes
- & (PREFIX_CS
- | PREFIX_DS
- | PREFIX_SS
- | PREFIX_ES
- | PREFIX_FS
- | PREFIX_GS)) == 0)
- prefixes |= PREFIX_DS;
- append_seg ();
- ptr_reg (code, sizeflag);
-}
-
-static void
-OP_C (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- sprintf (scratchbuf, "%%cr%d", reg + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_D (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- if (intel_syntax)
- sprintf (scratchbuf, "db%d", reg + add);
- else
- sprintf (scratchbuf, "%%db%d", reg + add);
- oappend (scratchbuf);
-}
-
-static void
-OP_T (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- sprintf (scratchbuf, "%%tr%d", reg);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_Rd (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (mod == 3)
- OP_E (bytemode, sizeflag);
- else
- BadOp ();
-}
-
-static void
-OP_MMX (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- sprintf (scratchbuf, "%%xmm%d", reg + add);
- else
- sprintf (scratchbuf, "%%mm%d", reg + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_XMM (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- sprintf (scratchbuf, "%%xmm%d", reg + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EM (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- if (mod != 3)
- {
- OP_E (bytemode, sizeflag);
- return;
- }
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add = 8;
-
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- sprintf (scratchbuf, "%%xmm%d", rm + add);
- else
- sprintf (scratchbuf, "%%mm%d", rm + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EX (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- if (mod != 3)
- {
- OP_E (bytemode, sizeflag);
- return;
- }
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add = 8;
-
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
- sprintf (scratchbuf, "%%xmm%d", rm + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_MS (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (mod == 3)
- OP_EM (bytemode, sizeflag);
- else
- BadOp ();
-}
-
-static void
-OP_XS (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (mod == 3)
- OP_EX (bytemode, sizeflag);
- else
- BadOp ();
-}
-
-static const char *Suffix3DNow[] = {
-/* 00 */ NULL, NULL, NULL, NULL,
-/* 04 */ NULL, NULL, NULL, NULL,
-/* 08 */ NULL, NULL, NULL, NULL,
-/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
-/* 10 */ NULL, NULL, NULL, NULL,
-/* 14 */ NULL, NULL, NULL, NULL,
-/* 18 */ NULL, NULL, NULL, NULL,
-/* 1C */ "pf2iw", "pf2id", NULL, NULL,
-/* 20 */ NULL, NULL, NULL, NULL,
-/* 24 */ NULL, NULL, NULL, NULL,
-/* 28 */ NULL, NULL, NULL, NULL,
-/* 2C */ NULL, NULL, NULL, NULL,
-/* 30 */ NULL, NULL, NULL, NULL,
-/* 34 */ NULL, NULL, NULL, NULL,
-/* 38 */ NULL, NULL, NULL, NULL,
-/* 3C */ NULL, NULL, NULL, NULL,
-/* 40 */ NULL, NULL, NULL, NULL,
-/* 44 */ NULL, NULL, NULL, NULL,
-/* 48 */ NULL, NULL, NULL, NULL,
-/* 4C */ NULL, NULL, NULL, NULL,
-/* 50 */ NULL, NULL, NULL, NULL,
-/* 54 */ NULL, NULL, NULL, NULL,
-/* 58 */ NULL, NULL, NULL, NULL,
-/* 5C */ NULL, NULL, NULL, NULL,
-/* 60 */ NULL, NULL, NULL, NULL,
-/* 64 */ NULL, NULL, NULL, NULL,
-/* 68 */ NULL, NULL, NULL, NULL,
-/* 6C */ NULL, NULL, NULL, NULL,
-/* 70 */ NULL, NULL, NULL, NULL,
-/* 74 */ NULL, NULL, NULL, NULL,
-/* 78 */ NULL, NULL, NULL, NULL,
-/* 7C */ NULL, NULL, NULL, NULL,
-/* 80 */ NULL, NULL, NULL, NULL,
-/* 84 */ NULL, NULL, NULL, NULL,
-/* 88 */ NULL, NULL, "pfnacc", NULL,
-/* 8C */ NULL, NULL, "pfpnacc", NULL,
-/* 90 */ "pfcmpge", NULL, NULL, NULL,
-/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
-/* 98 */ NULL, NULL, "pfsub", NULL,
-/* 9C */ NULL, NULL, "pfadd", NULL,
-/* A0 */ "pfcmpgt", NULL, NULL, NULL,
-/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
-/* A8 */ NULL, NULL, "pfsubr", NULL,
-/* AC */ NULL, NULL, "pfacc", NULL,
-/* B0 */ "pfcmpeq", NULL, NULL, NULL,
-/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
-/* B8 */ NULL, NULL, NULL, "pswapd",
-/* BC */ NULL, NULL, NULL, "pavgusb",
-/* C0 */ NULL, NULL, NULL, NULL,
-/* C4 */ NULL, NULL, NULL, NULL,
-/* C8 */ NULL, NULL, NULL, NULL,
-/* CC */ NULL, NULL, NULL, NULL,
-/* D0 */ NULL, NULL, NULL, NULL,
-/* D4 */ NULL, NULL, NULL, NULL,
-/* D8 */ NULL, NULL, NULL, NULL,
-/* DC */ NULL, NULL, NULL, NULL,
-/* E0 */ NULL, NULL, NULL, NULL,
-/* E4 */ NULL, NULL, NULL, NULL,
-/* E8 */ NULL, NULL, NULL, NULL,
-/* EC */ NULL, NULL, NULL, NULL,
-/* F0 */ NULL, NULL, NULL, NULL,
-/* F4 */ NULL, NULL, NULL, NULL,
-/* F8 */ NULL, NULL, NULL, NULL,
-/* FC */ NULL, NULL, NULL, NULL,
-};
-
-static void
-OP_3DNowSuffix (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- const char *mnemonic;
-
- FETCH_DATA (the_info, codep + 1);
- /* AMD 3DNow! instructions are specified by an opcode suffix in the
- place where an 8-bit immediate would normally go. ie. the last
- byte of the instruction. */
- obufp = obuf + strlen (obuf);
- mnemonic = Suffix3DNow[*codep++ & 0xff];
- if (mnemonic)
- oappend (mnemonic);
- else
- {
- /* Since a variable sized modrm/sib chunk is between the start
- of the opcode (0x0f0f) and the opcode suffix, we need to do
- all the modrm processing first, and don't know until now that
- we have a bad opcode. This necessitates some cleaning up. */
- op1out[0] = '\0';
- op2out[0] = '\0';
- BadOp ();
- }
-}
-
-static const char *simd_cmp_op[] = {
- "eq",
- "lt",
- "le",
- "unord",
- "neq",
- "nlt",
- "nle",
- "ord"
-};
-
-static void
-OP_SIMD_Suffix (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- unsigned int cmp_type;
-
- FETCH_DATA (the_info, codep + 1);
- obufp = obuf + strlen (obuf);
- cmp_type = *codep++ & 0xff;
- if (cmp_type < 8)
- {
- char suffix1 = 'p', suffix2 = 's';
- used_prefixes |= (prefixes & PREFIX_REPZ);
- if (prefixes & PREFIX_REPZ)
- suffix1 = 's';
- else
- {
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- suffix2 = 'd';
- else
- {
- used_prefixes |= (prefixes & PREFIX_REPNZ);
- if (prefixes & PREFIX_REPNZ)
- suffix1 = 's', suffix2 = 'd';
- }
- }
- sprintf (scratchbuf, "cmp%s%c%c",
- simd_cmp_op[cmp_type], suffix1, suffix2);
- used_prefixes |= (prefixes & PREFIX_REPZ);
- oappend (scratchbuf);
- }
- else
- {
- /* We have a bad extension byte. Clean up. */
- op1out[0] = '\0';
- op2out[0] = '\0';
- BadOp ();
- }
-}
-
-static void
-SIMD_Fixup (extrachar, sizeflag)
- int extrachar;
- int sizeflag;
-{
- /* Change movlps/movhps to movhlps/movlhps for 2 register operand
- forms of these instructions. */
- if (mod == 3)
- {
- char *p = obuf + strlen (obuf);
- *(p + 1) = '\0';
- *p = *(p - 1);
- *(p - 1) = *(p - 2);
- *(p - 2) = *(p - 3);
- *(p - 3) = extrachar;
- }
-}
-
-static void
-BadOp (void)
-{
- /* Throw away prefixes and 1st. opcode byte. */
- codep = insn_codep + 1;
- oappend ("(bad)");
-}
diff --git a/tools/ioemu/i386-vl.ld b/tools/ioemu/i386-vl.ld
deleted file mode 100644
index 428fe83e12..0000000000
--- a/tools/ioemu/i386-vl.ld
+++ /dev/null
@@ -1,140 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-ENTRY(_start)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0xa8000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
- __preinit_array_start = .;
- .preinit_array : { *(.preinit_array) }
- __preinit_array_end = .;
- __init_array_start = .;
- .init_array : { *(.init_array) }
- __init_array_end = .;
- __fini_array_start = .;
- .fini_array : { *(.fini_array) }
- __fini_array_end = .;
-
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
- {
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
-}
diff --git a/tools/ioemu/i386.ld b/tools/ioemu/i386.ld
deleted file mode 100644
index d41c62695e..0000000000
--- a/tools/ioemu/i386.ld
+++ /dev/null
@@ -1,140 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-ENTRY(_start)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- . = ALIGN(32 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
- {
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
-}
diff --git a/tools/ioemu/ia64.ld b/tools/ioemu/ia64.ld
deleted file mode 100644
index 8d2ede2d3d..0000000000
--- a/tools/ioemu/ia64.ld
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Default linker script, for normal executables */
-OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little",
- "elf64-ia64-little")
-OUTPUT_ARCH(ia64)
-ENTRY(_start)
-SEARCH_DIR("/usr/ia64-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
- .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
- .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
- .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
- .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
- .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
- .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
- .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) }
- .init :
- {
- KEEP (*(.init))
- } =0x00300000010070000002000001000400
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x00300000010070000002000001000400
- .fini :
- {
- KEEP (*(.fini))
- } =0x00300000010070000002000001000400
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) }
- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
- .opd : { *(.opd) }
- .IA_64.unwind_info : { *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) }
- .IA_64.unwind : { *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x10000) + (. & (0x10000 - 1));
- /* Ensure the __preinit_array_start label is properly aligned. We
- could instead move the label definition inside the section, but
- the linker would then create the section even if it turns out to
- be empty, which isn't pretty. */
- . = ALIGN(64 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .eh_frame : { KEEP (*(.eh_frame)) }
- .gcc_except_table : { *(.gcc_except_table) }
- .dynamic : { *(.dynamic) }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin*.o(.ctors))
- /* We don't want to include the .ctor section from
- from the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin*.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- /* Ensure __gp is outside the range of any normal data. We need to
- do this to avoid the linker optimizing the code in op.o and getting
- it out of sync with the relocs that we read when processing that
- file. A better solution might be to ensure that the dynamically
- generated code and static qemu code share a single gp-value. */
- __gp = . + 0x200000;
- .got : { *(.got.plt) *(.got) }
- .IA_64.pltoff : { *(.IA_64.pltoff) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata :
- {
- *(.sdata .sdata.* .gnu.linkonce.s.*)
- }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss :
- {
- PROVIDE (__sbss_start = .);
- PROVIDE (___sbss_start = .);
- *(.dynsbss)
- *(.sbss .sbss.* .gnu.linkonce.sb.*)
- *(.scommon)
- PROVIDE (__sbss_end = .);
- PROVIDE (___sbss_end = .);
- }
- .bss :
- {
- . += 0x400000; /* ensure .bss stuff is out of reach of gp */
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections. */
- . = ALIGN(64 / 8);
- }
- . = ALIGN(64 / 8);
- _end = .;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
diff --git a/tools/ioemu/keymaps.c b/tools/ioemu/keymaps.c
deleted file mode 100644
index 6d68d1a1f5..0000000000
--- a/tools/ioemu/keymaps.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * QEMU keysym to keycode conversion using rdesktop keymaps
- *
- * Copyright (c) 2004 Johannes Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-static int get_keysym(const char *name)
-{
- name2keysym_t *p;
- for(p = name2keysym; p->name != NULL; p++) {
- if (!strcmp(p->name, name))
- return p->keysym;
- }
- return 0;
-}
-
-struct key_range {
- int start;
- int end;
- struct key_range *next;
-};
-
-#define MAX_NORMAL_KEYCODE 512
-#define MAX_EXTRA_COUNT 256
-typedef struct {
- uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
- struct {
- int keysym;
- uint16_t keycode;
- } keysym2keycode_extra[MAX_EXTRA_COUNT];
- int extra_count;
- struct key_range *keypad_range;
- struct key_range *numlock_range;
- struct key_range *shift_range;
- struct key_range *localstate_range;
-} kbd_layout_t;
-
-static void add_to_key_range(struct key_range **krp, int code) {
- struct key_range *kr;
- for (kr = *krp; kr; kr = kr->next) {
- if (code >= kr->start && code <= kr->end)
- break;
- if (code == kr->start - 1) {
- kr->start--;
- break;
- }
- if (code == kr->end + 1) {
- kr->end++;
- break;
- }
- }
- if (kr == NULL) {
- kr = qemu_mallocz(sizeof(*kr));
- if (kr) {
- kr->start = kr->end = code;
- kr->next = *krp;
- *krp = kr;
- }
- }
-}
-
-static kbd_layout_t *parse_keyboard_layout(const char *language,
- kbd_layout_t * k)
-{
- FILE *f;
- char file_name[1024];
- char line[1024];
- int len;
-
- snprintf(file_name, sizeof(file_name),
- "%s/keymaps/%s", bios_dir, language);
-
- if (!k)
- k = qemu_mallocz(sizeof(kbd_layout_t));
- if (!k)
- return 0;
- if (!(f = fopen(file_name, "r"))) {
- fprintf(stderr,
- "Could not read keymap file: '%s'\n", file_name);
- return 0;
- }
- for(;;) {
- if (fgets(line, 1024, f) == NULL)
- break;
- len = strlen(line);
- if (len > 0 && line[len - 1] == '\n')
- line[len - 1] = '\0';
- if (line[0] == '#')
- continue;
- if (!strncmp(line, "map ", 4))
- continue;
- if (!strncmp(line, "include ", 8)) {
- parse_keyboard_layout(line + 8, k);
- } else {
- char *end_of_keysym = line;
- while (*end_of_keysym != 0 && *end_of_keysym != ' ')
- end_of_keysym++;
- if (*end_of_keysym) {
- int keysym;
- *end_of_keysym = 0;
- keysym = get_keysym(line);
- if (keysym == 0) {
- // fprintf(stderr, "Warning: unknown keysym %s\n", line);
- } else {
- const char *rest = end_of_keysym + 1;
- char *rest2;
- int keycode = strtol(rest, &rest2, 0);
-
- if (rest && strstr(rest, "numlock")) {
- add_to_key_range(&k->keypad_range, keycode);
- add_to_key_range(&k->numlock_range, keysym);
- //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
- }
- if (rest && strstr(rest, "shift")) {
- add_to_key_range(&k->shift_range, keysym);
- //fprintf(stderr, "shift keysym %04x keycode %d\n", keysym, keycode);
- }
- if (rest && strstr(rest, "localstate")) {
- add_to_key_range(&k->localstate_range, keycode);
- //fprintf(stderr, "localstate keysym %04x keycode %d\n", keysym, keycode);
- }
-
- /* if(keycode&0x80)
- keycode=(keycode<<8)^0x80e0; */
- if (keysym < MAX_NORMAL_KEYCODE) {
- //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
- k->keysym2keycode[keysym] = keycode;
- } else {
- if (k->extra_count >= MAX_EXTRA_COUNT) {
- fprintf(stderr,
- "Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n",
- line, keysym);
- } else {
-#if 0
- fprintf(stderr, "Setting %d: %d,%d\n",
- k->extra_count, keysym, keycode);
-#endif
- k->keysym2keycode_extra[k->extra_count].
- keysym = keysym;
- k->keysym2keycode_extra[k->extra_count].
- keycode = keycode;
- k->extra_count++;
- }
- }
- }
- }
- }
- }
- fclose(f);
- return k;
-}
-
-static void *init_keyboard_layout(const char *language)
-{
- return parse_keyboard_layout(language, 0);
-}
-
-static int keysym2scancode(void *kbd_layout, int keysym)
-{
- kbd_layout_t *k = kbd_layout;
- if (keysym < MAX_NORMAL_KEYCODE) {
- if (k->keysym2keycode[keysym] == 0)
- fprintf(stderr, "Warning: no scancode found for keysym %d\n",
- keysym);
- return k->keysym2keycode[keysym];
- } else {
- int i;
-#ifdef XK_ISO_Left_Tab
- if (keysym == XK_ISO_Left_Tab)
- keysym = XK_Tab;
-#endif
- for (i = 0; i < k->extra_count; i++)
- if (k->keysym2keycode_extra[i].keysym == keysym)
- return k->keysym2keycode_extra[i].keycode;
- }
- return 0;
-}
-
-static int keycodeIsKeypad(void *kbd_layout, int keycode)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->keypad_range; kr; kr = kr->next)
- if (keycode >= kr->start && keycode <= kr->end)
- return 1;
- return 0;
-}
-
-static int keysymIsNumlock(void *kbd_layout, int keysym)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->numlock_range; kr; kr = kr->next)
- if (keysym >= kr->start && keysym <= kr->end)
- return 1;
- return 0;
-}
-
-static int keysymIsShift(void *kbd_layout, int keysym)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->shift_range; kr; kr = kr->next)
- if (keysym >= kr->start && keysym <= kr->end)
- return 1;
- return 0;
-}
-
-static int keycodeIsShiftable(void *kbd_layout, int keycode)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->localstate_range; kr; kr = kr->next)
- if (keycode >= kr->start && keycode <= kr->end)
- return 0;
- return 1;
-}
diff --git a/tools/ioemu/keymaps/.CVS/Entries b/tools/ioemu/keymaps/.CVS/Entries
deleted file mode 100644
index e667718e8d..0000000000
--- a/tools/ioemu/keymaps/.CVS/Entries
+++ /dev/null
@@ -1,36 +0,0 @@
-/ar/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/common/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/da/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/de/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/de-ch/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/en-gb/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/en-us/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/es/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/et/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/fi/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/fo/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/fr/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/fr-be/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/fr-ca/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/fr-ch/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/hr/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/hu/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/is/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/it/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/ja/1.3/Thu May 3 17:18:01 2007//Trelease_0_9_0
-/lt/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/lv/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/mk/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/modifiers/1.2/Thu May 3 17:17:34 2007//Trelease_0_9_0
-/nl/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/nl-be/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/no/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/pl/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/pt/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/pt-br/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/ru/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/sl/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/sv/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/th/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-/tr/1.1/Thu Jul 13 09:23:22 2006//Trelease_0_9_0
-D
diff --git a/tools/ioemu/keymaps/.CVS/Repository b/tools/ioemu/keymaps/.CVS/Repository
deleted file mode 100644
index 2351e25b08..0000000000
--- a/tools/ioemu/keymaps/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu/keymaps
diff --git a/tools/ioemu/keymaps/.CVS/Root b/tools/ioemu/keymaps/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/keymaps/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/keymaps/.CVS/Tag b/tools/ioemu/keymaps/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/keymaps/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/keymaps/ar b/tools/ioemu/keymaps/ar
deleted file mode 100644
index c430c03bb3..0000000000
--- a/tools/ioemu/keymaps/ar
+++ /dev/null
@@ -1,98 +0,0 @@
-# generated from XKB map ar
-include common
-map 0x401
-exclam 0x02 shift
-at 0x03 shift
-numbersign 0x04 shift
-dollar 0x05 shift
-percent 0x06 shift
-asciicircum 0x07 shift
-ampersand 0x08 shift
-asterisk 0x09 shift
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-Arabic_dad 0x10 altgr
-Arabic_fatha 0x10 shift altgr
-Arabic_sad 0x11 altgr
-Arabic_fathatan 0x11 shift altgr
-Arabic_theh 0x12 altgr
-Arabic_damma 0x12 shift altgr
-Arabic_qaf 0x13 altgr
-Arabic_dammatan 0x13 shift altgr
-Arabic_feh 0x14 altgr
-UFEF9 0x14 shift altgr
-Arabic_ghain 0x15 altgr
-Arabic_hamzaunderalef 0x15 shift altgr
-Arabic_ain 0x16 altgr
-grave 0x16 shift altgr
-Arabic_ha 0x17 altgr
-division 0x17 shift altgr
-Arabic_khah 0x18 altgr
-multiply 0x18 shift altgr
-Arabic_hah 0x19 altgr
-Arabic_semicolon 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Arabic_jeem 0x1a altgr
-bracketright 0x1b
-braceright 0x1b shift
-Arabic_dal 0x1b altgr
-Arabic_sheen 0x1e altgr
-backslash 0x1e shift altgr
-Arabic_seen 0x1f altgr
-Arabic_yeh 0x20 altgr
-bracketleft 0x20 shift altgr
-Arabic_beh 0x21 altgr
-bracketright 0x21 shift altgr
-Arabic_lam 0x22 altgr
-UFEF7 0x22 shift altgr
-Arabic_alef 0x23 altgr
-Arabic_hamzaonalef 0x23 shift altgr
-Arabic_teh 0x24 altgr
-Arabic_tatweel 0x24 shift altgr
-Arabic_noon 0x25 altgr
-Arabic_comma 0x25 shift altgr
-Arabic_meem 0x26 altgr
-slash 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Arabic_kaf 0x27 altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Arabic_tah 0x28 altgr
-grave 0x29
-asciitilde 0x29 shift
-Arabic_thal 0x29 altgr
-Arabic_shadda 0x29 shift altgr
-backslash 0x2b
-bar 0x2b shift
-less 0x2b altgr
-greater 0x2b shift altgr
-Arabic_hamzaonyeh 0x2c altgr
-asciitilde 0x2c shift altgr
-Arabic_hamza 0x2d altgr
-Arabic_sukun 0x2d shift altgr
-Arabic_hamzaonwaw 0x2e altgr
-Arabic_kasra 0x2e shift altgr
-Arabic_ra 0x2f altgr
-Arabic_kasratan 0x2f shift altgr
-UFEFB 0x30 altgr
-UFEF5 0x30 shift altgr
-Arabic_alefmaksura 0x31 altgr
-Arabic_maddaonalef 0x31 shift altgr
-Arabic_tehmarbuta 0x32 altgr
-apostrophe 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-Arabic_waw 0x33 altgr
-period 0x34
-greater 0x34 shift
-Arabic_zain 0x34 altgr
-slash 0x35
-question 0x35 shift
-Arabic_zah 0x35 altgr
-Arabic_question_mark 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/common b/tools/ioemu/keymaps/common
deleted file mode 100644
index 0b53f1c254..0000000000
--- a/tools/ioemu/keymaps/common
+++ /dev/null
@@ -1,157 +0,0 @@
-include modifiers
-
-#
-# Top row
-#
-1 0x2
-2 0x3
-3 0x4
-4 0x5
-5 0x6
-6 0x7
-7 0x8
-8 0x9
-9 0xa
-0 0xb
-BackSpace 0xe
-
-#
-# QWERTY first row
-#
-Tab 0xf localstate
-ISO_Left_Tab 0xf shift
-q 0x10 addupper
-w 0x11 addupper
-e 0x12 addupper
-r 0x13 addupper
-t 0x14 addupper
-y 0x15 addupper
-u 0x16 addupper
-i 0x17 addupper
-o 0x18 addupper
-p 0x19 addupper
-
-#
-# QWERTY second row
-#
-a 0x1e addupper
-s 0x1f addupper
-d 0x20 addupper
-f 0x21 addupper
-g 0x22 addupper
-h 0x23 addupper
-j 0x24 addupper
-k 0x25 addupper
-l 0x26 addupper
-Return 0x1c localstate
-
-#
-# QWERTY third row
-#
-z 0x2c addupper
-x 0x2d addupper
-c 0x2e addupper
-v 0x2f addupper
-b 0x30 addupper
-n 0x31 addupper
-m 0x32 addupper
-
-space 0x39 localstate
-
-less 0x56
-greater 0x56 shift
-bar 0x56 altgr
-brokenbar 0x56 shift altgr
-
-#
-# Esc and Function keys
-#
-Escape 0x1 localstate
-F1 0x3b localstate
-F2 0x3c localstate
-F3 0x3d localstate
-F4 0x3e localstate
-F5 0x3f localstate
-F6 0x40 localstate
-F7 0x41 localstate
-F8 0x42 localstate
-F9 0x43 localstate
-F10 0x44 localstate
-F11 0x57 localstate
-F12 0x58 localstate
-
-# Printscreen, Scrollock and Pause
-# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
-# but (0xe0, 0x37) seems to work.
-Print 0xb7 localstate
-Sys_Req 0xb7 localstate
-Execute 0xb7 localstate
-Scroll_Lock 0x46
-
-#
-# Insert - PgDown
-#
-Insert 0xd2 localstate
-Delete 0xd3 localstate
-Home 0xc7 localstate
-End 0xcf localstate
-Page_Up 0xc9 localstate
-Page_Down 0xd1 localstate
-
-#
-# Arrow keys
-#
-Left 0xcb localstate
-Up 0xc8 localstate
-Down 0xd0 localstate
-Right 0xcd localstate
-
-#
-# Numpad
-#
-Num_Lock 0x45
-KP_Divide 0xb5
-KP_Multiply 0x37
-KP_Subtract 0x4a
-KP_Add 0x4e
-KP_Enter 0x9c
-
-KP_Decimal 0x53 numlock
-KP_Separator 0x53 numlock
-KP_Delete 0x53
-
-KP_0 0x52 numlock
-KP_Insert 0x52
-
-KP_1 0x4f numlock
-KP_End 0x4f
-
-KP_2 0x50 numlock
-KP_Down 0x50
-
-KP_3 0x51 numlock
-KP_Next 0x51
-
-KP_4 0x4b numlock
-KP_Left 0x4b
-
-KP_5 0x4c numlock
-KP_Begin 0x4c
-
-KP_6 0x4d numlock
-KP_Right 0x4d
-
-KP_7 0x47 numlock
-KP_Home 0x47
-
-KP_8 0x48 numlock
-KP_Up 0x48
-
-KP_9 0x49 numlock
-KP_Prior 0x49
-
-Caps_Lock 0x3a
-#
-# Inhibited keys
-#
-Multi_key 0x0 inhibit
diff --git a/tools/ioemu/keymaps/da b/tools/ioemu/keymaps/da
deleted file mode 100644
index 3884dcf145..0000000000
--- a/tools/ioemu/keymaps/da
+++ /dev/null
@@ -1,120 +0,0 @@
-# generated from XKB map dk
-include common
-map 0x406
-exclam 0x02 shift
-exclamdown 0x02 altgr
-onesuperior 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-twosuperior 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-threesuperior 0x04 shift altgr
-currency 0x05 shift
-dollar 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-cent 0x06 shift altgr
-ampersand 0x07 shift
-yen 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-division 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-guillemotleft 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-guillemotright 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-plus 0x0c
-question 0x0c shift
-plusminus 0x0c altgr
-questiondown 0x0c shift altgr
-dead_acute 0x0d
-dead_grave 0x0d shift
-bar 0x0d altgr
-brokenbar 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-registered 0x13 altgr
-thorn 0x14 altgr
-THORN 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oe 0x18 altgr
-OE 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-dead_tilde 0x1b altgr
-dead_caron 0x1b shift altgr
-ordfeminine 0x1e altgr
-masculine 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ae 0x27
-AE 0x27 shift
-oslash 0x28
-Ooblique 0x28 shift
-dead_caron 0x28 shift altgr
-onehalf 0x29
-section 0x29 shift
-threequarters 0x29 altgr
-paragraph 0x29 shift altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-dead_doubleacute 0x2b altgr
-multiply 0x2b shift altgr
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-copyright 0x2e altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-dead_cedilla 0x33 altgr
-dead_ogonek 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-dead_abovedot 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-hyphen 0x35 altgr
-macron 0x35 shift altgr
-nobreakspace 0x39 altgr
-less 0x56
-greater 0x56 shift
-backslash 0x56 altgr
-notsign 0x56 shift altgr
diff --git a/tools/ioemu/keymaps/de b/tools/ioemu/keymaps/de
deleted file mode 100644
index ed929c743b..0000000000
--- a/tools/ioemu/keymaps/de
+++ /dev/null
@@ -1,114 +0,0 @@
-# generated from XKB map de
-include common
-map 0x407
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-section 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-currency 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-ssharp 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-acute 0x0d
-dead_acute 0x0d
-grave 0x0d shift
-dead_grave 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-udiaeresis 0x1a
-Udiaeresis 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-asciitilde 0x1b altgr
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-dead_doubleacute 0x27 altgr
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-dead_caron 0x28 shift altgr
-asciicircum 0x29
-dead_circumflex 0x29
-degree 0x29 shift
-notsign 0x29 altgr
-numbersign 0x2b
-apostrophe 0x2b shift
-dead_breve 0x2b shift altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/de-ch b/tools/ioemu/keymaps/de-ch
deleted file mode 100644
index f83837b444..0000000000
--- a/tools/ioemu/keymaps/de-ch
+++ /dev/null
@@ -1,169 +0,0 @@
-# rdesktop Swiss-German (de-ch) keymap file
-# 2003-06-03 by noldi@tristar.ch
-#
-include common
-map 0x00000807
-#
-# Scan Code 1
-section 0x29
-degree 0x29 shift
-notsign 0x29 altgr inhibit
-#
-# Scan Code 2
-plus 0x2 shift
-brokenbar 0x02 altgr
-#
-# Scan Code 3
-quotedbl 0x03 shift
-at 0x03 altgr
-#
-# Scan Code 4
-asterisk 0x04 shift
-numbersign 0x04 altgr
-#
-# Scan Code 5
-ccedilla 0x05 shift
-onequarter 0x05 altgr inhibit
-#
-# Scan Code 6
-percent 0x06 shift
-onehalf 0x06 altgr inhibit
-#
-# Scan Code 7
-ampersand 0x07 shift
-notsign 0x07 altgr
-#
-# Scan Code 8
-slash 0x08 shift
-bar 0x08 altgr
-#
-# Scan Code 9
-parenleft 0x09 shift
-cent 0x09 altgr
-#
-# Scan Code 10
-parenright 0x0a shift
-#
-# Scan Code 11
-equal 0x0b shift
-braceright 0x0b altgr inhibit
-#
-# Scan Code 12
-apostrophe 0x0c
-question 0x0c shift
-dead_acute 0x0c altgr
-#
-# Scan Code 13
-dead_circumflex 0x0d
-dead_grave 0x0d shift
-dead_tilde 0x0d altgr
-#
-# Scan Code 19
-EuroSign 0x12 altgr
-#
-# Scan Code 22
-z 0x15 addupper
-#
-# Scan Code 27
-udiaeresis 0x1a
-egrave 0x1a shift
-bracketleft 0x1a altgr
-#
-# Scan Code 28
-dead_diaeresis 0x1b
-exclam 0x1b shift
-bracketright 0x1b altgr
-#
-# Scan Code 40
-odiaeresis 0x27
-eacute 0x27 shift
-#
-# Scan Code 41
-adiaeresis 0x28
-agrave 0x28 shift
-braceleft 0x28 altgr
-#
-# Scan Code 42 (only on international keyboards)
-dollar 0x2b
-sterling 0x2b shift
-braceright 0x2b altgr
-#
-# Scan Code 45 (only on international keyboards)
-backslash 0x56 altgr
-#
-# Scan Code 46
-y 0x2c addupper
-#
-# Scan Code 53
-comma 0x33
-semicolon 0x33 shift
-#
-# Scan Code 54
-period 0x34
-colon 0x34 shift
-#
-# Scan Code 55
-minus 0x35
-underscore 0x35 shift
-#
-# Suppress Windows unsupported AltGr keys
-#
-# Scan Code 17
-paragraph 0x10 altgr inhibit
-#
-# Scan Code 21
-tslash 0x14 altgr inhibit
-#
-# Scan Code 22
-leftarrow 0x15 altgr inhibit
-#
-# Scan Code 23
-downarrow 0x16 altgr inhibit
-#
-# Scan Code 24
-rightarrow 0x17 altgr inhibit
-#
-# Scan Code 25
-oslash 0x18 altgr inhibit
-#
-# Scan Code 26
-thorn 0x19 altgr inhibit
-#
-# Scan Code 31
-ae 0x1e altgr inhibit
-#
-# Scan Code 32
-ssharp 0x1f altgr inhibit
-#
-# Scan Code 33
-eth 0x20 altgr inhibit
-#
-# Scan Code 34
-dstroke 0x21 altgr inhibit
-#
-# Scan Code 35
-eng 0x22 altgr inhibit
-#
-# Scan Code 36
-hstroke 0x23 altgr inhibit
-#
-# Scan Code 38
-kra 0x25 altgr inhibit
-#
-# Scan Code 39
-lstroke 0x26 altgr inhibit
-#
-# Scan Code 46
-guillemotleft 0x2c altgr inhibit
-#
-# Scan Code 47
-guillemotright 0x2d altgr inhibit
-#
-# Scan Code 49
-leftdoublequotemark 0x2f altgr inhibit
-#
-# Scan Code 50
-rightdoublequotemark 0x30 altgr inhibit
-#
-# Scan Code 52
-mu 0x32 altgr inhibit
diff --git a/tools/ioemu/keymaps/en-gb b/tools/ioemu/keymaps/en-gb
deleted file mode 100644
index b45f06c7ce..0000000000
--- a/tools/ioemu/keymaps/en-gb
+++ /dev/null
@@ -1,119 +0,0 @@
-# generated from XKB map gb
-include common
-map 0x809
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-sterling 0x04 shift
-threesuperior 0x04 altgr
-dollar 0x05 shift
-EuroSign 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-asciicircum 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-apostrophe 0x28
-at 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-grave 0x29
-notsign 0x29 shift
-bar 0x29 altgr
-numbersign 0x2b
-asciitilde 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
-backslash 0x56
-bar 0x56 shift
diff --git a/tools/ioemu/keymaps/en-us b/tools/ioemu/keymaps/en-us
deleted file mode 100644
index f5784bbb39..0000000000
--- a/tools/ioemu/keymaps/en-us
+++ /dev/null
@@ -1,35 +0,0 @@
-# generated from XKB map us
-include common
-map 0x409
-exclam 0x02 shift
-at 0x03 shift
-numbersign 0x04 shift
-dollar 0x05 shift
-percent 0x06 shift
-asciicircum 0x07 shift
-ampersand 0x08 shift
-asterisk 0x09 shift
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-bracketleft 0x1a
-braceleft 0x1a shift
-bracketright 0x1b
-braceright 0x1b shift
-semicolon 0x27
-colon 0x27 shift
-apostrophe 0x28
-quotedbl 0x28 shift
-grave 0x29
-asciitilde 0x29 shift
-backslash 0x2b
-bar 0x2b shift
-comma 0x33
-less 0x33 shift
-period 0x34
-greater 0x34 shift
-slash 0x35
-question 0x35 shift
diff --git a/tools/ioemu/keymaps/es b/tools/ioemu/keymaps/es
deleted file mode 100644
index 0c29eec5ad..0000000000
--- a/tools/ioemu/keymaps/es
+++ /dev/null
@@ -1,105 +0,0 @@
-# generated from XKB map es
-include common
-map 0x40a
-exclam 0x02 shift
-bar 0x02 altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-periodcentered 0x04 shift
-numbersign 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-asciitilde 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-notsign 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-trademark 0x09 shift altgr
-parenright 0x0a shift
-plusminus 0x0a shift altgr
-equal 0x0b shift
-degree 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-exclamdown 0x0d
-questiondown 0x0d shift
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-dead_grave 0x1a
-dead_circumflex 0x1a shift
-bracketleft 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-bracketright 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ntilde 0x27
-Ntilde 0x27 shift
-dead_doubleacute 0x27 shift altgr
-dead_acute 0x28
-dead_diaeresis 0x28 shift
-braceleft 0x28 altgr
-masculine 0x29
-ordfeminine 0x29 shift
-backslash 0x29 altgr
-ccedilla 0x2b
-Ccedilla 0x2b shift
-braceright 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x56
-greater 0x56 shift
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/et b/tools/ioemu/keymaps/et
deleted file mode 100644
index b5a73fef70..0000000000
--- a/tools/ioemu/keymaps/et
+++ /dev/null
@@ -1,86 +0,0 @@
-map 0x00000425
-include common
-
-#
-# Top row
-#
-dead_caron 0x29
-dead_tilde 0x29 shift
-
-# 1
-exclam 0x2 shift
-
-# 2
-quotedbl 0x3 shift
-at 0x3 altgr
-
-# 3
-numbersign 0x4 shift
-sterling 0x4 altgr
-# 4
-currency 0x5 shift
-dollar 0x5 altgr
-# 5
-percent 0x6 shift
-# 6
-ampersand 0x7 shift
-# 7
-slash 0x8 shift
-braceleft 0x8 altgr
-# 8
-parenleft 0x9 shift
-bracketleft 0x9 altgr
-# 9
-parenright 0xa shift
-bracketright 0xa altgr
-# 0
-equal 0xb shift
-braceright 0xb altgr
-
-plus 0xc
-question 0xc shift
-backslash 0xc altgr
-
-acute 0xd
-dead_acute 0xd
-grave 0xd shift
-dead_grave 0xd shift
-
-#
-# QWERTY first row
-#
-EuroSign 0x12 altgr
-udiaeresis 0x1a
-Udiaeresis 0x1a shift
-otilde 0x1b
-Otilde 0x1b shift
-section 0x1b altgr
-
-#
-# QWERTY second row
-#
-scaron 0x1f altgr
-Scaron 0x1f altgr shift
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-asciicircum 0x28 altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-onehalf 0x2b altgr
-#
-# QWERTY third row
-#
-less 0x56
-greater 0x56 shift
-bar 0x56 altgr
-zcaron 0x2c altgr
-Zcaron 0x2c altgr shift
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-minus 0x35
-underscore 0x35 shift
-
diff --git a/tools/ioemu/keymaps/fi b/tools/ioemu/keymaps/fi
deleted file mode 100644
index 2a4e0f0454..0000000000
--- a/tools/ioemu/keymaps/fi
+++ /dev/null
@@ -1,124 +0,0 @@
-# generated from XKB map se_FI
-include common
-map 0x40b
-exclam 0x02 shift
-exclamdown 0x02 altgr
-onesuperior 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-twosuperior 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-threesuperior 0x04 shift altgr
-currency 0x05 shift
-dollar 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-cent 0x06 shift altgr
-ampersand 0x07 shift
-yen 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-division 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-guillemotleft 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-guillemotright 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-plus 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-dead_acute 0x0d
-dead_grave 0x0d shift
-plusminus 0x0d altgr
-notsign 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-registered 0x13 altgr
-thorn 0x14 altgr
-THORN 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oe 0x18 altgr
-OE 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-dead_tilde 0x1b altgr
-dead_caron 0x1b shift altgr
-ordfeminine 0x1e altgr
-masculine 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-ampersand 0x25 shift altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-oslash 0x27 altgr
-Ooblique 0x27 shift altgr
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-ae 0x28 altgr
-AE 0x28 shift altgr
-section 0x29
-onehalf 0x29 shift
-paragraph 0x29 altgr
-threequarters 0x29 shift altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-acute 0x2b altgr
-multiply 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-copyright 0x2e altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-dead_cedilla 0x33 altgr
-dead_ogonek 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-dead_abovedot 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-hyphen 0x35 altgr
-macron 0x35 shift altgr
-nobreakspace 0x39 altgr
diff --git a/tools/ioemu/keymaps/fo b/tools/ioemu/keymaps/fo
deleted file mode 100644
index 83add423c6..0000000000
--- a/tools/ioemu/keymaps/fo
+++ /dev/null
@@ -1,77 +0,0 @@
-map 0x438
-include common
-
-#
-# Top row
-#
-onehalf 0x29
-section 0x29 shift
-
-# 1
-exclam 0x2 shift
-
-# 2
-quotedbl 0x3 shift
-at 0x3 altgr
-
-# 3
-numbersign 0x4 shift
-sterling 0x4 altgr
-# 4
-currency 0x5 shift
-dollar 0x5 altgr
-# 5
-percent 0x6 shift
-# 6
-ampersand 0x7 shift
-# 7
-slash 0x8 shift
-braceleft 0x8 altgr
-# 8
-parenleft 0x9 shift
-bracketleft 0x9 altgr
-# 9
-parenright 0xa shift
-bracketright 0xa altgr
-# 0
-equal 0xb shift
-braceright 0xb altgr
-
-plus 0xc
-question 0xc shift
-plusminus 0xc altgr
-
-bar 0xd altgr
-dead_acute 0xd
-
-#
-# QWERTY first row
-#
-EuroSign 0x12 altgr
-aring 0x1a
-Aring 0x1a shift
-eth 0x1b addupper
-asciitilde 0x1b altgr
-
-#
-# QWERTY second row
-#
-ae 0x27 addupper
-oslash 0x28
-Ooblique 0x28 shift
-apostrophe 0x2b
-asterisk 0x2b shift
-
-#
-# QWERTY third row
-#
-less 0x56
-greater 0x56 shift
-backslash 0x56 altgr
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-minus 0x35
-underscore 0x35 shift
-
diff --git a/tools/ioemu/keymaps/fr b/tools/ioemu/keymaps/fr
deleted file mode 100644
index cbb45910f4..0000000000
--- a/tools/ioemu/keymaps/fr
+++ /dev/null
@@ -1,181 +0,0 @@
-include common
-map 0x40c
-#
-# Top row
-#
-twosuperior 0x29
-notsign 0x29 altgr
-
-ampersand 0x02
-1 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-
-eacute 0x03
-2 0x03 shift
-asciitilde 0x03 altgr
-oneeighth 0x03 shift altgr
-
-quotedbl 0x04
-3 0x04 shift
-numbersign 0x04 altgr
-
-apostrophe 0x05
-4 0x05 shift
-braceleft 0x05 altgr
-
-parenleft 0x06
-5 0x06 shift
-bracketleft 0x06 altgr
-threeeighths 0x06 shift altgr
-
-minus 0x07
-6 0x07 shift
-bar 0x07 altgr
-fiveeighths 0x07 shift altgr
-
-egrave 0x08
-7 0x08 shift
-grave 0x08 altgr
-seveneighths 0x08 shift altgr
-
-underscore 0x09
-8 0x09 shift
-backslash 0x09 altgr
-trademark 0x09 shift altgr
-
-ccedilla 0x0a
-9 0x0a shift
-asciicircum 0x0a altgr
-plusminus 0x0a shift altgr
-
-agrave 0x0b
-0 0x0b shift
-at 0x0b altgr
-
-parenright 0x0c
-degree 0x0c shift
-bracketright 0x0c altgr
-questiondown 0x0c shift altgr
-
-equal 0x0d
-plus 0x0d shift
-braceright 0x0d altgr
-dead_ogonek 0x0d shift altgr
-
-#
-# AZERTY first row
-#
-
-a 0x10 addupper
-ae 0x10 altgr
-AE 0x10 shift altgr
-
-z 0x11 addupper
-guillemotleft 0x11 altgr
-
-EuroSign 0x12 altgr
-
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-
-dead_circumflex 0x1a
-dead_diaeresis 0x1a shift
-dead_abovering 0x1a shift altgr
-
-dollar 0x1b
-sterling 0x1b shift
-currency 0x1b altgr
-dead_macron 0x1b shift altgr
-
-#
-# AZERTY second row
-#
-q 0x1e addupper
-Greek_OMEGA 0x1e shift altgr
-
-ssharp 0x1f altgr
-
-eth 0x20 altgr
-ETH 0x20 shift altgr
-
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-
-eng 0x22 altgr
-ENG 0x22 shift altgr
-
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-
-kra 0x25 altgr
-
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-
-m 0x27 addupper
-masculine 0x27 shift altgr
-
-ugrave 0x28
-percent 0x28 shift
-dead_caron 0x28 shift altgr
-
-asterisk 0x2b
-mu 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-
-#
-# AZERTY third row
-#
-less 0x56
-greater 0x56 shift
-
-w 0x2c addupper
-
-guillemotright 0x2d altgr
-
-cent 0x2e altgr
-copyright 0x2e shift altgr
-
-leftdoublequotemark 0x2f altgr
-
-rightdoublequotemark 0x30 altgr
-
-comma 0x32
-question 0x32 shift
-dead_acute 0x32 altgr
-dead_doubleacute 0x32 shift altgr
-
-semicolon 0x33
-period 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-
-colon 0x34
-slash 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-
-exclam 0x35
-section 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/fr-be b/tools/ioemu/keymaps/fr-be
deleted file mode 100644
index 92d668eb61..0000000000
--- a/tools/ioemu/keymaps/fr-be
+++ /dev/null
@@ -1,140 +0,0 @@
-# generated from XKB map be
-include common
-map 0x80c
-ampersand 0x02
-1 0x02 shift
-bar 0x02 altgr
-exclamdown 0x02 shift altgr
-eacute 0x03
-2 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-quotedbl 0x04
-3 0x04 shift
-numbersign 0x04 altgr
-sterling 0x04 shift altgr
-apostrophe 0x05
-4 0x05 shift
-onequarter 0x05 altgr
-dollar 0x05 shift altgr
-parenleft 0x06
-5 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-section 0x07
-6 0x07 shift
-asciicircum 0x07 altgr
-fiveeighths 0x07 shift altgr
-egrave 0x08
-7 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-exclam 0x09
-8 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-ccedilla 0x0a
-9 0x0a shift
-braceleft 0x0a altgr
-plusminus 0x0a shift altgr
-agrave 0x0b
-0 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-parenright 0x0c
-degree 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-minus 0x0d
-underscore 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-a 0x10 addupper
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-z 0x11 addupper
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-dead_circumflex 0x1a
-dead_diaeresis 0x1a shift
-bracketleft 0x1a altgr
-dead_abovering 0x1a shift altgr
-dollar 0x1b
-asterisk 0x1b shift
-bracketright 0x1b altgr
-dead_macron 0x1b shift altgr
-q 0x1e addupper
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-ampersand 0x25 shift altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-m 0x27 addupper
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-ugrave 0x28
-percent 0x28 shift
-dead_acute 0x28 altgr
-dead_caron 0x28 shift altgr
-twosuperior 0x29
-threesuperior 0x29 shift
-notsign 0x29 altgr
-mu 0x2b
-sterling 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-w 0x2c addupper
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-comma 0x32
-question 0x32 shift
-dead_cedilla 0x32 altgr
-masculine 0x32 shift altgr
-semicolon 0x33
-period 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-colon 0x34
-slash 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-equal 0x35
-plus 0x35 shift
-dead_tilde 0x35 altgr
-dead_abovedot 0x35 shift altgr
-backslash 0x56 altgr
diff --git a/tools/ioemu/keymaps/fr-ca b/tools/ioemu/keymaps/fr-ca
deleted file mode 100644
index b645208e42..0000000000
--- a/tools/ioemu/keymaps/fr-ca
+++ /dev/null
@@ -1,50 +0,0 @@
-# Canadian French
-# By Simon Germain
-include common
-map 0xc0c
-
-backslash 0x29 altgr
-plusminus 0x2 altgr
-at 0x3 altgr
-sterling 0x4 altgr
-cent 0x5 altgr
-currency 0x6 altgr
-notsign 0x7 altgr
-bar 0x29 shift
-twosuperior 0x9 altgr
-threesuperior 0xa altgr
-onequarter 0xb altgr
-onehalf 0xc altgr
-threequarters 0xd altgr
-section 0x18 altgr
-paragraph 0x19 altgr
-bracketleft 0x1a altgr
-bracketright 0x1b altgr
-asciitilde 0x27 altgr
-braceleft 0x28 altgr
-braceright 0x2b altgr
-less 0x2b
-greater 0x2b shift
-guillemotleft 0x56
-guillemotright 0x56 shift
-degree 0x56 altgr
-mu 0x32 altgr
-eacute 0x35
-dead_acute 0x35 altgr
-dead_grave 0x28
-dead_circumflex 0x1a
-dead_circumflex 0x1a shift
-dead_cedilla 0x1b
-dead_diaeresis 0x1b shift
-exclam 0x2 shift
-quotedbl 0x3 shift
-slash 0x4 shift
-dollar 0x5 shift
-percent 0x6 shift
-question 0x7 shift
-ampersand 0x8 shift
-asterisk 0x9 shift
-parenleft 0xa shift
-parenright 0xb shift
-underscore 0xc shift
-plus 0xd shift
diff --git a/tools/ioemu/keymaps/fr-ch b/tools/ioemu/keymaps/fr-ch
deleted file mode 100644
index 4620d2033b..0000000000
--- a/tools/ioemu/keymaps/fr-ch
+++ /dev/null
@@ -1,114 +0,0 @@
-# generated from XKB map fr_CH
-include common
-map 0x100c
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-section 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-currency 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-ssharp 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-acute 0x0d
-dead_acute 0x0d
-grave 0x0d shift
-dead_grave 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-udiaeresis 0x1a
-Udiaeresis 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-asciitilde 0x1b altgr
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-dead_doubleacute 0x27 altgr
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-dead_caron 0x28 shift altgr
-asciicircum 0x29
-dead_circumflex 0x29
-degree 0x29 shift
-notsign 0x29 altgr
-numbersign 0x2b
-apostrophe 0x2b shift
-dead_breve 0x2b shift altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/hr b/tools/ioemu/keymaps/hr
deleted file mode 100644
index 613aa6925d..0000000000
--- a/tools/ioemu/keymaps/hr
+++ /dev/null
@@ -1,125 +0,0 @@
-# generated from XKB map hr
-include common
-map 0x41a
-exclam 0x02 shift
-asciitilde 0x02 altgr
-dead_tilde 0x02 shift altgr
-quotedbl 0x03 shift
-dead_caron 0x03 altgr
-caron 0x03 shift altgr
-numbersign 0x04 shift
-asciicircum 0x04 altgr
-dead_circumflex 0x04 shift altgr
-dollar 0x05 shift
-dead_breve 0x05 altgr
-breve 0x05 shift altgr
-percent 0x06 shift
-degree 0x06 altgr
-dead_abovering 0x06 shift altgr
-ampersand 0x07 shift
-dead_ogonek 0x07 altgr
-ogonek 0x07 shift altgr
-slash 0x08 shift
-grave 0x08 altgr
-dead_grave 0x08 shift altgr
-parenleft 0x09 shift
-dead_abovedot 0x09 altgr
-abovedot 0x09 shift altgr
-parenright 0x0a shift
-dead_acute 0x0a altgr
-apostrophe 0x0a shift altgr
-equal 0x0b shift
-dead_doubleacute 0x0b altgr
-doubleacute 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-dead_diaeresis 0x0c altgr
-diaeresis 0x0c shift altgr
-plus 0x0d
-asterisk 0x0d shift
-dead_cedilla 0x0d altgr
-cedilla 0x0d shift altgr
-backslash 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-bar 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-scaron 0x1a
-Scaron 0x1a shift
-division 0x1a altgr
-dead_abovering 0x1a shift altgr
-dstroke 0x1b
-Dstroke 0x1b shift
-multiply 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-bracketleft 0x21 altgr
-ordfeminine 0x21 shift altgr
-bracketright 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-lstroke 0x25 altgr
-ampersand 0x25 shift altgr
-Lstroke 0x26 altgr
-ccaron 0x27
-Ccaron 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-cacute 0x28
-Cacute 0x28 shift
-ssharp 0x28 altgr
-dead_caron 0x28 shift altgr
-dead_cedilla 0x29
-dead_diaeresis 0x29 shift
-notsign 0x29 altgr
-zcaron 0x2b
-Zcaron 0x2b shift
-currency 0x2b altgr
-dead_breve 0x2b shift altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-at 0x2f altgr
-grave 0x2f shift altgr
-braceleft 0x30 altgr
-apostrophe 0x30 shift altgr
-braceright 0x31 altgr
-section 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/hu b/tools/ioemu/keymaps/hu
deleted file mode 100644
index 74783a771c..0000000000
--- a/tools/ioemu/keymaps/hu
+++ /dev/null
@@ -1,114 +0,0 @@
-# Hungarian keyboard layout (QWERTZ)
-# Created by: The NeverGone <never@delfin.klte.hu>
-
-include common
-map 0x40e
-
-
-# AltGr keys:
-notsign 0x29 altgr
-dead_tilde 0x02 altgr
-dead_caron 0x03 altgr
-dead_circumflex 0x04 altgr
-dead_breve 0x05 altgr
-dead_degree 0x06 altgr
-dead_ogonek 0x07 altgr
-dead_grave 0x08 altgr
-dead_abovedot 0x09 altgr
-dead_acute 0x0a altgr
-dead_doubleacute 0x0b altgr
-dead_diaeresis 0x0c altgr
-dead_cedilla 0x0d altgr
-backslash 0x10 altgr
-bar 0x11 altgr
-EuroSign 0x12 altgr
-division 0x1a altgr
-multiply 0x1b altgr
-dstroke 0x1f altgr
-Dstroke 0x20 altgr
-bracketleft 0x21 altgr
-bracketright 0x22 altgr
-lstroke 0x25 altgr
-Lstroke 0x26 altgr
-dollar 0x27 altgr
-ssharp 0x28 altgr
-currency 0x2b altgr
-less 0x56 altgr
-greater 0x2c altgr
-numbersign 0x2d altgr
-ampersand 0x2e altgr
-at 0x2f altgr
-braceleft 0x30 altgr
-braceright 0x31 altgr
-semicolon 0x33 altgr
-asterisk 0x35 altgr
-
-
-# Shift keys:
-section 0x29 shift
-apostrophe 0x02 shift
-quotedbl 0x03 shift
-plus 0x04 shift
-exclam 0x05 shift
-percent 0x06 shift
-slash 0x07 shift
-equal 0x08 shift
-parenleft 0x09 shift
-parenright 0x0a shift
-Odiaeresis 0x0b shift
-Udiaeresis 0x0c shift
-Oacute 0x0d shift
-Z 0x15 shift
-Odoubleacute 0x1a shift
-Uacute 0x1b shift
-Eacute 0x27 shift
-Aacute 0x28 shift
-Udoubleacute 0x2b shift
-Y 0x2c shift
-question 0x33 shift
-colon 0x34 shift
-underscore 0x35 shift
-F13 0x3b shift
-F14 0x3c shift
-F15 0x3d shift
-F16 0x3e shift
-F17 0x3f shift
-F18 0x40 shift
-F19 0x41 shift
-F20 0x42 shift
-F21 0x43 shift
-F22 0x44 shift
-F23 0x57 shift
-F24 0x58 shift
-Iacute 0x56 shift
-
-# Ctrl keys:
-F25 0x3b ctrl
-F26 0x3c ctrl
-F27 0x3d ctrl
-F28 0x3e ctrl
-F29 0x3f ctrl
-F30 0x40 ctrl
-F31 0x41 ctrl
-F32 0x42 ctrl
-F33 0x43 ctrl
-F34 0x44 ctrl
-F35 0x57 ctrl
-#NoSymbol 0x58 ctrl
-
-
-0 0x29
-odiaeresis 0x0b
-udiaeresis 0x0c
-oacute 0x0d
-z 0x15
-odoubleacute 0x1a
-uacute 0x1b
-eacute 0x27
-aacute 0x28
-udoubleacute 0x2b
-y 0x2c
-comma 0x33
-period 0x34
-minus 0x35
-iacute 0x56
diff --git a/tools/ioemu/keymaps/is b/tools/ioemu/keymaps/is
deleted file mode 100644
index 8fde40f19a..0000000000
--- a/tools/ioemu/keymaps/is
+++ /dev/null
@@ -1,140 +0,0 @@
-# 2004-03-16 Halldór Guðmundsson and Morten Lange
-# Keyboard definition file for the Icelandic keyboard
-# to be used in rdesktop 1.3.x ( See rdesktop.org)
-# generated from XKB map de, and changed manually
-# Location for example /usr/local/share/rdesktop/keymaps/is
-include common
-map 0x40f
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-#section 0x04 shift
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-currency 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-#ssharp 0x0c
-odiaeresis 0x0c
-#question 0x0c shift
-Odiaeresis 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-#acute 0x0d
-minus 0x0d
-#dead_acute 0x0d
-#grave 0x0d shift
-#dead_grave 0x0d shift
-underscore 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-#z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-#thorn 0x19 altgr
-#THORN 0x19 shift altgr
-#udiaeresis 0x1a
-#Udiaeresis 0x1a shift
-#dead_diaeresis 0x1a altgr
-#dead_abovering 0x1a shift altgr
-eth 0x1a
-ETH 0x1a shift
-apostrophe 0x1b
-question 0x1b shift
-#plus 0x1b
-#asterisk 0x1b shift
-asciitilde 0x1b altgr
-#grave 0x1b altgr
-#dead_tilde 0x1b altgr
-#dead_macron 0x1b shift altgr
-#ae 0x1e altgr
-#AE 0x1e shift altgr
-#eth 0x20 altgr
-#eth 0x20
-#ETH 0x20 shift altgr
-#ETH 0x20 shift
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-#adiaeresis 0x27
-#Adiaeresis 0x27 shift
-ae 0x27
-AE 0x27 shift
-dead_doubleacute 0x27 altgr
-#adiaeresis 0x28
-#Adiaeresis 0x28 shift
-#dead_caron 0x28 shift altgr
-#asciicircum 0x29
-acute 0x28
-dead_acute 0x28
-#dead_circumflex 0x29
-#degree 0x29 shift
-#notsign 0x29 altgr
-plus 0x2b
-asterisk 0x2b shift
-grave 0x2b altgr
-#numbersign 0x2b
-#apostrophe 0x2b shift
-#dead_breve 0x2b shift altgr
-#y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-#minus 0x35
-#underscore 0x35 shift
-thorn 0x35
-THORN 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
-
diff --git a/tools/ioemu/keymaps/it b/tools/ioemu/keymaps/it
deleted file mode 100644
index 00ca73a3e2..0000000000
--- a/tools/ioemu/keymaps/it
+++ /dev/null
@@ -1,115 +0,0 @@
-# generated from XKB map it
-include common
-map 0x410
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-sterling 0x04 shift
-threesuperior 0x04 altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-trademark 0x09 shift altgr
-parenright 0x0a shift
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-grave 0x0c altgr
-questiondown 0x0c shift altgr
-igrave 0x0d
-asciicircum 0x0d shift
-asciitilde 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-egrave 0x1a
-eacute 0x1a shift
-bracketleft 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-bracketright 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ograve 0x27
-ccedilla 0x27 shift
-at 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-agrave 0x28
-degree 0x28 shift
-numbersign 0x28 altgr
-backslash 0x29
-bar 0x29 shift
-notsign 0x29 altgr
-ugrave 0x2b
-section 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/ja b/tools/ioemu/keymaps/ja
deleted file mode 100644
index 9d90a78c81..0000000000
--- a/tools/ioemu/keymaps/ja
+++ /dev/null
@@ -1,109 +0,0 @@
-# generated from XKB map jp106
-include common
-map 0x411
-exclam 0x02 shift
-kana_NU 0x02 altgr
-quotedbl 0x03 shift
-kana_FU 0x03 altgr
-numbersign 0x04 shift
-kana_A 0x04 altgr
-kana_a 0x04 shift altgr
-dollar 0x05 shift
-kana_U 0x05 altgr
-kana_u 0x05 shift altgr
-percent 0x06 shift
-kana_E 0x06 altgr
-kana_e 0x06 shift altgr
-ampersand 0x07 shift
-kana_O 0x07 altgr
-kana_o 0x07 shift altgr
-apostrophe 0x08 shift
-kana_YA 0x08 altgr
-kana_ya 0x08 shift altgr
-parenleft 0x09 shift
-kana_YU 0x09 altgr
-kana_yu 0x09 shift altgr
-parenright 0x0a shift
-kana_YO 0x0a altgr
-kana_yo 0x0a shift altgr
-asciitilde 0x0b shift
-kana_WA 0x0b altgr
-kana_WO 0x0b shift altgr
-minus 0x0c
-equal 0x0c shift
-kana_HO 0x0c altgr
-asciicircum 0x0d
-asciitilde 0x0d shift
-kana_HE 0x0d altgr
-kana_TA 0x10 altgr
-kana_TE 0x11 altgr
-kana_I 0x12 altgr
-kana_i 0x12 shift altgr
-kana_SU 0x13 altgr
-kana_KA 0x14 altgr
-kana_N 0x15 altgr
-kana_NA 0x16 altgr
-kana_NI 0x17 altgr
-kana_RA 0x18 altgr
-kana_SE 0x19 altgr
-at 0x1a
-grave 0x1a shift
-voicedsound 0x1a altgr
-bracketleft 0x1b
-braceleft 0x1b shift
-semivoicedsound 0x1b altgr
-kana_openingbracket 0x1b shift altgr
-kana_CHI 0x1e altgr
-kana_TO 0x1f altgr
-kana_SHI 0x20 altgr
-kana_HA 0x21 altgr
-kana_KI 0x22 altgr
-kana_KU 0x23 altgr
-kana_MA 0x24 altgr
-kana_NO 0x25 altgr
-kana_RI 0x26 altgr
-semicolon 0x27
-plus 0x27 shift
-kana_RE 0x27 altgr
-colon 0x28
-asterisk 0x28 shift
-kana_KE 0x28 altgr
-Zenkaku_Hankaku 0x29
-bracketright 0x2b
-braceright 0x2b shift
-kana_MU 0x2b altgr
-kana_closingbracket 0x2b shift altgr
-kana_TSU 0x2c altgr
-kana_tsu 0x2c shift altgr
-kana_SA 0x2d altgr
-kana_SO 0x2e altgr
-kana_HI 0x2f altgr
-kana_KO 0x30 altgr
-kana_MI 0x31 altgr
-kana_MO 0x32 altgr
-comma 0x33
-less 0x33 shift
-kana_NE 0x33 altgr
-kana_comma 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-kana_RU 0x34 altgr
-kana_fullstop 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-kana_ME 0x35 altgr
-kana_conjunctive 0x35 shift altgr
-Eisu_toggle 0x3a shift
-Execute 0x54 shift
-Kanji 0x70
-backslash 0x73
-yen 0x7d
-bar 0x7d shift
-underscore 0x73 shift
-Henkan_Mode 0x79
-Katakana_Real 0x70
-Katakana 0x70
-Muhenkan 0x7b
-Henkan_Mode_Real 0x79
-Henkan_Mode_Ultra 0x79
-backslash_ja 0x73
diff --git a/tools/ioemu/keymaps/lt b/tools/ioemu/keymaps/lt
deleted file mode 100644
index 3d9d619ea5..0000000000
--- a/tools/ioemu/keymaps/lt
+++ /dev/null
@@ -1,57 +0,0 @@
-# generated from XKB map lt
-include common
-map 0x427
-exclam 0x02 shift
-aogonek 0x02 altgr
-Aogonek 0x02 shift altgr
-at 0x03 shift
-ccaron 0x03 altgr
-Ccaron 0x03 shift altgr
-numbersign 0x04 shift
-eogonek 0x04 altgr
-Eogonek 0x04 shift altgr
-dollar 0x05 shift
-eabovedot 0x05 altgr
-Eabovedot 0x05 shift altgr
-percent 0x06 shift
-iogonek 0x06 altgr
-Iogonek 0x06 shift altgr
-asciicircum 0x07 shift
-scaron 0x07 altgr
-Scaron 0x07 shift altgr
-ampersand 0x08 shift
-uogonek 0x08 altgr
-Uogonek 0x08 shift altgr
-asterisk 0x09 shift
-umacron 0x09 altgr
-Umacron 0x09 shift altgr
-parenleft 0x0a shift
-doublelowquotemark 0x0a altgr
-parenright 0x0b shift
-leftdoublequotemark 0x0b altgr
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-zcaron 0x0d altgr
-Zcaron 0x0d shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-bracketright 0x1b
-braceright 0x1b shift
-semicolon 0x27
-colon 0x27 shift
-apostrophe 0x28
-quotedbl 0x28 shift
-grave 0x29
-asciitilde 0x29 shift
-backslash 0x2b
-bar 0x2b shift
-comma 0x33
-less 0x33 shift
-period 0x34
-greater 0x34 shift
-slash 0x35
-question 0x35 shift
-endash 0x56
-EuroSign 0x56 shift
diff --git a/tools/ioemu/keymaps/lv b/tools/ioemu/keymaps/lv
deleted file mode 100644
index 1d91727912..0000000000
--- a/tools/ioemu/keymaps/lv
+++ /dev/null
@@ -1,128 +0,0 @@
-# generated from XKB map lv
-include common
-map 0x426
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-at 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-EuroSign 0x05 altgr
-cent 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-asciicircum 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-emacron 0x12 altgr
-Emacron 0x12 shift altgr
-rcedilla 0x13 altgr
-Rcedilla 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-umacron 0x16 altgr
-Umacron 0x16 shift altgr
-imacron 0x17 altgr
-Imacron 0x17 shift altgr
-omacron 0x18 altgr
-Omacron 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ISO_Next_Group 0x1c shift
-amacron 0x1e altgr
-Amacron 0x1e shift altgr
-scaron 0x1f altgr
-Scaron 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-gcedilla 0x22 altgr
-Gcedilla 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kcedilla 0x25 altgr
-Kcedilla 0x25 shift altgr
-lcedilla 0x26 altgr
-Lcedilla 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-leftdoublequotemark 0x28 altgr
-doublelowquotemark 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-notsign 0x29 altgr
-backslash 0x2b
-bar 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-zcaron 0x2c altgr
-Zcaron 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-ccaron 0x2e altgr
-Ccaron 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-ncedilla 0x31 altgr
-Ncedilla 0x31 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
-nobreakspace 0x39 altgr
diff --git a/tools/ioemu/keymaps/mk b/tools/ioemu/keymaps/mk
deleted file mode 100644
index 18c1504842..0000000000
--- a/tools/ioemu/keymaps/mk
+++ /dev/null
@@ -1,101 +0,0 @@
-# generated from XKB map mk
-include common
-map 0x42f
-exclam 0x02 shift
-at 0x03 shift
-doublelowquotemark 0x03 shift altgr
-numbersign 0x04 shift
-leftdoublequotemark 0x04 shift altgr
-dollar 0x05 shift
-percent 0x06 shift
-asciicircum 0x07 shift
-ampersand 0x08 shift
-asterisk 0x09 shift
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-Cyrillic_lje 0x10 altgr
-Cyrillic_LJE 0x10 shift altgr
-Cyrillic_nje 0x11 altgr
-Cyrillic_NJE 0x11 shift altgr
-Cyrillic_ie 0x12 altgr
-Cyrillic_IE 0x12 shift altgr
-Cyrillic_er 0x13 altgr
-Cyrillic_ER 0x13 shift altgr
-Cyrillic_te 0x14 altgr
-Cyrillic_TE 0x14 shift altgr
-Macedonia_dse 0x15 altgr
-Macedonia_DSE 0x15 shift altgr
-Cyrillic_u 0x16 altgr
-Cyrillic_U 0x16 shift altgr
-Cyrillic_i 0x17 altgr
-Cyrillic_I 0x17 shift altgr
-Cyrillic_o 0x18 altgr
-Cyrillic_O 0x18 shift altgr
-Cyrillic_pe 0x19 altgr
-Cyrillic_PE 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Cyrillic_sha 0x1a altgr
-Cyrillic_SHA 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-Macedonia_gje 0x1b altgr
-Macedonia_GJE 0x1b shift altgr
-Cyrillic_a 0x1e altgr
-Cyrillic_A 0x1e shift altgr
-Cyrillic_es 0x1f altgr
-Cyrillic_ES 0x1f shift altgr
-Cyrillic_de 0x20 altgr
-Cyrillic_DE 0x20 shift altgr
-Cyrillic_ef 0x21 altgr
-Cyrillic_EF 0x21 shift altgr
-Cyrillic_ghe 0x22 altgr
-Cyrillic_GHE 0x22 shift altgr
-Cyrillic_ha 0x23 altgr
-Cyrillic_HA 0x23 shift altgr
-Cyrillic_je 0x24 altgr
-Cyrillic_JE 0x24 shift altgr
-Cyrillic_ka 0x25 altgr
-Cyrillic_KA 0x25 shift altgr
-Cyrillic_el 0x26 altgr
-Cyrillic_EL 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Cyrillic_che 0x27 altgr
-Cyrillic_CHE 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Macedonia_kje 0x28 altgr
-Macedonia_KJE 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-backslash 0x2b
-bar 0x2b shift
-Cyrillic_zhe 0x2b altgr
-Cyrillic_ZHE 0x2b shift altgr
-Cyrillic_ze 0x2c altgr
-Cyrillic_ZE 0x2c shift altgr
-Cyrillic_dzhe 0x2d altgr
-Cyrillic_DZHE 0x2d shift altgr
-Cyrillic_tse 0x2e altgr
-Cyrillic_TSE 0x2e shift altgr
-Cyrillic_ve 0x2f altgr
-Cyrillic_VE 0x2f shift altgr
-Cyrillic_be 0x30 altgr
-Cyrillic_BE 0x30 shift altgr
-Cyrillic_en 0x31 altgr
-Cyrillic_EN 0x31 shift altgr
-Cyrillic_em 0x32 altgr
-Cyrillic_EM 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-semicolon 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-colon 0x34 shift altgr
-slash 0x35
-question 0x35 shift
diff --git a/tools/ioemu/keymaps/modifiers b/tools/ioemu/keymaps/modifiers
deleted file mode 100644
index ad35a90f7c..0000000000
--- a/tools/ioemu/keymaps/modifiers
+++ /dev/null
@@ -1,18 +0,0 @@
-Shift_R 0x36
-Shift_L 0x2a
-
-Alt_R 0xb8
-Mode_switch 0xb8
-ISO_Level3_Shift 0xb8
-Alt_L 0x38
-
-Control_R 0x9d
-Control_L 0x1d
-
-# Translate Super to Windows keys.
-# This is hardcoded. See documentation for details.
-Super_R 0xdc
-Super_L 0xdb
-
-# Translate Menu to the Windows Application key.
-Menu 0xdd
diff --git a/tools/ioemu/keymaps/nl b/tools/ioemu/keymaps/nl
deleted file mode 100644
index bc823bd2f7..0000000000
--- a/tools/ioemu/keymaps/nl
+++ /dev/null
@@ -1,60 +0,0 @@
-# Dutch (Netherlands)
-include common
-map 0x413
-
-exclam 0x02 shift
-onesuperior 0x02 altgr
-quotebl 0x03 shift
-twosuperior 0x03 altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-underscore 0x08 shift
-sterling 0x08 altgr
-parenleft 0x09 shift
-braceleft 0x09 altgr
-parenright 0x0a shift
-braceright 0x0a altgr
-apostrophe 0x0b shift
-slash 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-degree 0x0d
-dead_tilde 0x0d shift
-dead_cedilla 0x0d altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-dead_diaeresis 0x1a
-dead_circumflex 0x1a shift
-asterisk 0x1b
-bar 0x1b shift
-ssharp 0x1f altgr
-plus 0x27
-plusminus 0x27 shift
-dead_acute 0x28
-dead_grave 0x28 shift
-at 0x29
-section 0x29 shift
-notsign 0x29 altgr
-less 0x2b
-greater 0x2b shift
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-copyright 0x2e altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-hyphen 0x35
-equal 0x35 shift
-bracketright 0x56
-bracketleft 0x56 shift
-brokenbar 0x56 altgr
-
diff --git a/tools/ioemu/keymaps/nl-be b/tools/ioemu/keymaps/nl-be
deleted file mode 100644
index cd162486d0..0000000000
--- a/tools/ioemu/keymaps/nl-be
+++ /dev/null
@@ -1,69 +0,0 @@
-# Dutch (Belgium)
-map 0x813
-include common
-ampersand 0x02
-1 0x02 shift
-bar 0x02 altgr
-eacute 0x03
-2 0x03 shift
-at 0x03 altgr
-quotedbl 0x04
-3 0x04 shift
-numbersign 0x04 altgr
-apostrophe 0x05
-4 0x05 shift
-parenleft 0x06
-5 0x06 shift
-section 0x07
-6 0x07 shift
-circumflex 0x07 altgr
-egrave 0x08
-7 0x08 shift
-exclam 0x09
-8 0x09 shift
-bracketleft 0x09 altgr
-ccedilla 0x0a
-9 0x0a shift
-braceleft 0x0a altgr
-agrave 0x0b
-0 0x0b shift
-braceright 0x0b altgr
-parenright 0x0c
-degree 0x0c shift
-minus 0x0d
-underscore 0x0d shift
-a 0x10 addupper
-z 0x11 addupper
-EuroSign 0x12 altgr
-dead_circumflex 0x1a
-dead_diaeresis 0x1a shift
-bracketleft 0x1a altgr
-dollar 0x1b
-asterisk 0x1b shift
-bracketright 0x1b altgr
-q 0x1e addupper
-m 0x27 addupper
-ugrave 0x28
-percent 0x28 shift
-dead_acute 0x28 altgr
-twosuperior 0x29
-threesuperior 0x29 shift
-mu 0x2b
-sterling 0x2b shift
-dead_grave 0x2b altgr
-w 0x2c addupper
-comma 0x32
-question 0x32 shift
-semicolon 0x33
-period 0x33 shift
-colon 0x34
-slash 0x34 shift
-periodcentered 0x34 altgr
-equal 0x35
-plus 0x35 shift
-tilde 0x35 altgr
-dead_tilde 0x35 shift altgr
-less 0x56
-greater 0x56 shift
-backslash 0x56 altgr
-
diff --git a/tools/ioemu/keymaps/no b/tools/ioemu/keymaps/no
deleted file mode 100644
index 40a64790d1..0000000000
--- a/tools/ioemu/keymaps/no
+++ /dev/null
@@ -1,119 +0,0 @@
-# generated from XKB map no
-include common
-map 0x414
-exclam 0x02 shift
-exclamdown 0x02 altgr
-onesuperior 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-twosuperior 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-threesuperior 0x04 shift altgr
-currency 0x05 shift
-dollar 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-cent 0x06 shift altgr
-ampersand 0x07 shift
-yen 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-division 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-guillemotleft 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-guillemotright 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-plus 0x0c
-question 0x0c shift
-plusminus 0x0c altgr
-questiondown 0x0c shift altgr
-backslash 0x0d
-dead_grave 0x0d shift
-dead_acute 0x0d altgr
-notsign 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-registered 0x13 altgr
-thorn 0x14 altgr
-THORN 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oe 0x18 altgr
-OE 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-asciicircum 0x01b shift
-dead_tilde 0x1b altgr
-asciitilde 0x1b altgr
-dead_caron 0x1b shift altgr
-ordfeminine 0x1e altgr
-masculine 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-oslash 0x27
-Ooblique 0x27 shift
-dead_doubleacute 0x27 shift altgr
-ae 0x28
-AE 0x28 shift
-dead_caron 0x28 shift altgr
-bar 0x29
-section 0x29 shift
-brokenbar 0x29 altgr
-paragraph 0x29 shift altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-multiply 0x2b shift altgr
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-copyright 0x2e altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-dead_cedilla 0x33 altgr
-dead_ogonek 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-dead_abovedot 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-hyphen 0x35 altgr
-macron 0x35 shift altgr
-nobreakspace 0x39 altgr
-onehalf 0x56 altgr
-threequarters 0x56 shift altgr
diff --git a/tools/ioemu/keymaps/pl b/tools/ioemu/keymaps/pl
deleted file mode 100644
index 09c600d355..0000000000
--- a/tools/ioemu/keymaps/pl
+++ /dev/null
@@ -1,122 +0,0 @@
-# generated from XKB map pl
-include common
-map 0x415
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-at 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-asciicircum 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-eogonek 0x12 altgr
-Eogonek 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-EuroSign 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oacute 0x18 altgr
-Oacute 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-aogonek 0x1e altgr
-Aogonek 0x1e shift altgr
-sacute 0x1f altgr
-Sacute 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-notsign 0x29 altgr
-backslash 0x2b
-bar 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-zabovedot 0x2c altgr
-Zabovedot 0x2c shift altgr
-zacute 0x2d altgr
-Zacute 0x2d shift altgr
-cacute 0x2e altgr
-Cacute 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-nacute 0x31 altgr
-Nacute 0x31 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/pt b/tools/ioemu/keymaps/pt
deleted file mode 100644
index c6941f651c..0000000000
--- a/tools/ioemu/keymaps/pt
+++ /dev/null
@@ -1,113 +0,0 @@
-# generated from XKB map pt
-include common
-map 0x816
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-dollar 0x05 shift
-section 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-guillemotleft 0x0d
-guillemotright 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-plus 0x1a
-asterisk 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_acute 0x1b
-dead_grave 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ccedilla 0x27
-Ccedilla 0x27 shift
-dead_doubleacute 0x27 shift altgr
-masculine 0x28
-ordfeminine 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-backslash 0x29
-bar 0x29 shift
-notsign 0x29 altgr
-dead_tilde 0x2b
-dead_circumflex 0x2b shift
-dead_breve 0x2b shift altgr
-less 0x56
-greater 0x56 shift
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/pt-br b/tools/ioemu/keymaps/pt-br
deleted file mode 100644
index 54bafc5dc3..0000000000
--- a/tools/ioemu/keymaps/pt-br
+++ /dev/null
@@ -1,69 +0,0 @@
-# generated from XKB map br
-include common
-map 0x416
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-at 0x03 shift
-twosuperior 0x03 altgr
-onehalf 0x03 shift altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-threequarters 0x04 shift altgr
-dollar 0x05 shift
-sterling 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-cent 0x06 altgr
-dead_diaeresis 0x07 shift
-notsign 0x07 altgr
-diaeresis 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-equal 0x0d
-plus 0x0d shift
-section 0x0d altgr
-EuroSign 0x12 altgr
-registered 0x13 altgr
-dead_acute 0x1a
-dead_grave 0x1a shift
-acute 0x1a altgr
-grave 0x1a shift altgr
-bracketleft 0x1b
-braceleft 0x1b shift
-ordfeminine 0x1b altgr
-ccedilla 0x27
-Ccedilla 0x27 shift
-dead_tilde 0x28
-dead_circumflex 0x28 shift
-asciitilde 0x28 altgr
-asciicircum 0x28 shift altgr
-apostrophe 0x29
-quotedbl 0x29 shift
-bracketright 0x2b
-braceright 0x2b shift
-masculine 0x2b altgr
-copyright 0x2e altgr
-mu 0x32 altgr
-comma 0x33
-less 0x33 shift
-period 0x34
-greater 0x34 shift
-semicolon 0x35
-colon 0x35 shift
-comma 0x53 numlock
-backslash 0x56
-bar 0x56 shift
-slash 0x73
-question 0x73 shift
-degree 0x73 altgr
-KP_Decimal 0x34
diff --git a/tools/ioemu/keymaps/ru b/tools/ioemu/keymaps/ru
deleted file mode 100644
index b3e7d24de5..0000000000
--- a/tools/ioemu/keymaps/ru
+++ /dev/null
@@ -1,109 +0,0 @@
-# generated from XKB map ru
-include common
-map 0x419
-exclam 0x02 shift
-at 0x03 shift
-quotedbl 0x03 shift altgr
-numbersign 0x04 shift
-dollar 0x05 shift
-asterisk 0x05 shift altgr
-percent 0x06 shift
-colon 0x06 shift altgr
-asciicircum 0x07 shift
-comma 0x07 shift altgr
-ampersand 0x08 shift
-period 0x08 shift altgr
-asterisk 0x09 shift
-semicolon 0x09 shift altgr
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-Cyrillic_shorti 0x10 altgr
-Cyrillic_SHORTI 0x10 shift altgr
-Cyrillic_tse 0x11 altgr
-Cyrillic_TSE 0x11 shift altgr
-Cyrillic_u 0x12 altgr
-Cyrillic_U 0x12 shift altgr
-Cyrillic_ka 0x13 altgr
-Cyrillic_KA 0x13 shift altgr
-Cyrillic_ie 0x14 altgr
-Cyrillic_IE 0x14 shift altgr
-Cyrillic_en 0x15 altgr
-Cyrillic_EN 0x15 shift altgr
-Cyrillic_ghe 0x16 altgr
-Cyrillic_GHE 0x16 shift altgr
-Cyrillic_sha 0x17 altgr
-Cyrillic_SHA 0x17 shift altgr
-Cyrillic_shcha 0x18 altgr
-Cyrillic_SHCHA 0x18 shift altgr
-Cyrillic_ze 0x19 altgr
-Cyrillic_ZE 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Cyrillic_ha 0x1a altgr
-Cyrillic_HA 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-Cyrillic_hardsign 0x1b altgr
-Cyrillic_HARDSIGN 0x1b shift altgr
-Cyrillic_ef 0x1e altgr
-Cyrillic_EF 0x1e shift altgr
-Cyrillic_yeru 0x1f altgr
-Cyrillic_YERU 0x1f shift altgr
-Cyrillic_ve 0x20 altgr
-Cyrillic_VE 0x20 shift altgr
-Cyrillic_a 0x21 altgr
-Cyrillic_A 0x21 shift altgr
-Cyrillic_pe 0x22 altgr
-Cyrillic_PE 0x22 shift altgr
-Cyrillic_er 0x23 altgr
-Cyrillic_ER 0x23 shift altgr
-Cyrillic_o 0x24 altgr
-Cyrillic_O 0x24 shift altgr
-Cyrillic_el 0x25 altgr
-Cyrillic_EL 0x25 shift altgr
-Cyrillic_de 0x26 altgr
-Cyrillic_DE 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Cyrillic_zhe 0x27 altgr
-Cyrillic_ZHE 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Cyrillic_e 0x28 altgr
-Cyrillic_E 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-Cyrillic_io 0x29 altgr
-Cyrillic_IO 0x29 shift altgr
-backslash 0x2b
-bar 0x2b shift
-Cyrillic_ya 0x2c altgr
-Cyrillic_YA 0x2c shift altgr
-Cyrillic_che 0x2d altgr
-Cyrillic_CHE 0x2d shift altgr
-Cyrillic_es 0x2e altgr
-Cyrillic_ES 0x2e shift altgr
-Cyrillic_em 0x2f altgr
-Cyrillic_EM 0x2f shift altgr
-Cyrillic_i 0x30 altgr
-Cyrillic_I 0x30 shift altgr
-Cyrillic_te 0x31 altgr
-Cyrillic_TE 0x31 shift altgr
-Cyrillic_softsign 0x32 altgr
-Cyrillic_SOFTSIGN 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-Cyrillic_be 0x33 altgr
-Cyrillic_BE 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-Cyrillic_yu 0x34 altgr
-Cyrillic_YU 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-slash 0x56 altgr
-bar 0x56 shift altgr
diff --git a/tools/ioemu/keymaps/sl b/tools/ioemu/keymaps/sl
deleted file mode 100644
index 56835a92c3..0000000000
--- a/tools/ioemu/keymaps/sl
+++ /dev/null
@@ -1,110 +0,0 @@
-# generated from XKB map sl
-include common
-map 0x424
-exclam 0x02 shift
-asciitilde 0x02 altgr
-dead_tilde 0x02 shift altgr
-quotedbl 0x03 shift
-dead_caron 0x03 altgr
-caron 0x03 shift altgr
-numbersign 0x04 shift
-asciicircum 0x04 altgr
-dead_circumflex 0x04 shift altgr
-dollar 0x05 shift
-dead_breve 0x05 altgr
-breve 0x05 shift altgr
-percent 0x06 shift
-degree 0x06 altgr
-dead_abovering 0x06 shift altgr
-ampersand 0x07 shift
-dead_ogonek 0x07 altgr
-ogonek 0x07 shift altgr
-slash 0x08 shift
-grave 0x08 altgr
-dead_grave 0x08 shift altgr
-parenleft 0x09 shift
-dead_abovedot 0x09 altgr
-abovedot 0x09 shift altgr
-parenright 0x0a shift
-dead_acute 0x0a altgr
-equal 0x0b shift
-dead_doubleacute 0x0b altgr
-doubleacute 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-dead_diaeresis 0x0c altgr
-diaeresis 0x0c shift altgr
-plus 0x0d
-asterisk 0x0d shift
-dead_cedilla 0x0d altgr
-cedilla 0x0d shift altgr
-backslash 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-bar 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-scaron 0x1a
-Scaron 0x1a shift
-division 0x1a altgr
-dstroke 0x1b
-Dstroke 0x1b shift
-multiply 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-bracketleft 0x21 altgr
-ordfeminine 0x21 shift altgr
-bracketright 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-lstroke 0x25 altgr
-Lstroke 0x26 altgr
-ccaron 0x27
-Ccaron 0x27 shift
-cacute 0x28
-Cacute 0x28 shift
-ssharp 0x28 altgr
-dead_cedilla 0x29
-notsign 0x29 altgr
-zcaron 0x2b
-Zcaron 0x2b shift
-currency 0x2b altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-at 0x2f altgr
-braceleft 0x30 altgr
-braceright 0x31 altgr
-section 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
diff --git a/tools/ioemu/keymaps/sv b/tools/ioemu/keymaps/sv
deleted file mode 100644
index 736d637b3f..0000000000
--- a/tools/ioemu/keymaps/sv
+++ /dev/null
@@ -1,82 +0,0 @@
-map 0x0000041d
-include common
-
-#
-# Top row
-#
-section 0x29
-onehalf 0x29 shift
-
-# 1
-exclam 0x2 shift
-
-# 2
-quotedbl 0x3 shift
-at 0x3 altgr
-
-# 3
-numbersign 0x4 shift
-sterling 0x4 altgr
-# 4
-currency 0x5 shift
-dollar 0x5 altgr
-# 5
-percent 0x6 shift
-# 6
-ampersand 0x7 shift
-# 7
-slash 0x8 shift
-braceleft 0x8 altgr
-# 8
-parenleft 0x9 shift
-bracketleft 0x9 altgr
-# 9
-parenright 0xa shift
-bracketright 0xa altgr
-# 0
-equal 0xb shift
-braceright 0xb altgr
-
-plus 0xc
-question 0xc shift
-backslash 0xc altgr
-
-acute 0xd
-dead_acute 0xd
-grave 0xd shift
-dead_grave 0xd shift
-
-#
-# QWERTY first row
-#
-EuroSign 0x12 altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-dead_tilde 0x1b altgr
-
-#
-# QWERTY second row
-#
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-apostrophe 0x2b
-asterisk 0x2b shift
-
-#
-# QWERTY third row
-#
-less 0x56
-greater 0x56 shift
-bar 0x56 altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-minus 0x35
-underscore 0x35 shift
-
diff --git a/tools/ioemu/keymaps/th b/tools/ioemu/keymaps/th
deleted file mode 100644
index b65b6da5d9..0000000000
--- a/tools/ioemu/keymaps/th
+++ /dev/null
@@ -1,131 +0,0 @@
-# generated from XKB map th
-include common
-map 0x41e
-exclam 0x02 shift
-Thai_lakkhangyao 0x02 altgr
-plus 0x02 shift altgr
-at 0x03 shift
-slash 0x03 altgr
-Thai_leknung 0x03 shift altgr
-numbersign 0x04 shift
-minus 0x04 altgr
-Thai_leksong 0x04 shift altgr
-dollar 0x05 shift
-Thai_phosamphao 0x05 altgr
-Thai_leksam 0x05 shift altgr
-percent 0x06 shift
-Thai_thothung 0x06 altgr
-Thai_leksi 0x06 shift altgr
-asciicircum 0x07 shift
-Thai_sarau 0x07 altgr
-Thai_sarauu 0x07 shift altgr
-ampersand 0x08 shift
-Thai_saraue 0x08 altgr
-Thai_baht 0x08 shift altgr
-asterisk 0x09 shift
-Thai_khokhwai 0x09 altgr
-Thai_lekha 0x09 shift altgr
-parenleft 0x0a shift
-Thai_totao 0x0a altgr
-Thai_lekhok 0x0a shift altgr
-parenright 0x0b shift
-Thai_chochan 0x0b altgr
-Thai_lekchet 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-Thai_khokhai 0x0c altgr
-Thai_lekpaet 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-Thai_chochang 0x0d altgr
-Thai_lekkao 0x0d shift altgr
-Thai_maiyamok 0x10 altgr
-Thai_leksun 0x10 shift altgr
-Thai_saraaimaimalai 0x11 altgr
-quotedbl 0x11 shift altgr
-Thai_saraam 0x12 altgr
-Thai_dochada 0x12 shift altgr
-Thai_phophan 0x13 altgr
-Thai_thonangmontho 0x13 shift altgr
-Thai_saraa 0x14 altgr
-Thai_thothong 0x14 shift altgr
-Thai_maihanakat 0x15 altgr
-Thai_nikhahit 0x15 shift altgr
-Thai_saraii 0x16 altgr
-Thai_maitri 0x16 shift altgr
-Thai_rorua 0x17 altgr
-Thai_nonen 0x17 shift altgr
-Thai_nonu 0x18 altgr
-Thai_paiyannoi 0x18 shift altgr
-Thai_yoyak 0x19 altgr
-Thai_yoying 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Thai_bobaimai 0x1a altgr
-Thai_thothan 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-Thai_loling 0x1b altgr
-comma 0x1b shift altgr
-Thai_fofan 0x1e altgr
-Thai_ru 0x1e shift altgr
-Thai_hohip 0x1f altgr
-Thai_khorakhang 0x1f shift altgr
-Thai_kokai 0x20 altgr
-Thai_topatak 0x20 shift altgr
-Thai_dodek 0x21 altgr
-Thai_sarao 0x21 shift altgr
-Thai_sarae 0x22 altgr
-Thai_chochoe 0x22 shift altgr
-Thai_maitho 0x23 altgr
-Thai_maitaikhu 0x23 shift altgr
-Thai_maiek 0x24 altgr
-Thai_maichattawa 0x24 shift altgr
-Thai_saraaa 0x25 altgr
-Thai_sorusi 0x25 shift altgr
-Thai_sosua 0x26 altgr
-Thai_sosala 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Thai_wowaen 0x27 altgr
-Thai_soso 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Thai_ngongu 0x28 altgr
-period 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-underscore 0x29 altgr
-percent 0x29 shift altgr
-ISO_First_Group 0x2a shift
-backslash 0x2b
-bar 0x2b shift
-Thai_khokhuat 0x2b altgr
-Thai_khokhon 0x2b shift altgr
-Thai_phophung 0x2c altgr
-parenleft 0x2c shift altgr
-Thai_popla 0x2d altgr
-parenright 0x2d shift altgr
-Thai_saraae 0x2e altgr
-Thai_choching 0x2e shift altgr
-Thai_oang 0x2f altgr
-Thai_honokhuk 0x2f shift altgr
-Thai_sarai 0x30 altgr
-Thai_phinthu 0x30 shift altgr
-Thai_sarauee 0x31 altgr
-Thai_thanthakhat 0x31 shift altgr
-Thai_thothahan 0x32 altgr
-question 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-Thai_moma 0x33 altgr
-Thai_thophuthao 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-Thai_saraaimaimuan 0x34 altgr
-Thai_lochula 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-Thai_fofa 0x35 altgr
-Thai_lu 0x35 shift altgr
-ISO_Last_Group 0x36 shift
diff --git a/tools/ioemu/keymaps/tr b/tools/ioemu/keymaps/tr
deleted file mode 100644
index 5650e1e93f..0000000000
--- a/tools/ioemu/keymaps/tr
+++ /dev/null
@@ -1,123 +0,0 @@
-# generated from XKB map tr
-include common
-map 0x41f
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-apostrophe 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-dead_circumflex 0x04 shift
-numbersign 0x04 altgr
-sterling 0x04 shift altgr
-plus 0x05 shift
-dollar 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-asciicircum 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-asterisk 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-minus 0x0d
-underscore 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-idotless 0x17
-I 0x17 shift
-rightarrow 0x17 altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-gbreve 0x1a
-Gbreve 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-udiaeresis 0x1b
-Udiaeresis 0x1b shift
-asciitilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-ampersand 0x25 shift altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-scedilla 0x27
-Scedilla 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-i 0x28
-Iabovedot 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-backslash 0x29
-quotedbl 0x29 shift
-asciitilde 0x29 altgr
-comma 0x2b
-semicolon 0x2b shift
-bar 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-odiaeresis 0x33
-Odiaeresis 0x33 shift
-less 0x33 altgr
-multiply 0x33 shift altgr
-ccedilla 0x34
-Ccedilla 0x34 shift
-greater 0x34 altgr
-division 0x34 shift altgr
-period 0x35
-colon 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/kqemu.c b/tools/ioemu/kqemu.c
deleted file mode 100644
index 96ca5826c2..0000000000
--- a/tools/ioemu/kqemu.c
+++ /dev/null
@@ -1,912 +0,0 @@
-/*
- * KQEMU support
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef _WIN32
-#include <windows.h>
-#include <winioctl.h>
-#else
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#endif
-#ifdef HOST_SOLARIS
-#include <sys/modctl.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-
-#ifdef USE_KQEMU
-
-#define DEBUG
-//#define PROFILE
-
-#include <unistd.h>
-#include <fcntl.h>
-#include "kqemu.h"
-
-/* compatibility stuff */
-#ifndef KQEMU_RET_SYSCALL
-#define KQEMU_RET_SYSCALL 0x0300 /* syscall insn */
-#endif
-#ifndef KQEMU_MAX_RAM_PAGES_TO_UPDATE
-#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512
-#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)
-#endif
-#ifndef KQEMU_MAX_MODIFIED_RAM_PAGES
-#define KQEMU_MAX_MODIFIED_RAM_PAGES 512
-#endif
-
-#ifdef _WIN32
-#define KQEMU_DEVICE "\\\\.\\kqemu"
-#else
-#define KQEMU_DEVICE "/dev/kqemu"
-#endif
-
-#ifdef _WIN32
-#define KQEMU_INVALID_FD INVALID_HANDLE_VALUE
-HANDLE kqemu_fd = KQEMU_INVALID_FD;
-#define kqemu_closefd(x) CloseHandle(x)
-#else
-#define KQEMU_INVALID_FD -1
-int kqemu_fd = KQEMU_INVALID_FD;
-#define kqemu_closefd(x) close(x)
-#endif
-
-/* 0 = not allowed
- 1 = user kqemu
- 2 = kernel kqemu
-*/
-int kqemu_allowed = 1;
-unsigned long *pages_to_flush;
-unsigned int nb_pages_to_flush;
-unsigned long *ram_pages_to_update;
-unsigned int nb_ram_pages_to_update;
-unsigned long *modified_ram_pages;
-unsigned int nb_modified_ram_pages;
-uint8_t *modified_ram_pages_table;
-extern uint32_t **l1_phys_map;
-
-#define cpuid(index, eax, ebx, ecx, edx) \
- asm volatile ("cpuid" \
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
- : "0" (index))
-
-#ifdef __x86_64__
-static int is_cpuid_supported(void)
-{
- return 1;
-}
-#else
-static int is_cpuid_supported(void)
-{
- int v0, v1;
- asm volatile ("pushf\n"
- "popl %0\n"
- "movl %0, %1\n"
- "xorl $0x00200000, %0\n"
- "pushl %0\n"
- "popf\n"
- "pushf\n"
- "popl %0\n"
- : "=a" (v0), "=d" (v1)
- :
- : "cc");
- return (v0 != v1);
-}
-#endif
-
-static void kqemu_update_cpuid(CPUState *env)
-{
- int critical_features_mask, features, ext_features, ext_features_mask;
- uint32_t eax, ebx, ecx, edx;
-
- /* the following features are kept identical on the host and
- target cpus because they are important for user code. Strictly
- speaking, only SSE really matters because the OS must support
- it if the user code uses it. */
- critical_features_mask =
- CPUID_CMOV | CPUID_CX8 |
- CPUID_FXSR | CPUID_MMX | CPUID_SSE |
- CPUID_SSE2 | CPUID_SEP;
- ext_features_mask = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR;
- if (!is_cpuid_supported()) {
- features = 0;
- ext_features = 0;
- } else {
- cpuid(1, eax, ebx, ecx, edx);
- features = edx;
- ext_features = ecx;
- }
-#ifdef __x86_64__
- /* NOTE: on x86_64 CPUs, SYSENTER is not supported in
- compatibility mode, so in order to have the best performances
- it is better not to use it */
- features &= ~CPUID_SEP;
-#endif
- env->cpuid_features = (env->cpuid_features & ~critical_features_mask) |
- (features & critical_features_mask);
- env->cpuid_ext_features = (env->cpuid_ext_features & ~ext_features_mask) |
- (ext_features & ext_features_mask);
- /* XXX: we could update more of the target CPUID state so that the
- non accelerated code sees exactly the same CPU features as the
- accelerated code */
-}
-
-int kqemu_init(CPUState *env)
-{
- struct kqemu_init init;
- int ret, version;
-#ifdef _WIN32
- DWORD temp;
-#endif
-
- if (!kqemu_allowed)
- return -1;
-
-#ifdef _WIN32
- kqemu_fd = CreateFile(KQEMU_DEVICE, GENERIC_WRITE | GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
- NULL);
-#else
- kqemu_fd = open(KQEMU_DEVICE, O_RDWR);
-#endif
- if (kqemu_fd == KQEMU_INVALID_FD) {
- fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated\n", KQEMU_DEVICE);
- return -1;
- }
- version = 0;
-#ifdef _WIN32
- DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0,
- &version, sizeof(version), &temp, NULL);
-#else
- ioctl(kqemu_fd, KQEMU_GET_VERSION, &version);
-#endif
- if (version != KQEMU_VERSION) {
- fprintf(stderr, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n",
- version, KQEMU_VERSION);
- goto fail;
- }
-
- pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *
- sizeof(unsigned long));
- if (!pages_to_flush)
- goto fail;
-
- ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *
- sizeof(unsigned long));
- if (!ram_pages_to_update)
- goto fail;
-
- modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *
- sizeof(unsigned long));
- if (!modified_ram_pages)
- goto fail;
- modified_ram_pages_table = qemu_mallocz(phys_ram_size >> TARGET_PAGE_BITS);
- if (!modified_ram_pages_table)
- goto fail;
-
- init.ram_base = phys_ram_base;
- init.ram_size = phys_ram_size;
- init.ram_dirty = phys_ram_dirty;
- init.phys_to_ram_map = l1_phys_map;
- init.pages_to_flush = pages_to_flush;
-#if KQEMU_VERSION >= 0x010200
- init.ram_pages_to_update = ram_pages_to_update;
-#endif
-#if KQEMU_VERSION >= 0x010300
- init.modified_ram_pages = modified_ram_pages;
-#endif
-#ifdef _WIN32
- ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &init, sizeof(init),
- NULL, 0, &temp, NULL) == TRUE ? 0 : -1;
-#else
- ret = ioctl(kqemu_fd, KQEMU_INIT, &init);
-#endif
- if (ret < 0) {
- fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret);
- fail:
- kqemu_closefd(kqemu_fd);
- kqemu_fd = KQEMU_INVALID_FD;
- return -1;
- }
- kqemu_update_cpuid(env);
- env->kqemu_enabled = kqemu_allowed;
- nb_pages_to_flush = 0;
- nb_ram_pages_to_update = 0;
- return 0;
-}
-
-void kqemu_flush_page(CPUState *env, target_ulong addr)
-{
-#if defined(DEBUG)
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu_flush_page: addr=" TARGET_FMT_lx "\n", addr);
- }
-#endif
- if (nb_pages_to_flush >= KQEMU_MAX_PAGES_TO_FLUSH)
- nb_pages_to_flush = KQEMU_FLUSH_ALL;
- else
- pages_to_flush[nb_pages_to_flush++] = addr;
-}
-
-void kqemu_flush(CPUState *env, int global)
-{
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu_flush:\n");
- }
-#endif
- nb_pages_to_flush = KQEMU_FLUSH_ALL;
-}
-
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
-{
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu_set_notdirty: addr=%08lx\n", ram_addr);
- }
-#endif
- /* we only track transitions to dirty state */
- if (phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] != 0xff)
- return;
- if (nb_ram_pages_to_update >= KQEMU_MAX_RAM_PAGES_TO_UPDATE)
- nb_ram_pages_to_update = KQEMU_RAM_PAGES_UPDATE_ALL;
- else
- ram_pages_to_update[nb_ram_pages_to_update++] = ram_addr;
-}
-
-static void kqemu_reset_modified_ram_pages(void)
-{
- int i;
- unsigned long page_index;
-
- for(i = 0; i < nb_modified_ram_pages; i++) {
- page_index = modified_ram_pages[i] >> TARGET_PAGE_BITS;
- modified_ram_pages_table[page_index] = 0;
- }
- nb_modified_ram_pages = 0;
-}
-
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
-{
- unsigned long page_index;
- int ret;
-#ifdef _WIN32
- DWORD temp;
-#endif
-
- page_index = ram_addr >> TARGET_PAGE_BITS;
- if (!modified_ram_pages_table[page_index]) {
-#if 0
- printf("%d: modify_page=%08lx\n", nb_modified_ram_pages, ram_addr);
-#endif
- modified_ram_pages_table[page_index] = 1;
- modified_ram_pages[nb_modified_ram_pages++] = ram_addr;
- if (nb_modified_ram_pages >= KQEMU_MAX_MODIFIED_RAM_PAGES) {
- /* flush */
-#ifdef _WIN32
- ret = DeviceIoControl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
- &nb_modified_ram_pages,
- sizeof(nb_modified_ram_pages),
- NULL, 0, &temp, NULL);
-#else
- ret = ioctl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
- &nb_modified_ram_pages);
-#endif
- kqemu_reset_modified_ram_pages();
- }
- }
-}
-
-struct fpstate {
- uint16_t fpuc;
- uint16_t dummy1;
- uint16_t fpus;
- uint16_t dummy2;
- uint16_t fptag;
- uint16_t dummy3;
-
- uint32_t fpip;
- uint32_t fpcs;
- uint32_t fpoo;
- uint32_t fpos;
- uint8_t fpregs1[8 * 10];
-};
-
-struct fpxstate {
- uint16_t fpuc;
- uint16_t fpus;
- uint16_t fptag;
- uint16_t fop;
- uint32_t fpuip;
- uint16_t cs_sel;
- uint16_t dummy0;
- uint32_t fpudp;
- uint16_t ds_sel;
- uint16_t dummy1;
- uint32_t mxcsr;
- uint32_t mxcsr_mask;
- uint8_t fpregs1[8 * 16];
- uint8_t xmm_regs[16 * 16];
- uint8_t dummy2[96];
-};
-
-static struct fpxstate fpx1 __attribute__((aligned(16)));
-
-static void restore_native_fp_frstor(CPUState *env)
-{
- int fptag, i, j;
- struct fpstate fp1, *fp = &fp1;
-
- fp->fpuc = env->fpuc;
- fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for (i=7; i>=0; i--) {
- fptag <<= 2;
- if (env->fptags[i]) {
- fptag |= 3;
- } else {
- /* the FPU automatically computes it */
- }
- }
- fp->fptag = fptag;
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);
- j = (j + 1) & 7;
- }
- asm volatile ("frstor %0" : "=m" (*fp));
-}
-
-static void save_native_fp_fsave(CPUState *env)
-{
- int fptag, i, j;
- uint16_t fpuc;
- struct fpstate fp1, *fp = &fp1;
-
- asm volatile ("fsave %0" : : "m" (*fp));
- env->fpuc = fp->fpuc;
- env->fpstt = (fp->fpus >> 11) & 7;
- env->fpus = fp->fpus & ~0x3800;
- fptag = fp->fptag;
- for(i = 0;i < 8; i++) {
- env->fptags[i] = ((fptag & 3) == 3);
- fptag >>= 2;
- }
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 10], 10);
- j = (j + 1) & 7;
- }
- /* we must restore the default rounding state */
- fpuc = 0x037f | (env->fpuc & (3 << 10));
- asm volatile("fldcw %0" : : "m" (fpuc));
-}
-
-static void restore_native_fp_fxrstor(CPUState *env)
-{
- struct fpxstate *fp = &fpx1;
- int i, j, fptag;
-
- fp->fpuc = env->fpuc;
- fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for(i = 0; i < 8; i++)
- fptag |= (env->fptags[i] << i);
- fp->fptag = fptag ^ 0xff;
-
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&fp->fpregs1[i * 16], &env->fpregs[j].d, 10);
- j = (j + 1) & 7;
- }
- if (env->cpuid_features & CPUID_SSE) {
- fp->mxcsr = env->mxcsr;
- /* XXX: check if DAZ is not available */
- fp->mxcsr_mask = 0xffff;
- memcpy(fp->xmm_regs, env->xmm_regs, CPU_NB_REGS * 16);
- }
- asm volatile ("fxrstor %0" : "=m" (*fp));
-}
-
-static void save_native_fp_fxsave(CPUState *env)
-{
- struct fpxstate *fp = &fpx1;
- int fptag, i, j;
- uint16_t fpuc;
-
- asm volatile ("fxsave %0" : : "m" (*fp));
- env->fpuc = fp->fpuc;
- env->fpstt = (fp->fpus >> 11) & 7;
- env->fpus = fp->fpus & ~0x3800;
- fptag = fp->fptag ^ 0xff;
- for(i = 0;i < 8; i++) {
- env->fptags[i] = (fptag >> i) & 1;
- }
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 16], 10);
- j = (j + 1) & 7;
- }
- if (env->cpuid_features & CPUID_SSE) {
- env->mxcsr = fp->mxcsr;
- memcpy(env->xmm_regs, fp->xmm_regs, CPU_NB_REGS * 16);
- }
-
- /* we must restore the default rounding state */
- asm volatile ("fninit");
- fpuc = 0x037f | (env->fpuc & (3 << 10));
- asm volatile("fldcw %0" : : "m" (fpuc));
-}
-
-static int do_syscall(CPUState *env,
- struct kqemu_cpu_state *kenv)
-{
- int selector;
-
- selector = (env->star >> 32) & 0xffff;
-#ifdef __x86_64__
- if (env->hflags & HF_LMA_MASK) {
- int code64;
-
- env->regs[R_ECX] = kenv->next_eip;
- env->regs[11] = env->eflags;
-
- code64 = env->hflags & HF_CS64_MASK;
-
- cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~env->fmask;
- if (code64)
- env->eip = env->lstar;
- else
- env->eip = env->cstar;
- } else
-#endif
- {
- env->regs[R_ECX] = (uint32_t)kenv->next_eip;
-
- cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
- env->eip = (uint32_t)env->star;
- }
- return 2;
-}
-
-#ifdef CONFIG_PROFILER
-
-#define PC_REC_SIZE 1
-#define PC_REC_HASH_BITS 16
-#define PC_REC_HASH_SIZE (1 << PC_REC_HASH_BITS)
-
-typedef struct PCRecord {
- unsigned long pc;
- int64_t count;
- struct PCRecord *next;
-} PCRecord;
-
-static PCRecord *pc_rec_hash[PC_REC_HASH_SIZE];
-static int nb_pc_records;
-
-static void kqemu_record_pc(unsigned long pc)
-{
- unsigned long h;
- PCRecord **pr, *r;
-
- h = pc / PC_REC_SIZE;
- h = h ^ (h >> PC_REC_HASH_BITS);
- h &= (PC_REC_HASH_SIZE - 1);
- pr = &pc_rec_hash[h];
- for(;;) {
- r = *pr;
- if (r == NULL)
- break;
- if (r->pc == pc) {
- r->count++;
- return;
- }
- pr = &r->next;
- }
- r = malloc(sizeof(PCRecord));
- r->count = 1;
- r->pc = pc;
- r->next = NULL;
- *pr = r;
- nb_pc_records++;
-}
-
-static int pc_rec_cmp(const void *p1, const void *p2)
-{
- PCRecord *r1 = *(PCRecord **)p1;
- PCRecord *r2 = *(PCRecord **)p2;
- if (r1->count < r2->count)
- return 1;
- else if (r1->count == r2->count)
- return 0;
- else
- return -1;
-}
-
-static void kqemu_record_flush(void)
-{
- PCRecord *r, *r_next;
- int h;
-
- for(h = 0; h < PC_REC_HASH_SIZE; h++) {
- for(r = pc_rec_hash[h]; r != NULL; r = r_next) {
- r_next = r->next;
- free(r);
- }
- pc_rec_hash[h] = NULL;
- }
- nb_pc_records = 0;
-}
-
-void kqemu_record_dump(void)
-{
- PCRecord **pr, *r;
- int i, h;
- FILE *f;
- int64_t total, sum;
-
- pr = malloc(sizeof(PCRecord *) * nb_pc_records);
- i = 0;
- total = 0;
- for(h = 0; h < PC_REC_HASH_SIZE; h++) {
- for(r = pc_rec_hash[h]; r != NULL; r = r->next) {
- pr[i++] = r;
- total += r->count;
- }
- }
- qsort(pr, nb_pc_records, sizeof(PCRecord *), pc_rec_cmp);
-
- f = fopen("/tmp/kqemu.stats", "w");
- if (!f) {
- perror("/tmp/kqemu.stats");
- exit(1);
- }
- fprintf(f, "total: %" PRId64 "\n", total);
- sum = 0;
- for(i = 0; i < nb_pc_records; i++) {
- r = pr[i];
- sum += r->count;
- fprintf(f, "%08lx: %" PRId64 " %0.2f%% %0.2f%%\n",
- r->pc,
- r->count,
- (double)r->count / (double)total * 100.0,
- (double)sum / (double)total * 100.0);
- }
- fclose(f);
- free(pr);
-
- kqemu_record_flush();
-}
-#endif
-
-int kqemu_cpu_exec(CPUState *env)
-{
- struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
- int ret, cpl, i;
-#ifdef CONFIG_PROFILER
- int64_t ti;
-#endif
-
-#ifdef _WIN32
- DWORD temp;
-#endif
-
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: cpu_exec: enter\n");
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- memcpy(kenv->regs, env->regs, sizeof(kenv->regs));
- kenv->eip = env->eip;
- kenv->eflags = env->eflags;
- memcpy(&kenv->segs, &env->segs, sizeof(env->segs));
- memcpy(&kenv->ldt, &env->ldt, sizeof(env->ldt));
- memcpy(&kenv->tr, &env->tr, sizeof(env->tr));
- memcpy(&kenv->gdt, &env->gdt, sizeof(env->gdt));
- memcpy(&kenv->idt, &env->idt, sizeof(env->idt));
- kenv->cr0 = env->cr[0];
- kenv->cr2 = env->cr[2];
- kenv->cr3 = env->cr[3];
- kenv->cr4 = env->cr[4];
- kenv->a20_mask = env->a20_mask;
-#if KQEMU_VERSION >= 0x010100
- kenv->efer = env->efer;
-#endif
-#if KQEMU_VERSION >= 0x010300
- kenv->tsc_offset = 0;
- kenv->star = env->star;
- kenv->sysenter_cs = env->sysenter_cs;
- kenv->sysenter_esp = env->sysenter_esp;
- kenv->sysenter_eip = env->sysenter_eip;
-#ifdef __x86_64__
- kenv->lstar = env->lstar;
- kenv->cstar = env->cstar;
- kenv->fmask = env->fmask;
- kenv->kernelgsbase = env->kernelgsbase;
-#endif
-#endif
- if (env->dr[7] & 0xff) {
- kenv->dr7 = env->dr[7];
- kenv->dr0 = env->dr[0];
- kenv->dr1 = env->dr[1];
- kenv->dr2 = env->dr[2];
- kenv->dr3 = env->dr[3];
- } else {
- kenv->dr7 = 0;
- }
- kenv->dr6 = env->dr[6];
- cpl = (env->hflags & HF_CPL_MASK);
- kenv->cpl = cpl;
- kenv->nb_pages_to_flush = nb_pages_to_flush;
-#if KQEMU_VERSION >= 0x010200
- kenv->user_only = (env->kqemu_enabled == 1);
- kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
-#endif
- nb_ram_pages_to_update = 0;
-
-#if KQEMU_VERSION >= 0x010300
- kenv->nb_modified_ram_pages = nb_modified_ram_pages;
-#endif
- kqemu_reset_modified_ram_pages();
-
- if (env->cpuid_features & CPUID_FXSR)
- restore_native_fp_fxrstor(env);
- else
- restore_native_fp_frstor(env);
-
-#ifdef _WIN32
- if (DeviceIoControl(kqemu_fd, KQEMU_EXEC,
- kenv, sizeof(struct kqemu_cpu_state),
- kenv, sizeof(struct kqemu_cpu_state),
- &temp, NULL)) {
- ret = kenv->retval;
- } else {
- ret = -1;
- }
-#else
-#if KQEMU_VERSION >= 0x010100
- ioctl(kqemu_fd, KQEMU_EXEC, kenv);
- ret = kenv->retval;
-#else
- ret = ioctl(kqemu_fd, KQEMU_EXEC, kenv);
-#endif
-#endif
- if (env->cpuid_features & CPUID_FXSR)
- save_native_fp_fxsave(env);
- else
- save_native_fp_fsave(env);
-
- memcpy(env->regs, kenv->regs, sizeof(env->regs));
- env->eip = kenv->eip;
- env->eflags = kenv->eflags;
- memcpy(env->segs, kenv->segs, sizeof(env->segs));
- cpu_x86_set_cpl(env, kenv->cpl);
- memcpy(&env->ldt, &kenv->ldt, sizeof(env->ldt));
-#if 0
- /* no need to restore that */
- memcpy(env->tr, kenv->tr, sizeof(env->tr));
- memcpy(env->gdt, kenv->gdt, sizeof(env->gdt));
- memcpy(env->idt, kenv->idt, sizeof(env->idt));
- env->a20_mask = kenv->a20_mask;
-#endif
- env->cr[0] = kenv->cr0;
- env->cr[4] = kenv->cr4;
- env->cr[3] = kenv->cr3;
- env->cr[2] = kenv->cr2;
- env->dr[6] = kenv->dr6;
-#if KQEMU_VERSION >= 0x010300
-#ifdef __x86_64__
- env->kernelgsbase = kenv->kernelgsbase;
-#endif
-#endif
-
- /* flush pages as indicated by kqemu */
- if (kenv->nb_pages_to_flush >= KQEMU_FLUSH_ALL) {
- tlb_flush(env, 1);
- } else {
- for(i = 0; i < kenv->nb_pages_to_flush; i++) {
- tlb_flush_page(env, pages_to_flush[i]);
- }
- }
- nb_pages_to_flush = 0;
-
-#ifdef CONFIG_PROFILER
- kqemu_time += profile_getclock() - ti;
- kqemu_exec_count++;
-#endif
-
-#if KQEMU_VERSION >= 0x010200
- if (kenv->nb_ram_pages_to_update > 0) {
- cpu_tlb_update_dirty(env);
- }
-#endif
-
-#if KQEMU_VERSION >= 0x010300
- if (kenv->nb_modified_ram_pages > 0) {
- for(i = 0; i < kenv->nb_modified_ram_pages; i++) {
- unsigned long addr;
- addr = modified_ram_pages[i];
- tb_invalidate_phys_page_range(addr, addr + TARGET_PAGE_SIZE, 0);
- }
- }
-#endif
-
- /* restore the hidden flags */
- {
- unsigned int new_hflags;
-#ifdef TARGET_X86_64
- if ((env->hflags & HF_LMA_MASK) &&
- (env->segs[R_CS].flags & DESC_L_MASK)) {
- /* long mode */
- new_hflags = HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
- } else
-#endif
- {
- /* legacy / compatibility case */
- new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
- >> (DESC_B_SHIFT - HF_CS32_SHIFT);
- new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
- >> (DESC_B_SHIFT - HF_SS32_SHIFT);
- if (!(env->cr[0] & CR0_PE_MASK) ||
- (env->eflags & VM_MASK) ||
- !(env->hflags & HF_CS32_MASK)) {
- /* XXX: try to avoid this test. The problem comes from the
- fact that is real mode or vm86 mode we only modify the
- 'base' and 'selector' fields of the segment cache to go
- faster. A solution may be to force addseg to one in
- translate-i386.c. */
- new_hflags |= HF_ADDSEG_MASK;
- } else {
- new_hflags |= ((env->segs[R_DS].base |
- env->segs[R_ES].base |
- env->segs[R_SS].base) != 0) <<
- HF_ADDSEG_SHIFT;
- }
- }
- env->hflags = (env->hflags &
- ~(HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)) |
- new_hflags;
- }
- /* update FPU flags */
- env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
- ((env->cr[0] << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
- if (env->cr[4] & CR4_OSFXSR_MASK)
- env->hflags |= HF_OSFXSR_MASK;
- else
- env->hflags &= ~HF_OSFXSR_MASK;
-
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
- }
-#endif
- if (ret == KQEMU_RET_SYSCALL) {
- /* syscall instruction */
- return do_syscall(env, kenv);
- } else
- if ((ret & 0xff00) == KQEMU_RET_INT) {
- env->exception_index = ret & 0xff;
- env->error_code = 0;
- env->exception_is_int = 1;
- env->exception_next_eip = kenv->next_eip;
-#ifdef CONFIG_PROFILER
- kqemu_ret_int_count++;
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: interrupt v=%02x:\n",
- env->exception_index);
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 1;
- } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
- env->exception_index = ret & 0xff;
- env->error_code = kenv->error_code;
- env->exception_is_int = 0;
- env->exception_next_eip = 0;
-#ifdef CONFIG_PROFILER
- kqemu_ret_excp_count++;
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: exception v=%02x e=%04x:\n",
- env->exception_index, env->error_code);
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 1;
- } else if (ret == KQEMU_RET_INTR) {
-#ifdef CONFIG_PROFILER
- kqemu_ret_intr_count++;
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 0;
- } else if (ret == KQEMU_RET_SOFTMMU) {
-#ifdef CONFIG_PROFILER
- {
- unsigned long pc = env->eip + env->segs[R_CS].base;
- kqemu_record_pc(pc);
- }
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 2;
- } else {
- cpu_dump_state(env, stderr, fprintf, 0);
- fprintf(stderr, "Unsupported return value: 0x%x\n", ret);
- exit(1);
- }
- return 0;
-}
-
-void kqemu_cpu_interrupt(CPUState *env)
-{
-#if defined(_WIN32) && KQEMU_VERSION >= 0x010101
- /* cancelling the I/O request causes KQEMU to finish executing the
- current block and successfully returning. */
- CancelIo(kqemu_fd);
-#endif
-}
-
-#endif
diff --git a/tools/ioemu/kqemu.h b/tools/ioemu/kqemu.h
deleted file mode 100644
index 892e335935..0000000000
--- a/tools/ioemu/kqemu.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * KQEMU header
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef KQEMU_H
-#define KQEMU_H
-
-#define KQEMU_VERSION 0x010300
-
-struct kqemu_segment_cache {
- uint32_t selector;
- unsigned long base;
- uint32_t limit;
- uint32_t flags;
-};
-
-struct kqemu_cpu_state {
-#ifdef __x86_64__
- unsigned long regs[16];
-#else
- unsigned long regs[8];
-#endif
- unsigned long eip;
- unsigned long eflags;
-
- uint32_t dummy0, dummy1, dumm2, dummy3, dummy4;
-
- struct kqemu_segment_cache segs[6]; /* selector values */
- struct kqemu_segment_cache ldt;
- struct kqemu_segment_cache tr;
- struct kqemu_segment_cache gdt; /* only base and limit are used */
- struct kqemu_segment_cache idt; /* only base and limit are used */
-
- unsigned long cr0;
- unsigned long dummy5;
- unsigned long cr2;
- unsigned long cr3;
- unsigned long cr4;
- uint32_t a20_mask;
-
- /* sysenter registers */
- uint32_t sysenter_cs;
- uint32_t sysenter_esp;
- uint32_t sysenter_eip;
- uint64_t efer __attribute__((aligned(8)));
- uint64_t star;
-#ifdef __x86_64__
- unsigned long lstar;
- unsigned long cstar;
- unsigned long fmask;
- unsigned long kernelgsbase;
-#endif
- uint64_t tsc_offset;
-
- unsigned long dr0;
- unsigned long dr1;
- unsigned long dr2;
- unsigned long dr3;
- unsigned long dr6;
- unsigned long dr7;
-
- uint8_t cpl;
- uint8_t user_only;
-
- uint32_t error_code; /* error_code when exiting with an exception */
- unsigned long next_eip; /* next eip value when exiting with an interrupt */
- unsigned int nb_pages_to_flush; /* number of pages to flush,
- KQEMU_FLUSH_ALL means full flush */
-#define KQEMU_MAX_PAGES_TO_FLUSH 512
-#define KQEMU_FLUSH_ALL (KQEMU_MAX_PAGES_TO_FLUSH + 1)
-
- long retval;
-
- /* number of ram_dirty entries to update */
- unsigned int nb_ram_pages_to_update;
-#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512
-#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)
-
-#define KQEMU_MAX_MODIFIED_RAM_PAGES 512
- unsigned int nb_modified_ram_pages;
-};
-
-struct kqemu_init {
- uint8_t *ram_base; /* must be page aligned */
- unsigned long ram_size; /* must be multiple of 4 KB */
- uint8_t *ram_dirty; /* must be page aligned */
- uint32_t **phys_to_ram_map; /* must be page aligned */
- unsigned long *pages_to_flush; /* must be page aligned */
- unsigned long *ram_pages_to_update; /* must be page aligned */
- unsigned long *modified_ram_pages; /* must be page aligned */
-};
-
-#define KQEMU_RET_ABORT (-1)
-#define KQEMU_RET_EXCEPTION 0x0000 /* 8 low order bit are the exception */
-#define KQEMU_RET_INT 0x0100 /* 8 low order bit are the interrupt */
-#define KQEMU_RET_SOFTMMU 0x0200 /* emulation needed (I/O or
- unsupported INSN) */
-#define KQEMU_RET_INTR 0x0201 /* interrupted by a signal */
-#define KQEMU_RET_SYSCALL 0x0300 /* syscall insn */
-
-#ifdef _WIN32
-#define KQEMU_EXEC CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-#define KQEMU_INIT CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define KQEMU_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define KQEMU_MODIFY_RAM_PAGES CTL_CODE(FILE_DEVICE_UNKNOWN, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#else
-#define KQEMU_EXEC _IOWR('q', 1, struct kqemu_cpu_state)
-#define KQEMU_INIT _IOW('q', 2, struct kqemu_init)
-#define KQEMU_GET_VERSION _IOR('q', 3, int)
-#define KQEMU_MODIFY_RAM_PAGES _IOW('q', 4, int)
-#endif
-
-#endif /* KQEMU_H */
diff --git a/tools/ioemu/loader.c b/tools/ioemu/loader.c
deleted file mode 100644
index 7823add917..0000000000
--- a/tools/ioemu/loader.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * QEMU Executable loader
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "disas.h"
-
-/* return the size or -1 if error */
-int get_image_size(const char *filename)
-{
- int fd, size;
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- close(fd);
- return size;
-}
-
-/* return the size or -1 if error */
-int load_image(const char *filename, uint8_t *addr)
-{
- int fd, size;
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
- if (read(fd, addr, size) != size) {
- close(fd);
- return -1;
- }
- close(fd);
- return size;
-}
-
-/* A.OUT loader */
-
-struct exec
-{
- uint32_t a_info; /* Use macros N_MAGIC, etc for access */
- uint32_t a_text; /* length of text, in bytes */
- uint32_t a_data; /* length of data, in bytes */
- uint32_t a_bss; /* length of uninitialized data area, in bytes */
- uint32_t a_syms; /* length of symbol table data in file, in bytes */
- uint32_t a_entry; /* start address */
- uint32_t a_trsize; /* length of relocation info for text, in bytes */
- uint32_t a_drsize; /* length of relocation info for data, in bytes */
-};
-
-#ifdef BSWAP_NEEDED
-static void bswap_ahdr(struct exec *e)
-{
- bswap32s(&e->a_info);
- bswap32s(&e->a_text);
- bswap32s(&e->a_data);
- bswap32s(&e->a_bss);
- bswap32s(&e->a_syms);
- bswap32s(&e->a_entry);
- bswap32s(&e->a_trsize);
- bswap32s(&e->a_drsize);
-}
-#else
-#define bswap_ahdr(x) do { } while (0)
-#endif
-
-#define N_MAGIC(exec) ((exec).a_info & 0xffff)
-#define OMAGIC 0407
-#define NMAGIC 0410
-#define ZMAGIC 0413
-#define QMAGIC 0314
-#define _N_HDROFF(x) (1024 - sizeof (struct exec))
-#define N_TXTOFF(x) \
- (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
- (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
-#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
-#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
-#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
-
-#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
-
-#define N_DATADDR(x) \
- (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
- : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
-
-
-int load_aout(const char *filename, uint8_t *addr)
-{
- int fd, size, ret;
- struct exec e;
- uint32_t magic;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
-
- size = read(fd, &e, sizeof(e));
- if (size < 0)
- goto fail;
-
- bswap_ahdr(&e);
-
- magic = N_MAGIC(e);
- switch (magic) {
- case ZMAGIC:
- case QMAGIC:
- case OMAGIC:
- lseek(fd, N_TXTOFF(e), SEEK_SET);
- size = read(fd, addr, e.a_text + e.a_data);
- if (size < 0)
- goto fail;
- break;
- case NMAGIC:
- lseek(fd, N_TXTOFF(e), SEEK_SET);
- size = read(fd, addr, e.a_text);
- if (size < 0)
- goto fail;
- ret = read(fd, addr + N_DATADDR(e), e.a_data);
- if (ret < 0)
- goto fail;
- size += ret;
- break;
- default:
- goto fail;
- }
- close(fd);
- return size;
- fail:
- close(fd);
- return -1;
-}
-
-/* ELF loader */
-
-static void *load_at(int fd, int offset, int size)
-{
- void *ptr;
- if (lseek(fd, offset, SEEK_SET) < 0)
- return NULL;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- if (read(fd, ptr, size) != size) {
- qemu_free(ptr);
- return NULL;
- }
- return ptr;
-}
-
-
-#define ELF_CLASS ELFCLASS32
-#include "elf.h"
-
-#define SZ 32
-#define elf_word uint32_t
-#define bswapSZs bswap32s
-#include "elf_ops.h"
-
-#undef elfhdr
-#undef elf_phdr
-#undef elf_shdr
-#undef elf_sym
-#undef elf_note
-#undef elf_word
-#undef bswapSZs
-#undef SZ
-#define elfhdr elf64_hdr
-#define elf_phdr elf64_phdr
-#define elf_note elf64_note
-#define elf_shdr elf64_shdr
-#define elf_sym elf64_sym
-#define elf_word uint64_t
-#define bswapSZs bswap64s
-#define SZ 64
-#include "elf_ops.h"
-
-/* return < 0 if error, otherwise the number of bytes loaded in memory */
-int load_elf(const char *filename, int64_t virt_to_phys_addend,
- uint64_t *pentry)
-{
- int fd, data_order, host_data_order, must_swab, ret;
- uint8_t e_ident[EI_NIDENT];
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0) {
- perror(filename);
- return -1;
- }
- if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
- goto fail;
- if (e_ident[0] != ELFMAG0 ||
- e_ident[1] != ELFMAG1 ||
- e_ident[2] != ELFMAG2 ||
- e_ident[3] != ELFMAG3)
- goto fail;
-#ifdef WORDS_BIGENDIAN
- data_order = ELFDATA2MSB;
-#else
- data_order = ELFDATA2LSB;
-#endif
- must_swab = data_order != e_ident[EI_DATA];
-
-#ifdef TARGET_WORDS_BIGENDIAN
- host_data_order = ELFDATA2MSB;
-#else
- host_data_order = ELFDATA2LSB;
-#endif
- if (host_data_order != e_ident[EI_DATA])
- return -1;
-
- lseek(fd, 0, SEEK_SET);
- if (e_ident[EI_CLASS] == ELFCLASS64) {
- ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry);
- } else {
- ret = load_elf32(fd, virt_to_phys_addend, must_swab, pentry);
- }
-
- close(fd);
- return ret;
-
- fail:
- close(fd);
- return -1;
-}
diff --git a/tools/ioemu/monitor.c b/tools/ioemu/monitor.c
deleted file mode 100644
index 49a92fe748..0000000000
--- a/tools/ioemu/monitor.c
+++ /dev/null
@@ -1,2569 +0,0 @@
-/*
- * QEMU monitor
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "disas.h"
-#include <dirent.h>
-#include "block_int.h"
-
-//#define DEBUG
-//#define DEBUG_COMPLETION
-
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-/*
- * Supported types:
- *
- * 'F' filename
- * 'B' block device name
- * 's' string (accept optional quote)
- * 'i' 32 bit integer
- * 'l' target long (32 or 64 bit)
- * '/' optional gdb-like print format (like "/10x")
- *
- * '?' optional type (for 'F', 's' and 'i')
- *
- */
-
-typedef struct term_cmd_t {
- const char *name;
- const char *args_type;
- void (*handler)();
- const char *params;
- const char *help;
-} term_cmd_t;
-
-static CharDriverState *monitor_hd;
-static int hide_banner;
-
-static term_cmd_t term_cmds[];
-static term_cmd_t info_cmds[];
-
-static char term_outbuf[1024];
-static int term_outbuf_index;
-
-static void monitor_start_input(void);
-
-CPUState *mon_cpu = NULL;
-
-void term_flush(void)
-{
-#ifdef CONFIG_DM
- if (term_outbuf_index > 0 && !monitor_hd) {
- fwrite(term_outbuf, term_outbuf_index, 1, stderr);
- term_outbuf_index = 0;
- }
-#endif
- if (term_outbuf_index > 0) {
- qemu_chr_write(monitor_hd, term_outbuf, term_outbuf_index);
- term_outbuf_index = 0;
- }
-}
-
-/* flush at every end of line or if the buffer is full */
-void term_puts(const char *str)
-{
- int c;
- for(;;) {
- c = *str++;
- if (c == '\0')
- break;
- if (c == '\n')
- term_outbuf[term_outbuf_index++] = '\r';
- term_outbuf[term_outbuf_index++] = c;
- if (term_outbuf_index >= (sizeof(term_outbuf) - 1) ||
- c == '\n')
- term_flush();
- }
-}
-
-void term_vprintf(const char *fmt, va_list ap)
-{
- char buf[4096];
- vsnprintf(buf, sizeof(buf), fmt, ap);
- term_puts(buf);
-}
-
-void term_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- term_vprintf(fmt, ap);
- va_end(ap);
-}
-
-void term_print_filename(const char *filename)
-{
- int i;
-
- for (i = 0; filename[i]; i++) {
- switch (filename[i]) {
- case ' ':
- case '"':
- case '\\':
- term_printf("\\%c", filename[i]);
- break;
- case '\t':
- term_printf("\\t");
- break;
- case '\r':
- term_printf("\\r");
- break;
- case '\n':
- term_printf("\\n");
- break;
- default:
- term_printf("%c", filename[i]);
- break;
- }
- }
-}
-
-#ifndef CONFIG_DM
-static int monitor_fprintf(FILE *stream, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- term_vprintf(fmt, ap);
- va_end(ap);
- return 0;
-}
-#endif /* !CONFIG_DM */
-
-static int compare_cmd(const char *name, const char *list)
-{
- const char *p, *pstart;
- int len;
- len = strlen(name);
- p = list;
- for(;;) {
- pstart = p;
- p = strchr(p, '|');
- if (!p)
- p = pstart + strlen(pstart);
- if ((p - pstart) == len && !memcmp(pstart, name, len))
- return 1;
- if (*p == '\0')
- break;
- p++;
- }
- return 0;
-}
-
-static void help_cmd1(term_cmd_t *cmds, const char *prefix, const char *name)
-{
- term_cmd_t *cmd;
-
- for(cmd = cmds; cmd->name != NULL; cmd++) {
- if (!name || !strcmp(name, cmd->name))
- term_printf("%s%s %s -- %s\n", prefix, cmd->name, cmd->params, cmd->help);
- }
-}
-
-static void help_cmd(const char *name)
-{
- if (name && !strcmp(name, "info")) {
- help_cmd1(info_cmds, "info ", NULL);
- } else {
- help_cmd1(term_cmds, "", name);
- if (name && !strcmp(name, "log")) {
- CPULogItem *item;
- term_printf("Log items (comma separated):\n");
- term_printf("%-10s %s\n", "none", "remove all logs");
- for(item = cpu_log_items; item->mask != 0; item++) {
- term_printf("%-10s %s\n", item->name, item->help);
- }
- }
- }
-}
-
-static void do_help(const char *name)
-{
- help_cmd(name);
-}
-
-static void do_commit(const char *device)
-{
- int i, all_devices;
-
- all_devices = !strcmp(device, "all");
- for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (bs_table[i]) {
- if (all_devices ||
- !strcmp(bdrv_get_device_name(bs_table[i]), device))
- bdrv_commit(bs_table[i]);
- }
- }
-}
-
-static void do_info(const char *item)
-{
- term_cmd_t *cmd;
-
- if (!item)
- goto help;
- for(cmd = info_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(item, cmd->name))
- goto found;
- }
- help:
- help_cmd("info");
- return;
- found:
- cmd->handler();
-}
-
-static void do_info_version(void)
-{
- term_printf("%s\n", QEMU_VERSION);
-}
-
-static void do_info_block(void)
-{
- bdrv_info();
-}
-
-/* get the current CPU defined by the user */
-int mon_set_cpu(int cpu_index)
-{
- CPUState *env;
-
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- if (env->cpu_index == cpu_index) {
- mon_cpu = env;
- return 0;
- }
- }
- return -1;
-}
-
-CPUState *mon_get_cpu(void)
-{
- if (!mon_cpu) {
- mon_set_cpu(0);
- }
- return mon_cpu;
-}
-
-#ifndef CONFIG_DM
-static void do_info_registers(void)
-{
- CPUState *env;
- env = mon_get_cpu();
- if (!env)
- return;
-#ifdef TARGET_I386
- cpu_dump_state(env, NULL, monitor_fprintf,
- X86_DUMP_FPU);
-#else
- cpu_dump_state(env, NULL, monitor_fprintf,
- 0);
-#endif
-}
-
-static void do_info_cpus(void)
-{
- CPUState *env;
-
- /* just to set the default cpu if not already done */
- mon_get_cpu();
-
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- term_printf("%c CPU #%d:",
- (env == mon_cpu) ? '*' : ' ',
- env->cpu_index);
-#if defined(TARGET_I386)
- term_printf(" pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base);
- if (env->hflags & HF_HALTED_MASK)
- term_printf(" (halted)");
-#elif defined(TARGET_PPC)
- term_printf(" nip=0x" TARGET_FMT_lx, env->nip);
- if (env->halted)
- term_printf(" (halted)");
-#elif defined(TARGET_SPARC)
- term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
- if (env->halted)
- term_printf(" (halted)");
-#endif
- term_printf("\n");
- }
-}
-
-static void do_cpu_set(int index)
-{
- if (mon_set_cpu(index) < 0)
- term_printf("Invalid CPU index\n");
-}
-
-static void do_info_jit(void)
-{
- dump_exec_info(NULL, monitor_fprintf);
-}
-#endif /* !CONFIG_DM */
-
-static void do_info_history (void)
-{
- int i;
- const char *str;
-
- i = 0;
- for(;;) {
- str = readline_get_history(i);
- if (!str)
- break;
- term_printf("%d: '%s'\n", i, str);
- i++;
- }
-}
-
-static void do_quit(void)
-{
- destroy_hvm_domain();
- exit(0);
-}
-
-static int eject_device(BlockDriverState *bs, int force)
-{
- if (bdrv_is_inserted(bs)) {
- if (!force) {
- if (!bdrv_is_removable(bs)) {
- term_printf("device is not removable\n");
- return -1;
- }
- if (bdrv_is_locked(bs)) {
- term_printf("device is locked\n");
- return -1;
- }
- }
- bdrv_close(bs);
- }
- return 0;
-}
-
-void do_eject(int force, const char *filename)
-{
- BlockDriverState *bs;
-
- bs = bdrv_find(filename);
- if (!bs) {
- term_printf("device not found\n");
- return;
- }
- eject_device(bs, force);
-}
-
-static void do_change_block(const char *device, const char *filename)
-{
- BlockDriverState *bs;
- int i;
- char password[256];
-
- bs = bdrv_find(device);
- if (!bs) {
- term_printf("device not found\n");
- return;
- }
- if (eject_device(bs, 0) < 0)
- return;
- bdrv_open2(bs, filename, 0, &bdrv_raw);
- if (bdrv_is_encrypted(bs)) {
- term_printf("%s is encrypted.\n", device);
- for(i = 0; i < 3; i++) {
- monitor_readline("Password: ", 1, password, sizeof(password));
- if (bdrv_set_key(bs, password) == 0)
- break;
- term_printf("invalid password\n");
- }
- }
-}
-
-static void do_change_vnc(const char *target)
-{
- if (strcmp(target, "passwd") == 0 ||
- strcmp(target, "password") == 0) {
- char password[9];
- monitor_readline("Password: ", 1, password, sizeof(password)-1);
- password[sizeof(password)-1] = '\0';
- if (vnc_display_password(NULL, password) < 0)
- term_printf("could not set VNC server password\n");
- } else {
- if (vnc_display_open(NULL, target, 0) < 0)
- term_printf("could not start VNC server on %s\n", target);
- }
-}
-
-void do_change(const char *device, const char *target)
-{
- if (strcmp(device, "vnc") == 0) {
- do_change_vnc(target);
- } else {
- do_change_block(device, target);
- }
-}
-
-static void do_screen_dump(const char *filename)
-{
- vga_hw_screen_dump(filename);
-}
-
-static void do_log(const char *items)
-{
- int mask;
-
- if (!strcmp(items, "none")) {
- mask = 0;
- } else {
- mask = cpu_str_to_log_mask(items);
- if (!mask) {
- help_cmd("log");
- return;
- }
- }
- cpu_set_log(mask);
-}
-
-#ifndef CONFIG_DM
-static void do_stop(void)
-{
- vm_stop(EXCP_INTERRUPT);
-}
-
-static void do_cont(void)
-{
- vm_start();
-}
-
-#ifdef CONFIG_GDBSTUB
-static void do_gdbserver(int has_port, int port)
-{
- if (!has_port)
- port = DEFAULT_GDBSTUB_PORT;
- if (gdbserver_start_port(port) < 0) {
- qemu_printf("Could not open gdbserver socket on port %d\n", port);
- } else {
- qemu_printf("Waiting gdb connection on port %d\n", port);
- }
-}
-#endif
-
-static void term_printc(int c)
-{
- term_printf("'");
- switch(c) {
- case '\'':
- term_printf("\\'");
- break;
- case '\\':
- term_printf("\\\\");
- break;
- case '\n':
- term_printf("\\n");
- break;
- case '\r':
- term_printf("\\r");
- break;
- default:
- if (c >= 32 && c <= 126) {
- term_printf("%c", c);
- } else {
- term_printf("\\x%02x", c);
- }
- break;
- }
- term_printf("'");
-}
-
-static void memory_dump(int count, int format, int wsize,
- target_ulong addr, int is_physical)
-{
- CPUState *env;
- int nb_per_line, l, line_size, i, max_digits, len;
- uint8_t buf[16];
- uint64_t v;
-
- if (format == 'i') {
- int flags;
- flags = 0;
- env = mon_get_cpu();
- if (!env && !is_physical)
- return;
-#ifdef TARGET_I386
- if (wsize == 2) {
- flags = 1;
- } else if (wsize == 4) {
- flags = 0;
- } else {
- /* as default we use the current CS size */
- flags = 0;
- if (env) {
-#ifdef TARGET_X86_64
- if ((env->efer & MSR_EFER_LMA) &&
- (env->segs[R_CS].flags & DESC_L_MASK))
- flags = 2;
- else
-#endif
- if (!(env->segs[R_CS].flags & DESC_B_MASK))
- flags = 1;
- }
- }
-#endif
- monitor_disas(env, addr, count, is_physical, flags);
- return;
- }
-
- len = wsize * count;
- if (wsize == 1)
- line_size = 8;
- else
- line_size = 16;
- nb_per_line = line_size / wsize;
- max_digits = 0;
-
- switch(format) {
- case 'o':
- max_digits = (wsize * 8 + 2) / 3;
- break;
- default:
- case 'x':
- max_digits = (wsize * 8) / 4;
- break;
- case 'u':
- case 'd':
- max_digits = (wsize * 8 * 10 + 32) / 33;
- break;
- case 'c':
- wsize = 1;
- break;
- }
-
- while (len > 0) {
- term_printf(TARGET_FMT_lx ":", addr);
- l = len;
- if (l > line_size)
- l = line_size;
- if (is_physical) {
- cpu_physical_memory_rw(addr, buf, l, 0);
- } else {
- env = mon_get_cpu();
- if (!env)
- break;
- cpu_memory_rw_debug(env, addr, buf, l, 0);
- }
- i = 0;
- while (i < l) {
- switch(wsize) {
- default:
- case 1:
- v = ldub_raw(buf + i);
- break;
- case 2:
- v = lduw_raw(buf + i);
- break;
- case 4:
- v = (uint32_t)ldl_raw(buf + i);
- break;
- case 8:
- v = ldq_raw(buf + i);
- break;
- }
- term_printf(" ");
- switch(format) {
- case 'o':
- term_printf("%#*" PRIo64, max_digits, v);
- break;
- case 'x':
- term_printf("0x%0*" PRIx64, max_digits, v);
- break;
- case 'u':
- term_printf("%*" PRIu64, max_digits, v);
- break;
- case 'd':
- term_printf("%*" PRId64, max_digits, v);
- break;
- case 'c':
- term_printc(v);
- break;
- }
- i += wsize;
- }
- term_printf("\n");
- addr += l;
- len -= l;
- }
-}
-
-#if TARGET_LONG_BITS == 64
-#define GET_TLONG(h, l) (((uint64_t)(h) << 32) | (l))
-#else
-#define GET_TLONG(h, l) (l)
-#endif
-
-static void do_memory_dump(int count, int format, int size,
- uint32_t addrh, uint32_t addrl)
-{
- target_long addr = GET_TLONG(addrh, addrl);
- memory_dump(count, format, size, addr, 0);
-}
-
-static void do_physical_memory_dump(int count, int format, int size,
- uint32_t addrh, uint32_t addrl)
-
-{
- target_long addr = GET_TLONG(addrh, addrl);
- memory_dump(count, format, size, addr, 1);
-}
-
-static void do_print(int count, int format, int size, unsigned int valh, unsigned int vall)
-{
- target_long val = GET_TLONG(valh, vall);
-#if TARGET_LONG_BITS == 32
- switch(format) {
- case 'o':
- term_printf("%#o", val);
- break;
- case 'x':
- term_printf("%#x", val);
- break;
- case 'u':
- term_printf("%u", val);
- break;
- default:
- case 'd':
- term_printf("%d", val);
- break;
- case 'c':
- term_printc(val);
- break;
- }
-#else
- switch(format) {
- case 'o':
- term_printf("%#" PRIo64, val);
- break;
- case 'x':
- term_printf("%#" PRIx64, val);
- break;
- case 'u':
- term_printf("%" PRIu64, val);
- break;
- default:
- case 'd':
- term_printf("%" PRId64, val);
- break;
- case 'c':
- term_printc(val);
- break;
- }
-#endif
- term_printf("\n");
-}
-
-static void do_memory_save(unsigned int valh, unsigned int vall,
- uint32_t size, const char *filename)
-{
- FILE *f;
- target_long addr = GET_TLONG(valh, vall);
- uint32_t l;
- CPUState *env;
- uint8_t buf[1024];
-
- env = mon_get_cpu();
- if (!env)
- return;
-
- f = fopen(filename, "wb");
- if (!f) {
- term_printf("could not open '%s'\n", filename);
- return;
- }
- while (size != 0) {
- l = sizeof(buf);
- if (l > size)
- l = size;
- cpu_memory_rw_debug(env, addr, buf, l, 0);
- fwrite(buf, 1, l, f);
- addr += l;
- size -= l;
- }
- fclose(f);
-}
-#endif /* !CONFIG_DM */
-
-static void do_sum(uint32_t start, uint32_t size)
-{
- uint32_t addr;
- uint8_t buf[1];
- uint16_t sum;
-
- sum = 0;
- for(addr = start; addr < (start + size); addr++) {
- cpu_physical_memory_rw(addr, buf, 1, 0);
- /* BSD sum algorithm ('sum' Unix command) */
- sum = (sum >> 1) | (sum << 15);
- sum += buf[0];
- }
- term_printf("%05d\n", sum);
-}
-
-typedef struct {
- int keycode;
- const char *name;
-} KeyDef;
-
-static const KeyDef key_defs[] = {
- { 0x2a, "shift" },
- { 0x36, "shift_r" },
-
- { 0x38, "alt" },
- { 0xb8, "alt_r" },
- { 0x1d, "ctrl" },
- { 0x9d, "ctrl_r" },
-
- { 0xdd, "menu" },
-
- { 0x01, "esc" },
-
- { 0x02, "1" },
- { 0x03, "2" },
- { 0x04, "3" },
- { 0x05, "4" },
- { 0x06, "5" },
- { 0x07, "6" },
- { 0x08, "7" },
- { 0x09, "8" },
- { 0x0a, "9" },
- { 0x0b, "0" },
- { 0x0c, "minus" },
- { 0x0d, "equal" },
- { 0x0e, "backspace" },
-
- { 0x0f, "tab" },
- { 0x10, "q" },
- { 0x11, "w" },
- { 0x12, "e" },
- { 0x13, "r" },
- { 0x14, "t" },
- { 0x15, "y" },
- { 0x16, "u" },
- { 0x17, "i" },
- { 0x18, "o" },
- { 0x19, "p" },
-
- { 0x1c, "ret" },
-
- { 0x1e, "a" },
- { 0x1f, "s" },
- { 0x20, "d" },
- { 0x21, "f" },
- { 0x22, "g" },
- { 0x23, "h" },
- { 0x24, "j" },
- { 0x25, "k" },
- { 0x26, "l" },
-
- { 0x2c, "z" },
- { 0x2d, "x" },
- { 0x2e, "c" },
- { 0x2f, "v" },
- { 0x30, "b" },
- { 0x31, "n" },
- { 0x32, "m" },
-
- { 0x39, "spc" },
- { 0x3a, "caps_lock" },
- { 0x3b, "f1" },
- { 0x3c, "f2" },
- { 0x3d, "f3" },
- { 0x3e, "f4" },
- { 0x3f, "f5" },
- { 0x40, "f6" },
- { 0x41, "f7" },
- { 0x42, "f8" },
- { 0x43, "f9" },
- { 0x44, "f10" },
- { 0x45, "num_lock" },
- { 0x46, "scroll_lock" },
-
- { 0xb5, "kp_divide" },
- { 0x37, "kp_multiply" },
- { 0x4a, "kp_substract" },
- { 0x4e, "kp_add" },
- { 0x9c, "kp_enter" },
- { 0x53, "kp_decimal" },
-
- { 0x52, "kp_0" },
- { 0x4f, "kp_1" },
- { 0x50, "kp_2" },
- { 0x51, "kp_3" },
- { 0x4b, "kp_4" },
- { 0x4c, "kp_5" },
- { 0x4d, "kp_6" },
- { 0x47, "kp_7" },
- { 0x48, "kp_8" },
- { 0x49, "kp_9" },
-
- { 0x56, "<" },
-
- { 0x57, "f11" },
- { 0x58, "f12" },
-
- { 0xb7, "print" },
-
- { 0xc7, "home" },
- { 0xc9, "pgup" },
- { 0xd1, "pgdn" },
- { 0xcf, "end" },
-
- { 0xcb, "left" },
- { 0xc8, "up" },
- { 0xd0, "down" },
- { 0xcd, "right" },
-
- { 0xd2, "insert" },
- { 0xd3, "delete" },
- { 0, NULL },
-};
-
-static int get_keycode(const char *key)
-{
- const KeyDef *p;
- char *endp;
- int ret;
-
- for(p = key_defs; p->name != NULL; p++) {
- if (!strcmp(key, p->name))
- return p->keycode;
- }
- if (strstart(key, "0x", NULL)) {
- ret = strtoul(key, &endp, 0);
- if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)
- return ret;
- }
- return -1;
-}
-
-static void do_send_key(const char *string)
-{
- char keybuf[16], *q;
- uint8_t keycodes[16];
- const char *p;
- int nb_keycodes, keycode, i;
-
- nb_keycodes = 0;
- p = string;
- while (*p != '\0') {
- q = keybuf;
- while (*p != '\0' && *p != '-') {
- if ((q - keybuf) < sizeof(keybuf) - 1) {
- *q++ = *p;
- }
- p++;
- }
- *q = '\0';
- keycode = get_keycode(keybuf);
- if (keycode < 0) {
- term_printf("unknown key: '%s'\n", keybuf);
- return;
- }
- keycodes[nb_keycodes++] = keycode;
- if (*p == '\0')
- break;
- p++;
- }
- /* key down events */
- for(i = 0; i < nb_keycodes; i++) {
- keycode = keycodes[i];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode & 0x7f);
- }
- /* key up events */
- for(i = nb_keycodes - 1; i >= 0; i--) {
- keycode = keycodes[i];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode | 0x80);
- }
-}
-
-static int mouse_button_state;
-
-static void do_mouse_move(const char *dx_str, const char *dy_str,
- const char *dz_str)
-{
- int dx, dy, dz;
- dx = strtol(dx_str, NULL, 0);
- dy = strtol(dy_str, NULL, 0);
- dz = 0;
- if (dz_str)
- dz = strtol(dz_str, NULL, 0);
- kbd_mouse_event(dx, dy, dz, mouse_button_state);
-}
-
-static void do_mouse_button(int button_state)
-{
- mouse_button_state = button_state;
- kbd_mouse_event(0, 0, 0, mouse_button_state);
-}
-
-#ifndef CONFIG_DM
-static void do_ioport_read(int count, int format, int size, int addr, int has_index, int index)
-{
- uint32_t val;
- int suffix;
-
- if (has_index) {
- cpu_outb(NULL, addr & 0xffff, index & 0xff);
- addr++;
- }
- addr &= 0xffff;
-
- switch(size) {
- default:
- case 1:
- val = cpu_inb(NULL, addr);
- suffix = 'b';
- break;
- case 2:
- val = cpu_inw(NULL, addr);
- suffix = 'w';
- break;
- case 4:
- val = cpu_inl(NULL, addr);
- suffix = 'l';
- break;
- }
- term_printf("port%c[0x%04x] = %#0*x\n",
- suffix, addr, size * 2, val);
-}
-
-static void do_system_reset(void)
-{
- qemu_system_reset_request();
-}
-
-static void do_system_powerdown(void)
-{
- qemu_system_powerdown_request();
-}
-
-#if defined(TARGET_I386)
-static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
-{
- term_printf("%08x: %08x %c%c%c%c%c%c%c%c\n",
- addr,
- pte & mask,
- pte & PG_GLOBAL_MASK ? 'G' : '-',
- pte & PG_PSE_MASK ? 'P' : '-',
- pte & PG_DIRTY_MASK ? 'D' : '-',
- pte & PG_ACCESSED_MASK ? 'A' : '-',
- pte & PG_PCD_MASK ? 'C' : '-',
- pte & PG_PWT_MASK ? 'T' : '-',
- pte & PG_USER_MASK ? 'U' : '-',
- pte & PG_RW_MASK ? 'W' : '-');
-}
-
-static void tlb_info(void)
-{
- CPUState *env;
- int l1, l2;
- uint32_t pgd, pde, pte;
-
- env = mon_get_cpu();
- if (!env)
- return;
-
- if (!(env->cr[0] & CR0_PG_MASK)) {
- term_printf("PG disabled\n");
- return;
- }
- pgd = env->cr[3] & ~0xfff;
- for(l1 = 0; l1 < 1024; l1++) {
- cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
- pde = le32_to_cpu(pde);
- if (pde & PG_PRESENT_MASK) {
- if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
- print_pte((l1 << 22), pde, ~((1 << 20) - 1));
- } else {
- for(l2 = 0; l2 < 1024; l2++) {
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
- (uint8_t *)&pte, 4);
- pte = le32_to_cpu(pte);
- if (pte & PG_PRESENT_MASK) {
- print_pte((l1 << 22) + (l2 << 12),
- pte & ~PG_PSE_MASK,
- ~0xfff);
- }
- }
- }
- }
- }
-}
-
-static void mem_print(uint32_t *pstart, int *plast_prot,
- uint32_t end, int prot)
-{
- int prot1;
- prot1 = *plast_prot;
- if (prot != prot1) {
- if (*pstart != -1) {
- term_printf("%08x-%08x %08x %c%c%c\n",
- *pstart, end, end - *pstart,
- prot1 & PG_USER_MASK ? 'u' : '-',
- 'r',
- prot1 & PG_RW_MASK ? 'w' : '-');
- }
- if (prot != 0)
- *pstart = end;
- else
- *pstart = -1;
- *plast_prot = prot;
- }
-}
-
-static void mem_info(void)
-{
- CPUState *env;
- int l1, l2, prot, last_prot;
- uint32_t pgd, pde, pte, start, end;
-
- env = mon_get_cpu();
- if (!env)
- return;
-
- if (!(env->cr[0] & CR0_PG_MASK)) {
- term_printf("PG disabled\n");
- return;
- }
- pgd = env->cr[3] & ~0xfff;
- last_prot = 0;
- start = -1;
- for(l1 = 0; l1 < 1024; l1++) {
- cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
- pde = le32_to_cpu(pde);
- end = l1 << 22;
- if (pde & PG_PRESENT_MASK) {
- if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
- prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
- mem_print(&start, &last_prot, end, prot);
- } else {
- for(l2 = 0; l2 < 1024; l2++) {
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
- (uint8_t *)&pte, 4);
- pte = le32_to_cpu(pte);
- end = (l1 << 22) + (l2 << 12);
- if (pte & PG_PRESENT_MASK) {
- prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
- } else {
- prot = 0;
- }
- mem_print(&start, &last_prot, end, prot);
- }
- }
- } else {
- prot = 0;
- mem_print(&start, &last_prot, end, prot);
- }
- }
-}
-#endif
-
-static void do_info_kqemu(void)
-{
-#ifdef USE_KQEMU
- CPUState *env;
- int val;
- val = 0;
- env = mon_get_cpu();
- if (!env) {
- term_printf("No cpu initialized yet");
- return;
- }
- val = env->kqemu_enabled;
- term_printf("kqemu support: ");
- switch(val) {
- default:
- case 0:
- term_printf("disabled\n");
- break;
- case 1:
- term_printf("enabled for user code\n");
- break;
- case 2:
- term_printf("enabled for user and kernel code\n");
- break;
- }
-#else
- term_printf("kqemu support: not compiled\n");
-#endif
-}
-#endif /* !CONFIG_DM */
-
-#ifdef CONFIG_PROFILER
-
-int64_t kqemu_time;
-int64_t qemu_time;
-int64_t kqemu_exec_count;
-int64_t dev_time;
-int64_t kqemu_ret_int_count;
-int64_t kqemu_ret_excp_count;
-int64_t kqemu_ret_intr_count;
-
-static void do_info_profile(void)
-{
- int64_t total;
- total = qemu_time;
- if (total == 0)
- total = 1;
- term_printf("async time %" PRId64 " (%0.3f)\n",
- dev_time, dev_time / (double)ticks_per_sec);
- term_printf("qemu time %" PRId64 " (%0.3f)\n",
- qemu_time, qemu_time / (double)ticks_per_sec);
- term_printf("kqemu time %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
- kqemu_time, kqemu_time / (double)ticks_per_sec,
- kqemu_time / (double)total * 100.0,
- kqemu_exec_count,
- kqemu_ret_int_count,
- kqemu_ret_excp_count,
- kqemu_ret_intr_count);
- qemu_time = 0;
- kqemu_time = 0;
- kqemu_exec_count = 0;
- dev_time = 0;
- kqemu_ret_int_count = 0;
- kqemu_ret_excp_count = 0;
- kqemu_ret_intr_count = 0;
-#ifdef USE_KQEMU
- kqemu_record_dump();
-#endif
-}
-#else
-static void do_info_profile(void)
-{
- term_printf("Internal profiler not compiled\n");
-}
-#endif
-
-/* Capture support */
-static LIST_HEAD (capture_list_head, CaptureState) capture_head;
-
-static void do_info_capture (void)
-{
- int i;
- CaptureState *s;
-
- for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
- term_printf ("[%d]: ", i);
- s->ops.info (s->opaque);
- }
-}
-
-static void do_stop_capture (int n)
-{
- int i;
- CaptureState *s;
-
- for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
- if (i == n) {
- s->ops.destroy (s->opaque);
- LIST_REMOVE (s, entries);
- qemu_free (s);
- return;
- }
- }
-}
-
-#ifdef HAS_AUDIO
-int wav_start_capture (CaptureState *s, const char *path, int freq,
- int bits, int nchannels);
-
-static void do_wav_capture (const char *path,
- int has_freq, int freq,
- int has_bits, int bits,
- int has_channels, int nchannels)
-{
- CaptureState *s;
-
- s = qemu_mallocz (sizeof (*s));
- if (!s) {
- term_printf ("Not enough memory to add wave capture\n");
- return;
- }
-
- freq = has_freq ? freq : 44100;
- bits = has_bits ? bits : 16;
- nchannels = has_channels ? nchannels : 2;
-
- if (wav_start_capture (s, path, freq, bits, nchannels)) {
- term_printf ("Faied to add wave capture\n");
- qemu_free (s);
- }
- LIST_INSERT_HEAD (&capture_head, s, entries);
-}
-#endif
-
-static term_cmd_t term_cmds[] = {
- { "help|?", "s?", do_help,
- "[cmd]", "show the help" },
- { "commit", "s", do_commit,
- "device|all", "commit changes to the disk images (if -snapshot is used) or backing files" },
- { "info", "s?", do_info,
- "subcommand", "show various information about the system state" },
- { "q|quit", "", do_quit,
- "", "quit the emulator" },
- { "eject", "-fB", do_eject,
- "[-f] device", "eject a removable media (use -f to force it)" },
- { "change", "BF", do_change,
- "device filename", "change a removable media" },
- { "screendump", "F", do_screen_dump,
- "filename", "save screen into PPM image 'filename'" },
- { "log", "s", do_log,
- "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
-#ifndef CONFIG_DM
- { "savevm", "s?", do_savevm,
- "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
- { "loadvm", "s", do_loadvm,
- "tag|id", "restore a VM snapshot from its tag or id" },
- { "delvm", "s", do_delvm,
- "tag|id", "delete a VM snapshot from its tag or id" },
- { "stop", "", do_stop,
- "", "stop emulation", },
- { "c|cont", "", do_cont,
- "", "resume emulation", },
-#ifdef CONFIG_GDBSTUB
- { "gdbserver", "i?", do_gdbserver,
- "[port]", "start gdbserver session (default port=1234)", },
-#endif
- { "x", "/l", do_memory_dump,
- "/fmt addr", "virtual memory dump starting at 'addr'", },
- { "xp", "/l", do_physical_memory_dump,
- "/fmt addr", "physical memory dump starting at 'addr'", },
- { "p|print", "/l", do_print,
- "/fmt expr", "print expression value (use $reg for CPU register access)", },
- { "i", "/ii.", do_ioport_read,
- "/fmt addr", "I/O port read" },
-#endif/* !CONFIG_DM */
-
- { "sendkey", "s", do_send_key,
- "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
-#ifndef CONFIG_DM
- { "system_reset", "", do_system_reset,
- "", "reset the system" },
- { "system_powerdown", "", do_system_powerdown,
- "", "send system power down event" },
-#endif /* !CONFIG_DM */
- { "sum", "ii", do_sum,
- "addr size", "compute the checksum of a memory region" },
- { "usb_add", "s", do_usb_add,
- "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
- { "usb_del", "s", do_usb_del,
- "device", "remove USB device 'bus.addr'" },
-#ifdef CONFIG_PHP_DEBUG
- { "pci_add", "s", do_pci_add,
- "device", "insert PCI pass-through device by BDF,e.g. (dom, bus, dev, func) by hex '0x0, 0x3, 0x0, 0x0'" },
- { "pci_del", "s", do_pci_del,
- "device", "remove PCI pass-through device by BDF,e.g. (dom, bus, dev, func) by hex '0x0, 0x3, 0x0, 0x0'" },
-#endif
-#ifndef CONFIG_DM
- { "cpu", "i", do_cpu_set,
- "index", "set the default CPU" },
-#endif /* !CONFIG_DM */
- { "mouse_move", "sss?", do_mouse_move,
- "dx dy [dz]", "send mouse move events" },
- { "mouse_button", "i", do_mouse_button,
- "state", "change mouse button state (1=L, 2=M, 4=R)" },
- { "mouse_set", "i", do_mouse_set,
- "index", "set which mouse device receives events" },
-#ifdef HAS_AUDIO
- { "wavcapture", "si?i?i?", do_wav_capture,
- "path [frequency bits channels]",
- "capture audio to a wave file (default frequency=44100 bits=16 channels=2)" },
-#endif
- { "stopcapture", "i", do_stop_capture,
- "capture index", "stop capture" },
-#ifndef CONFIG_DM
- { "memsave", "lis", do_memory_save,
- "addr size file", "save to disk virtual memory dump starting at 'addr' of size 'size'", },
-#endif /* !CONFIG_DM */
- { NULL, NULL, },
-};
-
-static term_cmd_t info_cmds[] = {
- { "version", "", do_info_version,
- "", "show the version of qemu" },
- { "network", "", do_info_network,
- "", "show the network state" },
- { "block", "", do_info_block,
- "", "show the block devices" },
-#ifndef CONFIG_DM
- { "registers", "", do_info_registers,
- "", "show the cpu registers" },
- { "cpus", "", do_info_cpus,
- "", "show infos for each CPU" },
-#endif /* !CONFIG_DM */
- { "history", "", do_info_history,
- "", "show the command line history", },
- { "irq", "", irq_info,
- "", "show the interrupts statistics (if available)", },
- { "pic", "", pic_info,
- "", "show i8259 (PIC) state", },
- { "pci", "", pci_info,
- "", "show PCI info", },
-#ifndef CONFIG_DM
-#if defined(TARGET_I386)
- { "tlb", "", tlb_info,
- "", "show virtual to physical memory mappings", },
- { "mem", "", mem_info,
- "", "show the active virtual memory mappings", },
-#endif
- { "jit", "", do_info_jit,
- "", "show dynamic compiler info", },
- { "kqemu", "", do_info_kqemu,
- "", "show kqemu information", },
-#endif /* !CONFIG_DM */
- { "usb", "", usb_info,
- "", "show guest USB devices", },
- { "usbhost", "", usb_host_info,
- "", "show host USB devices", },
- { "profile", "", do_info_profile,
- "", "show profiling information", },
- { "capture", "", do_info_capture,
- "", "show capture information" },
- { "snapshots", "", do_info_snapshots,
- "", "show the currently saved VM snapshots" },
- { "mice", "", do_info_mice,
- "", "show which guest mouse is receiving events" },
- { "vnc", "", do_info_vnc,
- "", "show the vnc server status"},
-#ifdef CONFIG_DM
- { "hvmiopage", "", sp_info,
- "", "show HVM device model shared page info" },
-#endif /* CONFIG_DM */
- { NULL, NULL, },
-};
-
-/*******************************************************************/
-
-#ifndef CONFIG_DM
-static const char *pch;
-static jmp_buf expr_env;
-
-#define MD_TLONG 0
-#define MD_I32 1
-
-typedef struct MonitorDef {
- const char *name;
- int offset;
- target_long (*get_value)(struct MonitorDef *md, int val);
- int type;
-} MonitorDef;
-
-#if defined(TARGET_I386)
-static target_long monitor_get_pc (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return env->eip + env->segs[R_CS].base;
-}
-#endif
-
-#if defined(TARGET_PPC)
-static target_long monitor_get_ccr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- unsigned int u;
- int i;
-
- if (!env)
- return 0;
-
- u = 0;
- for (i = 0; i < 8; i++)
- u |= env->crf[i] << (32 - (4 * i));
-
- return u;
-}
-
-static target_long monitor_get_msr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return (env->msr[MSR_POW] << MSR_POW) |
- (env->msr[MSR_ILE] << MSR_ILE) |
- (env->msr[MSR_EE] << MSR_EE) |
- (env->msr[MSR_PR] << MSR_PR) |
- (env->msr[MSR_FP] << MSR_FP) |
- (env->msr[MSR_ME] << MSR_ME) |
- (env->msr[MSR_FE0] << MSR_FE0) |
- (env->msr[MSR_SE] << MSR_SE) |
- (env->msr[MSR_BE] << MSR_BE) |
- (env->msr[MSR_FE1] << MSR_FE1) |
- (env->msr[MSR_IP] << MSR_IP) |
- (env->msr[MSR_IR] << MSR_IR) |
- (env->msr[MSR_DR] << MSR_DR) |
- (env->msr[MSR_RI] << MSR_RI) |
- (env->msr[MSR_LE] << MSR_LE);
-}
-
-static target_long monitor_get_xer (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return (env->xer[XER_SO] << XER_SO) |
- (env->xer[XER_OV] << XER_OV) |
- (env->xer[XER_CA] << XER_CA) |
- (env->xer[XER_BC] << XER_BC);
-}
-
-static target_long monitor_get_decr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return cpu_ppc_load_decr(env);
-}
-
-static target_long monitor_get_tbu (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return cpu_ppc_load_tbu(env);
-}
-
-static target_long monitor_get_tbl (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return cpu_ppc_load_tbl(env);
-}
-#endif
-
-#if defined(TARGET_SPARC)
-#ifndef TARGET_SPARC64
-static target_long monitor_get_psr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return GET_PSR(env);
-}
-#endif
-
-static target_long monitor_get_reg(struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return env->regwptr[val];
-}
-#endif
-
-static MonitorDef monitor_defs[] = {
-#ifdef TARGET_I386
-
-#define SEG(name, seg) \
- { name, offsetof(CPUState, segs[seg].selector), NULL, MD_I32 },\
- { name ".base", offsetof(CPUState, segs[seg].base) },\
- { name ".limit", offsetof(CPUState, segs[seg].limit), NULL, MD_I32 },
-
- { "eax", offsetof(CPUState, regs[0]) },
- { "ecx", offsetof(CPUState, regs[1]) },
- { "edx", offsetof(CPUState, regs[2]) },
- { "ebx", offsetof(CPUState, regs[3]) },
- { "esp|sp", offsetof(CPUState, regs[4]) },
- { "ebp|fp", offsetof(CPUState, regs[5]) },
- { "esi", offsetof(CPUState, regs[6]) },
- { "edi", offsetof(CPUState, regs[7]) },
-#ifdef TARGET_X86_64
- { "r8", offsetof(CPUState, regs[8]) },
- { "r9", offsetof(CPUState, regs[9]) },
- { "r10", offsetof(CPUState, regs[10]) },
- { "r11", offsetof(CPUState, regs[11]) },
- { "r12", offsetof(CPUState, regs[12]) },
- { "r13", offsetof(CPUState, regs[13]) },
- { "r14", offsetof(CPUState, regs[14]) },
- { "r15", offsetof(CPUState, regs[15]) },
-#endif
- { "eflags", offsetof(CPUState, eflags) },
- { "eip", offsetof(CPUState, eip) },
- SEG("cs", R_CS)
- SEG("ds", R_DS)
- SEG("es", R_ES)
- SEG("ss", R_SS)
- SEG("fs", R_FS)
- SEG("gs", R_GS)
- { "pc", 0, monitor_get_pc, },
-#elif defined(TARGET_PPC)
- { "r0", offsetof(CPUState, gpr[0]) },
- { "r1", offsetof(CPUState, gpr[1]) },
- { "r2", offsetof(CPUState, gpr[2]) },
- { "r3", offsetof(CPUState, gpr[3]) },
- { "r4", offsetof(CPUState, gpr[4]) },
- { "r5", offsetof(CPUState, gpr[5]) },
- { "r6", offsetof(CPUState, gpr[6]) },
- { "r7", offsetof(CPUState, gpr[7]) },
- { "r8", offsetof(CPUState, gpr[8]) },
- { "r9", offsetof(CPUState, gpr[9]) },
- { "r10", offsetof(CPUState, gpr[10]) },
- { "r11", offsetof(CPUState, gpr[11]) },
- { "r12", offsetof(CPUState, gpr[12]) },
- { "r13", offsetof(CPUState, gpr[13]) },
- { "r14", offsetof(CPUState, gpr[14]) },
- { "r15", offsetof(CPUState, gpr[15]) },
- { "r16", offsetof(CPUState, gpr[16]) },
- { "r17", offsetof(CPUState, gpr[17]) },
- { "r18", offsetof(CPUState, gpr[18]) },
- { "r19", offsetof(CPUState, gpr[19]) },
- { "r20", offsetof(CPUState, gpr[20]) },
- { "r21", offsetof(CPUState, gpr[21]) },
- { "r22", offsetof(CPUState, gpr[22]) },
- { "r23", offsetof(CPUState, gpr[23]) },
- { "r24", offsetof(CPUState, gpr[24]) },
- { "r25", offsetof(CPUState, gpr[25]) },
- { "r26", offsetof(CPUState, gpr[26]) },
- { "r27", offsetof(CPUState, gpr[27]) },
- { "r28", offsetof(CPUState, gpr[28]) },
- { "r29", offsetof(CPUState, gpr[29]) },
- { "r30", offsetof(CPUState, gpr[30]) },
- { "r31", offsetof(CPUState, gpr[31]) },
- { "nip|pc", offsetof(CPUState, nip) },
- { "lr", offsetof(CPUState, lr) },
- { "ctr", offsetof(CPUState, ctr) },
- { "decr", 0, &monitor_get_decr, },
- { "ccr", 0, &monitor_get_ccr, },
- { "msr", 0, &monitor_get_msr, },
- { "xer", 0, &monitor_get_xer, },
- { "tbu", 0, &monitor_get_tbu, },
- { "tbl", 0, &monitor_get_tbl, },
- { "sdr1", offsetof(CPUState, sdr1) },
- { "sr0", offsetof(CPUState, sr[0]) },
- { "sr1", offsetof(CPUState, sr[1]) },
- { "sr2", offsetof(CPUState, sr[2]) },
- { "sr3", offsetof(CPUState, sr[3]) },
- { "sr4", offsetof(CPUState, sr[4]) },
- { "sr5", offsetof(CPUState, sr[5]) },
- { "sr6", offsetof(CPUState, sr[6]) },
- { "sr7", offsetof(CPUState, sr[7]) },
- { "sr8", offsetof(CPUState, sr[8]) },
- { "sr9", offsetof(CPUState, sr[9]) },
- { "sr10", offsetof(CPUState, sr[10]) },
- { "sr11", offsetof(CPUState, sr[11]) },
- { "sr12", offsetof(CPUState, sr[12]) },
- { "sr13", offsetof(CPUState, sr[13]) },
- { "sr14", offsetof(CPUState, sr[14]) },
- { "sr15", offsetof(CPUState, sr[15]) },
- /* Too lazy to put BATs and SPRs ... */
-#elif defined(TARGET_SPARC)
- { "g0", offsetof(CPUState, gregs[0]) },
- { "g1", offsetof(CPUState, gregs[1]) },
- { "g2", offsetof(CPUState, gregs[2]) },
- { "g3", offsetof(CPUState, gregs[3]) },
- { "g4", offsetof(CPUState, gregs[4]) },
- { "g5", offsetof(CPUState, gregs[5]) },
- { "g6", offsetof(CPUState, gregs[6]) },
- { "g7", offsetof(CPUState, gregs[7]) },
- { "o0", 0, monitor_get_reg },
- { "o1", 1, monitor_get_reg },
- { "o2", 2, monitor_get_reg },
- { "o3", 3, monitor_get_reg },
- { "o4", 4, monitor_get_reg },
- { "o5", 5, monitor_get_reg },
- { "o6", 6, monitor_get_reg },
- { "o7", 7, monitor_get_reg },
- { "l0", 8, monitor_get_reg },
- { "l1", 9, monitor_get_reg },
- { "l2", 10, monitor_get_reg },
- { "l3", 11, monitor_get_reg },
- { "l4", 12, monitor_get_reg },
- { "l5", 13, monitor_get_reg },
- { "l6", 14, monitor_get_reg },
- { "l7", 15, monitor_get_reg },
- { "i0", 16, monitor_get_reg },
- { "i1", 17, monitor_get_reg },
- { "i2", 18, monitor_get_reg },
- { "i3", 19, monitor_get_reg },
- { "i4", 20, monitor_get_reg },
- { "i5", 21, monitor_get_reg },
- { "i6", 22, monitor_get_reg },
- { "i7", 23, monitor_get_reg },
- { "pc", offsetof(CPUState, pc) },
- { "npc", offsetof(CPUState, npc) },
- { "y", offsetof(CPUState, y) },
-#ifndef TARGET_SPARC64
- { "psr", 0, &monitor_get_psr, },
- { "wim", offsetof(CPUState, wim) },
-#endif
- { "tbr", offsetof(CPUState, tbr) },
- { "fsr", offsetof(CPUState, fsr) },
- { "f0", offsetof(CPUState, fpr[0]) },
- { "f1", offsetof(CPUState, fpr[1]) },
- { "f2", offsetof(CPUState, fpr[2]) },
- { "f3", offsetof(CPUState, fpr[3]) },
- { "f4", offsetof(CPUState, fpr[4]) },
- { "f5", offsetof(CPUState, fpr[5]) },
- { "f6", offsetof(CPUState, fpr[6]) },
- { "f7", offsetof(CPUState, fpr[7]) },
- { "f8", offsetof(CPUState, fpr[8]) },
- { "f9", offsetof(CPUState, fpr[9]) },
- { "f10", offsetof(CPUState, fpr[10]) },
- { "f11", offsetof(CPUState, fpr[11]) },
- { "f12", offsetof(CPUState, fpr[12]) },
- { "f13", offsetof(CPUState, fpr[13]) },
- { "f14", offsetof(CPUState, fpr[14]) },
- { "f15", offsetof(CPUState, fpr[15]) },
- { "f16", offsetof(CPUState, fpr[16]) },
- { "f17", offsetof(CPUState, fpr[17]) },
- { "f18", offsetof(CPUState, fpr[18]) },
- { "f19", offsetof(CPUState, fpr[19]) },
- { "f20", offsetof(CPUState, fpr[20]) },
- { "f21", offsetof(CPUState, fpr[21]) },
- { "f22", offsetof(CPUState, fpr[22]) },
- { "f23", offsetof(CPUState, fpr[23]) },
- { "f24", offsetof(CPUState, fpr[24]) },
- { "f25", offsetof(CPUState, fpr[25]) },
- { "f26", offsetof(CPUState, fpr[26]) },
- { "f27", offsetof(CPUState, fpr[27]) },
- { "f28", offsetof(CPUState, fpr[28]) },
- { "f29", offsetof(CPUState, fpr[29]) },
- { "f30", offsetof(CPUState, fpr[30]) },
- { "f31", offsetof(CPUState, fpr[31]) },
-#ifdef TARGET_SPARC64
- { "f32", offsetof(CPUState, fpr[32]) },
- { "f34", offsetof(CPUState, fpr[34]) },
- { "f36", offsetof(CPUState, fpr[36]) },
- { "f38", offsetof(CPUState, fpr[38]) },
- { "f40", offsetof(CPUState, fpr[40]) },
- { "f42", offsetof(CPUState, fpr[42]) },
- { "f44", offsetof(CPUState, fpr[44]) },
- { "f46", offsetof(CPUState, fpr[46]) },
- { "f48", offsetof(CPUState, fpr[48]) },
- { "f50", offsetof(CPUState, fpr[50]) },
- { "f52", offsetof(CPUState, fpr[52]) },
- { "f54", offsetof(CPUState, fpr[54]) },
- { "f56", offsetof(CPUState, fpr[56]) },
- { "f58", offsetof(CPUState, fpr[58]) },
- { "f60", offsetof(CPUState, fpr[60]) },
- { "f62", offsetof(CPUState, fpr[62]) },
- { "asi", offsetof(CPUState, asi) },
- { "pstate", offsetof(CPUState, pstate) },
- { "cansave", offsetof(CPUState, cansave) },
- { "canrestore", offsetof(CPUState, canrestore) },
- { "otherwin", offsetof(CPUState, otherwin) },
- { "wstate", offsetof(CPUState, wstate) },
- { "cleanwin", offsetof(CPUState, cleanwin) },
- { "fprs", offsetof(CPUState, fprs) },
-#endif
-#endif
- { NULL },
-};
-
-static void expr_error(const char *fmt)
-{
- term_printf(fmt);
- term_printf("\n");
- longjmp(expr_env, 1);
-}
-
-/* return 0 if OK, -1 if not found, -2 if no CPU defined */
-static int get_monitor_def(target_long *pval, const char *name)
-{
- MonitorDef *md;
- void *ptr;
-
- for(md = monitor_defs; md->name != NULL; md++) {
- if (compare_cmd(name, md->name)) {
- if (md->get_value) {
- *pval = md->get_value(md, md->offset);
- } else {
- CPUState *env = mon_get_cpu();
- if (!env)
- return -2;
- ptr = (uint8_t *)env + md->offset;
- switch(md->type) {
- case MD_I32:
- *pval = *(int32_t *)ptr;
- break;
- case MD_TLONG:
- *pval = *(target_long *)ptr;
- break;
- default:
- *pval = 0;
- break;
- }
- }
- return 0;
- }
- }
- return -1;
-}
-
-static void next(void)
-{
- if (pch != '\0') {
- pch++;
- while (isspace((uint8_t)*pch))
- pch++;
- }
-}
-
-static target_long expr_sum(void);
-
-static target_long expr_unary(void)
-{
- target_long n;
- char *p;
- int ret;
-
- switch(*pch) {
- case '+':
- next();
- n = expr_unary();
- break;
- case '-':
- next();
- n = -expr_unary();
- break;
- case '~':
- next();
- n = ~expr_unary();
- break;
- case '(':
- next();
- n = expr_sum();
- if (*pch != ')') {
- expr_error("')' expected");
- }
- next();
- break;
- case '\'':
- pch++;
- if (*pch == '\0')
- expr_error("character constant expected");
- n = *pch;
- pch++;
- if (*pch != '\'')
- expr_error("missing terminating \' character");
- next();
- break;
- case '$':
- {
- char buf[128], *q;
-
- pch++;
- q = buf;
- while ((*pch >= 'a' && *pch <= 'z') ||
- (*pch >= 'A' && *pch <= 'Z') ||
- (*pch >= '0' && *pch <= '9') ||
- *pch == '_' || *pch == '.') {
- if ((q - buf) < sizeof(buf) - 1)
- *q++ = *pch;
- pch++;
- }
- while (isspace((uint8_t)*pch))
- pch++;
- *q = 0;
- ret = get_monitor_def(&n, buf);
- if (ret == -1)
- expr_error("unknown register");
- else if (ret == -2)
- expr_error("no cpu defined");
- }
- break;
- case '\0':
- expr_error("unexpected end of expression");
- n = 0;
- break;
- default:
-#if TARGET_LONG_BITS == 64
- n = strtoull(pch, &p, 0);
-#else
- n = strtoul(pch, &p, 0);
-#endif
- if (pch == p) {
- expr_error("invalid char in expression");
- }
- pch = p;
- while (isspace((uint8_t)*pch))
- pch++;
- break;
- }
- return n;
-}
-
-
-static target_long expr_prod(void)
-{
- target_long val, val2;
- int op;
-
- val = expr_unary();
- for(;;) {
- op = *pch;
- if (op != '*' && op != '/' && op != '%')
- break;
- next();
- val2 = expr_unary();
- switch(op) {
- default:
- case '*':
- val *= val2;
- break;
- case '/':
- case '%':
- if (val2 == 0)
- expr_error("division by zero");
- if (op == '/')
- val /= val2;
- else
- val %= val2;
- break;
- }
- }
- return val;
-}
-
-static target_long expr_logic(void)
-{
- target_long val, val2;
- int op;
-
- val = expr_prod();
- for(;;) {
- op = *pch;
- if (op != '&' && op != '|' && op != '^')
- break;
- next();
- val2 = expr_prod();
- switch(op) {
- default:
- case '&':
- val &= val2;
- break;
- case '|':
- val |= val2;
- break;
- case '^':
- val ^= val2;
- break;
- }
- }
- return val;
-}
-
-static target_long expr_sum(void)
-{
- target_long val, val2;
- int op;
-
- val = expr_logic();
- for(;;) {
- op = *pch;
- if (op != '+' && op != '-')
- break;
- next();
- val2 = expr_logic();
- if (op == '+')
- val += val2;
- else
- val -= val2;
- }
- return val;
-}
-
-static int get_expr(target_long *pval, const char **pp)
-{
- pch = *pp;
- if (setjmp(expr_env)) {
- *pp = pch;
- return -1;
- }
- while (isspace((uint8_t)*pch))
- pch++;
- *pval = expr_sum();
- *pp = pch;
- return 0;
-}
-#endif /* !CONFIG_DM */
-
-static int get_str(char *buf, int buf_size, const char **pp)
-{
- const char *p;
- char *q;
- int c;
-
- q = buf;
- p = *pp;
- while (isspace((uint8_t)*p))
- p++;
- if (*p == '\0') {
- fail:
- *q = '\0';
- *pp = p;
- return -1;
- }
- if (*p == '\"') {
- p++;
- while (*p != '\0' && *p != '\"') {
- if (*p == '\\') {
- p++;
- c = *p++;
- switch(c) {
- case 'n':
- c = '\n';
- break;
- case 'r':
- c = '\r';
- break;
- case '\\':
- case '\'':
- case '\"':
- break;
- default:
- qemu_printf("unsupported escape code: '\\%c'\n", c);
- goto fail;
- }
- if ((q - buf) < buf_size - 1) {
- *q++ = c;
- }
- } else {
- if ((q - buf) < buf_size - 1) {
- *q++ = *p;
- }
- p++;
- }
- }
- if (*p != '\"') {
- qemu_printf("unterminated string\n");
- goto fail;
- }
- p++;
- } else {
- while (*p != '\0' && !isspace((uint8_t)*p)) {
- if ((q - buf) < buf_size - 1) {
- *q++ = *p;
- }
- p++;
- }
- }
- *q = '\0';
- *pp = p;
- return 0;
-}
-
-#ifndef CONFIG_DM
-static int default_fmt_format = 'x';
-static int default_fmt_size = 4;
-#endif /* !CONFIG_DM */
-
-#define MAX_ARGS 16
-
-static void monitor_handle_command(const char *cmdline)
-{
- const char *p, *pstart, *typestr;
- char *q;
- int c, nb_args, len, i;
-#ifndef CONFIG_DM
- int has_arg;
-#endif /* !CONFIG_DM */
- term_cmd_t *cmd;
- char cmdname[256];
- char buf[1024];
- void *str_allocated[MAX_ARGS];
- void *args[MAX_ARGS];
-
-#ifdef DEBUG
- term_printf("command='%s'\n", cmdline);
-#endif
-
- /* extract the command name */
- p = cmdline;
- q = cmdname;
- while (isspace((uint8_t)*p))
- p++;
- if (*p == '\0')
- return;
- pstart = p;
- while (*p != '\0' && *p != '/' && !isspace((uint8_t)*p))
- p++;
- len = p - pstart;
- if (len > sizeof(cmdname) - 1)
- len = sizeof(cmdname) - 1;
- memcpy(cmdname, pstart, len);
- cmdname[len] = '\0';
-
- /* find the command */
- for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(cmdname, cmd->name))
- goto found;
- }
- term_printf("unknown command: '%s'\n", cmdname);
- return;
- found:
-
- for(i = 0; i < MAX_ARGS; i++)
- str_allocated[i] = NULL;
-
- /* parse the parameters */
- typestr = cmd->args_type;
- nb_args = 0;
- for(;;) {
- c = *typestr;
- if (c == '\0')
- break;
- typestr++;
- switch(c) {
- case 'F':
- case 'B':
- case 's':
- {
- int ret;
- char *str;
-
- while (isspace((uint8_t)*p))
- p++;
- if (*typestr == '?') {
- typestr++;
- if (*p == '\0') {
- /* no optional string: NULL argument */
- str = NULL;
- goto add_str;
- }
- }
- ret = get_str(buf, sizeof(buf), &p);
- if (ret < 0) {
- switch(c) {
- case 'F':
- term_printf("%s: filename expected\n", cmdname);
- break;
- case 'B':
- term_printf("%s: block device name expected\n", cmdname);
- break;
- default:
- term_printf("%s: string expected\n", cmdname);
- break;
- }
- goto fail;
- }
- str = qemu_malloc(strlen(buf) + 1);
- strcpy(str, buf);
- str_allocated[nb_args] = str;
- add_str:
- if (nb_args >= MAX_ARGS) {
- error_args:
- term_printf("%s: too many arguments\n", cmdname);
- goto fail;
- }
- args[nb_args++] = str;
- }
- break;
-#ifndef CONFIG_DM
- case '/':
- {
- int count, format, size;
-
- while (isspace((uint8_t)*p))
- p++;
- if (*p == '/') {
- /* format found */
- p++;
- count = 1;
- if (isdigit((uint8_t)*p)) {
- count = 0;
- while (isdigit((uint8_t)*p)) {
- count = count * 10 + (*p - '0');
- p++;
- }
- }
- size = -1;
- format = -1;
- for(;;) {
- switch(*p) {
- case 'o':
- case 'd':
- case 'u':
- case 'x':
- case 'i':
- case 'c':
- format = *p++;
- break;
- case 'b':
- size = 1;
- p++;
- break;
- case 'h':
- size = 2;
- p++;
- break;
- case 'w':
- size = 4;
- p++;
- break;
- case 'g':
- case 'L':
- size = 8;
- p++;
- break;
- default:
- goto next;
- }
- }
- next:
- if (*p != '\0' && !isspace((uint8_t)*p)) {
- term_printf("invalid char in format: '%c'\n", *p);
- goto fail;
- }
- if (format < 0)
- format = default_fmt_format;
- if (format != 'i') {
- /* for 'i', not specifying a size gives -1 as size */
- if (size < 0)
- size = default_fmt_size;
- }
- default_fmt_size = size;
- default_fmt_format = format;
- } else {
- count = 1;
- format = default_fmt_format;
- if (format != 'i') {
- size = default_fmt_size;
- } else {
- size = -1;
- }
- }
- if (nb_args + 3 > MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void*)count;
- args[nb_args++] = (void*)format;
- args[nb_args++] = (void*)size;
- }
- break;
- case 'i':
- case 'l':
- {
- target_long val;
- while (isspace((uint8_t)*p))
- p++;
- if (*typestr == '?' || *typestr == '.') {
- if (*typestr == '?') {
- if (*p == '\0')
- has_arg = 0;
- else
- has_arg = 1;
- } else {
- if (*p == '.') {
- p++;
- while (isspace((uint8_t)*p))
- p++;
- has_arg = 1;
- } else {
- has_arg = 0;
- }
- }
- typestr++;
- if (nb_args >= MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void *)has_arg;
- if (!has_arg) {
- if (nb_args >= MAX_ARGS)
- goto error_args;
- val = -1;
- goto add_num;
- }
- }
- if (get_expr(&val, &p))
- goto fail;
- add_num:
- if (c == 'i') {
- if (nb_args >= MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void *)(int)val;
- } else {
- if ((nb_args + 1) >= MAX_ARGS)
- goto error_args;
-#if TARGET_LONG_BITS == 64
- args[nb_args++] = (void *)(int)((val >> 32) & 0xffffffff);
-#else
- args[nb_args++] = (void *)0;
-#endif
- args[nb_args++] = (void *)(int)(val & 0xffffffff);
- }
- }
- break;
-#endif /* !CONFIG_DM */
- case '-':
- {
- int has_option;
- /* option */
-
- c = *typestr++;
- if (c == '\0')
- goto bad_type;
- while (isspace((uint8_t)*p))
- p++;
- has_option = 0;
- if (*p == '-') {
- p++;
- if (*p != c) {
- term_printf("%s: unsupported option -%c\n",
- cmdname, *p);
- goto fail;
- }
- p++;
- has_option = 1;
- }
- if (nb_args >= MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void *)has_option;
- }
- break;
-#ifdef CONFIG_DM
- /* TODO: add more commands we need here to support hvm device model */
- case '/':
- case 'i':
-#endif /* CONFIG_DM */
- default:
- bad_type:
- term_printf("%s: unknown type '%c'\n", cmdname, c);
- goto fail;
- }
- }
- /* check that all arguments were parsed */
- while (isspace((uint8_t)*p))
- p++;
- if (*p != '\0') {
- term_printf("%s: extraneous characters at the end of line\n",
- cmdname);
- goto fail;
- }
-
- switch(nb_args) {
- case 0:
- cmd->handler();
- break;
- case 1:
- cmd->handler(args[0]);
- break;
- case 2:
- cmd->handler(args[0], args[1]);
- break;
- case 3:
- cmd->handler(args[0], args[1], args[2]);
- break;
- case 4:
- cmd->handler(args[0], args[1], args[2], args[3]);
- break;
- case 5:
- cmd->handler(args[0], args[1], args[2], args[3], args[4]);
- break;
- case 6:
- cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);
- break;
- case 7:
- cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
- break;
- default:
- term_printf("unsupported number of arguments: %d\n", nb_args);
- goto fail;
- }
- fail:
- for(i = 0; i < MAX_ARGS; i++)
- qemu_free(str_allocated[i]);
- return;
-}
-
-#ifndef CONFIG_DM
-static void cmd_completion(const char *name, const char *list)
-{
- const char *p, *pstart;
- char cmd[128];
- int len;
-
- p = list;
- for(;;) {
- pstart = p;
- p = strchr(p, '|');
- if (!p)
- p = pstart + strlen(pstart);
- len = p - pstart;
- if (len > sizeof(cmd) - 2)
- len = sizeof(cmd) - 2;
- memcpy(cmd, pstart, len);
- cmd[len] = '\0';
- if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
- add_completion(cmd);
- }
- if (*p == '\0')
- break;
- p++;
- }
-}
-
-static void file_completion(const char *input)
-{
- DIR *ffs;
- struct dirent *d;
- char path[1024];
- char file[1024], file_prefix[1024];
- int input_path_len;
- const char *p;
-
- p = strrchr(input, '/');
- if (!p) {
- input_path_len = 0;
- pstrcpy(file_prefix, sizeof(file_prefix), input);
- strcpy(path, ".");
- } else {
- input_path_len = p - input + 1;
- memcpy(path, input, input_path_len);
- if (input_path_len > sizeof(path) - 1)
- input_path_len = sizeof(path) - 1;
- path[input_path_len] = '\0';
- pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
- }
-#ifdef DEBUG_COMPLETION
- term_printf("input='%s' path='%s' prefix='%s'\n", input, path, file_prefix);
-#endif
- ffs = opendir(path);
- if (!ffs)
- return;
- for(;;) {
- struct stat sb;
- d = readdir(ffs);
- if (!d)
- break;
- if (strstart(d->d_name, file_prefix, NULL)) {
- memcpy(file, input, input_path_len);
- strcpy(file + input_path_len, d->d_name);
- /* stat the file to find out if it's a directory.
- * In that case add a slash to speed up typing long paths
- */
- stat(file, &sb);
- if(S_ISDIR(sb.st_mode))
- strcat(file, "/");
- add_completion(file);
- }
- }
- closedir(ffs);
-}
-
-static void block_completion_it(void *opaque, const char *name)
-{
- const char *input = opaque;
-
- if (input[0] == '\0' ||
- !strncmp(name, (char *)input, strlen(input))) {
- add_completion(name);
- }
-}
-
-/* NOTE: this parser is an approximate form of the real command parser */
-static void parse_cmdline(const char *cmdline,
- int *pnb_args, char **args)
-{
- const char *p;
- int nb_args, ret;
- char buf[1024];
-
- p = cmdline;
- nb_args = 0;
- for(;;) {
- while (isspace((uint8_t)*p))
- p++;
- if (*p == '\0')
- break;
- if (nb_args >= MAX_ARGS)
- break;
- ret = get_str(buf, sizeof(buf), &p);
- args[nb_args] = qemu_strdup(buf);
- nb_args++;
- if (ret < 0)
- break;
- }
- *pnb_args = nb_args;
-}
-
-void readline_find_completion(const char *cmdline)
-{
- const char *cmdname;
- char *args[MAX_ARGS];
- int nb_args, i, len;
- const char *ptype, *str;
- term_cmd_t *cmd;
- const KeyDef *key;
-
- parse_cmdline(cmdline, &nb_args, args);
-#ifdef DEBUG_COMPLETION
- for(i = 0; i < nb_args; i++) {
- term_printf("arg%d = '%s'\n", i, (char *)args[i]);
- }
-#endif
-
- /* if the line ends with a space, it means we want to complete the
- next arg */
- len = strlen(cmdline);
- if (len > 0 && isspace((uint8_t)cmdline[len - 1])) {
- if (nb_args >= MAX_ARGS)
- return;
- args[nb_args++] = qemu_strdup("");
- }
- if (nb_args <= 1) {
- /* command completion */
- if (nb_args == 0)
- cmdname = "";
- else
- cmdname = args[0];
- completion_index = strlen(cmdname);
- for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- cmd_completion(cmdname, cmd->name);
- }
- } else {
- /* find the command */
- for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(args[0], cmd->name))
- goto found;
- }
- return;
- found:
- ptype = cmd->args_type;
- for(i = 0; i < nb_args - 2; i++) {
- if (*ptype != '\0') {
- ptype++;
- while (*ptype == '?')
- ptype++;
- }
- }
- str = args[nb_args - 1];
- switch(*ptype) {
- case 'F':
- /* file completion */
- completion_index = strlen(str);
- file_completion(str);
- break;
- case 'B':
- /* block device name completion */
- completion_index = strlen(str);
- bdrv_iterate(block_completion_it, (void *)str);
- break;
- case 's':
- /* XXX: more generic ? */
- if (!strcmp(cmd->name, "info")) {
- completion_index = strlen(str);
- for(cmd = info_cmds; cmd->name != NULL; cmd++) {
- cmd_completion(str, cmd->name);
- }
- } else if (!strcmp(cmd->name, "sendkey")) {
- completion_index = strlen(str);
- for(key = key_defs; key->name != NULL; key++) {
- cmd_completion(str, key->name);
- }
- }
- break;
- default:
- break;
- }
- }
- for(i = 0; i < nb_args; i++)
- qemu_free(args[i]);
-}
-#else
-void readline_find_completion(const char *cmdline)
-{
-}
-#endif /* !CONFIG_DM */
-
-static int term_can_read(void *opaque)
-{
- return 128;
-}
-
-static void term_read(void *opaque, const uint8_t *buf, int size)
-{
- int i;
- for(i = 0; i < size; i++)
- readline_handle_byte(buf[i]);
-}
-
-static void monitor_start_input(void);
-
-static void monitor_handle_command1(void *opaque, const char *cmdline)
-{
- monitor_handle_command(cmdline);
- monitor_start_input();
-}
-
-static void monitor_start_input(void)
-{
- readline_start("(qemu) ", 0, monitor_handle_command1, NULL);
-}
-
-static void term_event(void *opaque, int event)
-{
- if (event != CHR_EVENT_RESET)
- return;
-
- if (!hide_banner)
- term_printf("HVM device model. type 'q' to exit\n");
- monitor_start_input();
-}
-
-void monitor_init(CharDriverState *hd, int show_banner)
-{
- monitor_hd = hd;
- hide_banner = !show_banner;
-
- qemu_chr_add_handlers(hd, term_can_read, term_read, term_event, NULL);
-}
-
-/* XXX: use threads ? */
-/* modal monitor readline */
-static int monitor_readline_started;
-static char *monitor_readline_buf;
-static int monitor_readline_buf_size;
-
-static void monitor_readline_cb(void *opaque, const char *input)
-{
- pstrcpy(monitor_readline_buf, monitor_readline_buf_size, input);
- monitor_readline_started = 0;
-}
-
-void monitor_readline(const char *prompt, int is_password,
- char *buf, int buf_size)
-{
- if (is_password) {
- qemu_chr_send_event(monitor_hd, CHR_EVENT_FOCUS);
- }
- readline_start(prompt, is_password, monitor_readline_cb, NULL);
- monitor_readline_buf = buf;
- monitor_readline_buf_size = buf_size;
- monitor_readline_started = 1;
- while (monitor_readline_started) {
- main_loop_wait(10);
- }
-}
diff --git a/tools/ioemu/osdep.c b/tools/ioemu/osdep.c
deleted file mode 100644
index e3a870154a..0000000000
--- a/tools/ioemu/osdep.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * QEMU low level functions
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "config-host.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#ifdef HOST_SOLARIS
-#include <sys/types.h>
-#include <sys/statvfs.h>
-#endif
-
-#if defined(USE_KQEMU)
-#include "vl.h"
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#elif defined(_BSD)
-#include <stdlib.h>
-#else
-#include <malloc.h>
-#endif
-
-void *get_mmap_addr(unsigned long size)
-{
- return NULL;
-}
-
-void qemu_free(void *ptr)
-{
- free(ptr);
-}
-
-void *qemu_malloc(size_t size)
-{
- return malloc(size);
-}
-
-#if defined(_WIN32)
-void *qemu_memalign(size_t alignment, size_t size)
-{
- return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
-}
-
-void *qemu_vmalloc(size_t size)
-{
- /* FIXME: this is not exactly optimal solution since VirtualAlloc
- has 64Kb granularity, but at least it guarantees us that the
- memory is page aligned. */
- return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
-}
-
-void qemu_vfree(void *ptr)
-{
- VirtualFree(ptr, 0, MEM_RELEASE);
-}
-
-#else
-
-#if defined(USE_KQEMU)
-
-#include <sys/vfs.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-void *kqemu_vmalloc(size_t size)
-{
- static int phys_ram_fd = -1;
- static int phys_ram_size = 0;
- const char *tmpdir;
- char phys_ram_file[1024];
- void *ptr;
-#ifdef HOST_SOLARIS
- struct statvfs stfs;
-#else
- struct statfs stfs;
-#endif
-
- if (phys_ram_fd < 0) {
- tmpdir = getenv("QEMU_TMPDIR");
- if (!tmpdir)
-#ifdef HOST_SOLARIS
- tmpdir = "/tmp";
- if (statvfs(tmpdir, &stfs) == 0) {
-#else
- tmpdir = "/dev/shm";
- if (statfs(tmpdir, &stfs) == 0) {
-#endif
- int64_t free_space;
- int ram_mb;
-
- extern int ram_size;
- free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
- if ((ram_size + 8192 * 1024) >= free_space) {
- ram_mb = (ram_size / (1024 * 1024));
- fprintf(stderr,
- "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
- tmpdir, ram_mb);
- if (strcmp(tmpdir, "/dev/shm") == 0) {
- fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
- "umount /dev/shm\n"
- "mount -t tmpfs -o size=%dm none /dev/shm\n",
- ram_mb + 16);
- } else {
- fprintf(stderr,
- "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
- "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
- "temporary RAM file will be opened.\n");
- }
- fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
- exit(1);
- }
- }
- snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
- tmpdir);
- phys_ram_fd = mkstemp(phys_ram_file);
- if (phys_ram_fd < 0) {
- fprintf(stderr,
- "warning: could not create temporary file in '%s'.\n"
- "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
- "Using '/tmp' as fallback.\n",
- tmpdir);
- snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
- "/tmp");
- phys_ram_fd = mkstemp(phys_ram_file);
- if (phys_ram_fd < 0) {
- fprintf(stderr, "Could not create temporary memory file '%s'\n",
- phys_ram_file);
- exit(1);
- }
- }
- unlink(phys_ram_file);
- }
- size = (size + 4095) & ~4095;
- ftruncate(phys_ram_fd, phys_ram_size + size);
- ptr = mmap(NULL,
- size,
- PROT_WRITE | PROT_READ, MAP_SHARED,
- phys_ram_fd, phys_ram_size);
- if (ptr == MAP_FAILED) {
- fprintf(stderr, "Could not map physical memory\n");
- exit(1);
- }
- phys_ram_size += size;
- return ptr;
-}
-
-void kqemu_vfree(void *ptr)
-{
- /* may be useful some day, but currently we do not need to free */
-}
-
-#endif
-
-void *qemu_memalign(size_t alignment, size_t size)
-{
-#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
- int ret;
- void *ptr;
- ret = posix_memalign(&ptr, alignment, size);
- if (ret != 0)
- return NULL;
- return ptr;
-#elif defined(_BSD)
- return valloc(size);
-#else
- return memalign(alignment, size);
-#endif
-}
-
-/* alloc shared memory pages */
-void *qemu_vmalloc(size_t size)
-{
-#if defined(USE_KQEMU)
- if (kqemu_allowed)
- return kqemu_vmalloc(size);
-#endif
-#ifdef _BSD
- return valloc(size);
-#else
- return memalign(4096, size);
-#endif
-}
-
-void qemu_vfree(void *ptr)
-{
-#if defined(USE_KQEMU)
- if (kqemu_allowed)
- kqemu_vfree(ptr);
-#endif
- free(ptr);
-}
-
-#endif
-
-void *qemu_mallocz(size_t size)
-{
- void *ptr;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- memset(ptr, 0, size);
- return ptr;
-}
-
-char *qemu_strdup(const char *str)
-{
- char *ptr;
- ptr = qemu_malloc(strlen(str) + 1);
- if (!ptr)
- return NULL;
- strcpy(ptr, str);
- return ptr;
-}
diff --git a/tools/ioemu/osdep.h b/tools/ioemu/osdep.h
deleted file mode 100644
index 6df1d87d12..0000000000
--- a/tools/ioemu/osdep.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef QEMU_OSDEP_H
-#define QEMU_OSDEP_H
-
-#include <stdarg.h>
-#ifdef __OpenBSD__
-#include <sys/types.h>
-#include <sys/signal.h>
-#endif
-
-#define qemu_printf printf
-
-void *qemu_malloc(size_t size);
-void *qemu_mallocz(size_t size);
-void qemu_free(void *ptr);
-char *qemu_strdup(const char *str);
-
-void *qemu_memalign(size_t alignment, size_t size);
-void *qemu_vmalloc(size_t size);
-void qemu_vfree(void *ptr);
-
-void *get_mmap_addr(unsigned long size);
-
-#endif
diff --git a/tools/ioemu/patches/acpi-poweroff-support b/tools/ioemu/patches/acpi-poweroff-support
deleted file mode 100644
index 61965bbd98..0000000000
--- a/tools/ioemu/patches/acpi-poweroff-support
+++ /dev/null
@@ -1,46 +0,0 @@
-Index: ioemu/hw/piix4acpi.c
-===================================================================
---- ioemu.orig/hw/piix4acpi.c 2007-05-03 19:46:01.000000000 +0100
-+++ ioemu/hw/piix4acpi.c 2007-05-03 19:46:09.000000000 +0100
-@@ -45,6 +45,10 @@
- #define GBL_RLS (1 << 2)
- #define SLP_EN (1 << 13)
-
-+/* Bits of PM1a register define here */
-+#define SLP_TYP_MASK 0x1C00
-+#define SLP_VAL 0x1C00
-+
- typedef struct AcpiDeviceState AcpiDeviceState;
- AcpiDeviceState *acpi_device_table;
-
-@@ -81,7 +85,13 @@
- s->pm1_control = (s->pm1_control & 0xff) | (val << 8);
- /* printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
-
--}
-+ // Check for power off request
-+ val <<= 8;
-+ if (((val & SLP_EN) != 0) &&
-+ ((val & SLP_TYP_MASK) == SLP_VAL)) {
-+ qemu_system_shutdown_request();
-+ }
-+}
-
- static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
- {
-@@ -105,7 +115,14 @@
- s->pm1_control = val;
- /* printf("acpiPm1Control_writew \n addr %x val:%x\n", addr, val); */
-
--}
-+ // Check for power off request
-+
-+ if (((val & SLP_EN) != 0) &&
-+ ((val & SLP_TYP_MASK) == SLP_VAL)) {
-+ qemu_system_shutdown_request();
-+ }
-+
-+}
-
- static uint32_t acpiPm1Control_readw(void *opaque, uint32_t addr)
- {
diff --git a/tools/ioemu/patches/acpi-support b/tools/ioemu/patches/acpi-support
deleted file mode 100644
index 5de41c87e8..0000000000
--- a/tools/ioemu/patches/acpi-support
+++ /dev/null
@@ -1,301 +0,0 @@
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-09 13:47:48.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-09 13:53:57.000000000 +0100
-@@ -389,6 +389,7 @@
- VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
- VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
-+VL_OBJS+= piix4acpi.o
- CPPFLAGS += -DHAS_AUDIO
- endif
- ifeq ($(TARGET_BASE_ARCH), ppc)
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-09 13:47:48.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-09 13:53:56.000000000 +0100
-@@ -727,10 +727,15 @@
-
- cmos_init(ram_size, boot_device, bs_table);
-
-+ /* using PIIX4 acpi model */
-+ if (pci_enabled && acpi_enabled)
-+ pci_piix4_acpi_init(pci_bus, piix3_devfn + 2);
-+
- if (pci_enabled && usb_enabled) {
-- usb_uhci_init(pci_bus, piix3_devfn + 2);
-+ usb_uhci_init(pci_bus, piix3_devfn + (acpi_enabled ? 3 : 2));
- }
-
-+#ifndef CONFIG_DM
- if (pci_enabled && acpi_enabled) {
- uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
- piix4_pm_init(pci_bus, piix3_devfn + 3);
-@@ -740,6 +745,7 @@
- piix4_smbus_register_device(eeprom, 0x50 + i);
- }
- }
-+#endif /* !CONFIG_DM */
-
- if (i440fx_state) {
- i440fx_init_memory_mappings(i440fx_state);
-Index: ioemu/hw/piix4acpi.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/hw/piix4acpi.c 2007-05-09 13:54:18.000000000 +0100
-@@ -0,0 +1,186 @@
-+/*
-+ * PIIX4 ACPI controller emulation
-+ *
-+ * Winston liwen Wang, winston.l.wang@intel.com
-+ * Copyright (c) 2006 , Intel Corporation.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "vl.h"
-+#define FREQUENCE_PMTIMER 3753425
-+/* acpi register bit define here */
-+
-+/* PM1_STS */
-+#define TMROF_STS (1 << 0)
-+#define BM_STS (1 << 4)
-+#define GBL_STS (1 << 5)
-+#define PWRBTN_STS (1 << 8)
-+#define RTC_STS (1 << 10)
-+#define PRBTNOR_STS (1 << 11)
-+#define WAK_STS (1 << 15)
-+/* PM1_EN */
-+#define TMROF_EN (1 << 0)
-+#define GBL_EN (1 << 5)
-+#define PWRBTN_EN (1 << 8)
-+#define RTC_EN (1 << 10)
-+/* PM1_CNT */
-+#define SCI_EN (1 << 0)
-+#define GBL_RLS (1 << 2)
-+#define SLP_EN (1 << 13)
-+
-+typedef struct AcpiDeviceState AcpiDeviceState;
-+AcpiDeviceState *acpi_device_table;
-+
-+typedef struct PCIAcpiState {
-+ PCIDevice dev;
-+ uint16_t pm1_control; /* pm1a_ECNT_BLK */
-+} PCIAcpiState;
-+
-+static inline void acpi_set_irq(PCIAcpiState *s)
-+{
-+/* no real SCI event need for now, so comment the following line out */
-+/* pic_set_irq(s->irq, 1); */
-+ printf("acpi_set_irq: s->irq %x \n",s->irq);
-+}
-+
-+static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+ PCIAcpiState *s = opaque;
-+
-+ s->pm1_control = (s->pm1_control & 0xff00) | (val & 0xff);
-+/* printf("acpiPm1Control_writeb \n addr %x val:%x\n", addr, val); */
-+
-+}
-+
-+static uint32_t acpiPm1Control_readb(void *opaque, uint32_t addr)
-+{
-+ PCIAcpiState *s = opaque;
-+ uint32_t val;
-+
-+ /* Mask out the write-only bits */
-+ val = s->pm1_control & ~(GBL_RLS|SLP_EN) & 0xff;
-+/* printf("acpiPm1Control_readb \n addr %x val:%x\n", addr, val); */
-+
-+ return val;
-+}
-+
-+static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+ PCIAcpiState *s = opaque;
-+
-+ s->pm1_control = (s->pm1_control & 0xff) | (val << 8);
-+/* printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
-+
-+}
-+
-+static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
-+{
-+ PCIAcpiState *s = opaque;
-+ uint32_t val;
-+
-+ /* Mask out the write-only bits */
-+ val = (s->pm1_control & ~(GBL_RLS|SLP_EN)) >> 8;
-+/* printf("acpiPm1ControlP1_readb \n addr %x val:%x\n", addr, val); */
-+
-+ return val;
-+}
-+
-+
-+/* word access */
-+
-+static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val)
-+{
-+ PCIAcpiState *s = opaque;
-+
-+ s->pm1_control = val;
-+/* printf("acpiPm1Control_writew \n addr %x val:%x\n", addr, val); */
-+
-+}
-+
-+static uint32_t acpiPm1Control_readw(void *opaque, uint32_t addr)
-+{
-+ PCIAcpiState *s = opaque;
-+ uint32_t val;
-+
-+ /* Mask out the write-only bits */
-+ val = s->pm1_control & ~(GBL_RLS|SLP_EN);
-+/* printf("acpiPm1Control_readw \n addr %x val:%x\n", addr, val); */
-+
-+ return val;
-+}
-+
-+
-+static void acpi_map(PCIDevice *pci_dev, int region_num,
-+ uint32_t addr, uint32_t size, int type)
-+{
-+ PCIAcpiState *d = (PCIAcpiState *)pci_dev;
-+
-+ printf("register acpi io \n");
-+
-+ /* Byte access */
-+ register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
-+ register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
-+ register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
-+ register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
-+
-+ /* Word access */
-+ register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
-+ register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
-+}
-+
-+/* PIIX4 acpi pci configuration space, func 2 */
-+void pci_piix4_acpi_init(PCIBus *bus, int devfn)
-+{
-+ PCIAcpiState *d;
-+ uint8_t *pci_conf;
-+
-+ /* register a function 2 of PIIX4 */
-+ d = (PCIAcpiState *)pci_register_device(
-+ bus, "PIIX4 ACPI", sizeof(PCIAcpiState),
-+ devfn, NULL, NULL);
-+
-+ pci_conf = d->dev.config;
-+ pci_conf[0x00] = 0x86; /* Intel */
-+ pci_conf[0x01] = 0x80;
-+ pci_conf[0x02] = 0x13;
-+ pci_conf[0x03] = 0x71;
-+ pci_conf[0x08] = 0x01; /* B0 stepping */
-+ pci_conf[0x09] = 0x00; /* base class */
-+ pci_conf[0x0a] = 0x80; /* Sub class */
-+ pci_conf[0x0b] = 0x06;
-+ pci_conf[0x0e] = 0x00;
-+ pci_conf[0x3d] = 0x01; /* Hardwired to PIRQA is used */
-+
-+
-+ /* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40
-+ * to make shutdown work for IPF, due to IPF Guest Firmware
-+ * will enumerate pci devices.
-+ *
-+ * TODO: if Guest Firmware or Guest OS will change this PMBA,
-+ * More logic will be added.
-+ */
-+ pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
-+ pci_conf[0x41] = 0x1f;
-+ pci_conf[0x42] = 0x00;
-+ pci_conf[0x43] = 0x00;
-+ d->pm1_control = SCI_EN;
-+
-+ acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
-+}
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-09 13:47:48.000000000 +0100
-+++ ioemu/vl.c 2007-05-09 13:53:57.000000000 +0100
-@@ -168,7 +168,7 @@
- #else
- #define MAX_CPUS 1
- #endif
--int acpi_enabled = 1;
-+int acpi_enabled = 0;
- int fd_bootchk = 1;
- int no_reboot = 0;
- int daemonize = 0;
-@@ -6313,6 +6313,7 @@
- "-daemonize daemonize QEMU after initializing\n"
- #endif
- "-option-rom rom load a file, rom, into the option ROM space\n"
-+ "-acpi disable or enable ACPI of HVM domain \n"
- "\n"
- "During emulation, the following keys are useful:\n"
- "ctrl-alt-f toggle full screen\n"
-@@ -6402,6 +6403,7 @@
- ,
- QEMU_OPTION_d,
- QEMU_OPTION_vcpus,
-+ QEMU_OPTION_acpi,
- };
-
- typedef struct QEMUOption {
-@@ -6494,6 +6496,7 @@
-
- { "d", HAS_ARG, QEMU_OPTION_d },
- { "vcpus", 1, QEMU_OPTION_vcpus },
-+ { "acpi", 0, QEMU_OPTION_acpi },
- { NULL },
- };
-
-@@ -7258,6 +7261,9 @@
- vcpus = atoi(optarg);
- fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
- break;
-+ case QEMU_OPTION_acpi:
-+ acpi_enabled = 1;
-+ break;
- }
- }
- }
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-09 13:47:48.000000000 +0100
-+++ ioemu/vl.h 2007-05-09 13:53:57.000000000 +0100
-@@ -173,6 +173,7 @@
- extern int kqemu_allowed;
- extern int win2k_install_hack;
- extern int usb_enabled;
-+extern int acpi_enabled;
- extern int smp_cpus;
- extern int no_quit;
- extern int semihosting_enabled;
-@@ -1079,6 +1080,9 @@
- /* smbus_eeprom.c */
- SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
-
-+/* piix4acpi.c */
-+extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
-+
- /* pc.c */
- extern QEMUMachine pc_machine;
- extern QEMUMachine isapc_machine;
diff --git a/tools/ioemu/patches/acpi-timer-support b/tools/ioemu/patches/acpi-timer-support
deleted file mode 100644
index 4f28ae5662..0000000000
--- a/tools/ioemu/patches/acpi-timer-support
+++ /dev/null
@@ -1,66 +0,0 @@
-Index: ioemu/hw/piix4acpi.c
-===================================================================
---- ioemu.orig/hw/piix4acpi.c 2007-05-03 19:36:00.000000000 +0100
-+++ ioemu/hw/piix4acpi.c 2007-05-03 19:46:01.000000000 +0100
-@@ -24,26 +24,26 @@
- */
-
- #include "vl.h"
--#define FREQUENCE_PMTIMER 3753425
-+#define FREQUENCE_PMTIMER 3579545
- /* acpi register bit define here */
-
--/* PM1_STS */
--#define TMROF_STS (1 << 0)
--#define BM_STS (1 << 4)
--#define GBL_STS (1 << 5)
--#define PWRBTN_STS (1 << 8)
--#define RTC_STS (1 << 10)
-+/* PM1_STS */
-+#define TMROF_STS (1 << 0)
-+#define BM_STS (1 << 4)
-+#define GBL_STS (1 << 5)
-+#define PWRBTN_STS (1 << 8)
-+#define RTC_STS (1 << 10)
- #define PRBTNOR_STS (1 << 11)
--#define WAK_STS (1 << 15)
--/* PM1_EN */
-+#define WAK_STS (1 << 15)
-+/* PM1_EN */
- #define TMROF_EN (1 << 0)
- #define GBL_EN (1 << 5)
- #define PWRBTN_EN (1 << 8)
--#define RTC_EN (1 << 10)
--/* PM1_CNT */
-+#define RTC_EN (1 << 10)
-+/* PM1_CNT */
- #define SCI_EN (1 << 0)
- #define GBL_RLS (1 << 2)
--#define SLP_EN (1 << 13)
-+#define SLP_EN (1 << 13)
-
- typedef struct AcpiDeviceState AcpiDeviceState;
- AcpiDeviceState *acpi_device_table;
-@@ -53,13 +53,6 @@
- uint16_t pm1_control; /* pm1a_ECNT_BLK */
- } PCIAcpiState;
-
--static inline void acpi_set_irq(PCIAcpiState *s)
--{
--/* no real SCI event need for now, so comment the following line out */
--/* pic_set_irq(s->irq, 1); */
-- printf("acpi_set_irq: s->irq %x \n",s->irq);
--}
--
- static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
- {
- PCIAcpiState *s = opaque;
-@@ -132,7 +125,7 @@
- {
- PCIAcpiState *d = (PCIAcpiState *)pci_dev;
-
-- printf("register acpi io \n");
-+ printf("register acpi io\n");
-
- /* Byte access */
- register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
diff --git a/tools/ioemu/patches/domain-destroy b/tools/ioemu/patches/domain-destroy
deleted file mode 100644
index a447c6bac9..0000000000
--- a/tools/ioemu/patches/domain-destroy
+++ /dev/null
@@ -1,55 +0,0 @@
-Index: ioemu/monitor.c
-===================================================================
---- ioemu.orig/monitor.c 2007-05-03 19:01:49.000000000 +0100
-+++ ioemu/monitor.c 2007-05-03 19:12:02.000000000 +0100
-@@ -339,6 +339,7 @@
-
- static void do_quit(void)
- {
-+ destroy_hvm_domain();
- exit(0);
- }
-
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- ioemu.orig/target-i386-dm/helper2.c 2007-05-03 19:12:00.000000000 +0100
-+++ ioemu/target-i386-dm/helper2.c 2007-05-03 19:12:02.000000000 +0100
-@@ -549,5 +549,26 @@
- /* Wait up to 10 msec. */
- main_loop_wait(10);
-
-+ destroy_hvm_domain();
-+
- return 0;
- }
-+
-+void destroy_hvm_domain(void)
-+{
-+ int xcHandle;
-+ int sts;
-+
-+ xcHandle = xc_interface_open();
-+ if (xcHandle < 0)
-+ fprintf(logfile, "Cannot acquire xenctrl handle\n");
-+ else {
-+ sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_poweroff);
-+ if (sts != 0)
-+ fprintf(logfile, "? xc_domain_shutdown failed to issue poweroff, "
-+ "sts %d, errno %d\n", sts, errno);
-+ else
-+ fprintf(logfile, "Issued domain %d poweroff\n", domid);
-+ xc_interface_close(xcHandle);
-+ }
-+}
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 19:12:00.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 19:12:02.000000000 +0100
-@@ -1410,4 +1410,7 @@
- void kqemu_record_dump(void);
-
- extern char domain_name[];
-+
-+void destroy_hvm_domain(void);
-+
- #endif /* VL_H */
diff --git a/tools/ioemu/patches/domain-reset b/tools/ioemu/patches/domain-reset
deleted file mode 100644
index 93e825f3a5..0000000000
--- a/tools/ioemu/patches/domain-reset
+++ /dev/null
@@ -1,87 +0,0 @@
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- ioemu.orig/target-i386-dm/helper2.c 2007-05-09 13:43:01.000000000 +0100
-+++ ioemu/target-i386-dm/helper2.c 2007-05-09 13:44:09.000000000 +0100
-@@ -127,6 +127,22 @@
- /* called from main_cpu_reset */
- void cpu_reset(CPUX86State *env)
- {
-+ int xcHandle;
-+ int sts;
-+
-+ xcHandle = xc_interface_open();
-+ if (xcHandle < 0)
-+ fprintf(logfile, "Cannot acquire xenctrl handle\n");
-+ else {
-+ sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_reboot);
-+ if (sts != 0)
-+ fprintf(logfile,
-+ "? xc_domain_shutdown failed to issue reboot, sts %d\n",
-+ sts);
-+ else
-+ fprintf(logfile, "Issued domain %d reboot\n", domid);
-+ xc_interface_close(xcHandle);
-+ }
- }
-
- void cpu_x86_close(CPUX86State *env)
-@@ -529,14 +545,9 @@
-
- qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
-
-- while (1) {
-- if (vm_running) {
-- if (shutdown_requested)
-- break;
-- }
--
-+ while (!(vm_running && suspend_requested))
- /* Wait up to 10 msec. */
- main_loop_wait(10);
-- }
-+
- return 0;
- }
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-09 13:43:02.000000000 +0100
-+++ ioemu/vl.c 2007-05-09 13:44:20.000000000 +0100
-@@ -5843,7 +5843,7 @@
- } QEMUResetEntry;
-
- static QEMUResetEntry *first_reset_entry;
--static int reset_requested;
-+int reset_requested;
- int shutdown_requested;
- static int powerdown_requested;
-
-@@ -5861,7 +5861,7 @@
- *pre = re;
- }
-
--static void qemu_system_reset(void)
-+void qemu_system_reset(void)
- {
- QEMUResetEntry *re;
-
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-09 13:43:01.000000000 +0100
-+++ ioemu/vl.h 2007-05-09 13:44:09.000000000 +0100
-@@ -136,6 +136,7 @@
-
- void qemu_register_reset(QEMUResetHandler *func, void *opaque);
- void qemu_system_reset_request(void);
-+void qemu_system_reset(void);
- void qemu_system_shutdown_request(void);
- void qemu_system_powerdown_request(void);
- #if !defined(TARGET_SPARC)
-@@ -145,6 +146,8 @@
- void qemu_system_powerdown(void);
- #endif
-
-+extern int reset_requested;
-+
- void main_loop_wait(int timeout);
-
- extern FILE *logfile;
diff --git a/tools/ioemu/patches/domain-timeoffset b/tools/ioemu/patches/domain-timeoffset
deleted file mode 100644
index f58057ab80..0000000000
--- a/tools/ioemu/patches/domain-timeoffset
+++ /dev/null
@@ -1,87 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-11 10:04:50.000000000 +0100
-+++ ioemu/vl.c 2007-05-11 10:04:50.000000000 +0100
-@@ -7530,6 +7530,9 @@
- }
- free(page_array);
- #endif
-+
-+ timeoffset_get();
-+
- #else /* !CONFIG_DM */
-
- phys_ram_base = qemu_vmalloc(phys_ram_size);
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-11 10:04:50.000000000 +0100
-+++ ioemu/vl.h 2007-05-11 10:04:50.000000000 +0100
-@@ -1433,6 +1433,10 @@
- int xenstore_vm_write(int domid, char *key, char *val);
- char *xenstore_vm_read(int domid, char *key, int *len);
-
-+/* helper2.c */
-+extern long time_offset;
-+void timeoffset_get(void);
-+
- void kqemu_record_dump(void);
-
- extern char domain_name[];
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- ioemu.orig/target-i386-dm/helper2.c 2007-05-11 10:04:48.000000000 +0100
-+++ ioemu/target-i386-dm/helper2.c 2007-05-11 10:04:50.000000000 +0100
-@@ -74,6 +74,8 @@
-
- int xc_handle;
-
-+long time_offset = 0;
-+
- shared_iopage_t *shared_page = NULL;
-
- /* the evtchn fd for polling */
-@@ -447,6 +449,34 @@
- req->data = tmp1;
- }
-
-+void timeoffset_get()
-+{
-+ char *p;
-+
-+ p = xenstore_vm_read(domid, "rtc/timeoffset", NULL);
-+ if (!p)
-+ return;
-+
-+ if (sscanf(p, "%ld", &time_offset) == 1)
-+ fprintf(logfile, "Time offset set %ld\n", time_offset);
-+ else
-+ time_offset = 0;
-+
-+ xc_domain_set_time_offset(xc_handle, domid, time_offset);
-+
-+ free(p);
-+}
-+
-+void cpu_ioreq_timeoffset(CPUState *env, ioreq_t *req)
-+{
-+ char b[64];
-+
-+ time_offset += (ulong)req->data;
-+
-+ sprintf(b, "%ld", time_offset);
-+ xenstore_vm_write(domid, "rtc/timeoffset", b);
-+}
-+
- void cpu_ioreq_xchg(CPUState *env, ioreq_t *req)
- {
- unsigned long tmp1;
-@@ -497,6 +527,9 @@
- case IOREQ_TYPE_XCHG:
- cpu_ioreq_xchg(env, req);
- break;
-+ case IOREQ_TYPE_TIMEOFFSET:
-+ cpu_ioreq_timeoffset(env, req);
-+ break;
- default:
- hw_error("Invalid ioreq type 0x%x\n", req->type);
- }
diff --git a/tools/ioemu/patches/fix-interrupt-routing b/tools/ioemu/patches/fix-interrupt-routing
deleted file mode 100644
index 235e78e8af..0000000000
--- a/tools/ioemu/patches/fix-interrupt-routing
+++ /dev/null
@@ -1,507 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID f555a90bcc373a7379bc18f875eac5e7c7122ae9
-# Parent b80f00215bbaf2050765e557f1a017a71e1e8529
-[HVM] Reworked interrupt distribution logic.
-
-TODO:
- 1. Fix IO-APIC ID to not conflict with LAPIC IDS.
- 2. Fix i8259 device model (seems to work already though!).
- 3. Add INTSRC overrides in MPBIOS and ACPI tables so
- that PCI legacy IRQ routing always ends up at an
- IO-APIC input with level trigger. Restricting link
- routing to {5,6,10,11} and setting overrides for all
- four of those would work.
-
-Signed-off-by: Keir Fraser <keir@xensource.com>
-
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-09 13:56:55.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-09 13:56:55.000000000 +0100
-@@ -325,9 +325,9 @@
-
- # qemu-dm objects
- ifeq ($(ARCH),ia64)
--LIBOBJS=helper2.o exec-dm.o i8259-dm.o
-+LIBOBJS=helper2.o exec-dm.o i8259-dm.o piix_pci-dm.o
- else
--LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o
-+LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o
- endif
-
- all: $(PROGS)
-@@ -395,7 +395,7 @@
- else
- VL_OBJS+= fdc.o serial.o pc.o
- endif
--VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
-+VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
- VL_OBJS+= piix4acpi.o
- VL_OBJS+= xenstore.o
-Index: ioemu/target-i386-dm/i8259-dm.c
-===================================================================
---- ioemu.orig/target-i386-dm/i8259-dm.c 2007-05-09 13:56:35.000000000 +0100
-+++ ioemu/target-i386-dm/i8259-dm.c 2007-05-09 13:56:55.000000000 +0100
-@@ -33,7 +33,7 @@
-
- void pic_set_irq_new(void *opaque, int irq, int level)
- {
-- xc_hvm_set_irq_level(xc_handle, domid, irq, level);
-+ xc_hvm_set_isa_irq_level(xc_handle, domid, irq, level);
- }
-
- /* obsolete function */
-Index: ioemu/target-i386-dm/piix_pci-dm.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/piix_pci-dm.c 2007-05-09 14:07:46.000000000 +0100
-@@ -0,0 +1,447 @@
-+/*
-+ * QEMU i440FX/PIIX3 PCI Bridge Emulation
-+ *
-+ * Copyright (c) 2006 Fabrice Bellard
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "vl.h"
-+typedef uint32_t pci_addr_t;
-+#include "hw/pci_host.h"
-+
-+typedef PCIHostState I440FXState;
-+
-+static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
-+{
-+ I440FXState *s = opaque;
-+ s->config_reg = val;
-+}
-+
-+static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
-+{
-+ I440FXState *s = opaque;
-+ return s->config_reg;
-+}
-+
-+/* return the global irq number corresponding to a given device irq
-+ pin. We could also use the bus number to have a more precise
-+ mapping. */
-+static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
-+{
-+#ifndef CONFIG_DM
-+ int slot_addend;
-+ slot_addend = (pci_dev->devfn >> 3) - 1;
-+ return (irq_num + slot_addend) & 3;
-+#else /* !CONFIG_DM */
-+ return irq_num + ((pci_dev->devfn >> 3) << 2);
-+#endif /* !CONFIG_DM */
-+}
-+
-+static void i440fx_set_irq(void *pic, int irq_num, int level)
-+{
-+ xc_hvm_set_pci_intx_level(xc_handle, domid, 0, 0, irq_num >> 2,
-+ irq_num & 3, level);
-+}
-+
-+static void i440fx_save(QEMUFile* f, void *opaque)
-+{
-+ PCIDevice *d = opaque;
-+ pci_device_save(d, f);
-+#ifndef CONFIG_DM
-+ qemu_put_8s(f, &smm_enabled);
-+#endif /* !CONFIG_DM */
-+}
-+
-+static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
-+{
-+ PCIDevice *d = opaque;
-+ int ret;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+ ret = pci_device_load(d, f);
-+ if (ret < 0)
-+ return ret;
-+#ifndef CONFIG_DM
-+ i440fx_update_memory_mappings(d);
-+ qemu_get_8s(f, &smm_enabled);
-+#endif /* !CONFIG_DM */
-+ return 0;
-+}
-+
-+PCIBus *i440fx_init(PCIDevice **pi440fx_state)
-+{
-+ PCIBus *b;
-+ PCIDevice *d;
-+ I440FXState *s;
-+
-+ s = qemu_mallocz(sizeof(I440FXState));
-+ b = pci_register_bus(i440fx_set_irq, pci_slot_get_pirq, NULL, 0, 128);
-+ s->bus = b;
-+
-+ register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
-+ register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
-+
-+ register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
-+ register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
-+ register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
-+ register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
-+ register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
-+ register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
-+
-+ d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
-+ NULL, NULL);
-+
-+ d->config[0x00] = 0x86; // vendor_id
-+ d->config[0x01] = 0x80;
-+ d->config[0x02] = 0x37; // device_id
-+ d->config[0x03] = 0x12;
-+ d->config[0x08] = 0x02; // revision
-+ d->config[0x0a] = 0x00; // class_sub = host2pci
-+ d->config[0x0b] = 0x06; // class_base = PCI_bridge
-+ d->config[0x0e] = 0x00; // header_type
-+
-+ register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d);
-+ *pi440fx_state = d;
-+ return b;
-+}
-+
-+/* PIIX3 PCI to ISA bridge */
-+
-+static PCIDevice *piix3_dev;
-+
-+static void piix3_write_config(PCIDevice *d,
-+ uint32_t address, uint32_t val, int len)
-+{
-+ int i;
-+
-+ /* Scan for updates to PCI link routes (0x60-0x63). */
-+ for (i = 0; i < len; i++) {
-+ uint8_t v = (val >> (8*i)) & 0xff;
-+ if (v & 0x80)
-+ v = 0;
-+ v &= 0xf;
-+ if (((address+i) >= 0x60) && ((address+i) <= 0x63))
-+ xc_hvm_set_pci_link_route(xc_handle, domid, address + i - 0x60, v);
-+ }
-+
-+ /* Hand off to default logic. */
-+ pci_default_write_config(d, address, val, len);
-+}
-+
-+static void piix3_reset(PCIDevice *d)
-+{
-+ uint8_t *pci_conf = d->config;
-+
-+ pci_conf[0x04] = 0x07; // master, memory and I/O
-+ pci_conf[0x05] = 0x00;
-+ pci_conf[0x06] = 0x00;
-+ pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
-+ pci_conf[0x4c] = 0x4d;
-+ pci_conf[0x4e] = 0x03;
-+ pci_conf[0x4f] = 0x00;
-+ pci_conf[0x60] = 0x80;
-+ pci_conf[0x61] = 0x80;
-+ pci_conf[0x62] = 0x80;
-+ pci_conf[0x63] = 0x80;
-+ pci_conf[0x69] = 0x02;
-+ pci_conf[0x70] = 0x80;
-+ pci_conf[0x76] = 0x0c;
-+ pci_conf[0x77] = 0x0c;
-+ pci_conf[0x78] = 0x02;
-+ pci_conf[0x79] = 0x00;
-+ pci_conf[0x80] = 0x00;
-+ pci_conf[0x82] = 0x00;
-+ pci_conf[0xa0] = 0x08;
-+ pci_conf[0xa2] = 0x00;
-+ pci_conf[0xa3] = 0x00;
-+ pci_conf[0xa4] = 0x00;
-+ pci_conf[0xa5] = 0x00;
-+ pci_conf[0xa6] = 0x00;
-+ pci_conf[0xa7] = 0x00;
-+ pci_conf[0xa8] = 0x0f;
-+ pci_conf[0xaa] = 0x00;
-+ pci_conf[0xab] = 0x00;
-+ pci_conf[0xac] = 0x00;
-+ pci_conf[0xae] = 0x00;
-+}
-+
-+static void piix_save(QEMUFile* f, void *opaque)
-+{
-+ PCIDevice *d = opaque;
-+ pci_device_save(d, f);
-+}
-+
-+static int piix_load(QEMUFile* f, void *opaque, int version_id)
-+{
-+ PCIDevice *d = opaque;
-+ if (version_id != 2)
-+ return -EINVAL;
-+ return pci_device_load(d, f);
-+}
-+
-+int piix3_init(PCIBus *bus, int devfn)
-+{
-+ PCIDevice *d;
-+ uint8_t *pci_conf;
-+
-+ d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),
-+ devfn, NULL, piix3_write_config);
-+ register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);
-+
-+ piix3_dev = d;
-+ pci_conf = d->config;
-+
-+ pci_conf[0x00] = 0x86; // Intel
-+ pci_conf[0x01] = 0x80;
-+ pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-+ pci_conf[0x03] = 0x70;
-+ pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
-+ pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
-+ pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
-+
-+ piix3_reset(d);
-+ return d->devfn;
-+}
-+
-+/***********************************************************/
-+/* XXX: the following should be moved to the PC BIOS */
-+
-+static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
-+{
-+ return cpu_inb(NULL, addr);
-+}
-+
-+static void isa_outb(uint32_t val, uint32_t addr)
-+{
-+ cpu_outb(NULL, addr, val);
-+}
-+
-+static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
-+{
-+ return cpu_inw(NULL, addr);
-+}
-+
-+static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
-+{
-+ cpu_outw(NULL, addr, val);
-+}
-+
-+static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
-+{
-+ return cpu_inl(NULL, addr);
-+}
-+
-+static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
-+{
-+ cpu_outl(NULL, addr, val);
-+}
-+
-+static uint32_t pci_bios_io_addr;
-+static uint32_t pci_bios_mem_addr;
-+/* host irqs corresponding to PCI irqs A-D */
-+static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
-+
-+static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
-+{
-+ PCIBus *s = d->bus;
-+ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-+ pci_data_write(s, addr, val, 4);
-+}
-+
-+static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
-+{
-+ PCIBus *s = d->bus;
-+ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-+ pci_data_write(s, addr, val, 2);
-+}
-+
-+static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
-+{
-+ PCIBus *s = d->bus;
-+ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-+ pci_data_write(s, addr, val, 1);
-+}
-+
-+static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
-+{
-+ PCIBus *s = d->bus;
-+ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-+ return pci_data_read(s, addr, 4);
-+}
-+
-+static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
-+{
-+ PCIBus *s = d->bus;
-+ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-+ return pci_data_read(s, addr, 2);
-+}
-+
-+static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
-+{
-+ PCIBus *s = d->bus;
-+ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-+ return pci_data_read(s, addr, 1);
-+}
-+
-+static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
-+{
-+ PCIIORegion *r;
-+ uint16_t cmd;
-+ uint32_t ofs;
-+
-+ if ( region_num == PCI_ROM_SLOT ) {
-+ ofs = 0x30;
-+ }else{
-+ ofs = 0x10 + region_num * 4;
-+ }
-+
-+ pci_config_writel(d, ofs, addr);
-+ r = &d->io_regions[region_num];
-+
-+ /* enable memory mappings */
-+ cmd = pci_config_readw(d, PCI_COMMAND);
-+ if ( region_num == PCI_ROM_SLOT )
-+ cmd |= 2;
-+ else if (r->type & PCI_ADDRESS_SPACE_IO)
-+ cmd |= 1;
-+ else
-+ cmd |= 2;
-+ pci_config_writew(d, PCI_COMMAND, cmd);
-+}
-+
-+static void pci_bios_init_device(PCIDevice *d)
-+{
-+ int class;
-+ PCIIORegion *r;
-+ uint32_t *paddr;
-+ int i, pin, pic_irq, vendor_id, device_id;
-+
-+ class = pci_config_readw(d, PCI_CLASS_DEVICE);
-+ vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
-+ device_id = pci_config_readw(d, PCI_DEVICE_ID);
-+ switch(class) {
-+ case 0x0101:
-+ if (vendor_id == 0x8086 && device_id == 0x7010) {
-+ /* PIIX3 IDE */
-+ pci_config_writew(d, 0x40, 0x8000); // enable IDE0
-+ pci_config_writew(d, 0x42, 0x8000); // enable IDE1
-+ goto default_map;
-+ } else {
-+ /* IDE: we map it as in ISA mode */
-+ pci_set_io_region_addr(d, 0, 0x1f0);
-+ pci_set_io_region_addr(d, 1, 0x3f4);
-+ pci_set_io_region_addr(d, 2, 0x170);
-+ pci_set_io_region_addr(d, 3, 0x374);
-+ }
-+ break;
-+ case 0x0680:
-+ if (vendor_id == 0x8086 && device_id == 0x7113) {
-+ /*
-+ * PIIX4 ACPI PM.
-+ * Special device with special PCI config space. No ordinary BARs.
-+ */
-+ pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
-+ pci_config_writew(d, 0x22, 0x0000);
-+ pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
-+ pci_config_writew(d, 0x3d, 0x0001);
-+ }
-+ break;
-+ case 0x0300:
-+ if (vendor_id != 0x1234)
-+ goto default_map;
-+ /* VGA: map frame buffer to default Bochs VBE address */
-+ pci_set_io_region_addr(d, 0, 0xE0000000);
-+ break;
-+ case 0x0800:
-+ /* PIC */
-+ vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
-+ device_id = pci_config_readw(d, PCI_DEVICE_ID);
-+ if (vendor_id == 0x1014) {
-+ /* IBM */
-+ if (device_id == 0x0046 || device_id == 0xFFFF) {
-+ /* MPIC & MPIC2 */
-+ pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
-+ }
-+ }
-+ break;
-+ case 0xff00:
-+ if (vendor_id == 0x0106b &&
-+ (device_id == 0x0017 || device_id == 0x0022)) {
-+ /* macio bridge */
-+ pci_set_io_region_addr(d, 0, 0x80800000);
-+ }
-+ break;
-+ default:
-+ default_map:
-+ /* default memory mappings */
-+ for(i = 0; i < PCI_NUM_REGIONS; i++) {
-+ r = &d->io_regions[i];
-+ if (r->size) {
-+ if (r->type & PCI_ADDRESS_SPACE_IO)
-+ paddr = &pci_bios_io_addr;
-+ else
-+ paddr = &pci_bios_mem_addr;
-+ *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
-+ pci_set_io_region_addr(d, i, *paddr);
-+ *paddr += r->size;
-+ }
-+ }
-+ break;
-+ }
-+
-+ /* map the interrupt */
-+ pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
-+ if (pin != 0) {
-+ pin = pci_slot_get_pirq(d, pin - 1);
-+ pic_irq = pci_irqs[pin];
-+ pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
-+ }
-+}
-+
-+/*
-+ * This function initializes the PCI devices as a normal PCI BIOS
-+ * would do. It is provided just in case the BIOS has no support for
-+ * PCI.
-+ */
-+void pci_bios_init(void)
-+{
-+ int i, irq;
-+ uint8_t elcr[2];
-+
-+ pci_bios_io_addr = 0xc000;
-+ pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START;
-+
-+ /* activate IRQ mappings */
-+ elcr[0] = 0x00;
-+ elcr[1] = 0x00;
-+ for(i = 0; i < 4; i++) {
-+ irq = pci_irqs[i];
-+ /* set to trigger level */
-+ elcr[irq >> 3] |= (1 << (irq & 7));
-+ /* activate irq remapping in PIIX */
-+ pci_config_writeb(piix3_dev, 0x60 + i, irq);
-+ }
-+ isa_outb(elcr[0], 0x4d0);
-+ isa_outb(elcr[1], 0x4d1);
-+
-+ pci_for_each_device(pci_bios_init_device);
-+}
-+
diff --git a/tools/ioemu/patches/fix-vga-scanning-code-overflow b/tools/ioemu/patches/fix-vga-scanning-code-overflow
deleted file mode 100644
index a4bb19b186..0000000000
--- a/tools/ioemu/patches/fix-vga-scanning-code-overflow
+++ /dev/null
@@ -1,45 +0,0 @@
-Index: ioemu/hw/vga.c
-===================================================================
---- ioemu.orig/hw/vga.c 2007-05-03 19:15:57.000000000 +0100
-+++ ioemu/hw/vga.c 2007-05-03 19:46:13.000000000 +0100
-@@ -1477,14 +1477,15 @@
- */
- static void vga_draw_graphic(VGAState *s, int full_update)
- {
-- int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
-+ int y1, y, update, linesize, y_start, double_scan, mask;
- int width, height, shift_control, line_offset, bwidth;
- ram_addr_t page0, page1;
- int disp_width, multi_scan, multi_run;
- uint8_t *d;
- uint32_t v, addr1, addr;
- vga_draw_line_func *vga_draw_line;
--
-+ ram_addr_t page_min, page_max;
-+
- full_update |= update_basic_params(s);
-
- s->get_resolution(s, &width, &height);
-@@ -1575,8 +1576,8 @@
- addr1 = (s->start_addr * 4);
- bwidth = width * 4;
- y_start = -1;
-- page_min = 0x7fffffff;
-- page_max = -1;
-+ page_min = 0;
-+ page_max = 0;
- d = s->ds->data;
- linesize = s->ds->linesize;
- y1 = 0;
-@@ -1606,9 +1607,9 @@
- if (update) {
- if (y_start < 0)
- y_start = y;
-- if (page0 < page_min)
-+ if (page_min == 0 || page0 < page_min)
- page_min = page0;
-- if (page1 > page_max)
-+ if (page_max == 0 || page1 > page_max)
- page_max = page1;
- vga_draw_line(s, d, s->vram_ptr + addr, width);
- if (s->cursor_draw_line)
diff --git a/tools/ioemu/patches/hypervisor-pit b/tools/ioemu/patches/hypervisor-pit
deleted file mode 100644
index 3cd26c49de..0000000000
--- a/tools/ioemu/patches/hypervisor-pit
+++ /dev/null
@@ -1,58 +0,0 @@
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-03 19:09:54.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-03 19:15:05.000000000 +0100
-@@ -386,7 +386,7 @@
- ifeq ($(TARGET_BASE_ARCH), i386)
- # Hardware support
- VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
--VL_OBJS+= fdc.o mc146818rtc.o serial.o i8254.o pcspk.o pc.o
-+VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
- VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
- CPPFLAGS += -DHAS_AUDIO
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-03 19:11:08.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-03 19:15:05.000000000 +0100
-@@ -38,7 +38,9 @@
-
- static fdctrl_t *floppy_controller;
- static RTCState *rtc_state;
-+#ifndef CONFIG_DM
- static PITState *pit;
-+#endif /* !CONFIG_DM */
- #ifndef CONFIG_DM
- static IOAPICState *ioapic;
- #endif /* !CONFIG_DM */
-@@ -664,8 +666,10 @@
- }
- #endif /* !CONFIG_DM */
- isa_pic = pic_init(pic_irq_request, first_cpu);
-+#ifndef CONFIG_DM
- pit = pit_init(0x40, 0);
- pcspk_init(pit);
-+#endif /* !CONFIG_DM */
- #ifndef CONFIG_DM
- if (pci_enabled) {
- pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:14:57.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:15:05.000000000 +0100
-@@ -6537,6 +6537,7 @@
-
- #ifdef HAS_AUDIO
- struct soundhw soundhw[] = {
-+#ifndef CONFIG_DM
- #ifdef TARGET_I386
- {
- "pcspk",
-@@ -6546,6 +6547,7 @@
- { .init_isa = pcspk_audio_init }
- },
- #endif
-+#endif /* !CONFIG_DM */
- {
- "sb16",
- "Creative Sound Blaster 16",
diff --git a/tools/ioemu/patches/hypervisor-rtc b/tools/ioemu/patches/hypervisor-rtc
deleted file mode 100644
index 4df37e5dc4..0000000000
--- a/tools/ioemu/patches/hypervisor-rtc
+++ /dev/null
@@ -1,164 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID 71e2a165aa7f81602c569430b18ba1ea705f0b70
-# Parent da66691687dfd90c55420cfdf27f55d18cca7810
-[HVM] Move RTC emulation into the hypervisor.
-Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
-
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-09 14:12:44.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-09 14:14:08.000000000 +0100
-@@ -324,7 +324,11 @@
- endif
-
- # qemu-dm objects
-+ifeq ($(ARCH),ia64)
- LIBOBJS=helper2.o exec-dm.o i8259-dm.o
-+else
-+LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o
-+endif
-
- all: $(PROGS)
-
-@@ -386,7 +390,11 @@
- ifeq ($(TARGET_BASE_ARCH), i386)
- # Hardware support
- VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
-+ifeq ($(ARCH),ia64)
- VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
-+else
-+VL_OBJS+= fdc.o serial.o pc.o
-+endif
- VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
- VL_OBJS+= piix4acpi.o
-Index: ioemu/target-i386-dm/rtc-dm.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/rtc-dm.c 2007-05-09 14:14:13.000000000 +0100
-@@ -0,0 +1,124 @@
-+/*
-+ * QEMU MC146818 RTC emulation
-+ *
-+ * Copyright (c) 2003-2004 Fabrice Bellard
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "vl.h"
-+
-+// #define DEBUG_CMOS
-+
-+struct RTCState {
-+ uint8_t cmos_data[128];
-+ uint8_t cmos_index;
-+};
-+
-+static inline int to_bcd(RTCState *s, int a)
-+{
-+ return ((a / 10) << 4) | (a % 10);
-+}
-+
-+void rtc_set_memory(RTCState *s, int addr, int val)
-+{
-+ if (addr >= 0 && addr <= 127)
-+ s->cmos_data[addr] = val;
-+}
-+
-+static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
-+{
-+ RTCState *s = opaque;
-+
-+ if ((addr & 1) == 0) {
-+ s->cmos_index = data & 0x7f;
-+ } else {
-+#ifdef DEBUG_CMOS
-+ printf("cmos: write index=0x%02x val=0x%02x\n",
-+ s->cmos_index, data);
-+#endif
-+ s->cmos_data[s->cmos_index] = data;
-+ }
-+}
-+
-+static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
-+{
-+ RTCState *s = opaque;
-+ int ret;
-+ if ((addr & 1) == 0) {
-+ return 0xff;
-+ } else {
-+ ret = s->cmos_data[s->cmos_index];
-+#ifdef DEBUG_CMOS
-+ printf("cmos: read index=0x%02x val=0x%02x\n",
-+ s->cmos_index, ret);
-+#endif
-+ return ret;
-+ }
-+}
-+
-+static void rtc_save(QEMUFile *f, void *opaque)
-+{
-+ RTCState *s = opaque;
-+
-+ qemu_put_buffer(f, s->cmos_data, 128);
-+ qemu_put_8s(f, &s->cmos_index);
-+}
-+
-+static int rtc_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ RTCState *s = opaque;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+
-+ qemu_get_buffer(f, s->cmos_data, 128);
-+ qemu_get_8s(f, &s->cmos_index);
-+
-+ return 0;
-+}
-+
-+RTCState *rtc_init(int base, int irq)
-+{
-+ RTCState *s;
-+ time_t ti;
-+ struct tm *tm;
-+ int val;
-+
-+ s = qemu_mallocz(sizeof(RTCState));
-+ if (!s)
-+ return NULL;
-+
-+/* PC cmos mappings */
-+#define REG_IBM_CENTURY_BYTE 0x32
-+#define REG_IBM_PS2_CENTURY_BYTE 0x37
-+ time(&ti);
-+ tm = gmtime(&ti); /* XXX localtime and update from guest? */
-+ val = to_bcd(s, (tm->tm_year / 100) + 19);
-+ rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
-+ rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
-+
-+ register_ioport_write(base, 2, 1, cmos_ioport_write, s);
-+ register_ioport_read(base, 2, 1, cmos_ioport_read, s);
-+
-+ register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
-+ return s;
-+}
-+
-+void rtc_set_date(RTCState *s, const struct tm *tm) {}
diff --git a/tools/ioemu/patches/ide-cd-dma b/tools/ioemu/patches/ide-cd-dma
deleted file mode 100644
index 875f27786f..0000000000
--- a/tools/ioemu/patches/ide-cd-dma
+++ /dev/null
@@ -1,23 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID 1e8ba8d2117548d4f13b7b438d1e992b1815f580
-# Parent f247e0b52dda257c0000c9da5a0cdff507b3ced8
-[HVM] Enable DMA mode for CD-ROM IDE ATAPI interface.
-Signed-off-by: Winston Wang <winston.l.wang@intel.com
-
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-03 15:07:16.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-03 15:07:16.000000000 +0100
-@@ -713,9 +713,9 @@
- padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
- padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
- put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
-- put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
-+ put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
- put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
-- put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
-+ put_le16(p + 63, 0x07); /* mdma0-2 supported */
- put_le16(p + 64, 1); /* PIO modes */
- put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
- put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
diff --git a/tools/ioemu/patches/ide-error-reporting b/tools/ioemu/patches/ide-error-reporting
deleted file mode 100644
index cb5ecaf6ea..0000000000
--- a/tools/ioemu/patches/ide-error-reporting
+++ /dev/null
@@ -1,81 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID fd28a1b139dea91b8bfcf06dd233dbdda8f51ff1
-# Parent d8befb109c394c2c2d3e1870a500107d461724ef
-[QEMU] Error reporting in IDE device model.
-
-Following on from my patch to make blktap report I/O errors back to
-guest OS, a similar problem exists in the QEMU codebase. The IDE
-driver never reports I/O errors during read/write operations back to
-the guest OS. Instead all I/O operations are reported as
-succesfull. If, for example, the host FS holding the disk image fills
-up, then writes may fail due to lack of space. Since the guest OS
-never sees these failures, it assumes all is well & will continue
-writing. Eventually this can lead to severe & unrecoverable filesystem
-corruption.
-
-The attached patch fixes QEMU ide driver such that any failure of a
-read or write operation sets the appropriate IDE status/error
-registers. Having read the ATA-6 spec I think the most compliant
-behaviour is to set the status register to 'READY_STAT | ERR_STAT',
-and the error register to ABRT_ERR. There is already a convenience
-function ide_abort_command() in the QEMU codebase which does just
-this, so the attached patch simply calls that function.
-
-With this patch the guest OS sees the I/O failure & the kernel logs
-IDE errors and then retries the operation. This at least ensures that
-the guest can be shutdown the out of space issue in the host corrected
-and the guest restarted, without any serious filesystem damage having
-occurred.
-
-From: Daniel Berrange <berrange@redhat.com>
-Signed-off-by: Keir Fraser <keir@xensource.com>
-
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-03 20:38:33.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-03 20:45:33.000000000 +0100
-@@ -767,7 +767,7 @@
- static void ide_sector_read(IDEState *s)
- {
- int64_t sector_num;
-- int ret, n;
-+ int n;
-
- s->status = READY_STAT | SEEK_STAT;
- s->error = 0; /* not needed by IDE spec, but needed by Windows */
-@@ -782,7 +782,11 @@
- #endif
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
-- ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
-+ if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) {
-+ ide_abort_command(s);
-+ ide_set_irq(s);
-+ return;
-+ }
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
- ide_set_irq(s);
- ide_set_sector(s, sector_num + n);
-@@ -899,7 +903,7 @@
- static void ide_sector_write(IDEState *s)
- {
- int64_t sector_num;
-- int ret, n, n1;
-+ int n, n1;
-
- s->status = READY_STAT | SEEK_STAT;
- sector_num = ide_get_sector(s);
-@@ -909,7 +913,11 @@
- n = s->nsector;
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
-- ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
-+ if (bdrv_write(s->bs, sector_num, s->io_buffer, n) != 0) {
-+ ide_abort_command(s);
-+ ide_set_irq(s);
-+ return;
-+ }
- s->nsector -= n;
- if (s->nsector == 0) {
- /* no more sector to write */
diff --git a/tools/ioemu/patches/ide-hd-multithread b/tools/ioemu/patches/ide-hd-multithread
deleted file mode 100644
index e70c8d3e17..0000000000
--- a/tools/ioemu/patches/ide-hd-multithread
+++ /dev/null
@@ -1,224 +0,0 @@
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-03 15:03:18.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-03 15:06:48.000000000 +0100
-@@ -22,6 +22,7 @@
- * THE SOFTWARE.
- */
- #include "vl.h"
-+#include <pthread.h>
-
- /* debug IDE devices */
- //#define DEBUG_IDE
-@@ -390,6 +391,89 @@
- int type; /* see IDE_TYPE_xxx */
- } PCIIDEState;
-
-+#define DMA_MULTI_THREAD
-+
-+#ifdef DMA_MULTI_THREAD
-+
-+static pthread_t ide_dma_thread;
-+static int file_pipes[2];
-+
-+static void ide_dma_loop(BMDMAState *bm);
-+static void dma_thread_loop(BMDMAState *bm);
-+
-+extern int suspend_requested;
-+static void *dma_thread_func(void* opaque)
-+{
-+ BMDMAState* req;
-+ fd_set fds;
-+ int rv, nfds = file_pipes[0] + 1;
-+ struct timeval tm;
-+
-+ while (1) {
-+
-+ /* Wait at most a second for the pipe to become readable */
-+ FD_ZERO(&fds);
-+ FD_SET(file_pipes[0], &fds);
-+ tm.tv_sec = 1;
-+ tm.tv_usec = 0;
-+ rv = select(nfds, &fds, NULL, NULL, &tm);
-+
-+ if (rv != 0) {
-+ if (read(file_pipes[0], &req, sizeof(req)) == 0)
-+ return NULL;
-+ dma_thread_loop(req);
-+ } else {
-+ if (suspend_requested) {
-+ /* Need to tidy up the DMA thread so that we don't end up
-+ * finishing operations after the domain's ioreqs are
-+ * drained and its state saved */
-+ return NULL;
-+ }
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+static void dma_create_thread(void)
-+{
-+ int rt;
-+ pthread_attr_t a;
-+
-+ if (pipe(file_pipes) != 0) {
-+ fprintf(stderr, "create pipe failed\n");
-+ exit(1);
-+ }
-+
-+ if ((rt = pthread_attr_init(&a))
-+ || (rt = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_JOINABLE))) {
-+ fprintf(stderr, "Oops, dma thread attr setup failed, errno=%d\n", rt);
-+ exit(1);
-+ }
-+
-+ if ((rt = pthread_create(&ide_dma_thread, &a, dma_thread_func, NULL))) {
-+ fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt);
-+ exit(1);
-+ }
-+}
-+
-+void ide_stop_dma_thread(void)
-+{
-+ int rc;
-+ /* Make sure the IDE DMA thread is stopped */
-+ if ( (rc = pthread_join(ide_dma_thread, NULL)) != 0 )
-+ {
-+ fprintf(stderr, "Oops, error collecting IDE DMA thread (%s)\n",
-+ strerror(rc));
-+ }
-+}
-+
-+#else
-+void ide_stop_dma_thread(void)
-+{
-+}
-+#endif /* DMA_MULTI_THREAD */
-+
- static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
-
- static void padstr(char *str, const char *src, int len)
-@@ -695,7 +779,9 @@
- }
- if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
- s->status = READY_STAT | SEEK_STAT;
-+#ifndef DMA_MULTI_THREAD
- ide_set_irq(s);
-+#endif /* !DMA_MULTI_THREAD */
- #ifdef DEBUG_IDE_ATAPI
- printf("dma status=0x%x\n", s->status);
- #endif
-@@ -795,7 +881,11 @@
- qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
- } else
- #endif
-+#ifndef DMA_MULTI_THREAD
- ide_set_irq(s);
-+#else /* !DMA_MULTI_THREAD */
-+ ;
-+#endif /* DMA_MULTI_THREAD */
- return 0;
- }
- if (n > MAX_MULT_SECTORS)
-@@ -1046,7 +1136,9 @@
- if (s->packet_transfer_size <= 0) {
- s->status = READY_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
-+#ifndef DMA_MULTI_THREAD
- ide_set_irq(s);
-+#endif /* !DMA_MULTI_THREAD */
- #ifdef DEBUG_IDE_ATAPI
- printf("dma status=0x%x\n", s->status);
- #endif
-@@ -2103,9 +2195,30 @@
- }
- }
-
-+static void ide_dma_finish(BMDMAState *bm)
-+{
-+ IDEState *s = bm->ide_if;
-+
-+ bm->status &= ~BM_STATUS_DMAING;
-+ bm->status |= BM_STATUS_INT;
-+ bm->dma_cb = NULL;
-+ bm->ide_if = NULL;
-+#ifdef DMA_MULTI_THREAD
-+ ide_set_irq(s);
-+#endif /* DMA_MULTI_THREAD */
-+}
-+
- /* XXX: full callback usage to prepare non blocking I/Os support -
- error handling */
-+#ifdef DMA_MULTI_THREAD
-+static void ide_dma_loop(BMDMAState *bm)
-+{
-+ write(file_pipes[1], &bm, sizeof(bm));
-+}
-+static void dma_thread_loop(BMDMAState *bm)
-+#else /* DMA_MULTI_THREAD */
- static void ide_dma_loop(BMDMAState *bm)
-+#endif /* !DMA_MULTI_THREAD */
- {
- struct {
- uint32_t addr;
-@@ -2141,10 +2254,7 @@
- }
- /* end of transfer */
- the_end:
-- bm->status &= ~BM_STATUS_DMAING;
-- bm->status |= BM_STATUS_INT;
-- bm->dma_cb = NULL;
-- bm->ide_if = NULL;
-+ ide_dma_finish(bm);
- }
-
- static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
-@@ -2370,6 +2480,9 @@
- cmd646_set_irq, d, 0);
- ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
- cmd646_set_irq, d, 1);
-+#ifdef DMA_MULTI_THREAD
-+ dma_create_thread();
-+#endif /* DMA_MULTI_THREAD */
- }
-
- static void pci_ide_save(QEMUFile* f, void *opaque)
-@@ -2522,6 +2635,10 @@
-
- register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
- register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
-+
-+#ifdef DMA_MULTI_THREAD
-+ dma_create_thread();
-+#endif //DMA_MULTI_THREAD
- }
-
- /***********************************************************/
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- ioemu.orig/target-i386-dm/helper2.c 2007-05-03 15:03:18.000000000 +0100
-+++ ioemu/target-i386-dm/helper2.c 2007-05-03 15:06:41.000000000 +0100
-@@ -556,6 +556,9 @@
- handle_buffered_io(env);
- main_loop_wait(1); /* For the select() on events */
-
-+ /* Stop the IDE thread */
-+ ide_stop_dma_thread();
-+
- /* Save the device state */
- sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid);
- if (qemu_savevm(qemu_file) < 0)
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 15:03:18.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 15:06:42.000000000 +0100
-@@ -797,6 +797,7 @@
- void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
- int pmac_ide_init (BlockDriverState **hd_table,
- SetIRQFunc *set_irq, void *irq_opaque, int irq);
-+void ide_stop_dma_thread(void);
-
- /* cdrom.c */
- int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
diff --git a/tools/ioemu/patches/ioemu-buffer-pio-ia64 b/tools/ioemu/patches/ioemu-buffer-pio-ia64
deleted file mode 100644
index d5a216b68e..0000000000
--- a/tools/ioemu/patches/ioemu-buffer-pio-ia64
+++ /dev/null
@@ -1,224 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:34:24.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:34:24.000000000 +0100
-@@ -6824,6 +6824,7 @@
- unsigned long ioreq_pfn;
- extern void *shared_page;
- extern void *buffered_io_page;
-+ extern void *buffered_pio_page;
- unsigned long nr_pages;
-
- char qemu_dm_logfilename[64];
-@@ -7521,6 +7522,10 @@
- PROT_READ|PROT_WRITE,
- BUFFER_IO_PAGE_START >> PAGE_SHIFT);
-
-+ buffered_pio_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-+ PROT_READ|PROT_WRITE,
-+ BUFFER_PIO_PAGE_START >> PAGE_SHIFT);
-+
- for (i = 0; i < nr_pages; i++)
- page_array[i] = i;
-
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-10 15:32:53.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-10 15:34:24.000000000 +0100
-@@ -393,6 +393,121 @@
- int type; /* see IDE_TYPE_xxx */
- } PCIIDEState;
-
-+#if defined(__ia64__)
-+#include <xen/hvm/ioreq.h>
-+
-+struct buffered_piopage *buffered_pio_page;
-+
-+static inline struct pio_buffer *
-+piobuf_by_addr(uint32_t addr)
-+{
-+ if (addr == 0x1F0)
-+ return &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
-+ if (addr == 0x170)
-+ return &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
-+ return NULL;
-+}
-+
-+static void
-+buffered_pio_init(void)
-+{
-+ struct pio_buffer *p1, *p2;
-+ uint32_t off1, off2;
-+
-+ if (!buffered_pio_page)
-+ return;
-+
-+ p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
-+ p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
-+ off1 = offsetof(struct buffered_piopage, buffer);
-+ off2 = (off1 + TARGET_PAGE_SIZE)/2;
-+
-+ p1->buf_size = off2 - off1;
-+ p1->page_offset = off1;
-+
-+ p2->buf_size = TARGET_PAGE_SIZE - off2;
-+ p2->page_offset = off2;
-+}
-+
-+static inline void
-+buffered_pio_flush(struct pio_buffer *piobuf)
-+{
-+ IDEState *s = piobuf->opaque;
-+ uint32_t pointer = piobuf->pointer;
-+
-+ if (s != NULL && pointer > 0) {
-+ uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
-+ memcpy(s->data_ptr, buf, pointer);
-+ s->data_ptr += pointer;
-+ }
-+}
-+
-+static inline void
-+buffered_pio_reset(IDEState *s)
-+{
-+ struct pio_buffer *piobuf;
-+
-+ if ((unsigned)s->drive_serial - 1 < 2) /* 1,2 */
-+ piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
-+ else if ((unsigned)s->drive_serial - 3 < 2) /* 3,4 */
-+ piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
-+ else
-+ return;
-+ buffered_pio_flush(piobuf);
-+ piobuf->pointer = 0;
-+ piobuf->data_end = 0;
-+ piobuf->opaque = NULL;
-+}
-+
-+static inline void
-+buffered_pio_write(IDEState *s, uint32_t addr, int size)
-+{
-+ struct pio_buffer *piobuf = piobuf_by_addr(addr);
-+ int data_end;
-+
-+ if (!piobuf)
-+ return;
-+ buffered_pio_flush(piobuf);
-+ data_end = s->data_end - s->data_ptr - size;
-+ if (data_end <= 0)
-+ data_end = 0;
-+ else if (data_end > piobuf->buf_size)
-+ data_end = piobuf->buf_size;
-+ piobuf->pointer = 0;
-+ piobuf->data_end = data_end;
-+ piobuf->opaque = s;
-+}
-+
-+static inline void
-+buffered_pio_read(IDEState *s, uint32_t addr, int size)
-+{
-+ struct pio_buffer *piobuf = piobuf_by_addr(addr);
-+ int data_end;
-+
-+ if (!piobuf)
-+ return;
-+ s->data_ptr += piobuf->pointer;
-+ data_end = s->data_end - s->data_ptr - size;
-+ if (data_end <= 0) {
-+ data_end = 0;
-+ } else {
-+ uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
-+ if (data_end > piobuf->buf_size)
-+ data_end = piobuf->buf_size;
-+ memcpy(buf, s->data_ptr + size, data_end);
-+ }
-+ piobuf->pointer = 0;
-+ piobuf->data_end = data_end;
-+ piobuf->opaque = NULL;
-+}
-+
-+#else /* !__ia64__ */
-+#define buffered_pio_init() do {} while (0)
-+#define buffered_pio_reset(I) do {} while (0)
-+#define buffered_pio_write(I,A,S) do {} while (0)
-+#define buffered_pio_read(I,A,S) do {} while (0)
-+#endif
-+
- static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
- static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
-
-@@ -587,6 +702,7 @@
- s->data_ptr = buf;
- s->data_end = buf + size;
- s->status |= DRQ_STAT;
-+ buffered_pio_reset(s);
- }
-
- static void ide_transfer_stop(IDEState *s)
-@@ -595,6 +711,7 @@
- s->data_ptr = s->io_buffer;
- s->data_end = s->io_buffer;
- s->status &= ~DRQ_STAT;
-+ buffered_pio_reset(s);
- }
-
- static int64_t ide_get_sector(IDEState *s)
-@@ -1596,6 +1713,7 @@
- ide_if[0].select = (val & ~0x10) | 0xa0;
- ide_if[1].select = (val | 0x10) | 0xa0;
- /* select drive */
-+ buffered_pio_reset(ide_if->cur_drive);
- unit = (val >> 4) & 1;
- s = ide_if + unit;
- ide_if->cur_drive = s;
-@@ -1954,6 +2072,7 @@
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
-
-+ buffered_pio_write(s, addr, 2);
- p = s->data_ptr;
- *(uint16_t *)p = le16_to_cpu(val);
- p += 2;
-@@ -1967,6 +2086,8 @@
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
- int ret;
-+
-+ buffered_pio_read(s, addr, 2);
- p = s->data_ptr;
- ret = cpu_to_le16(*(uint16_t *)p);
- p += 2;
-@@ -1981,6 +2102,7 @@
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
-
-+ buffered_pio_write(s, addr, 4);
- p = s->data_ptr;
- *(uint32_t *)p = le32_to_cpu(val);
- p += 4;
-@@ -1995,6 +2117,7 @@
- uint8_t *p;
- int ret;
-
-+ buffered_pio_read(s, addr, 4);
- p = s->data_ptr;
- ret = cpu_to_le32(*(uint32_t *)p);
- p += 4;
-@@ -2624,6 +2747,8 @@
- ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
- ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
-
-+ buffered_pio_init();
-+
- register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
- }
-
-@@ -2663,6 +2788,8 @@
- ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
- ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
-
-+ buffered_pio_init();
-+
- register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
- }
-
diff --git a/tools/ioemu/patches/ioemu-ia64 b/tools/ioemu/patches/ioemu-ia64
deleted file mode 100644
index bfa8bd7267..0000000000
--- a/tools/ioemu/patches/ioemu-ia64
+++ /dev/null
@@ -1,93 +0,0 @@
-Index: ioemu/hw/iommu.c
-===================================================================
---- ioemu.orig/hw/iommu.c 2007-05-11 10:00:33.000000000 +0100
-+++ ioemu/hw/iommu.c 2007-05-11 10:01:09.000000000 +0100
-@@ -82,7 +82,11 @@
- #define IOPTE_VALID 0x00000002 /* IOPTE is valid */
- #define IOPTE_WAZ 0x00000001 /* Write as zeros */
-
-+#if defined(__i386__) || defined(__x86_64__)
- #define PAGE_SHIFT 12
-+#elif defined(__ia64__)
-+#define PAGE_SHIFT 14
-+#endif
- #define PAGE_SIZE (1 << PAGE_SHIFT)
- #define PAGE_MASK (PAGE_SIZE - 1)
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-11 10:01:09.000000000 +0100
-+++ ioemu/vl.c 2007-05-11 10:01:09.000000000 +0100
-@@ -7149,6 +7149,11 @@
- }
- #endif
-
-+#if defined (__ia64__)
-+ if (ram_size > MMIO_START)
-+ ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
-+#endif
-+
- /* init the memory */
- phys_ram_size = ram_size + vga_ram_size + bios_size;
-
-@@ -7198,6 +7203,44 @@
-
- free(page_array);
-
-+#elif defined(__ia64__)
-+
-+ nr_pages = ram_size/PAGE_SIZE;
-+
-+ page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
-+ if (page_array == NULL) {
-+ fprintf(logfile, "malloc returned error %d\n", errno);
-+ exit(-1);
-+ }
-+
-+ shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-+ PROT_READ|PROT_WRITE,
-+ IO_PAGE_START >> PAGE_SHIFT);
-+
-+ buffered_io_page =xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-+ PROT_READ|PROT_WRITE,
-+ BUFFER_IO_PAGE_START >> PAGE_SHIFT);
-+
-+ for (i = 0; i < nr_pages; i++)
-+ page_array[i] = i;
-+
-+ /* VTI will not use memory between 3G~4G, so we just pass a legal pfn
-+ to make QEMU map continuous virtual memory space */
-+ if (ram_size > MMIO_START) {
-+ for (i = 0 ; i < (MEM_G >> PAGE_SHIFT); i++)
-+ page_array[(MMIO_START >> PAGE_SHIFT) + i] =
-+ (STORE_PAGE_START >> PAGE_SHIFT);
-+ }
-+
-+ phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
-+ PROT_READ|PROT_WRITE,
-+ page_array, nr_pages);
-+ if (phys_ram_base == 0) {
-+ fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
-+ exit(-1);
-+ }
-+ free(page_array);
-+#endif
- #else /* !CONFIG_DM */
-
- phys_ram_base = qemu_vmalloc(phys_ram_size);
-Index: ioemu/target-i386-dm/cpu.h
-===================================================================
---- ioemu.orig/target-i386-dm/cpu.h 2007-05-11 10:01:09.000000000 +0100
-+++ ioemu/target-i386-dm/cpu.h 2007-05-11 10:01:09.000000000 +0100
-@@ -78,7 +78,11 @@
- /* helper2.c */
- int main_loop(void);
-
-+#if defined(__i386__) || defined(__x86_64__)
- #define TARGET_PAGE_BITS 12
-+#elif defined(__ia64__)
-+#define TARGET_PAGE_BITS 14
-+#endif
- #include "cpu-all.h"
-
- #endif /* CPU_I386_H */
diff --git a/tools/ioemu/patches/ioemu-save-restore b/tools/ioemu/patches/ioemu-save-restore
deleted file mode 100644
index 7978b53271..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore
+++ /dev/null
@@ -1,180 +0,0 @@
-Index: ioemu/hw/cirrus_vga.c
-===================================================================
---- ioemu.orig/hw/cirrus_vga.c 2007-05-09 14:09:12.000000000 +0100
-+++ ioemu/hw/cirrus_vga.c 2007-05-09 14:10:58.000000000 +0100
-@@ -3016,11 +3016,42 @@
- cirrus_mmio_writel,
- };
-
-+void cirrus_stop_acc(CirrusVGAState *s)
-+{
-+ if (s->map_addr){
-+ int error;
-+ s->map_addr = 0;
-+ error = unset_vram_mapping(s->cirrus_lfb_addr,
-+ s->cirrus_lfb_end, s->vram_ptr);
-+ fprintf(stderr, "cirrus_stop_acc:unset_vram_mapping.\n");
-+ }
-+}
-+
-+void cirrus_restart_acc(CirrusVGAState *s)
-+{
-+ if (s->cirrus_lfb_addr && s->cirrus_lfb_end) {
-+ void *vram_pointer, *old_vram;
-+ fprintf(stderr, "cirrus_vga_load:re-enable vga acc.lfb_addr=0x%lx, lfb_end=0x%lx.\n",
-+ s->cirrus_lfb_addr, s->cirrus_lfb_end);
-+ vram_pointer = set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
-+ if (!vram_pointer){
-+ fprintf(stderr, "cirrus_vga_load:NULL vram_pointer\n");
-+ } else {
-+ old_vram = vga_update_vram((VGAState *)s, vram_pointer,
-+ VGA_RAM_SIZE);
-+ qemu_free(old_vram);
-+ s->map_addr = s->cirrus_lfb_addr;
-+ s->map_end = s->cirrus_lfb_end;
-+ }
-+ }
-+}
-+
- /* load/save state */
-
- static void cirrus_vga_save(QEMUFile *f, void *opaque)
- {
- CirrusVGAState *s = opaque;
-+ uint8_t vga_acc;
-
- if (s->pci_dev)
- pci_device_save(s->pci_dev, f);
-@@ -3058,11 +3089,20 @@
- qemu_put_be32s(f, &s->hw_cursor_y);
- /* XXX: we do not save the bitblt state - we assume we do not save
- the state when the blitter is active */
-+
-+ vga_acc = (!!s->map_addr);
-+ qemu_put_8s(f, &vga_acc);
-+ qemu_put_be64s(f, (uint64_t*)&s->cirrus_lfb_addr);
-+ qemu_put_be64s(f, (uint64_t*)&s->cirrus_lfb_end);
-+ qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
-+ if (vga_acc)
-+ cirrus_stop_acc(s);
- }
-
- static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
- {
- CirrusVGAState *s = opaque;
-+ uint8_t vga_acc = 0;
- int ret;
-
- if (version_id > 2)
-@@ -3108,6 +3148,14 @@
- qemu_get_be32s(f, &s->hw_cursor_x);
- qemu_get_be32s(f, &s->hw_cursor_y);
-
-+ qemu_get_8s(f, &vga_acc);
-+ qemu_get_be64s(f, (uint64_t*)&s->cirrus_lfb_addr);
-+ qemu_get_be64s(f, (uint64_t*)&s->cirrus_lfb_end);
-+ qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
-+ if (vga_acc){
-+ cirrus_restart_acc(s);
-+ }
-+
- /* force refresh */
- s->graphic_mode = -1;
- cirrus_update_bank_ptr(s, 0);
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-09 14:09:12.000000000 +0100
-+++ ioemu/vl.c 2007-05-09 14:10:50.000000000 +0100
-@@ -5025,6 +5025,11 @@
- if (ret < 0) {
- term_printf("Error %d while loading VM state\n", ret);
- }
-+
-+ /* del tmp file */
-+ if (unlink(name) == -1)
-+ fprintf(stderr, "delete tmp qemu state file failed.\n");
-+
- the_end:
- if (saved_vm_running)
- vm_start();
-@@ -5942,6 +5947,7 @@
- static QEMUResetEntry *first_reset_entry;
- int reset_requested;
- int shutdown_requested;
-+int suspend_requested;
- static int powerdown_requested;
-
- void qemu_register_reset(QEMUResetHandler *func, void *opaque)
-@@ -6731,6 +6737,15 @@
- return 0;
- }
-
-+void suspend(int sig)
-+{
-+ fprintf(logfile, "suspend sig handler called with requested=%d!\n",
-+ suspend_requested);
-+ if (sig != SIGUSR1)
-+ fprintf(logfile, "suspend signal dismatch, get sig=%d!\n", sig);
-+ suspend_requested = 1;
-+}
-+
- int main(int argc, char **argv)
- {
- #ifdef CONFIG_GDBSTUB
-@@ -7625,6 +7640,25 @@
- close(fd);
- }
-
-+ /* register signal for the suspend request when save */
-+ {
-+ struct sigaction act;
-+ sigset_t set;
-+ act.sa_handler = suspend;
-+ act.sa_flags = SA_RESTART;
-+ sigemptyset(&act.sa_mask);
-+
-+ sigaction(SIGUSR1, &act, NULL);
-+
-+ /* control panel mask some signals when spawn qemu, need unmask here*/
-+ sigemptyset(&set);
-+ sigaddset(&set, SIGUSR1);
-+ sigaddset(&set, SIGTERM);
-+ if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
-+ fprintf(stderr, "unblock signal fail, possible issue for HVM save!\n");
-+
-+ }
-+
- main_loop();
- quit_timers();
- return 0;
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- ioemu.orig/target-i386-dm/helper2.c 2007-05-09 14:09:11.000000000 +0100
-+++ ioemu/target-i386-dm/helper2.c 2007-05-09 14:10:49.000000000 +0100
-@@ -540,8 +540,10 @@
- {
- extern int vm_running;
- extern int shutdown_requested;
-+ extern int suspend_requested;
- CPUState *env = cpu_single_env;
- int evtchn_fd = xc_evtchn_fd(xce_handle);
-+ char qemu_file[20];
-
- qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
-
-@@ -549,7 +551,14 @@
- /* Wait up to 10 msec. */
- main_loop_wait(10);
-
-- destroy_hvm_domain();
-+ fprintf(logfile, "device model received suspend signal!\n");
-+
-+ /* Pull all outstanding ioreqs through the system */
-+ main_loop_wait(1); /* For the select() on events */
-+
-+ /* Save the device state */
-+ sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid);
-+ do_savevm(qemu_file);
-
- return 0;
- }
diff --git a/tools/ioemu/patches/ioemu-save-restore-acpi b/tools/ioemu/patches/ioemu-save-restore-acpi
deleted file mode 100644
index b367c5656c..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-acpi
+++ /dev/null
@@ -1,38 +0,0 @@
-Index: ioemu/hw/piix4acpi.c
-===================================================================
---- ioemu.orig/hw/piix4acpi.c 2007-05-09 13:54:28.000000000 +0100
-+++ ioemu/hw/piix4acpi.c 2007-05-09 13:54:41.000000000 +0100
-@@ -57,6 +57,26 @@
- uint16_t pm1_control; /* pm1a_ECNT_BLK */
- } PCIAcpiState;
-
-+static void piix4acpi_save(QEMUFile *f, void *opaque)
-+{
-+ PCIAcpiState *s = opaque;
-+ pci_device_save(&s->dev, f);
-+ qemu_put_be16s(f, &s->pm1_control);
-+}
-+
-+static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ PCIAcpiState *s = opaque;
-+ int ret;
-+ if (version_id > 1)
-+ return -EINVAL;
-+ ret = pci_device_load(&s->dev, f);
-+ if (ret < 0)
-+ return ret;
-+ qemu_get_be16s(f, &s->pm1_control);
-+ return 0;
-+}
-+
- static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
- {
- PCIAcpiState *s = opaque;
-@@ -193,4 +213,6 @@
- d->pm1_control = SCI_EN;
-
- acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
-+
-+ register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);
- }
diff --git a/tools/ioemu/patches/ioemu-save-restore-ide b/tools/ioemu/patches/ioemu-save-restore-ide
deleted file mode 100644
index 1177091ac5..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-ide
+++ /dev/null
@@ -1,137 +0,0 @@
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-03 19:24:12.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-03 19:24:43.000000000 +0100
-@@ -2623,9 +2623,124 @@
- ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
- ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
-
-+ register_savevm("ide_pci", 0, 1, pci_device_save, pci_device_load, d);
- register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
- }
-
-+static void pci_ide_save(QEMUFile* f, void *opaque)
-+{
-+ PCIIDEState *d = opaque;
-+ int i;
-+
-+ for(i = 0; i < 2; i++) {
-+ BMDMAState *bm = &d->bmdma[i];
-+ qemu_put_8s(f, &bm->cmd);
-+ qemu_put_8s(f, &bm->status);
-+ qemu_put_be32s(f, &bm->addr);
-+ /* XXX: if a transfer is pending, we do not save it yet */
-+ }
-+
-+ /* per IDE interface data */
-+ for(i = 0; i < 2; i++) {
-+ IDEState *s = &d->ide_if[i * 2];
-+ uint8_t drive1_selected;
-+ qemu_put_8s(f, &s->cmd);
-+ drive1_selected = (s->cur_drive != s);
-+ qemu_put_8s(f, &drive1_selected);
-+ }
-+
-+ /* per IDE drive data */
-+ for(i = 0; i < 4; i++) {
-+ IDEState *s = &d->ide_if[i];
-+ qemu_put_be32s(f, &s->mult_sectors);
-+ qemu_put_be32s(f, &s->identify_set);
-+ if (s->identify_set) {
-+ qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
-+ }
-+ qemu_put_8s(f, &s->write_cache);
-+ qemu_put_8s(f, &s->feature);
-+ qemu_put_8s(f, &s->error);
-+ qemu_put_be32s(f, &s->nsector);
-+ qemu_put_8s(f, &s->sector);
-+ qemu_put_8s(f, &s->lcyl);
-+ qemu_put_8s(f, &s->hcyl);
-+ qemu_put_8s(f, &s->hob_feature);
-+ qemu_put_8s(f, &s->hob_nsector);
-+ qemu_put_8s(f, &s->hob_sector);
-+ qemu_put_8s(f, &s->hob_lcyl);
-+ qemu_put_8s(f, &s->hob_hcyl);
-+ qemu_put_8s(f, &s->select);
-+ qemu_put_8s(f, &s->status);
-+ qemu_put_8s(f, &s->lba48);
-+
-+ qemu_put_8s(f, &s->sense_key);
-+ qemu_put_8s(f, &s->asc);
-+ /* XXX: if a transfer is pending, we do not save it yet */
-+ }
-+}
-+
-+static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
-+{
-+ PCIIDEState *d = opaque;
-+ int ret, i;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+
-+ for(i = 0; i < 2; i++) {
-+ BMDMAState *bm = &d->bmdma[i];
-+ qemu_get_8s(f, &bm->cmd);
-+ qemu_get_8s(f, &bm->status);
-+ qemu_get_be32s(f, &bm->addr);
-+ /* XXX: if a transfer is pending, we do not save it yet */
-+ }
-+
-+ /* per IDE interface data */
-+ for(i = 0; i < 2; i++) {
-+ IDEState *s = &d->ide_if[i * 2];
-+ uint8_t drive1_selected;
-+ qemu_get_8s(f, &s->cmd);
-+ qemu_get_8s(f, &drive1_selected);
-+ s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
-+ }
-+
-+ /* per IDE drive data */
-+ for(i = 0; i < 4; i++) {
-+ IDEState *s = &d->ide_if[i];
-+ qemu_get_be32s(f, &s->mult_sectors);
-+ qemu_get_be32s(f, &s->identify_set);
-+ if (s->identify_set) {
-+ qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
-+ }
-+ qemu_get_8s(f, &s->write_cache);
-+ qemu_get_8s(f, &s->feature);
-+ qemu_get_8s(f, &s->error);
-+ qemu_get_be32s(f, &s->nsector);
-+ qemu_get_8s(f, &s->sector);
-+ qemu_get_8s(f, &s->lcyl);
-+ qemu_get_8s(f, &s->hcyl);
-+ qemu_get_8s(f, &s->hob_feature);
-+ qemu_get_8s(f, &s->hob_nsector);
-+ qemu_get_8s(f, &s->hob_sector);
-+ qemu_get_8s(f, &s->hob_lcyl);
-+ qemu_get_8s(f, &s->hob_hcyl);
-+ qemu_get_8s(f, &s->select);
-+ qemu_get_8s(f, &s->status);
-+ qemu_get_8s(f, &s->lba48);
-+
-+ qemu_get_8s(f, &s->sense_key);
-+ qemu_get_8s(f, &s->asc);
-+ /* XXX: if a transfer is pending, we do not save it yet */
-+ if (s->status & (DRQ_STAT|BUSY_STAT)) {
-+ /* Tell the guest that its transfer has gone away */
-+ ide_abort_command(s);
-+ ide_set_irq(s);
-+ }
-+ }
-+ return 0;
-+}
-+
-+
- /* hd_table must contain 4 block drivers */
- /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
- void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
-@@ -2662,6 +2777,7 @@
- ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
- ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
-
-+ register_savevm("ide_pci", 0, 1, pci_device_save, pci_device_load, d);
- register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
- }
-
diff --git a/tools/ioemu/patches/ioemu-save-restore-logdirty b/tools/ioemu/patches/ioemu-save-restore-logdirty
deleted file mode 100644
index 741e4feea1..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-logdirty
+++ /dev/null
@@ -1,190 +0,0 @@
-Index: ioemu/xenstore.c
-===================================================================
---- ioemu.orig/xenstore.c 2007-05-11 10:04:51.000000000 +0100
-+++ ioemu/xenstore.c 2007-05-11 10:04:52.000000000 +0100
-@@ -11,6 +11,11 @@
- #include "vl.h"
- #include "block_int.h"
- #include <unistd.h>
-+#include <sys/ipc.h>
-+#include <sys/shm.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-
- static struct xs_handle *xsh = NULL;
- static char *media_filename[MAX_DISKS];
-@@ -173,6 +178,13 @@
- }
- }
-
-+ /* Set a watch for log-dirty requests from the migration tools */
-+ if (pasprintf(&buf, "%s/logdirty/next-active", path) != -1) {
-+ xs_watch(xsh, buf, "logdirty");
-+ fprintf(logfile, "Watching %s\n", buf);
-+ }
-+
-+
- out:
- free(type);
- free(params);
-@@ -191,6 +203,112 @@
- return -1;
- }
-
-+unsigned long *logdirty_bitmap = NULL;
-+unsigned long logdirty_bitmap_size;
-+extern int vga_ram_size, bios_size;
-+
-+void xenstore_process_logdirty_event(void)
-+{
-+ char *act;
-+ static char *active_path = NULL;
-+ static char *next_active_path = NULL;
-+ static char *seg = NULL;
-+ unsigned int len;
-+ int i;
-+
-+ fprintf(logfile, "Triggered log-dirty buffer switch\n");
-+
-+ if (!seg) {
-+ char *path, *p, *key_ascii, key_terminated[17] = {0,};
-+ key_t key;
-+ int shmid;
-+
-+ /* Find and map the shared memory segment for log-dirty bitmaps */
-+ if (!(path = xs_get_domain_path(xsh, domid))) {
-+ fprintf(logfile, "Log-dirty: can't get domain path in store\n");
-+ exit(1);
-+ }
-+ if (!(path = realloc(path, strlen(path)
-+ + strlen("/logdirty/next-active") + 1))) {
-+ fprintf(logfile, "Log-dirty: out of memory\n");
-+ exit(1);
-+ }
-+ strcat(path, "/logdirty/");
-+ p = path + strlen(path);
-+ strcpy(p, "key");
-+
-+ key_ascii = xs_read(xsh, XBT_NULL, path, &len);
-+ if (!key_ascii) {
-+ /* No key yet: wait for the next watch */
-+ free(path);
-+ return;
-+ }
-+ strncpy(key_terminated, key_ascii, 16);
-+ free(key_ascii);
-+ key = (key_t) strtoull(key_terminated, NULL, 16);
-+
-+ /* Figure out how bit the log-dirty bitmaps are */
-+ logdirty_bitmap_size = xc_memory_op(xc_handle,
-+ XENMEM_maximum_gpfn, &domid) + 1;
-+ logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
-+ / HOST_LONG_BITS); /* longs */
-+ logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
-+
-+ /* Map the shared-memory segment */
-+ if ((shmid = shmget(key,
-+ 2 * logdirty_bitmap_size,
-+ S_IRUSR|S_IWUSR)) == -1
-+ || (seg = shmat(shmid, NULL, 0)) == (void *)-1) {
-+ fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n",
-+ (unsigned long long) key, strerror(errno));
-+ exit(1);
-+ }
-+
-+ fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
-+
-+ /* Double-check that the bitmaps are the size we expect */
-+ if (logdirty_bitmap_size != *(uint32_t *)seg) {
-+ fprintf(logfile, "Log-dirty: got %u, calc %lu\n",
-+ *(uint32_t *)seg, logdirty_bitmap_size);
-+ return;
-+ }
-+
-+ /* Remember the paths for the next-active and active entries */
-+ strcpy(p, "active");
-+ if (!(active_path = strdup(path))) {
-+ fprintf(logfile, "Log-dirty: out of memory\n");
-+ exit(1);
-+ }
-+ strcpy(p, "next-active");
-+ if (!(next_active_path = strdup(path))) {
-+ fprintf(logfile, "Log-dirty: out of memory\n");
-+ exit(1);
-+ }
-+ free(path);
-+ }
-+
-+ /* Read the required active buffer from the store */
-+ act = xs_read(xsh, XBT_NULL, next_active_path, &len);
-+ if (!act) {
-+ fprintf(logfile, "Log-dirty: can't read next-active\n");
-+ exit(1);
-+ }
-+
-+ /* Switch buffers */
-+ i = act[0] - '0';
-+ if (i != 0 && i != 1) {
-+ fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
-+ exit(1);
-+ }
-+ logdirty_bitmap = (unsigned long *)(seg + i * logdirty_bitmap_size);
-+
-+ /* Ack that we've switched */
-+ xs_write(xsh, XBT_NULL, active_path, act, len);
-+ free(act);
-+}
-+
-+
-+
- void xenstore_process_event(void *opaque)
- {
- char **vec, *image = NULL;
-@@ -200,6 +318,11 @@
- if (!vec)
- return;
-
-+ if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
-+ xenstore_process_logdirty_event();
-+ goto out;
-+ }
-+
- if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
- strlen(vec[XS_WATCH_TOKEN]) != 3)
- goto out;
-Index: ioemu/target-i386-dm/exec-dm.c
-===================================================================
---- ioemu.orig/target-i386-dm/exec-dm.c 2007-05-11 10:04:52.000000000 +0100
-+++ ioemu/target-i386-dm/exec-dm.c 2007-05-11 10:04:52.000000000 +0100
-@@ -436,6 +436,9 @@
- #define phys_ram_addr(x) ((addr < ram_size) ? (phys_ram_base + (x)) : NULL)
- #endif
-
-+extern unsigned long *logdirty_bitmap;
-+extern unsigned long logdirty_bitmap_size;
-+
- void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
- {
-@@ -471,8 +474,19 @@
- l = 1;
- }
- } else if ((ptr = phys_ram_addr(addr)) != NULL) {
-- /* Reading from RAM */
-+ /* Writing to RAM */
- memcpy(ptr, buf, l);
-+ if (logdirty_bitmap != NULL) {
-+ /* Record that we have dirtied this frame */
-+ unsigned long pfn = addr >> TARGET_PAGE_BITS;
-+ if (pfn / 8 >= logdirty_bitmap_size) {
-+ fprintf(logfile, "dirtying pfn %lx >= bitmap "
-+ "size %lx\n", pfn, logdirty_bitmap_size * 8);
-+ } else {
-+ logdirty_bitmap[pfn / HOST_LONG_BITS]
-+ |= 1UL << pfn % HOST_LONG_BITS;
-+ }
-+ }
- #ifdef __ia64__
- sync_icache(ptr, l);
- #endif
diff --git a/tools/ioemu/patches/ioemu-save-restore-ne2000 b/tools/ioemu/patches/ioemu-save-restore-ne2000
deleted file mode 100644
index d86058342d..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-ne2000
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: ioemu/hw/ne2000.c
-===================================================================
---- ioemu.orig/hw/ne2000.c 2007-05-09 13:47:48.000000000 +0100
-+++ ioemu/hw/ne2000.c 2007-05-09 13:55:24.000000000 +0100
-@@ -750,7 +750,7 @@
- s->macaddr[4],
- s->macaddr[5]);
-
-- register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
-+ register_savevm("ne2000", base, 2, ne2000_save, ne2000_load, s);
- }
-
- /***********************************************************/
diff --git a/tools/ioemu/patches/ioemu-save-restore-pcnet b/tools/ioemu/patches/ioemu-save-restore-pcnet
deleted file mode 100644
index 835bb610c5..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-pcnet
+++ /dev/null
@@ -1,32 +0,0 @@
-Index: ioemu/hw/pcnet.c
-===================================================================
---- ioemu.orig/hw/pcnet.c 2007-05-09 13:47:20.000000000 +0100
-+++ ioemu/hw/pcnet.c 2007-05-09 13:47:53.000000000 +0100
-@@ -1824,13 +1824,15 @@
-
- static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
- {
-+ int instance;
-+
- d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
-
- d->nd = nd;
-
- d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
- pcnet_can_receive, d);
--
-+
- snprintf(d->vc->info_str, sizeof(d->vc->info_str),
- "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- d->nd->macaddr[0],
-@@ -1841,7 +1843,9 @@
- d->nd->macaddr[5]);
-
- pcnet_h_reset(d);
-- register_savevm("pcnet", 0, 2, pcnet_save, pcnet_load, d);
-+
-+ instance = pci_bus_num(d->dev.bus) << 8 | d->dev.devfn;
-+ register_savevm("pcnet", instance, 2, pcnet_save, pcnet_load, d);
- }
-
- /* PCI interface */
diff --git a/tools/ioemu/patches/ioemu-save-restore-rtl8139 b/tools/ioemu/patches/ioemu-save-restore-rtl8139
deleted file mode 100644
index 65ca34c00f..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-rtl8139
+++ /dev/null
@@ -1,23 +0,0 @@
-Index: ioemu/hw/rtl8139.c
-===================================================================
---- ioemu.orig/hw/rtl8139.c 2007-05-09 14:08:41.000000000 +0100
-+++ ioemu/hw/rtl8139.c 2007-05-09 14:09:34.000000000 +0100
-@@ -3414,6 +3414,7 @@
- PCIRTL8139State *d;
- RTL8139State *s;
- uint8_t *pci_conf;
-+ int instance;
-
- d = (PCIRTL8139State *)pci_register_device(bus,
- "RTL8139", sizeof(PCIRTL8139State),
-@@ -3464,8 +3465,8 @@
- s->cplus_txbuffer_len = 0;
- s->cplus_txbuffer_offset = 0;
-
-- /* XXX: instance number ? */
-- register_savevm("rtl8139", 0, 3, rtl8139_save, rtl8139_load, s);
-+ instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
-+ register_savevm("rtl8139", instance, 3, rtl8139_save, rtl8139_load, s);
-
- #if RTL8139_ONBOARD_TIMER
- s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
diff --git a/tools/ioemu/patches/ioemu-save-restore-timer b/tools/ioemu/patches/ioemu-save-restore-timer
deleted file mode 100644
index a430f81fe3..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-timer
+++ /dev/null
@@ -1,27 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:25:11.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:26:37.000000000 +0100
-@@ -915,10 +915,22 @@
- #ifdef CONFIG_DM
- static void timer_save(QEMUFile *f, void *opaque)
- {
-+ /* need timer for save/restoe qemu_timer in usb_uhci */
-+ if (cpu_ticks_enabled) {
-+ hw_error("cannot save state if virtual timers are running");
-+ }
-+ qemu_put_be64s(f, &cpu_clock_offset);
- }
-
- static int timer_load(QEMUFile *f, void *opaque, int version_id)
- {
-+ if (version_id != 1)
-+ return -EINVAL;
-+ if (cpu_ticks_enabled) {
-+ return -EINVAL;
-+ }
-+
-+ qemu_get_be64s(f, &cpu_clock_offset);
- return 0;
- }
- #else /* !CONFIG_DM */
diff --git a/tools/ioemu/patches/ioemu-save-restore-usb b/tools/ioemu/patches/ioemu-save-restore-usb
deleted file mode 100644
index 7565b89447..0000000000
--- a/tools/ioemu/patches/ioemu-save-restore-usb
+++ /dev/null
@@ -1,262 +0,0 @@
-Index: ioemu/hw/usb-hid.c
-===================================================================
---- ioemu.orig/hw/usb-hid.c 2007-05-09 14:10:50.000000000 +0100
-+++ ioemu/hw/usb-hid.c 2007-05-09 14:11:27.000000000 +0100
-@@ -510,6 +510,51 @@
- qemu_free(s);
- }
-
-+void usb_mouse_save(QEMUFile *f, void *opaque)
-+{
-+ USBMouseState *s = (USBMouseState*)opaque;
-+
-+ qemu_put_be32s(f, &s->dx);
-+ qemu_put_be32s(f, &s->dy);
-+ qemu_put_be32s(f, &s->dz);
-+ qemu_put_be32s(f, &s->buttons_state);
-+ qemu_put_be32s(f, &s->x);
-+ qemu_put_be32s(f, &s->y);
-+ qemu_put_be32s(f, &s->kind);
-+ qemu_put_be32s(f, &s->mouse_grabbed);
-+ qemu_put_be32s(f, &s->status_changed);
-+
-+}
-+
-+int usb_mouse_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ USBMouseState *s = (USBMouseState*)opaque;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+
-+ qemu_get_be32s(f, &s->dx);
-+ qemu_get_be32s(f, &s->dy);
-+ qemu_get_be32s(f, &s->dz);
-+ qemu_get_be32s(f, &s->buttons_state);
-+ qemu_get_be32s(f, &s->x);
-+ qemu_get_be32s(f, &s->y);
-+ qemu_get_be32s(f, &s->kind);
-+ qemu_get_be32s(f, &s->mouse_grabbed);
-+ qemu_get_be32s(f, &s->status_changed);
-+
-+ if ( s->kind == USB_TABLET) {
-+ fprintf(logfile, "usb_mouse_load:add usb_tablet_event.\n");
-+ qemu_add_mouse_event_handler(usb_tablet_event, s, 1, "QEMU USB Tablet");
-+ } else if ( s->kind == USB_MOUSE) {
-+ fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n");
-+ qemu_add_mouse_event_handler(usb_mouse_event, s, 0, "QEMU USB MOUSE");
-+ }
-+
-+ return 0;
-+}
-+
-+
- USBDevice *usb_tablet_init(void)
- {
- USBMouseState *s;
-@@ -528,6 +573,8 @@
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
-
-+ register_savevm("USB tablet dev", 0, 1, usb_mouse_save, usb_mouse_load, s);
-+
- return (USBDevice *)s;
- }
-
-@@ -549,5 +596,7 @@
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
-
-+ register_savevm("USB mouse dev", 0, 1, usb_mouse_save, usb_mouse_load, s);
-+
- return (USBDevice *)s;
- }
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-09 14:10:50.000000000 +0100
-+++ ioemu/vl.c 2007-05-09 14:11:19.000000000 +0100
-@@ -4076,6 +4076,7 @@
- const char *p;
- USBDevice *dev;
- USBPort *port;
-+ char usb_name[256] = "USB ";
-
- if (!free_usb_ports)
- return -1;
-@@ -4112,6 +4113,12 @@
- free_usb_ports = port->next;
- port->next = used_usb_ports;
- used_usb_ports = port;
-+
-+ pstrcpy(usb_name + strlen(usb_name),
-+ sizeof(usb_name) - strlen(usb_name),
-+ devname);
-+ register_savevm(usb_name, 0, 1, generic_usb_save, generic_usb_load, dev);
-+
- usb_attach(port, dev);
- return 0;
- }
-Index: ioemu/hw/usb.c
-===================================================================
---- ioemu.orig/hw/usb.c 2007-05-09 14:10:50.000000000 +0100
-+++ ioemu/hw/usb.c 2007-05-09 14:11:01.000000000 +0100
-@@ -201,3 +201,42 @@
- dev->handle_packet(dev, &p);
- }
-
-+void generic_usb_save(QEMUFile* f, void *opaque)
-+{
-+ USBDevice *s = (USBDevice*)opaque;
-+
-+ qemu_put_be32s(f, &s->speed);
-+ qemu_put_8s(f, &s->addr);
-+ qemu_put_be32s(f, &s->state);
-+
-+ qemu_put_buffer(f, s->setup_buf, 8);
-+ qemu_put_buffer(f, s->data_buf, 1024);
-+
-+ qemu_put_be32s(f, &s->remote_wakeup);
-+ qemu_put_be32s(f, &s->setup_state);
-+ qemu_put_be32s(f, &s->setup_len);
-+ qemu_put_be32s(f, &s->setup_index);
-+
-+}
-+
-+int generic_usb_load(QEMUFile* f, void *opaque, int version_id)
-+{
-+ USBDevice *s = (USBDevice*)opaque;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+
-+ qemu_get_be32s(f, &s->speed);
-+ qemu_get_8s(f, &s->addr);
-+ qemu_get_be32s(f, &s->state);
-+
-+ qemu_get_buffer(f, s->setup_buf, 8);
-+ qemu_get_buffer(f, s->data_buf, 1024);
-+
-+ qemu_get_be32s(f, &s->remote_wakeup);
-+ qemu_get_be32s(f, &s->setup_state);
-+ qemu_get_be32s(f, &s->setup_len);
-+ qemu_get_be32s(f, &s->setup_index);
-+
-+ return 0;
-+}
-Index: ioemu/hw/usb-ohci.c
-===================================================================
---- ioemu.orig/hw/usb-ohci.c 2007-05-09 14:10:50.000000000 +0100
-+++ ioemu/hw/usb-ohci.c 2007-05-09 14:11:01.000000000 +0100
-@@ -1215,6 +1215,20 @@
- cpu_register_physical_memory(addr, size, ohci->mem);
- }
-
-+static void ohci_usb_save(QEMUFile *f, void *opaque)
-+{
-+ OHCIState *ohci = opaque;
-+
-+ pci_device_save(&ohci->pci_dev, f);
-+}
-+
-+static int ohci_usb_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ OHCIState *ohci = opaque;
-+
-+ return pci_device_load(&ohci->pci_dev, f);
-+}
-+
- void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn)
- {
- OHCIState *ohci;
-@@ -1265,6 +1279,8 @@
- qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
- }
-
-+ register_savevm("OHCI USB", 0, 1, ohci_usb_save, ohci_usb_load, ohci);
-+
- ohci->async_td = 0;
- ohci_reset(ohci);
- }
-Index: ioemu/hw/usb.h
-===================================================================
---- ioemu.orig/hw/usb.h 2007-05-09 14:10:50.000000000 +0100
-+++ ioemu/hw/usb.h 2007-05-09 14:11:01.000000000 +0100
-@@ -218,3 +218,9 @@
-
- /* usb-msd.c */
- USBDevice *usb_msd_init(const char *filename);
-+
-+/* usb.c */
-+void generic_usb_save(QEMUFile* f, void *opaque);
-+int generic_usb_load(QEMUFile* f, void *opaque, int version_id);
-+
-+
-Index: ioemu/hw/usb-uhci.c
-===================================================================
---- ioemu.orig/hw/usb-uhci.c 2007-05-09 14:10:50.000000000 +0100
-+++ ioemu/hw/usb-uhci.c 2007-05-09 14:11:18.000000000 +0100
-@@ -760,6 +760,57 @@
- register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
- }
-
-+void uhci_usb_save(QEMUFile *f, void *opaque)
-+{
-+ int i;
-+ UHCIState *s = (UHCIState*)opaque;
-+
-+ pci_device_save(&s->dev, f);
-+
-+ qemu_put_be16s(f, &s->cmd);
-+ qemu_put_be16s(f, &s->status);
-+ qemu_put_be16s(f, &s->intr);
-+ qemu_put_be16s(f, &s->frnum);
-+ qemu_put_be32s(f, &s->fl_base_addr);
-+ qemu_put_8s(f, &s->sof_timing);
-+ qemu_put_8s(f, &s->status2);
-+
-+ for(i = 0; i < NB_PORTS; i++) {
-+ qemu_put_be16s(f, &s->ports[i].ctrl);
-+ }
-+
-+ qemu_put_timer(f, s->frame_timer);
-+}
-+
-+int uhci_usb_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ int i;
-+ UHCIState *s = (UHCIState*)opaque;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+
-+ i = pci_device_load(&s->dev, f);
-+ if (i < 0)
-+ return i;
-+
-+ qemu_get_be16s(f, &s->cmd);
-+ qemu_get_be16s(f, &s->status);
-+ qemu_get_be16s(f, &s->intr);
-+ qemu_get_be16s(f, &s->frnum);
-+ qemu_get_be32s(f, &s->fl_base_addr);
-+ qemu_get_8s(f, &s->sof_timing);
-+ qemu_get_8s(f, &s->status2);
-+
-+ for(i = 0; i < NB_PORTS; i++) {
-+ qemu_get_be16s(f, &s->ports[i].ctrl);
-+ }
-+
-+ qemu_get_timer(f, s->frame_timer);
-+
-+ return 0;
-+}
-+
- void usb_uhci_init(PCIBus *bus, int devfn)
- {
- UHCIState *s;
-@@ -793,4 +844,6 @@
- to rely on this. */
- pci_register_io_region(&s->dev, 4, 0x20,
- PCI_ADDRESS_SPACE_IO, uhci_map);
-+
-+ register_savevm("UHCI usb controller", 0, 1, uhci_usb_save, uhci_usb_load, s);
- }
diff --git a/tools/ioemu/patches/limit-fdc-sector-size-to-16K b/tools/ioemu/patches/limit-fdc-sector-size-to-16K
deleted file mode 100644
index e97973fcec..0000000000
--- a/tools/ioemu/patches/limit-fdc-sector-size-to-16K
+++ /dev/null
@@ -1,32 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID f711b87ba951e608287abd0de028c6f0d83400a9
-# Parent f3ee62b7fb5299c89d442845e0883bcfab78c067
-[QEMU] fdc: Limit sector size to 16K
-
-In fdctrl_start_transfer the sector size field (fifo[5]) is not
-checked for overflows. This allows an arbitrarily large sector size
-to be used, which can in turn result in a negative data_len field that
-is then used for DMA transfers.
-
-This can lead to the corrpuption of qemu state because some subsequent
-checks on the transfer length is conducted using signed integers.
-
-This patch limits the value fifo[5] to 7 which is the standard limit
-on floppy sector size.
-
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-
-Index: ioemu/hw/fdc.c
-===================================================================
---- ioemu.orig/hw/fdc.c 2006-12-08 18:21:36.000000000 +0000
-+++ ioemu/hw/fdc.c 2006-12-08 18:22:57.000000000 +0000
-@@ -898,7 +898,7 @@
- fdctrl->data_len = fdctrl->fifo[8];
- } else {
- int tmp;
-- fdctrl->data_len = 128 << fdctrl->fifo[5];
-+ fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
- tmp = (cur_drv->last_sect - ks + 1);
- if (fdctrl->fifo[0] & 0x80)
- tmp += cur_drv->last_sect;
diff --git a/tools/ioemu/patches/ne2000-bounds-checks b/tools/ioemu/patches/ne2000-bounds-checks
deleted file mode 100644
index 6864d94b41..0000000000
--- a/tools/ioemu/patches/ne2000-bounds-checks
+++ /dev/null
@@ -1,113 +0,0 @@
-# HG changeset patch
-# User kaf24@localhost.localdomain
-# Node ID 66fe61db9e69e03e12d0c4086683bebfb4a67780
-# Parent 1940ee13f9d6ab1be2c614a0fbf7769536a056d2
-[QEMU] ne2000: Stop memory access beyond buffer
-
-As a program that runs in dom0 which serves users from guests,
-the qemu drivers need to be vigilant to the input that comes
-from the guests since they may be malicious.
-
-As it is there are multiple ways to get ne2000 to read/write
-memory beyond the 48K buffer that it has allocated for each
-adapter.
-
-This patch checks the addresses and prevents this from occuring.
-
-The boundary is checked each time since it's changed for every
-packet received while the other parameters are only changed
-(by the guest) during setup.
-
-Signed-off: Herbert Xu <herbert@gondor.apana.org.au>
-
-Index: ioemu/hw/ne2000.c
-===================================================================
---- ioemu.orig/hw/ne2000.c 2007-05-03 19:30:23.000000000 +0100
-+++ ioemu/hw/ne2000.c 2007-05-03 20:38:52.000000000 +0100
-@@ -137,6 +137,7 @@
- uint8_t curpag;
- uint8_t mult[8]; /* multicast mask array */
- int irq;
-+ int tainted;
- PCIDevice *pci_dev;
- VLANClientState *vc;
- uint8_t macaddr[6];
-@@ -226,6 +227,27 @@
-
- #define MIN_BUF_SIZE 60
-
-+static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr)
-+{
-+ addr <<= 8;
-+ return addr < s->stop && addr >= s->start;
-+}
-+
-+static inline int ne2000_check_state(NE2000State *s)
-+{
-+ if (!s->tainted)
-+ return 0;
-+
-+ if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE)
-+ return -EINVAL;
-+
-+ if (!ne2000_valid_ring_addr(s, s->curpag))
-+ return -EINVAL;
-+
-+ s->tainted = 0;
-+ return 0;
-+}
-+
- static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
- {
- NE2000State *s = opaque;
-@@ -239,6 +261,12 @@
- printf("NE2000: received len=%d\n", size);
- #endif
-
-+ if (ne2000_check_state(s))
-+ return;
-+
-+ if (!ne2000_valid_ring_addr(s, s->boundary))
-+ return;
-+
- if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
- return;
-
-@@ -359,9 +387,11 @@
- switch(offset) {
- case EN0_STARTPG:
- s->start = val << 8;
-+ s->tainted = 1;
- break;
- case EN0_STOPPG:
- s->stop = val << 8;
-+ s->tainted = 1;
- break;
- case EN0_BOUNDARY:
- s->boundary = val;
-@@ -406,6 +436,7 @@
- break;
- case EN1_CURPAG:
- s->curpag = val;
-+ s->tainted = 1;
- break;
- case EN1_MULT ... EN1_MULT + 7:
- s->mult[offset - EN1_MULT] = val;
-@@ -509,7 +540,7 @@
- {
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
-- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-+ (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
- cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
- }
- }
-@@ -539,7 +570,7 @@
- {
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
-- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-+ (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
- return le32_to_cpupu((uint32_t *)(s->mem + addr));
- } else {
- return 0xffffffff;
diff --git a/tools/ioemu/patches/nodelay-serial-over-tcp b/tools/ioemu/patches/nodelay-serial-over-tcp
deleted file mode 100644
index acaf18e30f..0000000000
--- a/tools/ioemu/patches/nodelay-serial-over-tcp
+++ /dev/null
@@ -1,29 +0,0 @@
-# HG changeset patch
-# User PeterJohnston <peter.johnston@xensource.com>
-# Node ID b8cc9ffda0a3dc449b026c72c97f78dea2e6f114
-# Parent a8d2b1393b769048c7b62822e45bef27eef80fb6
-[QEMU] Add TCP_NODELAY to tcp connections exporting serial ports.
-
-Signed-off-by: Steven Smith <sos22@cam.ac.uk>
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 10:09:02.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 10:09:03.000000000 +0100
-@@ -2586,6 +2586,7 @@
- int is_waitconnect = 1;
- const char *ptr;
- struct sockaddr_in saddr;
-+ int opt;
-
- if (parse_host_port(&saddr, host_str) < 0)
- goto fail;
-@@ -2654,6 +2655,8 @@
- }
- }
- s->fd = fd;
-+ opt = 1;
-+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
- if (s->connected)
- tcp_chr_connect(chr);
- else
diff --git a/tools/ioemu/patches/qemu-64bit b/tools/ioemu/patches/qemu-64bit
deleted file mode 100644
index 93ec5abbe0..0000000000
--- a/tools/ioemu/patches/qemu-64bit
+++ /dev/null
@@ -1,111 +0,0 @@
-Index: ioemu/cpu-all.h
-===================================================================
---- ioemu.orig/cpu-all.h 2007-05-03 18:38:09.000000000 +0100
-+++ ioemu/cpu-all.h 2007-05-03 19:00:05.000000000 +0100
-@@ -830,7 +830,7 @@
-
- /* memory API */
-
--extern int phys_ram_size;
-+extern uint64_t phys_ram_size;
- extern int phys_ram_fd;
- extern uint8_t *phys_ram_base;
- extern uint8_t *phys_ram_dirty;
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-03 18:44:07.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-03 19:00:05.000000000 +0100
-@@ -156,7 +156,7 @@
- }
-
- /* hd_table must contain 4 block drivers */
--static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table)
-+static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table)
- {
- RTCState *s = rtc_state;
- int val;
-@@ -445,7 +445,7 @@
- }
-
- /* PC hardware initialisation */
--static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
-+static void pc_init1(uint64_t ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename,
-@@ -738,7 +738,7 @@
- #endif
- }
-
--static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
-+static void pc_init_pci(uint64_t ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
-@@ -751,7 +751,7 @@
- initrd_filename, 1);
- }
-
--static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device,
-+static void pc_init_isa(uint64_t ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 18:57:23.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:00:05.000000000 +0100
-@@ -132,7 +132,7 @@
- const char* keyboard_layout = NULL;
- int64_t ticks_per_sec;
- int boot_device = 'c';
--int ram_size;
-+uint64_t ram_size;
- int pit_min_timer_count = 0;
- int nb_nics;
- NICInfo nd_table[MAX_NICS];
-@@ -6818,7 +6818,7 @@
- help();
- break;
- case QEMU_OPTION_m:
-- ram_size = atoi(optarg) * 1024 * 1024;
-+ ram_size = atol(optarg) * 1024 * 1024;
- if (ram_size <= 0)
- help();
- if (ram_size > PHYS_RAM_MAX_SIZE) {
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 18:57:23.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 19:00:05.000000000 +0100
-@@ -151,7 +151,7 @@
- extern int xc_handle;
- extern int domid;
-
--extern int ram_size;
-+extern uint64_t ram_size;
- extern int bios_size;
- extern int rtc_utc;
- extern int cirrus_vga_enabled;
-@@ -688,7 +688,7 @@
-
- #ifndef QEMU_TOOL
-
--typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size,
-+typedef void QEMUMachineInitFunc(uint64_t ram_size, int vga_ram_size,
- int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
-Index: ioemu/hw/vga.c
-===================================================================
---- ioemu.orig/hw/vga.c 2007-05-03 18:59:25.000000000 +0100
-+++ ioemu/hw/vga.c 2007-05-03 19:00:05.000000000 +0100
-@@ -1379,7 +1379,8 @@
- static void vga_draw_graphic(VGAState *s, int full_update)
- {
- int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
-- int width, height, shift_control, line_offset, page0, page1, bwidth;
-+ int width, height, shift_control, line_offset, bwidth;
-+ ram_addr_t page0, page1;
- int disp_width, multi_scan, multi_run;
- uint8_t *d;
- uint32_t v, addr1, addr;
diff --git a/tools/ioemu/patches/qemu-allow-disable-sdl b/tools/ioemu/patches/qemu-allow-disable-sdl
deleted file mode 100644
index 4df57c24e2..0000000000
--- a/tools/ioemu/patches/qemu-allow-disable-sdl
+++ /dev/null
@@ -1,28 +0,0 @@
-Index: ioemu/configure
-===================================================================
---- ioemu.orig/configure 2007-05-03 18:49:10.000000000 +0100
-+++ ioemu/configure 2007-05-03 20:29:35.000000000 +0100
-@@ -237,8 +237,6 @@
- ;;
- --enable-cocoa) cocoa="yes" ; coreaudio="yes" ; sdl="no"
- ;;
-- --disable-gfx-check) check_gfx="no"
-- ;;
- --disable-gcc-check) check_gcc="no"
- ;;
- --disable-system) softmmu="no"
-@@ -831,14 +829,6 @@
- target_darwin_user="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
diff --git a/tools/ioemu/patches/qemu-block-device-bounds-checks b/tools/ioemu/patches/qemu-block-device-bounds-checks
deleted file mode 100644
index 8456b62233..0000000000
--- a/tools/ioemu/patches/qemu-block-device-bounds-checks
+++ /dev/null
@@ -1,23 +0,0 @@
-Index: ioemu/block.c
-===================================================================
---- ioemu.orig/block.c 2007-05-09 13:31:35.000000000 +0100
-+++ ioemu/block.c 2007-05-09 13:32:33.000000000 +0100
-@@ -502,6 +502,9 @@
- if (!drv)
- return -ENOMEDIUM;
-
-+ if (sector_num < 0)
-+ return -EINVAL;
-+
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(buf, bs->boot_sector_data, 512);
- sector_num++;
-@@ -539,6 +542,8 @@
- return -ENOMEDIUM;
- if (bs->read_only)
- return -EACCES;
-+ if (sector_num < 0)
-+ return -EINVAL;
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(bs->boot_sector_data, buf, 512);
- }
diff --git a/tools/ioemu/patches/qemu-bootorder b/tools/ioemu/patches/qemu-bootorder
deleted file mode 100644
index 97e14d9056..0000000000
--- a/tools/ioemu/patches/qemu-bootorder
+++ /dev/null
@@ -1,183 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:34:25.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:35:16.000000000 +0100
-@@ -135,7 +135,7 @@
- int vncunused;
- const char* keyboard_layout = NULL;
- int64_t ticks_per_sec;
--int boot_device = 'c';
-+char *boot_device = NULL;
- uint64_t ram_size;
- int pit_min_timer_count = 0;
- int nb_nics;
-@@ -7051,14 +7051,14 @@
- break;
- #endif /* !CONFIG_DM */
- case QEMU_OPTION_boot:
-- boot_device = optarg[0];
-- if (boot_device != 'a' &&
-+ boot_device = strdup(optarg);
-+ if (strspn(boot_device, "a"
- #if defined(TARGET_SPARC) || defined(TARGET_I386)
- // Network boot
-- boot_device != 'n' &&
-+ "n"
- #endif
-- boot_device != 'c' && boot_device != 'd') {
-- fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
-+ "cd") != strlen(boot_device)) {
-+ fprintf(stderr, "qemu: invalid boot device in '%s'\n", boot_device);
- exit(1);
- }
- break;
-@@ -7419,6 +7419,7 @@
- exit(1);
- }
-
-+#ifndef CONFIG_DM
- #ifdef TARGET_I386
- if (boot_device == 'n') {
- for (i = 0; i < nb_nics; i++) {
-@@ -7440,6 +7441,7 @@
- boot_device = 'c'; /* to prevent confusion by the BIOS */
- }
- #endif
-+#endif /* !CONFIG_DM */
-
- #if defined (__ia64__)
- if (ram_size > MMIO_START)
-@@ -7449,6 +7451,7 @@
- /* init the memory */
- phys_ram_size = ram_size + vga_ram_size + bios_size;
-
-+#ifndef CONFIG_DM
- for (i = 0; i < nb_option_roms; i++) {
- int ret = get_image_size(option_rom[i]);
- if (ret == -1) {
-@@ -7457,6 +7460,7 @@
- }
- phys_ram_size += ret;
- }
-+#endif /* !CONFIG_DM */
-
- #ifdef CONFIG_DM
-
-@@ -7686,6 +7690,7 @@
- machine->init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename);
-+ free(boot_device);
-
- /* init USB devices */
- if (usb_enabled) {
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:34:25.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:34:28.000000000 +0100
-@@ -703,7 +703,7 @@
- #ifndef QEMU_TOOL
-
- typedef void QEMUMachineInitFunc(uint64_t ram_size, int vga_ram_size,
-- int boot_device,
-+ char *boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename);
-@@ -1217,7 +1217,7 @@
- uint32_t start, uint32_t count);
- int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
- const unsigned char *arch,
-- uint32_t RAM_size, int boot_device,
-+ uint32_t RAM_size, char *boot_device,
- uint32_t kernel_image, uint32_t kernel_size,
- const char *cmdline,
- uint32_t initrd_image, uint32_t initrd_size,
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-10 15:34:25.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-10 15:34:59.000000000 +0100
-@@ -159,8 +159,25 @@
- rtc_set_memory(s, info_ofs + 8, sectors);
- }
-
-+static int get_bios_disk(char *boot_device, int index) {
-+
-+ if (index < strlen(boot_device)) {
-+ switch (boot_device[index]) {
-+ case 'a':
-+ return 0x01; /* floppy */
-+ case 'c':
-+ return 0x02; /* hard drive */
-+ case 'd':
-+ return 0x03; /* cdrom */
-+ case 'n':
-+ return 0x04; /* network */
-+ }
-+ }
-+ return 0x00; /* no device */
-+}
-+
- /* hd_table must contain 4 block drivers */
--static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table)
-+static void cmos_init(uint64_t ram_size, char *boot_device, BlockDriverState **hd_table)
- {
- RTCState *s = rtc_state;
- int val;
-@@ -191,21 +208,14 @@
- rtc_set_memory(s, 0x34, val);
- rtc_set_memory(s, 0x35, val >> 8);
-
-- switch(boot_device) {
-- case 'a':
-- case 'b':
-- rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
-- if (!fd_bootchk)
-- rtc_set_memory(s, 0x38, 0x01); /* disable signature check */
-- break;
-- default:
-- case 'c':
-- rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
-- break;
-- case 'd':
-- rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
-- break;
-- }
-+ if (boot_device == NULL) {
-+ /* default to hd, then cd, then floppy. */
-+ boot_device = "cda";
-+ }
-+ rtc_set_memory(s, 0x3d, get_bios_disk(boot_device, 0) |
-+ (get_bios_disk(boot_device, 1) << 4));
-+ rtc_set_memory(s, 0x38, (get_bios_disk(boot_device, 2) << 4) |
-+ (!fd_bootchk ? 0x01 : 0x00));
-
- /* floppy type */
-
-@@ -451,7 +461,7 @@
- #define NOBIOS 1
-
- /* PC hardware initialisation */
--static void pc_init1(uint64_t ram_size, int vga_ram_size, int boot_device,
-+static void pc_init1(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename,
-@@ -772,7 +782,7 @@
- #endif
- }
-
--static void pc_init_pci(uint64_t ram_size, int vga_ram_size, int boot_device,
-+static void pc_init_pci(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
-@@ -785,7 +795,7 @@
- initrd_filename, 1);
- }
-
--static void pc_init_isa(uint64_t ram_size, int vga_ram_size, int boot_device,
-+static void pc_init_isa(uint64_t ram_size, int vga_ram_size, char *boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
diff --git a/tools/ioemu/patches/qemu-bugfixes b/tools/ioemu/patches/qemu-bugfixes
deleted file mode 100644
index 8a3851e35b..0000000000
--- a/tools/ioemu/patches/qemu-bugfixes
+++ /dev/null
@@ -1,50 +0,0 @@
-Index: ioemu/console.c
-===================================================================
---- ioemu.orig/console.c 2007-05-03 18:17:55.000000000 +0100
-+++ ioemu/console.c 2007-05-03 19:00:14.000000000 +0100
-@@ -503,7 +503,7 @@
- c++;
- }
- }
-- free(s->cells);
-+ qemu_free(s->cells);
- s->cells = cells;
- }
-
-@@ -1156,11 +1156,21 @@
- return !active_console->text_console;
- }
-
-+void set_color_table(DisplayState *ds)
-+{
-+ int i, j;
-+ for(j = 0; j < 2; j++) {
-+ for(i = 0; i < 8; i++) {
-+ color_table[j][i] =
-+ col_expand(ds, vga_get_color(ds, color_table_rgb[j][i]));
-+ }
-+ }
-+}
-+
- CharDriverState *text_console_init(DisplayState *ds)
- {
- CharDriverState *chr;
- TextConsole *s;
-- int i,j;
- static int color_inited;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
-@@ -1182,12 +1192,7 @@
-
- if (!color_inited) {
- color_inited = 1;
-- for(j = 0; j < 2; j++) {
-- for(i = 0; i < 8; i++) {
-- color_table[j][i] = col_expand(s->ds,
-- vga_get_color(s->ds, color_table_rgb[j][i]));
-- }
-- }
-+ set_color_table(ds);
- }
- s->y_displayed = 0;
- s->y_base = 0;
diff --git a/tools/ioemu/patches/qemu-cirrus-bounds-checks b/tools/ioemu/patches/qemu-cirrus-bounds-checks
deleted file mode 100644
index 171503efcb..0000000000
--- a/tools/ioemu/patches/qemu-cirrus-bounds-checks
+++ /dev/null
@@ -1,350 +0,0 @@
-Index: ioemu/hw/cirrus_vga.c
-===================================================================
---- ioemu.orig/hw/cirrus_vga.c 2007-05-03 20:36:50.000000000 +0100
-+++ ioemu/hw/cirrus_vga.c 2007-05-03 20:57:47.000000000 +0100
-@@ -601,7 +601,8 @@
- off_cur_end = off_cur + bytesperline;
- off_cur &= TARGET_PAGE_MASK;
- while (off_cur < off_cur_end) {
-- cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
-+ cpu_physical_memory_set_dirty(s->vram_offset +
-+ (off_cur & s->cirrus_addr_mask));
- off_cur += TARGET_PAGE_SIZE;
- }
- off_begin += off_pitch;
-Index: ioemu/hw/cirrus_vga_rop.h
-===================================================================
---- ioemu.orig/hw/cirrus_vga_rop.h 2007-05-03 18:17:34.000000000 +0100
-+++ ioemu/hw/cirrus_vga_rop.h 2007-05-03 20:57:47.000000000 +0100
-@@ -22,18 +22,36 @@
- * THE SOFTWARE.
- */
-
-+#define get_base(p, s, b) do { \
-+ if ((p) >= (s)->vram_ptr && (p) < (s)->vram_ptr + (s)->vram_size) \
-+ (b) = (s)->vram_ptr; \
-+ else if ((p) >= &(s)->cirrus_bltbuf[0] && \
-+ (p) < &(s)->cirrus_bltbuf[CIRRUS_BLTBUFSIZE]) \
-+ (b) = &(s)->cirrus_bltbuf[0]; \
-+ else \
-+ return; \
-+} while(0)
-+
-+#define m(x) ((x) & s->cirrus_addr_mask)
-+
- static void
- glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
-- uint8_t *dst,const uint8_t *src,
-+ uint8_t *dst_,const uint8_t *src_,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
- {
- int x,y;
-+ uint32_t dst, src;
-+ uint8_t *dst_base, *src_base;
-+ get_base(dst_, s, dst_base);
-+ get_base(src_, s, src_base);
-+ dst = dst_ - dst_base;
-+ src = src_ - src_base;
- dstpitch -= bltwidth;
- srcpitch -= bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
-- ROP_OP(*dst, *src);
-+ ROP_OP(*(dst_base + m(dst)), *(src_base + m(src)));
- dst++;
- src++;
- }
-@@ -44,16 +62,22 @@
-
- static void
- glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
-- uint8_t *dst,const uint8_t *src,
-+ uint8_t *dst_,const uint8_t *src_,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
- {
- int x,y;
-+ uint32_t dst, src;
-+ uint8_t *dst_base, *src_base;
-+ get_base(dst_, s, dst_base);
-+ get_base(src_, s, src_base);
-+ dst = dst_ - dst_base;
-+ src = src_ - src_base;
- dstpitch += bltwidth;
- srcpitch += bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
-- ROP_OP(*dst, *src);
-+ ROP_OP(*(dst_base + m(dst)), *(src_base + m(src)));
- dst--;
- src--;
- }
-@@ -76,3 +100,6 @@
-
- #undef ROP_NAME
- #undef ROP_OP
-+
-+#undef get_base
-+#undef m
-Index: ioemu/hw/cirrus_vga_rop2.h
-===================================================================
---- ioemu.orig/hw/cirrus_vga_rop2.h 2007-05-03 18:17:34.000000000 +0100
-+++ ioemu/hw/cirrus_vga_rop2.h 2007-05-03 20:57:47.000000000 +0100
-@@ -23,36 +23,42 @@
- */
-
- #if DEPTH == 8
--#define PUTPIXEL() ROP_OP(d[0], col)
-+#define PUTPIXEL() ROP_OP((dst_base + m(d))[0], col)
- #elif DEPTH == 16
--#define PUTPIXEL() ROP_OP(((uint16_t *)d)[0], col);
-+#define PUTPIXEL() ROP_OP(((uint16_t *)(dst_base + m(d)))[0], col);
- #elif DEPTH == 24
--#define PUTPIXEL() ROP_OP(d[0], col); \
-- ROP_OP(d[1], (col >> 8)); \
-- ROP_OP(d[2], (col >> 16))
-+#define PUTPIXEL() ROP_OP((dst_base + m(d))[0], col); \
-+ ROP_OP((dst_base + m(d))[1], (col >> 8)); \
-+ ROP_OP((dst_base + m(d))[2], (col >> 16))
- #elif DEPTH == 32
--#define PUTPIXEL() ROP_OP(((uint32_t *)d)[0], col)
-+#define PUTPIXEL() ROP_OP(((uint32_t *)(dst_base + m(d)))[0], col)
- #else
- #error unsupported DEPTH
- #endif
-
- static void
- glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
-- (CirrusVGAState * s, uint8_t * dst,
-- const uint8_t * src,
-+ (CirrusVGAState * s, uint8_t * dst_,
-+ const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
- {
-- uint8_t *d;
-+ uint8_t *dst_base, *src_base;
-+ uint32_t src, dst;
-+ uint32_t d;
- int x, y, pattern_y, pattern_pitch, pattern_x;
- unsigned int col;
-- const uint8_t *src1;
-+ uint32_t src1;
- #if DEPTH == 24
- int skipleft = s->gr[0x2f] & 0x1f;
- #else
- int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8);
- #endif
-
-+ get_base(dst_, s, dst_base);
-+ get_base(src_, s, src_base);
-+ dst = dst_ - dst_base;
-+ src = src_ - src_base;
- #if DEPTH == 8
- pattern_pitch = 8;
- #elif DEPTH == 16
-@@ -67,19 +73,19 @@
- src1 = src + pattern_y * pattern_pitch;
- for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
- #if DEPTH == 8
-- col = src1[pattern_x];
-+ col = *(src_base + m(src1 + pattern_x));
- pattern_x = (pattern_x + 1) & 7;
- #elif DEPTH == 16
-- col = ((uint16_t *)(src1 + pattern_x))[0];
-+ col = *(uint16_t *)(src_base + m(src1 + pattern_x));
- pattern_x = (pattern_x + 2) & 15;
- #elif DEPTH == 24
- {
-- const uint8_t *src2 = src1 + pattern_x * 3;
-+ const uint8_t *src2 = src_base + m(src1 + pattern_x * 3);
- col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
- pattern_x = (pattern_x + 1) & 7;
- }
- #else
-- col = ((uint32_t *)(src1 + pattern_x))[0];
-+ col = *(uint32_t *)(src_base + m(src1 + pattern_x));
- pattern_x = (pattern_x + 4) & 31;
- #endif
- PUTPIXEL();
-@@ -93,12 +99,14 @@
- /* NOTE: srcpitch is ignored */
- static void
- glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
-- (CirrusVGAState * s, uint8_t * dst,
-- const uint8_t * src,
-+ (CirrusVGAState * s, uint8_t * dst_,
-+ const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
- {
-- uint8_t *d;
-+ uint8_t *dst_base, *src_base;
-+ uint32_t src, dst;
-+ uint32_t d;
- int x, y;
- unsigned bits, bits_xor;
- unsigned int col;
-@@ -112,6 +120,10 @@
- int dstskipleft = srcskipleft * (DEPTH / 8);
- #endif
-
-+ get_base(dst_, s, dst_base);
-+ get_base(src_, s, src_base);
-+ dst = dst_ - dst_base;
-+ src = src_ - src_base;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
-@@ -122,12 +134,12 @@
-
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
-- bits = *src++ ^ bits_xor;
-+ bits = *(src_base + m(src++)) ^ bits_xor;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
-- bits = *src++ ^ bits_xor;
-+ bits = *(src_base + m(src++)) ^ bits_xor;
- }
- index = (bits & bitmask);
- if (index) {
-@@ -142,13 +154,15 @@
-
- static void
- glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
-- (CirrusVGAState * s, uint8_t * dst,
-- const uint8_t * src,
-+ (CirrusVGAState * s, uint8_t * dst_,
-+ const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
- {
-+ uint8_t *dst_base, *src_base;
-+ uint32_t src, dst;
- uint32_t colors[2];
-- uint8_t *d;
-+ uint32_t d;
- int x, y;
- unsigned bits;
- unsigned int col;
-@@ -156,16 +170,20 @@
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
-+ get_base(dst_, s, dst_base);
-+ get_base(src_, s, src_base);
-+ dst = dst_ - dst_base;
-+ src = src_ - src_base;
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
-- bits = *src++;
-+ bits = *(src_base + m(src++));
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
-- bits = *src++;
-+ bits = *(src_base + m(src++));
- }
- col = colors[!!(bits & bitmask)];
- PUTPIXEL();
-@@ -178,12 +196,14 @@
-
- static void
- glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
-- (CirrusVGAState * s, uint8_t * dst,
-- const uint8_t * src,
-+ (CirrusVGAState * s, uint8_t * dst_,
-+ const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
- {
-- uint8_t *d;
-+ uint8_t *dst_base, *src_base;
-+ uint32_t src, dst;
-+ uint32_t d;
- int x, y, bitpos, pattern_y;
- unsigned int bits, bits_xor;
- unsigned int col;
-@@ -195,6 +215,10 @@
- int dstskipleft = srcskipleft * (DEPTH / 8);
- #endif
-
-+ get_base(dst_, s, dst_base);
-+ get_base(src_, s, src_base);
-+ dst = dst_ - dst_base;
-+ src = src_ - src_base;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
-@@ -205,7 +229,7 @@
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
-- bits = src[pattern_y] ^ bits_xor;
-+ bits = *(src_base + m(src + pattern_y)) ^ bits_xor;
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
-@@ -222,25 +246,31 @@
-
- static void
- glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
-- (CirrusVGAState * s, uint8_t * dst,
-- const uint8_t * src,
-+ (CirrusVGAState * s, uint8_t * dst_,
-+ const uint8_t * src_,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
- {
-+ uint8_t *dst_base, *src_base;
-+ uint32_t src, dst;
- uint32_t colors[2];
-- uint8_t *d;
-+ uint32_t d;
- int x, y, bitpos, pattern_y;
- unsigned int bits;
- unsigned int col;
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
-+ get_base(dst_, s, dst_base);
-+ get_base(src_, s, src_base);
-+ dst = dst_ - dst_base;
-+ src = src_ - src_base;
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
-- bits = src[pattern_y];
-+ bits = *(src_base + m(src + pattern_y));
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
-@@ -257,13 +287,17 @@
- static void
- glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
- (CirrusVGAState *s,
-- uint8_t *dst, int dst_pitch,
-+ uint8_t *dst_, int dst_pitch,
- int width, int height)
- {
-- uint8_t *d, *d1;
-+ uint8_t *dst_base;
-+ uint32_t dst;
-+ uint32_t d, d1;
- uint32_t col;
- int x, y;
-
-+ get_base(dst_, s, dst_base);
-+ dst = dst_ - dst_base;
- col = s->cirrus_blt_fgcol;
-
- d1 = dst;
diff --git a/tools/ioemu/patches/qemu-cleanup b/tools/ioemu/patches/qemu-cleanup
deleted file mode 100644
index 6e27055df6..0000000000
--- a/tools/ioemu/patches/qemu-cleanup
+++ /dev/null
@@ -1,115 +0,0 @@
-Index: ioemu/hw/vga.c
-===================================================================
---- ioemu.orig/hw/vga.c 2007-05-03 18:18:01.000000000 +0100
-+++ ioemu/hw/vga.c 2007-05-03 18:59:25.000000000 +0100
-@@ -1636,7 +1636,9 @@
- static void vga_save(QEMUFile *f, void *opaque)
- {
- VGAState *s = opaque;
-+#ifdef CONFIG_BOCHS_VBE
- int i;
-+#endif
-
- if (s->pci_dev)
- pci_device_save(s->pci_dev, f);
-@@ -1680,7 +1682,10 @@
- static int vga_load(QEMUFile *f, void *opaque, int version_id)
- {
- VGAState *s = opaque;
-- int is_vbe, i, ret;
-+ int is_vbe, ret;
-+#ifdef CONFIG_BOCHS_VBE
-+ int i;
-+#endif
-
- if (version_id > 2)
- return -EINVAL;
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 18:57:13.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 18:57:23.000000000 +0100
-@@ -40,6 +40,7 @@
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-+#include <arpa/inet.h>
- #include <dirent.h>
- #include <netdb.h>
- #ifdef _BSD
-@@ -3129,7 +3130,7 @@
- }
-
- /* XXX: better tmp dir construction */
-- snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
-+ snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%ld", (long)getpid());
- if (mkdir(smb_dir, 0700) < 0) {
- fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
- exit(1);
-@@ -4092,7 +4093,7 @@
- perror("Opening pidfile");
- exit(1);
- }
-- fprintf(f, "%d\n", getpid());
-+ fprintf(f, "%ld\n", (long)getpid());
- fclose(f);
- pid_filename = qemu_strdup(filename);
- if (!pid_filename) {
-@@ -6207,7 +6208,9 @@
- QEMU_OPTION_d,
- QEMU_OPTION_hdachs,
- QEMU_OPTION_L,
-+#ifdef USE_CODE_COPY
- QEMU_OPTION_no_code_copy,
-+#endif
- QEMU_OPTION_k,
- QEMU_OPTION_localtime,
- QEMU_OPTION_cirrusvga,
-@@ -6284,7 +6287,9 @@
- { "d", HAS_ARG, QEMU_OPTION_d },
- { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
- { "L", HAS_ARG, QEMU_OPTION_L },
-+#ifdef USE_CODE_COPY
- { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
-+#endif
- #ifdef USE_KQEMU
- { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
- { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
-@@ -6772,9 +6777,11 @@
- fd_bootchk = 0;
- break;
- #endif
-+#ifdef USE_CODE_COPY
- case QEMU_OPTION_no_code_copy:
- code_copy_enabled = 0;
- break;
-+#endif
- case QEMU_OPTION_net:
- if (nb_net_clients >= MAX_NET_CLIENTS) {
- fprintf(stderr, "qemu: too many network clients\n");
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 18:49:10.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 18:57:23.000000000 +0100
-@@ -1133,7 +1133,7 @@
- unsigned long vram_offset, int vram_size, int width, int height);
-
- /* slavio_intctl.c */
--void *slavio_intctl_init();
-+void *slavio_intctl_init(void);
- void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env);
- void slavio_pic_info(void *opaque);
- void slavio_irq_info(void *opaque);
-Index: ioemu/usb-linux.c
-===================================================================
---- ioemu.orig/usb-linux.c 2007-05-03 18:17:59.000000000 +0100
-+++ ioemu/usb-linux.c 2007-05-03 18:59:55.000000000 +0100
-@@ -26,6 +26,9 @@
- #if defined(__linux__)
- #include <dirent.h>
- #include <sys/ioctl.h>
-+/* Some versions of usbdevice_fs.h need __user to be defined for them. */
-+/* This may (harmlessly) conflict with a definition in linux/compiler.h. */
-+#define __user
- #include <linux/usbdevice_fs.h>
- #include <linux/version.h>
-
diff --git a/tools/ioemu/patches/qemu-daemonize b/tools/ioemu/patches/qemu-daemonize
deleted file mode 100644
index 225f860cfb..0000000000
--- a/tools/ioemu/patches/qemu-daemonize
+++ /dev/null
@@ -1,20 +0,0 @@
-Changes required because qemu-dm runs daemonized.
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:34:24.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:34:25.000000000 +0100
-@@ -7030,10 +7030,11 @@
- }
- break;
- case QEMU_OPTION_nographic:
-- pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
-+ if(!strcmp(monitor_device, "vc"))
-+ pstrcpy(monitor_device, sizeof(monitor_device), "null");
- if(!strcmp(serial_devices[0], "vc"))
- pstrcpy(serial_devices[0], sizeof(serial_devices[0]),
-- "stdio");
-+ "null");
- nographic = 1;
- break;
- case QEMU_OPTION_kernel:
diff --git a/tools/ioemu/patches/qemu-dm b/tools/ioemu/patches/qemu-dm
deleted file mode 100644
index 6f66803855..0000000000
--- a/tools/ioemu/patches/qemu-dm
+++ /dev/null
@@ -1,526 +0,0 @@
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-10 16:22:45.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-11 10:00:33.000000000 +0100
-@@ -332,7 +332,7 @@
- endif
-
- # must use static linking to avoid leaving stuff in virtual address space
--VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o
-+VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o isa_mmio.o
- VL_OBJS+=cutils.o
- VL_OBJS+=block.o block-raw.o
- VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
-Index: ioemu/configure
-===================================================================
---- ioemu.orig/configure 2007-05-10 16:22:45.000000000 +0100
-+++ ioemu/configure 2007-05-11 10:00:33.000000000 +0100
-@@ -77,8 +77,8 @@
- bigendian="no"
- mingw32="no"
- EXESUF=""
--gdbstub="yes"
--slirp="yes"
-+gdbstub="no"
-+slirp="no"
- adlib="no"
- oss="no"
- dsound="no"
-@@ -812,6 +812,8 @@
- if expr $target : '.*-softmmu' > /dev/null ; then
- target_softmmu="yes"
- fi
-+#for support 256M guest
-+target_softmmu="yes"
- target_user_only="no"
- if expr $target : '.*-user' > /dev/null ; then
- target_user_only="yes"
-Index: ioemu/cpu-all.h
-===================================================================
---- ioemu.orig/cpu-all.h 2007-05-10 16:22:44.000000000 +0100
-+++ ioemu/cpu-all.h 2007-05-11 10:00:33.000000000 +0100
-@@ -690,7 +690,9 @@
- void page_set_flags(target_ulong start, target_ulong end, int flags);
- void page_unprotect_range(target_ulong data, target_ulong data_size);
-
-+#ifdef CONFIG_DM
- #define SINGLE_CPU_DEFINES
-+#endif
- #ifdef SINGLE_CPU_DEFINES
-
- #if defined(TARGET_I386)
-@@ -752,6 +754,12 @@
-
- #endif
-
-+#else /* SINGLE_CPU_DEFINES */
-+
-+#define CPUState CPUX86State
-+#define cpu_init cpu_x86_init
-+int main_loop(void);
-+
- #endif /* SINGLE_CPU_DEFINES */
-
- void cpu_dump_state(CPUState *env, FILE *f,
-Index: ioemu/disas.h
-===================================================================
---- ioemu.orig/disas.h 2007-05-10 16:22:44.000000000 +0100
-+++ ioemu/disas.h 2007-05-10 16:22:45.000000000 +0100
-@@ -1,6 +1,7 @@
- #ifndef _QEMU_DISAS_H
- #define _QEMU_DISAS_H
-
-+#ifndef CONFIG_DM
- /* Disassemble this for me please... (debugging). */
- void disas(FILE *out, void *code, unsigned long size);
- void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
-@@ -17,5 +18,6 @@
- const char *disas_strtab;
- struct syminfo *next;
- } *syminfos;
-+#endif /* !CONFIG_DM */
-
- #endif /* _QEMU_DISAS_H */
-Index: ioemu/exec-all.h
-===================================================================
---- ioemu.orig/exec-all.h 2007-05-10 16:22:44.000000000 +0100
-+++ ioemu/exec-all.h 2007-05-11 10:00:54.000000000 +0100
-@@ -519,7 +519,7 @@
-
- extern int tb_invalidated_flag;
-
--#if !defined(CONFIG_USER_ONLY)
-+#if !defined(CONFIG_USER_ONLY) && !defined(CONFIG_DM)
-
- void tlb_fill(target_ulong addr, int is_write, int is_user,
- void *retaddr);
-@@ -546,7 +546,7 @@
-
- #endif
-
--#if defined(CONFIG_USER_ONLY)
-+#if defined(CONFIG_USER_ONLY) || defined(CONFIG_DM)
- static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
- {
- return addr;
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-10 16:22:44.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-11 10:00:33.000000000 +0100
-@@ -74,6 +74,7 @@
- }
- }
-
-+#ifndef CONFIG_DM
- /* SMM support */
- void cpu_smm_update(CPUState *env)
- {
-@@ -98,6 +99,7 @@
- intno = pic_read_irq(isa_pic);
- return intno;
- }
-+#endif /* CONFIG_DM */
-
- static void pic_irq_request(void *opaque, int level)
- {
-@@ -463,12 +465,14 @@
- /* init CPUs */
- for(i = 0; i < smp_cpus; i++) {
- env = cpu_init();
-+#ifndef CONFIG_DM
- if (i != 0)
- env->hflags |= HF_HALTED_MASK;
- if (smp_cpus > 1) {
- /* XXX: enable it in all cases */
- env->cpuid_features |= CPUID_APIC;
- }
-+#endif /* !CONFIG_DM */
- register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
- qemu_register_reset(main_cpu_reset, env);
- if (pci_enabled) {
-@@ -541,6 +545,7 @@
-
- bochs_bios_init();
-
-+#ifndef CONFIG_DM
- if (linux_boot) {
- uint8_t bootsect[512];
- uint8_t old_bootsect[512];
-@@ -596,6 +601,7 @@
- /* loader type */
- stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
- }
-+#endif /* !CONFIG_DM */
-
- if (pci_enabled) {
- pci_bus = i440fx_init(&i440fx_state);
-@@ -639,9 +645,11 @@
- isa_pic = pic_init(pic_irq_request, first_cpu);
- pit = pit_init(0x40, 0);
- pcspk_init(pit);
-+#ifndef CONFIG_DM
- if (pci_enabled) {
- pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
- }
-+#endif /* !CONFIG_DM */
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_hds[i]) {
-Index: ioemu/hw/vga_int.h
-===================================================================
---- ioemu.orig/hw/vga_int.h 2007-05-10 16:22:44.000000000 +0100
-+++ ioemu/hw/vga_int.h 2007-05-11 10:00:32.000000000 +0100
-@@ -28,7 +28,7 @@
- #define ST01_DISP_ENABLE 0x01
-
- /* bochs VBE support */
--#define CONFIG_BOCHS_VBE
-+//#define CONFIG_BOCHS_VBE
-
- #define VBE_DISPI_MAX_XRES 1600
- #define VBE_DISPI_MAX_YRES 1200
-Index: ioemu/monitor.c
-===================================================================
---- ioemu.orig/monitor.c 2007-05-10 16:22:44.000000000 +0100
-+++ ioemu/monitor.c 2007-05-11 10:00:33.000000000 +0100
-@@ -69,6 +69,12 @@
-
- void term_flush(void)
- {
-+#ifdef CONFIG_DM
-+ if (term_outbuf_index > 0 && !monitor_hd) {
-+ fwrite(term_outbuf, term_outbuf_index, 1, stderr);
-+ term_outbuf_index = 0;
-+ }
-+#endif
- if (term_outbuf_index > 0) {
- qemu_chr_write(monitor_hd, term_outbuf, term_outbuf_index);
- term_outbuf_index = 0;
-@@ -134,6 +140,7 @@
- }
- }
-
-+#ifndef CONFIG_DM
- static int monitor_fprintf(FILE *stream, const char *fmt, ...)
- {
- va_list ap;
-@@ -142,6 +149,7 @@
- va_end(ap);
- return 0;
- }
-+#endif /* !CONFIG_DM */
-
- static int compare_cmd(const char *name, const char *list)
- {
-@@ -258,6 +266,7 @@
- return mon_cpu;
- }
-
-+#ifndef CONFIG_DM
- static void do_info_registers(void)
- {
- CPUState *env;
-@@ -311,6 +320,7 @@
- {
- dump_exec_info(NULL, monitor_fprintf);
- }
-+#endif /* !CONFIG_DM */
-
- static void do_info_history (void)
- {
-@@ -408,6 +418,7 @@
- cpu_set_log(mask);
- }
-
-+#ifndef CONFIG_DM
- static void do_stop(void)
- {
- vm_stop(EXCP_INTERRUPT);
-@@ -672,6 +683,7 @@
- }
- fclose(f);
- }
-+#endif /* !CONFIG_DM */
-
- static void do_sum(uint32_t start, uint32_t size)
- {
-@@ -890,6 +902,7 @@
- kbd_mouse_event(0, 0, 0, mouse_button_state);
- }
-
-+#ifndef CONFIG_DM
- static void do_ioport_read(int count, int format, int size, int addr, int has_index, int index)
- {
- uint32_t val;
-@@ -1080,6 +1093,7 @@
- term_printf("kqemu support: not compiled\n");
- #endif
- }
-+#endif /* !CONFIG_DM */
-
- #ifdef CONFIG_PROFILER
-
-@@ -1201,6 +1215,7 @@
- "filename", "save screen into PPM image 'filename'" },
- { "log", "s", do_log,
- "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
-+#ifndef CONFIG_DM
- { "savevm", "s?", do_savevm,
- "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
- { "loadvm", "s", do_loadvm,
-@@ -1223,21 +1238,26 @@
- "/fmt expr", "print expression value (use $reg for CPU register access)", },
- { "i", "/ii.", do_ioport_read,
- "/fmt addr", "I/O port read" },
-+#endif/* !CONFIG_DM */
-
- { "sendkey", "s", do_send_key,
- "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
-+#ifndef CONFIG_DM
- { "system_reset", "", do_system_reset,
- "", "reset the system" },
- { "system_powerdown", "", do_system_powerdown,
- "", "send system power down event" },
-+#endif /* !CONFIG_DM */
- { "sum", "ii", do_sum,
- "addr size", "compute the checksum of a memory region" },
- { "usb_add", "s", do_usb_add,
- "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
- { "usb_del", "s", do_usb_del,
- "device", "remove USB device 'bus.addr'" },
-+#ifndef CONFIG_DM
- { "cpu", "i", do_cpu_set,
- "index", "set the default CPU" },
-+#endif /* !CONFIG_DM */
- { "mouse_move", "sss?", do_mouse_move,
- "dx dy [dz]", "send mouse move events" },
- { "mouse_button", "i", do_mouse_button,
-@@ -1251,8 +1271,10 @@
- #endif
- { "stopcapture", "i", do_stop_capture,
- "capture index", "stop capture" },
-+#ifndef CONFIG_DM
- { "memsave", "lis", do_memory_save,
- "addr size file", "save to disk virtual memory dump starting at 'addr' of size 'size'", },
-+#endif /* !CONFIG_DM */
- { NULL, NULL, },
- };
-
-@@ -1263,10 +1285,12 @@
- "", "show the network state" },
- { "block", "", do_info_block,
- "", "show the block devices" },
-+#ifndef CONFIG_DM
- { "registers", "", do_info_registers,
- "", "show the cpu registers" },
- { "cpus", "", do_info_cpus,
- "", "show infos for each CPU" },
-+#endif /* !CONFIG_DM */
- { "history", "", do_info_history,
- "", "show the command line history", },
- { "irq", "", irq_info,
-@@ -1275,6 +1299,7 @@
- "", "show i8259 (PIC) state", },
- { "pci", "", pci_info,
- "", "show PCI info", },
-+#ifndef CONFIG_DM
- #if defined(TARGET_I386)
- { "tlb", "", tlb_info,
- "", "show virtual to physical memory mappings", },
-@@ -1285,6 +1310,7 @@
- "", "show dynamic compiler info", },
- { "kqemu", "", do_info_kqemu,
- "", "show kqemu information", },
-+#endif /* !CONFIG_DM */
- { "usb", "", usb_info,
- "", "show guest USB devices", },
- { "usbhost", "", usb_host_info,
-@@ -1304,6 +1330,7 @@
-
- /*******************************************************************/
-
-+#ifndef CONFIG_DM
- static const char *pch;
- static jmp_buf expr_env;
-
-@@ -1847,6 +1874,7 @@
- *pp = pch;
- return 0;
- }
-+#endif /* !CONFIG_DM */
-
- static int get_str(char *buf, int buf_size, const char **pp)
- {
-@@ -1913,8 +1941,10 @@
- return 0;
- }
-
-+#ifndef CONFIG_DM
- static int default_fmt_format = 'x';
- static int default_fmt_size = 4;
-+#endif /* !CONFIG_DM */
-
- #define MAX_ARGS 16
-
-@@ -1922,7 +1952,10 @@
- {
- const char *p, *pstart, *typestr;
- char *q;
-- int c, nb_args, len, i, has_arg;
-+ int c, nb_args, len, i;
-+#ifndef CONFIG_DM
-+ int has_arg;
-+#endif /* !CONFIG_DM */
- term_cmd_t *cmd;
- char cmdname[256];
- char buf[1024];
-@@ -2014,6 +2047,7 @@
- args[nb_args++] = str;
- }
- break;
-+#ifndef CONFIG_DM
- case '/':
- {
- int count, format, size;
-@@ -2146,6 +2180,7 @@
- }
- }
- break;
-+#endif /* !CONFIG_DM */
- case '-':
- {
- int has_option;
-@@ -2172,6 +2207,11 @@
- args[nb_args++] = (void *)has_option;
- }
- break;
-+#ifdef CONFIG_DM
-+ /* TODO: add more commands we need here to support hvm device model */
-+ case '/':
-+ case 'i':
-+#endif /* CONFIG_DM */
- default:
- bad_type:
- term_printf("%s: unknown type '%c'\n", cmdname, c);
-@@ -2222,6 +2262,7 @@
- return;
- }
-
-+#ifndef CONFIG_DM
- static void cmd_completion(const char *name, const char *list)
- {
- const char *p, *pstart;
-@@ -2415,6 +2456,11 @@
- for(i = 0; i < nb_args; i++)
- qemu_free(args[i]);
- }
-+#else
-+void readline_find_completion(const char *cmdline)
-+{
-+}
-+#endif /* !CONFIG_DM */
-
- static int term_can_read(void *opaque)
- {
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 16:22:44.000000000 +0100
-+++ ioemu/vl.c 2007-05-11 10:00:33.000000000 +0100
-@@ -396,12 +396,15 @@
- void hw_error(const char *fmt, ...)
- {
- va_list ap;
-+#ifndef CONFIG_DM
- CPUState *env;
-+#endif /* !CONFIG_DM */
-
- va_start(ap, fmt);
- fprintf(stderr, "qemu: hardware error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
-+#ifndef CONFIG_DM
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- fprintf(stderr, "CPU #%d:\n", env->cpu_index);
- #ifdef TARGET_I386
-@@ -410,6 +413,7 @@
- cpu_dump_state(env, stderr, fprintf, 0);
- #endif
- }
-+#endif /* !CONFIG_DM */
- va_end(ap);
- abort();
- }
-@@ -4953,6 +4957,7 @@
- qemu_free(sn_tab);
- }
-
-+#ifndef CONFIG_DM
- /***********************************************************/
- /* cpu save/restore */
-
-@@ -5582,6 +5587,25 @@
- ram_decompress_close(s);
- return 0;
- }
-+#else /* CONFIG_DM */
-+void cpu_save(QEMUFile *f, void *opaque)
-+{
-+}
-+
-+int cpu_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ return 0;
-+}
-+
-+static void ram_save(QEMUFile *f, void *opaque)
-+{
-+}
-+
-+static int ram_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ return 0;
-+}
-+#endif /* CONFIG_DM */
-
- /***********************************************************/
- /* bottom halves (can be seen as timers which expire ASAP) */
-@@ -6580,15 +6604,19 @@
- #endif
- cyls = heads = secs = 0;
- translation = BIOS_ATA_TRANSLATION_AUTO;
-- pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-+ pstrcpy(monitor_device, sizeof(monitor_device), "null");
-
-- pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
-- for(i = 1; i < MAX_SERIAL_PORTS; i++)
-+ for(i = 0; i < MAX_SERIAL_PORTS; i++)
- serial_devices[i][0] = '\0';
- serial_device_index = 0;
--
-+
-+#ifndef CONFIG_DM
- pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
- for(i = 1; i < MAX_PARALLEL_PORTS; i++)
-+#else
-+ /* Xen steals IRQ7 for PCI. Disable LPT1 by default. */
-+ for(i = 0; i < MAX_PARALLEL_PORTS; i++)
-+#endif
- parallel_devices[i][0] = '\0';
- parallel_device_index = 0;
-
-@@ -7040,6 +7068,7 @@
- socket_init();
- #endif
-
-+#ifndef CONFIG_DM
- /* init network clients */
- if (nb_net_clients == 0) {
- /* if no clients, we use a default config */
-@@ -7049,6 +7078,7 @@
- "user");
- nb_net_clients = 2;
- }
-+#endif /* !CONFIG_DM */
-
- for(i = 0;i < nb_net_clients; i++) {
- if (net_client_init(net_clients[i]) < 0)
diff --git a/tools/ioemu/patches/qemu-dma-null-pointer-check b/tools/ioemu/patches/qemu-dma-null-pointer-check
deleted file mode 100644
index 9cdf9d64c5..0000000000
--- a/tools/ioemu/patches/qemu-dma-null-pointer-check
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: ioemu/hw/dma.c
-===================================================================
---- ioemu.orig/hw/dma.c 2007-05-03 18:17:33.000000000 +0100
-+++ ioemu/hw/dma.c 2007-05-03 20:59:42.000000000 +0100
-@@ -340,6 +340,8 @@
- #endif
-
- r = dma_controllers[ncont].regs + ichan;
-+ if (r->transfer_handler == NULL)
-+ return;
- n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
- r->now[COUNT], (r->base[COUNT] + 1) << ncont);
- r->now[COUNT] = n;
diff --git a/tools/ioemu/patches/qemu-fix-memset-args b/tools/ioemu/patches/qemu-fix-memset-args
deleted file mode 100644
index c89172885f..0000000000
--- a/tools/ioemu/patches/qemu-fix-memset-args
+++ /dev/null
@@ -1,18 +0,0 @@
-Index: ioemu/audio/audio.c
-===================================================================
---- ioemu.orig/audio/audio.c 2006-08-17 19:37:35.755591169 +0100
-+++ ioemu/audio/audio.c 2006-08-17 19:50:26.867166346 +0100
-@@ -605,11 +605,11 @@
- }
-
- if (info->sign) {
-- memset (buf, len << info->shift, 0x00);
-+ memset (buf, 0x00, len << info->shift);
- }
- else {
- if (info->bits == 8) {
-- memset (buf, len << info->shift, 0x80);
-+ memset (buf, 0x80, len << info->shift);
- }
- else {
- int i;
diff --git a/tools/ioemu/patches/qemu-hvm-banner b/tools/ioemu/patches/qemu-hvm-banner
deleted file mode 100644
index 63adac9ab1..0000000000
--- a/tools/ioemu/patches/qemu-hvm-banner
+++ /dev/null
@@ -1,23 +0,0 @@
-Index: ioemu/monitor.c
-===================================================================
---- ioemu.orig/monitor.c 2007-05-09 14:09:10.000000000 +0100
-+++ ioemu/monitor.c 2007-05-09 14:09:10.000000000 +0100
-@@ -2488,7 +2488,7 @@
-
- static void monitor_start_input(void)
- {
-- readline_start("(qemu) ", 0, monitor_handle_command1, NULL);
-+ readline_start("(HVMXen) ", 0, monitor_handle_command1, NULL);
- }
-
- static void term_event(void *opaque, int event)
-@@ -2497,8 +2497,7 @@
- return;
-
- if (!hide_banner)
-- term_printf("QEMU %s monitor - type 'help' for more information\n",
-- QEMU_VERSION);
-+ term_printf("HVM device model. type 'q' to exit\n");
- monitor_start_input();
- }
-
diff --git a/tools/ioemu/patches/qemu-init-vgabios b/tools/ioemu/patches/qemu-init-vgabios
deleted file mode 100644
index 4cba5b7ac9..0000000000
--- a/tools/ioemu/patches/qemu-init-vgabios
+++ /dev/null
@@ -1,150 +0,0 @@
-Index: ioemu/hw/vga.c
-===================================================================
---- ioemu.orig/hw/vga.c 2007-05-03 19:00:05.000000000 +0100
-+++ ioemu/hw/vga.c 2007-05-03 19:11:39.000000000 +0100
-@@ -1757,6 +1757,136 @@
- }
- }
-
-+/* do the same job as vgabios before vgabios get ready - yeah */
-+void vga_bios_init(VGAState *s)
-+{
-+ uint8_t palette_model[192] = {
-+ 0, 0, 0, 0, 0, 170, 0, 170,
-+ 0, 0, 170, 170, 170, 0, 0, 170,
-+ 0, 170, 170, 85, 0, 170, 170, 170,
-+ 85, 85, 85, 85, 85, 255, 85, 255,
-+ 85, 85, 255, 255, 255, 85, 85, 255,
-+ 85, 255, 255, 255, 85, 255, 255, 255,
-+ 0, 21, 0, 0, 21, 42, 0, 63,
-+ 0, 0, 63, 42, 42, 21, 0, 42,
-+ 21, 42, 42, 63, 0, 42, 63, 42,
-+ 0, 21, 21, 0, 21, 63, 0, 63,
-+ 21, 0, 63, 63, 42, 21, 21, 42,
-+ 21, 63, 42, 63, 21, 42, 63, 63,
-+ 21, 0, 0, 21, 0, 42, 21, 42,
-+ 0, 21, 42, 42, 63, 0, 0, 63,
-+ 0, 42, 63, 42, 0, 63, 42, 42,
-+ 21, 0, 21, 21, 0, 63, 21, 42,
-+ 21, 21, 42, 63, 63, 0, 21, 63,
-+ 0, 63, 63, 42, 21, 63, 42, 63,
-+ 21, 21, 0, 21, 21, 42, 21, 63,
-+ 0, 21, 63, 42, 63, 21, 0, 63,
-+ 21, 42, 63, 63, 0, 63, 63, 42,
-+ 21, 21, 21, 21, 21, 63, 21, 63,
-+ 21, 21, 63, 63, 63, 21, 21, 63,
-+ 21, 63, 63, 63, 21, 63, 63, 63
-+ };
-+
-+ s->latch = 0;
-+
-+ s->sr_index = 3;
-+ s->sr[0] = 3;
-+ s->sr[1] = 0;
-+ s->sr[2] = 3;
-+ s->sr[3] = 0;
-+ s->sr[4] = 2;
-+ s->sr[5] = 0;
-+ s->sr[6] = 0;
-+ s->sr[7] = 0;
-+
-+ s->gr_index = 5;
-+ s->gr[0] = 0;
-+ s->gr[1] = 0;
-+ s->gr[2] = 0;
-+ s->gr[3] = 0;
-+ s->gr[4] = 0;
-+ s->gr[5] = 16;
-+ s->gr[6] = 14;
-+ s->gr[7] = 15;
-+ s->gr[8] = 255;
-+
-+ /* changed by out 0x03c0 */
-+ s->ar_index = 32;
-+ s->ar[0] = 0;
-+ s->ar[1] = 1;
-+ s->ar[2] = 2;
-+ s->ar[3] = 3;
-+ s->ar[4] = 4;
-+ s->ar[5] = 5;
-+ s->ar[6] = 6;
-+ s->ar[7] = 7;
-+ s->ar[8] = 8;
-+ s->ar[9] = 9;
-+ s->ar[10] = 10;
-+ s->ar[11] = 11;
-+ s->ar[12] = 12;
-+ s->ar[13] = 13;
-+ s->ar[14] = 14;
-+ s->ar[15] = 15;
-+ s->ar[16] = 12;
-+ s->ar[17] = 0;
-+ s->ar[18] = 15;
-+ s->ar[19] = 8;
-+ s->ar[20] = 0;
-+
-+ s->ar_flip_flop = 1;
-+
-+ s->cr_index = 15;
-+ s->cr[0] = 95;
-+ s->cr[1] = 79;
-+ s->cr[2] = 80;
-+ s->cr[3] = 130;
-+ s->cr[4] = 85;
-+ s->cr[5] = 129;
-+ s->cr[6] = 191;
-+ s->cr[7] = 31;
-+ s->cr[8] = 0;
-+ s->cr[9] = 79;
-+ s->cr[10] = 14;
-+ s->cr[11] = 15;
-+ s->cr[12] = 0;
-+ s->cr[13] = 0;
-+ s->cr[14] = 5;
-+ s->cr[15] = 160;
-+ s->cr[16] = 156;
-+ s->cr[17] = 142;
-+ s->cr[18] = 143;
-+ s->cr[19] = 40;
-+ s->cr[20] = 31;
-+ s->cr[21] = 150;
-+ s->cr[22] = 185;
-+ s->cr[23] = 163;
-+ s->cr[24] = 255;
-+
-+ s->msr = 103;
-+ s->fcr = 0;
-+ s->st00 = 0;
-+ s->st01 = 0;
-+
-+ /* dac_* & palette will be initialized by os through out 0x03c8 &
-+ * out 0c03c9(1:3) */
-+ s->dac_state = 0;
-+ s->dac_sub_index = 0;
-+ s->dac_read_index = 0;
-+ s->dac_write_index = 16;
-+ s->dac_cache[0] = 255;
-+ s->dac_cache[1] = 255;
-+ s->dac_cache[2] = 255;
-+
-+ /* palette */
-+ memcpy(s->palette, palette_model, 192);
-+
-+ s->bank_offset = 0;
-+ s->graphic_mode = -1;
-+
-+ /* TODO: add vbe support if enabled */
-+}
-+
- void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
- {
-@@ -1796,6 +1926,8 @@
- s->get_resolution = vga_get_resolution;
- graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
- vga_screen_dump, s);
-+
-+ vga_bios_init(s);
- }
-
- /* used by both ISA and PCI */
diff --git a/tools/ioemu/patches/qemu-logging b/tools/ioemu/patches/qemu-logging
deleted file mode 100644
index 61ae332428..0000000000
--- a/tools/ioemu/patches/qemu-logging
+++ /dev/null
@@ -1,61 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:00:14.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:00:51.000000000 +0100
-@@ -6127,7 +6127,7 @@
- "-S freeze CPU at startup (use 'c' to start execution)\n"
- "-s wait gdb connection to port %d\n"
- "-p port change gdb connection port\n"
-- "-d item1,... output log to %s (use -d ? for a list of log items)\n"
-+ "-l item1,... output log to %s (use -d ? for a list of log items)\n"
- "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
- " translation (t=none or lba) (usually qemu can guess them)\n"
- "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
-@@ -6205,7 +6205,7 @@
- QEMU_OPTION_S,
- QEMU_OPTION_s,
- QEMU_OPTION_p,
-- QEMU_OPTION_d,
-+ QEMU_OPTION_l,
- QEMU_OPTION_hdachs,
- QEMU_OPTION_L,
- #ifdef USE_CODE_COPY
-@@ -6284,7 +6284,7 @@
- { "S", 0, QEMU_OPTION_S },
- { "s", 0, QEMU_OPTION_s },
- { "p", HAS_ARG, QEMU_OPTION_p },
-- { "d", HAS_ARG, QEMU_OPTION_d },
-+ { "l", HAS_ARG, QEMU_OPTION_l },
- { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
- { "L", HAS_ARG, QEMU_OPTION_L },
- #ifdef USE_CODE_COPY
-@@ -6555,6 +6555,8 @@
- int usb_devices_index;
- int fds[2];
-
-+ char qemu_dm_logfilename[64];
-+
- LIST_INIT (&vm_change_state_head);
- #ifndef _WIN32
- {
-@@ -6634,6 +6636,11 @@
- nb_nics = 0;
- /* default mac address of the first network interface */
-
-+ /* init debug */
-+ sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%ld.log", (long)getpid());
-+ cpu_set_log_filename(qemu_dm_logfilename);
-+ cpu_set_log(0);
-+
- optind = 1;
- for(;;) {
- if (optind >= argc)
-@@ -6827,7 +6834,7 @@
- exit(1);
- }
- break;
-- case QEMU_OPTION_d:
-+ case QEMU_OPTION_l:
- {
- int mask;
- CPULogItem *item;
diff --git a/tools/ioemu/patches/qemu-no-apic b/tools/ioemu/patches/qemu-no-apic
deleted file mode 100644
index d71777026d..0000000000
--- a/tools/ioemu/patches/qemu-no-apic
+++ /dev/null
@@ -1,51 +0,0 @@
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-03 18:49:10.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-03 19:09:54.000000000 +0100
-@@ -387,7 +387,7 @@
- # Hardware support
- VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
- VL_OBJS+= fdc.o mc146818rtc.o serial.o i8254.o pcspk.o pc.o
--VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o
-+VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
- CPPFLAGS += -DHAS_AUDIO
- endif
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-03 19:08:19.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-03 19:09:34.000000000 +0100
-@@ -39,7 +39,9 @@
- static fdctrl_t *floppy_controller;
- static RTCState *rtc_state;
- static PITState *pit;
-+#ifndef CONFIG_DM
- static IOAPICState *ioapic;
-+#endif /* !CONFIG_DM */
- static PCIDevice *i440fx_state;
-
- static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
-@@ -475,9 +477,11 @@
- #endif /* !CONFIG_DM */
- register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
- qemu_register_reset(main_cpu_reset, env);
-+#ifndef CONFIG_DM
- if (pci_enabled) {
- apic_init(env);
- }
-+#endif /* !CONFIG_DM */
- }
-
- /* allocate RAM */
-@@ -643,9 +647,11 @@
- register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
- register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
-
-+#ifndef CONFIG_DM
- if (pci_enabled) {
- ioapic = ioapic_init();
- }
-+#endif /* !CONFIG_DM */
- isa_pic = pic_init(pic_irq_request, first_cpu);
- pit = pit_init(0x40, 0);
- pcspk_init(pit);
diff --git a/tools/ioemu/patches/qemu-nobios b/tools/ioemu/patches/qemu-nobios
deleted file mode 100644
index 9943ee8903..0000000000
--- a/tools/ioemu/patches/qemu-nobios
+++ /dev/null
@@ -1,62 +0,0 @@
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-03 19:09:34.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-03 19:11:08.000000000 +0100
-@@ -446,6 +446,8 @@
- nb_ne2k++;
- }
-
-+#define NOBIOS 1
-+
- /* PC hardware initialisation */
- static void pc_init1(uint64_t ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
-@@ -453,10 +455,15 @@
- const char *initrd_filename,
- int pci_enabled)
- {
-+#ifndef NOBIOS
- char buf[1024];
-- int ret, linux_boot, initrd_size, i;
-+ int ret, initrd_size;
-+#endif /* !NOBIOS */
-+ int linux_boot, i;
-+#ifndef NOBIOS
- unsigned long bios_offset, vga_bios_offset, option_rom_offset;
- int bios_size, isa_bios_size;
-+#endif /* !NOBIOS */
- PCIBus *pci_bus;
- int piix3_devfn = -1;
- CPUState *env;
-@@ -489,6 +496,7 @@
- cpu_register_physical_memory(0, ram_size, 0);
- #endif
-
-+#ifndef NOBIOS
- /* BIOS load */
- bios_offset = ram_size + vga_ram_size;
- vga_bios_offset = bios_offset + 256 * 1024;
-@@ -514,6 +522,7 @@
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
- }
- ret = load_image(buf, phys_ram_base + vga_bios_offset);
-+#endif /* !NOBIOS */
-
- /* setup basic memory access */
- #ifndef CONFIG_DM /* HVM domain owns memory */
-@@ -521,6 +530,7 @@
- vga_bios_offset | IO_MEM_ROM);
- #endif
-
-+#ifndef NOBIOS
- /* map the last 128KB of the BIOS in ISA space */
- isa_bios_size = bios_size;
- if (isa_bios_size > (128 * 1024))
-@@ -550,6 +560,7 @@
- /* map all the bios at the top of memory */
- cpu_register_physical_memory((uint32_t)(-bios_size),
- bios_size, bios_offset | IO_MEM_ROM);
-+#endif
-
- bochs_bios_init();
-
diff --git a/tools/ioemu/patches/qemu-pci b/tools/ioemu/patches/qemu-pci
deleted file mode 100755
index 97175d3a3f..0000000000
--- a/tools/ioemu/patches/qemu-pci
+++ /dev/null
@@ -1,75 +0,0 @@
-Index: ioemu/hw/pci.c
-===================================================================
---- ioemu.orig/hw/pci.c 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/hw/pci.c 2007-05-10 15:19:29.000000000 +0100
-@@ -314,6 +314,7 @@
- case 0x0b:
- case 0x0e:
- case 0x10 ... 0x27: /* base */
-+ case 0x2c ... 0x2f: /* subsystem vendor id, subsystem id */
- case 0x30 ... 0x33: /* rom */
- case 0x3d:
- can_write = 0;
-@@ -346,6 +347,18 @@
- break;
- }
- if (can_write) {
-+ if( addr == 0x05 ) {
-+ /* In Command Register, bits 15:11 are reserved */
-+ val &= 0x07;
-+ } else if ( addr == 0x06 ) {
-+ /* In Status Register, bits 6, 2:0 are reserved, */
-+ /* and bits 7,5,4,3 are read only */
-+ val = d->config[addr];
-+ } else if ( addr == 0x07 ) {
-+ /* In Status Register, bits 10,9 are reserved, */
-+ val = (val & ~0x06) | (d->config[addr] & 0x06);
-+ }
-+
- d->config[addr] = val;
- }
- if (++addr > 0xff)
-Index: ioemu/hw/rtl8139.c
-===================================================================
---- ioemu.orig/hw/rtl8139.c 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/hw/rtl8139.c 2007-05-10 15:19:29.000000000 +0100
-@@ -3432,6 +3432,8 @@
- pci_conf[0x0e] = 0x00; /* header_type */
- pci_conf[0x3d] = 1; /* interrupt pin 0 */
- pci_conf[0x34] = 0xdc;
-+ pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
-+ pci_conf[0x2d] = pci_conf[0x01];
-
- s = &d->rtl8139;
-
-Index: ioemu/hw/usb-uhci.c
-===================================================================
---- ioemu.orig/hw/usb-uhci.c 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/hw/usb-uhci.c 2007-05-10 15:19:29.000000000 +0100
-@@ -832,6 +832,8 @@
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x3d] = 4; // interrupt pin 3
- pci_conf[0x60] = 0x10; // release number
-+ pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
-+ pci_conf[0x2d] = pci_conf[0x01];
-
- for(i = 0; i < NB_PORTS; i++) {
- qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:19:28.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:19:29.000000000 +0100
-@@ -777,8 +777,11 @@
- #define PCI_MAX_LAT 0x3f /* 8 bits */
-
- struct PCIDevice {
-- /* PCI config space */
-- uint8_t config[256];
-+ /*
-+ * PCI config space. The 4 extra bytes are a safety buffer for guest
-+ * word/dword writes that can extend past byte 0xff.
-+ */
-+ uint8_t config[256+4];
-
- /* the following fields are read only */
- PCIBus *bus;
diff --git a/tools/ioemu/patches/qemu-pci-vendor-ids b/tools/ioemu/patches/qemu-pci-vendor-ids
deleted file mode 100644
index 6af51a971b..0000000000
--- a/tools/ioemu/patches/qemu-pci-vendor-ids
+++ /dev/null
@@ -1,47 +0,0 @@
-Index: ioemu/hw/cirrus_vga.c
-===================================================================
---- ioemu.orig/hw/cirrus_vga.c 2007-05-10 15:04:56.000000000 +0100
-+++ ioemu/hw/cirrus_vga.c 2007-05-10 15:05:07.000000000 +0100
-@@ -3354,6 +3354,10 @@
- pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
- pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
- pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
-+ pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
-+ pci_conf[0x2d] = 0x58;
-+ pci_conf[0x2e] = 0x01; /* subsystem device */
-+ pci_conf[0x2f] = 0x00;
-
- /* setup VGA */
- s = &d->cirrus_vga;
-Index: ioemu/hw/rtl8139.c
-===================================================================
---- ioemu.orig/hw/rtl8139.c 2007-05-10 15:05:06.000000000 +0100
-+++ ioemu/hw/rtl8139.c 2007-05-10 15:05:07.000000000 +0100
-@@ -3432,8 +3432,10 @@
- pci_conf[0x0e] = 0x00; /* header_type */
- pci_conf[0x3d] = 1; /* interrupt pin 0 */
- pci_conf[0x34] = 0xdc;
-- pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
-- pci_conf[0x2d] = pci_conf[0x01];
-+ pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
-+ pci_conf[0x2d] = 0x58;
-+ pci_conf[0x2e] = 0x01; /* subsystem device */
-+ pci_conf[0x2f] = 0x00;
-
- s = &d->rtl8139;
-
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-10 15:05:02.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-10 15:05:07.000000000 +0100
-@@ -2750,6 +2750,10 @@
- pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
- pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
- pci_conf[0x0e] = 0x00; // header_type
-+ pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
-+ pci_conf[0x2d] = 0x58;
-+ pci_conf[0x2e] = 0x01; /* subsystem device */
-+ pci_conf[0x2f] = 0x00;
-
- piix3_reset(d);
-
diff --git a/tools/ioemu/patches/qemu-serial-fixes b/tools/ioemu/patches/qemu-serial-fixes
deleted file mode 100644
index ff4a48b1b7..0000000000
--- a/tools/ioemu/patches/qemu-serial-fixes
+++ /dev/null
@@ -1,133 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID c33272c2571c7bab7056d8228490700d1df405f9
-# Parent b3d94f4ddffefed8a5cb8dd65a60da9491d460e7
-[HVM] Fix Qemu-dm serial issues:
- 1. Retry transmit via a polling timer if a byte cannot be written
- immediately to its destination.
- 2. Turn off output processing of raw serial lines.
-
-Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
-Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
-Signed-off-by: Keir Fraser <keir@xensource.com>
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:35:24.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:35:25.000000000 +0100
-@@ -1871,7 +1871,7 @@
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
-- tty.c_oflag |= OPOST;
-+ tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
- tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
- switch(data_bits) {
-Index: ioemu/hw/serial.c
-===================================================================
---- ioemu.orig/hw/serial.c 2007-05-10 15:35:24.000000000 +0100
-+++ ioemu/hw/serial.c 2007-05-10 15:35:25.000000000 +0100
-@@ -73,6 +73,11 @@
- #define UART_LSR_OE 0x02 /* Overrun error indicator */
- #define UART_LSR_DR 0x01 /* Receiver data ready */
-
-+/* Maximum retries for a single byte transmit. */
-+#define WRITE_MAX_SINGLE_RETRIES 3
-+/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */
-+#define WRITE_MAX_TOTAL_RETRIES 10
-+
- struct SerialState {
- uint16_t divider;
- uint8_t rbr; /* receive register */
-@@ -93,6 +98,19 @@
- int last_break_enable;
- target_ulong base;
- int it_shift;
-+
-+ /*
-+ * If a character transmitted via UART cannot be written to its
-+ * destination immediately we remember it here and retry a few times via
-+ * a polling timer.
-+ * - write_single_retries: Number of write retries for current byte.
-+ * - write_total_retries: Number of write retries for back-to-back
-+ * unsuccessful transmits.
-+ */
-+ int write_single_retries;
-+ int write_total_retries;
-+ char write_chr;
-+ QEMUTimer *write_retry_timer;
- };
-
- static void serial_update_irq(SerialState *s)
-@@ -204,10 +222,37 @@
- tokens_avail--;
- }
-
-+static void serial_chr_write(void *opaque)
-+{
-+ SerialState *s = opaque;
-+
-+ /* Cancel any outstanding retry if this is a new byte. */
-+ qemu_del_timer(s->write_retry_timer);
-+
-+ /* Retry every 100ms for 300ms total. */
-+ if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
-+ s->write_total_retries++;
-+ if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES)
-+ fprintf(stderr, "serial: write error\n");
-+ else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) {
-+ qemu_mod_timer(s->write_retry_timer,
-+ qemu_get_clock(vm_clock) + ticks_per_sec / 10);
-+ return;
-+ }
-+ } else {
-+ s->write_total_retries = 0; /* if successful then reset counter */
-+ }
-+
-+ /* Success: Notify guest that THR is empty. */
-+ s->thr_ipending = 1;
-+ s->lsr |= UART_LSR_THRE;
-+ s->lsr |= UART_LSR_TEMT;
-+ serial_update_irq(s);
-+}
-+
- static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- {
- SerialState *s = opaque;
-- unsigned char ch;
-
- addr &= 7;
- #ifdef DEBUG_SERIAL
-@@ -223,12 +268,9 @@
- s->thr_ipending = 0;
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
-- ch = val;
-- qemu_chr_write(s->chr, &ch, 1);
-- s->thr_ipending = 1;
-- s->lsr |= UART_LSR_THRE;
-- s->lsr |= UART_LSR_TEMT;
-- serial_update_irq(s);
-+ s->write_chr = val;
-+ s->write_single_retries = 0;
-+ serial_chr_write(s);
- }
- break;
- case 1:
-@@ -427,6 +469,7 @@
- s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
- s->iir = UART_IIR_NO_INT;
- s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
-+ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
-
- register_savevm("serial", base, 2, serial_save, serial_load, s);
-
-@@ -514,6 +557,7 @@
- s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
- s->base = base;
- s->it_shift = it_shift;
-+ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
-
- register_savevm("serial", base, 2, serial_save, serial_load, s);
-
diff --git a/tools/ioemu/patches/qemu-smp b/tools/ioemu/patches/qemu-smp
deleted file mode 100644
index 2bdfe01de4..0000000000
--- a/tools/ioemu/patches/qemu-smp
+++ /dev/null
@@ -1,48 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:09:15.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:09:18.000000000 +0100
-@@ -176,6 +176,8 @@
- int semihosting_enabled = 0;
- int autostart = 1;
-
-+extern int vcpus;
-+
- int xc_handle;
-
- char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
-@@ -6065,6 +6067,7 @@
- "-m megs set virtual RAM size to megs MB [default=%d]\n"
- "-smp n set the number of CPUs to 'n' [default=1]\n"
- "-nographic disable graphical output and redirect serial I/Os to console\n"
-+ "-vcpus set CPU number of guest platform\n"
- #ifndef _WIN32
- "-k language use keyboard layout (for example \"fr\" for French)\n"
- #endif
-@@ -6246,6 +6249,7 @@
- QEMU_OPTION_semihosting
- ,
- QEMU_OPTION_d,
-+ QEMU_OPTION_vcpus,
- };
-
- typedef struct QEMUOption {
-@@ -6337,6 +6341,7 @@
- #endif
-
- { "d", HAS_ARG, QEMU_OPTION_d },
-+ { "vcpus", 1, QEMU_OPTION_vcpus },
- { NULL },
- };
-
-@@ -7028,6 +7033,10 @@
- domid = atoi(optarg);
- fprintf(logfile, "domid: %d\n", domid);
- break;
-+ case QEMU_OPTION_vcpus:
-+ vcpus = atoi(optarg);
-+ fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
-+ break;
- }
- }
- }
diff --git a/tools/ioemu/patches/qemu-target-i386-dm b/tools/ioemu/patches/qemu-target-i386-dm
deleted file mode 100644
index be3beca354..0000000000
--- a/tools/ioemu/patches/qemu-target-i386-dm
+++ /dev/null
@@ -1,1446 +0,0 @@
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-11 10:00:33.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-11 10:04:05.000000000 +0100
-@@ -65,6 +65,8 @@
- QEMU_SYSTEM=qemu-fast
- endif
-
-+QEMU_SYSTEM=qemu-dm
-+
- ifdef CONFIG_USER_ONLY
- PROGS=$(QEMU_USER)
- else
-@@ -321,6 +323,9 @@
- OBJS+=gdbstub.o
- endif
-
-+# qemu-dm objects
-+LIBOBJS=helper2.o exec-dm.o i8259-dm.o
-+
- all: $(PROGS)
-
- $(QEMU_USER): $(OBJS)
-@@ -381,7 +386,7 @@
- ifeq ($(TARGET_BASE_ARCH), i386)
- # Hardware support
- VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
--VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
-+VL_OBJS+= fdc.o mc146818rtc.o serial.o i8254.o pcspk.o pc.o
- VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
- CPPFLAGS += -DHAS_AUDIO
-Index: ioemu/configure
-===================================================================
---- ioemu.orig/configure 2007-05-11 10:00:33.000000000 +0100
-+++ ioemu/configure 2007-05-11 10:04:04.000000000 +0100
-@@ -426,6 +426,8 @@
- if [ "$darwin_user" = "yes" ] ; then
- target_list="i386-darwin-user ppc-darwin-user $target_list"
- fi
-+# the i386-dm target
-+ target_list="i386-dm"
- else
- target_list=`echo "$target_list" | sed -e 's/,/ /g'`
- fi
-Index: ioemu/monitor.c
-===================================================================
---- ioemu.orig/monitor.c 2007-05-11 10:00:33.000000000 +0100
-+++ ioemu/monitor.c 2007-05-11 10:04:06.000000000 +0100
-@@ -1325,6 +1325,10 @@
- "", "show which guest mouse is receiving events" },
- { "vnc", "", do_info_vnc,
- "", "show the vnc server status"},
-+#ifdef CONFIG_DM
-+ { "hvmiopage", "", sp_info,
-+ "", "show HVM device model shared page info" },
-+#endif /* CONFIG_DM */
- { NULL, NULL, },
- };
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-11 10:00:33.000000000 +0100
-+++ ioemu/vl.c 2007-05-11 10:04:06.000000000 +0100
-@@ -88,7 +88,7 @@
-
- #include "exec-all.h"
-
--#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
-+#define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
- #ifdef __sun__
- #define SMBD_COMMAND "/usr/sfw/sbin/smbd"
- #else
-@@ -5805,7 +5805,7 @@
-
- static QEMUResetEntry *first_reset_entry;
- static int reset_requested;
--static int shutdown_requested;
-+int shutdown_requested;
- static int powerdown_requested;
-
- void qemu_register_reset(QEMUResetHandler *func, void *opaque)
-@@ -5957,6 +5957,7 @@
- qemu_get_clock(rt_clock));
- }
-
-+#ifndef CONFIG_DM
- static CPUState *cur_cpu;
-
- int main_loop(void)
-@@ -6031,6 +6032,7 @@
- cpu_disable_ticks();
- return ret;
- }
-+#endif /* !CONFIG_DM */
-
- void help(void)
- {
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-11 10:00:33.000000000 +0100
-+++ ioemu/vl.h 2007-05-11 10:04:06.000000000 +0100
-@@ -37,6 +37,8 @@
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/stat.h>
-+#include "xenctrl.h"
-+#include "xs.h"
-
- #ifndef O_LARGEFILE
- #define O_LARGEFILE 0
-@@ -144,6 +146,11 @@
-
- void main_loop_wait(int timeout);
-
-+extern FILE *logfile;
-+
-+extern int xc_handle;
-+extern int domid;
-+
- extern int ram_size;
- extern int bios_size;
- extern int rtc_utc;
-@@ -1023,6 +1030,7 @@
- uint32_t pic_intack_read(PicState2 *s);
- void pic_info(void);
- void irq_info(void);
-+void sp_info(void);
-
- /* APIC */
- typedef struct IOAPICState IOAPICState;
-Index: ioemu/target-i386-dm/cpu.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/cpu.h 2007-05-11 10:04:06.000000000 +0100
-@@ -0,0 +1,84 @@
-+/*
-+ * i386 virtual CPU header
-+ *
-+ * Copyright (c) 2003 Fabrice Bellard
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+#ifndef CPU_I386_H
-+#define CPU_I386_H
-+
-+#include "config.h"
-+
-+#ifdef TARGET_X86_64
-+#define TARGET_LONG_BITS 64
-+#else
-+#define TARGET_LONG_BITS 32
-+#endif
-+
-+/* target supports implicit self modifying code */
-+#define TARGET_HAS_SMC
-+/* support for self modifying code even if the modified instruction is
-+ close to the modifying instruction */
-+#define TARGET_HAS_PRECISE_SMC
-+
-+#include "cpu-defs.h"
-+
-+#include "softfloat.h"
-+
-+#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
-+#define USE_CODE_COPY
-+#endif
-+
-+#ifdef USE_X86LDOUBLE
-+typedef floatx80 CPU86_LDouble;
-+#else
-+typedef float64 CPU86_LDouble;
-+#endif
-+
-+/* Empty for now */
-+typedef struct CPUX86State {
-+ uint32_t a20_mask;
-+
-+ int interrupt_request;
-+
-+ CPU_COMMON
-+} CPUX86State;
-+
-+CPUX86State *cpu_x86_init(void);
-+int cpu_x86_exec(CPUX86State *s);
-+void cpu_x86_close(CPUX86State *s);
-+int cpu_get_pic_interrupt(CPUX86State *s);
-+/* MSDOS compatibility mode FPU exception support */
-+void cpu_set_ferr(CPUX86State *s);
-+
-+void cpu_x86_set_a20(CPUX86State *env, int a20_state);
-+
-+#ifndef IN_OP_I386
-+void cpu_x86_outb(CPUX86State *env, int addr, int val);
-+void cpu_x86_outw(CPUX86State *env, int addr, int val);
-+void cpu_x86_outl(CPUX86State *env, int addr, int val);
-+int cpu_x86_inb(CPUX86State *env, int addr);
-+int cpu_x86_inw(CPUX86State *env, int addr);
-+int cpu_x86_inl(CPUX86State *env, int addr);
-+#endif
-+
-+/* helper2.c */
-+int main_loop(void);
-+
-+#define TARGET_PAGE_BITS 12
-+#include "cpu-all.h"
-+
-+#endif /* CPU_I386_H */
-Index: ioemu/target-i386-dm/exec-dm.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/exec-dm.c 2007-05-11 10:04:04.000000000 +0100
-@@ -0,0 +1,545 @@
-+/*
-+ * virtual page mapping and translated block handling
-+ *
-+ * Copyright (c) 2003 Fabrice Bellard
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+#include "config.h"
-+#ifdef _WIN32
-+#include <windows.h>
-+#else
-+#include <sys/types.h>
-+#include <sys/mman.h>
-+#endif
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <inttypes.h>
-+
-+#include <xen/hvm/e820.h>
-+
-+#include "cpu.h"
-+#include "exec-all.h"
-+
-+//#define DEBUG_TB_INVALIDATE
-+//#define DEBUG_FLUSH
-+//#define DEBUG_TLB
-+
-+/* make various TB consistency checks */
-+//#define DEBUG_TB_CHECK
-+//#define DEBUG_TLB_CHECK
-+
-+#ifndef CONFIG_DM
-+/* threshold to flush the translated code buffer */
-+#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
-+
-+#define SMC_BITMAP_USE_THRESHOLD 10
-+
-+#define MMAP_AREA_START 0x00000000
-+#define MMAP_AREA_END 0xa8000000
-+
-+TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
-+TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
-+TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-+int nb_tbs;
-+/* any access to the tbs or the page table must use this lock */
-+spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
-+
-+uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
-+uint8_t *code_gen_ptr;
-+#endif /* !CONFIG_DM */
-+
-+uint64_t phys_ram_size;
-+extern uint64_t ram_size;
-+int phys_ram_fd;
-+uint8_t *phys_ram_base;
-+uint8_t *phys_ram_dirty;
-+
-+CPUState *first_cpu;
-+/* current CPU in the current thread. It is only valid inside
-+ cpu_exec() */
-+CPUState *cpu_single_env;
-+
-+typedef struct PageDesc {
-+ /* list of TBs intersecting this ram page */
-+ TranslationBlock *first_tb;
-+ /* in order to optimize self modifying code, we count the number
-+ of lookups we do to a given page to use a bitmap */
-+ unsigned int code_write_count;
-+ uint8_t *code_bitmap;
-+#if defined(CONFIG_USER_ONLY)
-+ unsigned long flags;
-+#endif
-+} PageDesc;
-+
-+typedef struct PhysPageDesc {
-+ /* offset in host memory of the page + io_index in the low 12 bits */
-+ unsigned long phys_offset;
-+} PhysPageDesc;
-+
-+typedef struct VirtPageDesc {
-+ /* physical address of code page. It is valid only if 'valid_tag'
-+ matches 'virt_valid_tag' */
-+ target_ulong phys_addr;
-+ unsigned int valid_tag;
-+#if !defined(CONFIG_SOFTMMU)
-+ /* original page access rights. It is valid only if 'valid_tag'
-+ matches 'virt_valid_tag' */
-+ unsigned int prot;
-+#endif
-+} VirtPageDesc;
-+
-+#define L2_BITS 10
-+#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
-+
-+#define L1_SIZE (1 << L1_BITS)
-+#define L2_SIZE (1 << L2_BITS)
-+
-+unsigned long qemu_real_host_page_size;
-+unsigned long qemu_host_page_bits;
-+unsigned long qemu_host_page_size;
-+unsigned long qemu_host_page_mask;
-+
-+/* io memory support */
-+CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-+CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-+void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-+static int io_mem_nb = 1;
-+
-+/* log support */
-+char *logfilename = "/tmp/qemu.log";
-+FILE *logfile;
-+int loglevel;
-+
-+void cpu_exec_init(CPUState *env)
-+{
-+ CPUState **penv;
-+ int cpu_index;
-+
-+ env->next_cpu = NULL;
-+ penv = &first_cpu;
-+ cpu_index = 0;
-+ while (*penv != NULL) {
-+ penv = (CPUState **)&(*penv)->next_cpu;
-+ cpu_index++;
-+ }
-+ env->cpu_index = cpu_index;
-+ *penv = env;
-+
-+ /* alloc dirty bits array */
-+ phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
-+}
-+
-+/* enable or disable low levels log */
-+void cpu_set_log(int log_flags)
-+{
-+ loglevel = log_flags;
-+ if (!logfile) {
-+ logfile = fopen(logfilename, "w");
-+ if (!logfile) {
-+ perror(logfilename);
-+ _exit(1);
-+ }
-+#if !defined(CONFIG_SOFTMMU)
-+ /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
-+ {
-+ static uint8_t logfile_buf[4096];
-+ setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
-+ }
-+#else
-+ setvbuf(logfile, NULL, _IOLBF, 0);
-+#endif
-+ stdout = logfile;
-+ stderr = logfile;
-+ }
-+}
-+
-+void cpu_set_log_filename(const char *filename)
-+{
-+ logfilename = strdup(filename);
-+}
-+
-+/* mask must never be zero, except for A20 change call */
-+void cpu_interrupt(CPUState *env, int mask)
-+{
-+ env->interrupt_request |= mask;
-+}
-+
-+void cpu_reset_interrupt(CPUState *env, int mask)
-+{
-+ env->interrupt_request &= ~mask;
-+}
-+
-+CPULogItem cpu_log_items[] = {
-+ { CPU_LOG_TB_OUT_ASM, "out_asm",
-+ "show generated host assembly code for each compiled TB" },
-+ { CPU_LOG_TB_IN_ASM, "in_asm",
-+ "show target assembly code for each compiled TB" },
-+ { CPU_LOG_TB_OP, "op",
-+ "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
-+#ifdef TARGET_I386
-+ { CPU_LOG_TB_OP_OPT, "op_opt",
-+ "show micro ops after optimization for each compiled TB" },
-+#endif
-+ { CPU_LOG_INT, "int",
-+ "show interrupts/exceptions in short format" },
-+ { CPU_LOG_EXEC, "exec",
-+ "show trace before each executed TB (lots of logs)" },
-+ { CPU_LOG_TB_CPU, "cpu",
-+ "show CPU state before bloc translation" },
-+#ifdef TARGET_I386
-+ { CPU_LOG_PCALL, "pcall",
-+ "show protected mode far calls/returns/exceptions" },
-+#endif
-+#ifdef DEBUG_IOPORT
-+ { CPU_LOG_IOPORT, "ioport",
-+ "show all i/o ports accesses" },
-+#endif
-+ { 0, NULL, NULL },
-+};
-+
-+static int cmp1(const char *s1, int n, const char *s2)
-+{
-+ if (strlen(s2) != n)
-+ return 0;
-+ return memcmp(s1, s2, n) == 0;
-+}
-+
-+/* takes a comma separated list of log masks. Return 0 if error. */
-+int cpu_str_to_log_mask(const char *str)
-+{
-+ CPULogItem *item;
-+ int mask;
-+ const char *p, *p1;
-+
-+ p = str;
-+ mask = 0;
-+ for(;;) {
-+ p1 = strchr(p, ',');
-+ if (!p1)
-+ p1 = p + strlen(p);
-+ if(cmp1(p,p1-p,"all")) {
-+ for(item = cpu_log_items; item->mask != 0; item++) {
-+ mask |= item->mask;
-+ }
-+ } else {
-+ for(item = cpu_log_items; item->mask != 0; item++) {
-+ if (cmp1(p, p1 - p, item->name))
-+ goto found;
-+ }
-+ return 0;
-+ }
-+ found:
-+ mask |= item->mask;
-+ if (*p1 != ',')
-+ break;
-+ p = p1 + 1;
-+ }
-+ return mask;
-+}
-+
-+void cpu_abort(CPUState *env, const char *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ fprintf(stderr, "qemu: fatal: ");
-+ vfprintf(stderr, fmt, ap);
-+ fprintf(stderr, "\n");
-+ va_end(ap);
-+ abort();
-+}
-+
-+
-+/* XXX: Simple implementation. Fix later */
-+#define MAX_MMIO 32
-+struct mmio_space {
-+ target_phys_addr_t start;
-+ unsigned long size;
-+ unsigned long io_index;
-+} mmio[MAX_MMIO];
-+unsigned long mmio_cnt;
-+
-+/* register physical memory. 'size' must be a multiple of the target
-+ page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
-+ io memory page */
-+void cpu_register_physical_memory(target_phys_addr_t start_addr,
-+ unsigned long size,
-+ unsigned long phys_offset)
-+{
-+ int i;
-+
-+ for (i = 0; i < mmio_cnt; i++) {
-+ if(mmio[i].start == start_addr) {
-+ mmio[i].io_index = phys_offset;
-+ mmio[i].size = size;
-+ return;
-+ }
-+ }
-+
-+ if (mmio_cnt == MAX_MMIO) {
-+ fprintf(logfile, "too many mmio regions\n");
-+ exit(-1);
-+ }
-+
-+ mmio[mmio_cnt].io_index = phys_offset;
-+ mmio[mmio_cnt].start = start_addr;
-+ mmio[mmio_cnt++].size = size;
-+}
-+
-+/* mem_read and mem_write are arrays of functions containing the
-+ function to access byte (index 0), word (index 1) and dword (index
-+ 2). All functions must be supplied. If io_index is non zero, the
-+ corresponding io zone is modified. If it is zero, a new io zone is
-+ allocated. The return value can be used with
-+ cpu_register_physical_memory(). (-1) is returned if error. */
-+int cpu_register_io_memory(int io_index,
-+ CPUReadMemoryFunc **mem_read,
-+ CPUWriteMemoryFunc **mem_write,
-+ void *opaque)
-+{
-+ int i;
-+
-+ if (io_index <= 0) {
-+ if (io_index >= IO_MEM_NB_ENTRIES)
-+ return -1;
-+ io_index = io_mem_nb++;
-+ } else {
-+ if (io_index >= IO_MEM_NB_ENTRIES)
-+ return -1;
-+ }
-+
-+ for(i = 0;i < 3; i++) {
-+ io_mem_read[io_index][i] = mem_read[i];
-+ io_mem_write[io_index][i] = mem_write[i];
-+ }
-+ io_mem_opaque[io_index] = opaque;
-+ return io_index << IO_MEM_SHIFT;
-+}
-+
-+CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
-+{
-+ return io_mem_write[io_index >> IO_MEM_SHIFT];
-+}
-+
-+CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
-+{
-+ return io_mem_read[io_index >> IO_MEM_SHIFT];
-+}
-+
-+#ifdef __ia64__
-+
-+#define __ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
-+#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
-+#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
-+
-+/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
-+ * So to emulate right behavior that guest OS is assumed, we need to flush
-+ * I/D cache here.
-+ */
-+static void sync_icache(unsigned long address, int len)
-+{
-+ int l;
-+
-+ for(l = 0; l < (len + 32); l += 32)
-+ __ia64_fc(address + l);
-+
-+ ia64_sync_i();
-+ ia64_srlz_i();
-+}
-+#endif
-+
-+/* physical memory access (slow version, mainly for debug) */
-+#if defined(CONFIG_USER_ONLY)
-+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
-+ int len, int is_write)
-+{
-+ int l, flags;
-+ target_ulong page;
-+
-+ while (len > 0) {
-+ page = addr & TARGET_PAGE_MASK;
-+ l = (page + TARGET_PAGE_SIZE) - addr;
-+ if (l > len)
-+ l = len;
-+ flags = page_get_flags(page);
-+ if (!(flags & PAGE_VALID))
-+ return;
-+ if (is_write) {
-+ if (!(flags & PAGE_WRITE))
-+ return;
-+ memcpy((uint8_t *)addr, buf, len);
-+ } else {
-+ if (!(flags & PAGE_READ))
-+ return;
-+ memcpy(buf, (uint8_t *)addr, len);
-+ }
-+ len -= l;
-+ buf += l;
-+ addr += l;
-+ }
-+}
-+#else
-+
-+int iomem_index(target_phys_addr_t addr)
-+{
-+ int i;
-+
-+ for (i = 0; i < mmio_cnt; i++) {
-+ unsigned long start, end;
-+
-+ start = mmio[i].start;
-+ end = mmio[i].start + mmio[i].size;
-+
-+ if ((addr >= start) && (addr < end)){
-+ return (mmio[i].io_index >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static inline int paddr_is_ram(target_phys_addr_t addr)
-+{
-+ /* Is this guest physical address RAM-backed? */
-+#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__))
-+ return ((addr < HVM_BELOW_4G_MMIO_START) ||
-+ (addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH));
-+#else
-+ return (addr < ram_size);
-+#endif
-+}
-+
-+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
-+ int len, int is_write)
-+{
-+ int l, io_index;
-+ uint8_t *ptr;
-+ uint32_t val;
-+
-+ while (len > 0) {
-+ /* How much can we copy before the next page boundary? */
-+ l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
-+ if (l > len)
-+ l = len;
-+
-+ io_index = iomem_index(addr);
-+ if (is_write) {
-+ if (io_index) {
-+ if (l >= 4 && ((addr & 3) == 0)) {
-+ /* 32 bit read access */
-+ val = ldl_raw(buf);
-+ io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
-+ l = 4;
-+ } else if (l >= 2 && ((addr & 1) == 0)) {
-+ /* 16 bit read access */
-+ val = lduw_raw(buf);
-+ io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
-+ l = 2;
-+ } else {
-+ /* 8 bit access */
-+ val = ldub_raw(buf);
-+ io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
-+ l = 1;
-+ }
-+ } else if (paddr_is_ram(addr)) {
-+ /* Reading from RAM */
-+ memcpy(phys_ram_base + addr, buf, l);
-+#ifdef __ia64__
-+ sync_icache((unsigned long)(phys_ram_base + addr), l);
-+#endif
-+ }
-+ } else {
-+ if (io_index) {
-+ if (l >= 4 && ((addr & 3) == 0)) {
-+ /* 32 bit read access */
-+ val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
-+ stl_raw(buf, val);
-+ l = 4;
-+ } else if (l >= 2 && ((addr & 1) == 0)) {
-+ /* 16 bit read access */
-+ val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
-+ stw_raw(buf, val);
-+ l = 2;
-+ } else {
-+ /* 8 bit access */
-+ val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
-+ stb_raw(buf, val);
-+ l = 1;
-+ }
-+ } else if (paddr_is_ram(addr)) {
-+ /* Reading from RAM */
-+ memcpy(buf, phys_ram_base + addr, l);
-+ } else {
-+ /* Neither RAM nor known MMIO space */
-+ memset(buf, 0xff, len);
-+ }
-+ }
-+ len -= l;
-+ buf += l;
-+ addr += l;
-+ }
-+}
-+#endif
-+
-+/* virtual memory access for debug */
-+int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
-+ uint8_t *buf, int len, int is_write)
-+{
-+ int l;
-+ target_ulong page, phys_addr;
-+
-+ while (len > 0) {
-+ page = addr & TARGET_PAGE_MASK;
-+ phys_addr = cpu_get_phys_page_debug(env, page);
-+ /* if no physical page mapped, return an error */
-+ if (phys_addr == -1)
-+ return -1;
-+ l = (page + TARGET_PAGE_SIZE) - addr;
-+ if (l > len)
-+ l = len;
-+ cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
-+ buf, l, is_write);
-+ len -= l;
-+ buf += l;
-+ addr += l;
-+ }
-+ return 0;
-+}
-+
-+void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
-+ int dirty_flags)
-+{
-+ unsigned long length;
-+ int i, mask, len;
-+ uint8_t *p;
-+
-+ start &= TARGET_PAGE_MASK;
-+ end = TARGET_PAGE_ALIGN(end);
-+
-+ length = end - start;
-+ if (length == 0)
-+ return;
-+ mask = ~dirty_flags;
-+ p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
-+ len = length >> TARGET_PAGE_BITS;
-+ for(i = 0; i < len; i++)
-+ p[i] &= mask;
-+
-+ return;
-+}
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/helper2.c 2007-05-11 10:04:05.000000000 +0100
-@@ -0,0 +1,542 @@
-+/*
-+ * i386 helpers (without register variable usage)
-+ *
-+ * Copyright (c) 2003 Fabrice Bellard
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+/*
-+ * Main cpu loop for handling I/O requests coming from a virtual machine
-+ * Copyright © 2004, Intel Corporation.
-+ * Copyright © 2005, International Business Machines Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU Lesser General Public License,
-+ * version 2.1, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ * more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this program; if not, write to the Free Software Foundation,
-+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
-+ */
-+#include <stdarg.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <inttypes.h>
-+#include <signal.h>
-+#include <assert.h>
-+
-+#include <limits.h>
-+#include <fcntl.h>
-+
-+#include <xenctrl.h>
-+#include <xen/hvm/ioreq.h>
-+
-+#include "cpu.h"
-+#include "exec-all.h"
-+
-+//#define DEBUG_MMU
-+
-+#ifdef USE_CODE_COPY
-+#include <asm/ldt.h>
-+#include <linux/unistd.h>
-+#include <linux/version.h>
-+
-+_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
-+#define modify_ldt_ldt_s user_desc
-+#endif
-+#endif /* USE_CODE_COPY */
-+
-+#include "vl.h"
-+
-+int domid = -1;
-+int vcpus = 1;
-+
-+int xc_handle;
-+
-+shared_iopage_t *shared_page = NULL;
-+
-+/* the evtchn fd for polling */
-+int xce_handle = -1;
-+
-+/* which vcpu we are serving */
-+int send_vcpu = 0;
-+
-+//the evtchn port for polling the notification,
-+#define NR_CPUS 32
-+evtchn_port_t ioreq_local_port[NR_CPUS];
-+
-+CPUX86State *cpu_x86_init(void)
-+{
-+ CPUX86State *env;
-+ static int inited;
-+ int i, rc;
-+
-+ env = qemu_mallocz(sizeof(CPUX86State));
-+ if (!env)
-+ return NULL;
-+ cpu_exec_init(env);
-+
-+ /* init various static tables */
-+ if (!inited) {
-+ inited = 1;
-+
-+ cpu_single_env = env;
-+
-+ xce_handle = xc_evtchn_open();
-+ if (xce_handle == -1) {
-+ perror("open");
-+ return NULL;
-+ }
-+
-+ /* FIXME: how about if we overflow the page here? */
-+ for (i = 0; i < vcpus; i++) {
-+ rc = xc_evtchn_bind_interdomain(
-+ xce_handle, domid, shared_page->vcpu_iodata[i].vp_eport);
-+ if (rc == -1) {
-+ fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
-+ return NULL;
-+ }
-+ ioreq_local_port[i] = rc;
-+ }
-+ }
-+
-+ return env;
-+}
-+
-+/* called from main_cpu_reset */
-+void cpu_reset(CPUX86State *env)
-+{
-+}
-+
-+void cpu_x86_close(CPUX86State *env)
-+{
-+ free(env);
-+}
-+
-+
-+void cpu_dump_state(CPUState *env, FILE *f,
-+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
-+ int flags)
-+{
-+}
-+
-+/***********************************************************/
-+/* x86 mmu */
-+/* XXX: add PGE support */
-+
-+void cpu_x86_set_a20(CPUX86State *env, int a20_state)
-+{
-+ a20_state = (a20_state != 0);
-+ if (a20_state != ((env->a20_mask >> 20) & 1)) {
-+#if defined(DEBUG_MMU)
-+ printf("A20 update: a20=%d\n", a20_state);
-+#endif
-+ env->a20_mask = 0xffefffff | (a20_state << 20);
-+ }
-+}
-+
-+target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-+{
-+ return addr;
-+}
-+
-+//some functions to handle the io req packet
-+void sp_info()
-+{
-+ ioreq_t *req;
-+ int i;
-+
-+ for (i = 0; i < vcpus; i++) {
-+ req = &(shared_page->vcpu_iodata[i].vp_ioreq);
-+ term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
-+ term_printf(" req state: %x, ptr: %x, addr: %"PRIx64", "
-+ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
-+ req->state, req->data_is_ptr, req->addr,
-+ req->data, req->count, req->size);
-+ term_printf(" IO totally occurred on this vcpu: %"PRIx64"\n",
-+ req->io_count);
-+ }
-+}
-+
-+//get the ioreq packets from share mem
-+static ioreq_t *__cpu_get_ioreq(int vcpu)
-+{
-+ ioreq_t *req;
-+
-+ req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
-+
-+ if (req->state != STATE_IOREQ_READY) {
-+ fprintf(logfile, "I/O request not ready: "
-+ "%x, ptr: %x, port: %"PRIx64", "
-+ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
-+ req->state, req->data_is_ptr, req->addr,
-+ req->data, req->count, req->size);
-+ return NULL;
-+ }
-+
-+ rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
-+
-+ req->state = STATE_IOREQ_INPROCESS;
-+ return req;
-+}
-+
-+//use poll to get the port notification
-+//ioreq_vec--out,the
-+//retval--the number of ioreq packet
-+static ioreq_t *cpu_get_ioreq(void)
-+{
-+ int i;
-+ evtchn_port_t port;
-+
-+ port = xc_evtchn_pending(xce_handle);
-+ if (port != -1) {
-+ for ( i = 0; i < vcpus; i++ )
-+ if ( ioreq_local_port[i] == port )
-+ break;
-+
-+ if ( i == vcpus ) {
-+ fprintf(logfile, "Fatal error while trying to get io event!\n");
-+ exit(1);
-+ }
-+
-+ // unmask the wanted port again
-+ xc_evtchn_unmask(xce_handle, port);
-+
-+ //get the io packet from shared memory
-+ send_vcpu = i;
-+ return __cpu_get_ioreq(i);
-+ }
-+
-+ //read error or read nothing
-+ return NULL;
-+}
-+
-+unsigned long do_inp(CPUState *env, unsigned long addr, unsigned long size)
-+{
-+ switch(size) {
-+ case 1:
-+ return cpu_inb(env, addr);
-+ case 2:
-+ return cpu_inw(env, addr);
-+ case 4:
-+ return cpu_inl(env, addr);
-+ default:
-+ fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
-+ exit(-1);
-+ }
-+}
-+
-+void do_outp(CPUState *env, unsigned long addr,
-+ unsigned long size, unsigned long val)
-+{
-+ switch(size) {
-+ case 1:
-+ return cpu_outb(env, addr, val);
-+ case 2:
-+ return cpu_outw(env, addr, val);
-+ case 4:
-+ return cpu_outl(env, addr, val);
-+ default:
-+ fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
-+ exit(-1);
-+ }
-+}
-+
-+extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
-+ int len, int is_write);
-+
-+static inline void read_physical(uint64_t addr, unsigned long size, void *val)
-+{
-+ return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0);
-+}
-+
-+static inline void write_physical(uint64_t addr, unsigned long size, void *val)
-+{
-+ return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1);
-+}
-+
-+void cpu_ioreq_pio(CPUState *env, ioreq_t *req)
-+{
-+ int i, sign;
-+
-+ sign = req->df ? -1 : 1;
-+
-+ if (req->dir == IOREQ_READ) {
-+ if (!req->data_is_ptr) {
-+ req->data = do_inp(env, req->addr, req->size);
-+ } else {
-+ unsigned long tmp;
-+
-+ for (i = 0; i < req->count; i++) {
-+ tmp = do_inp(env, req->addr, req->size);
-+ write_physical((target_phys_addr_t) req->data
-+ + (sign * i * req->size),
-+ req->size, &tmp);
-+ }
-+ }
-+ } else if (req->dir == IOREQ_WRITE) {
-+ if (!req->data_is_ptr) {
-+ do_outp(env, req->addr, req->size, req->data);
-+ } else {
-+ for (i = 0; i < req->count; i++) {
-+ unsigned long tmp;
-+
-+ read_physical((target_phys_addr_t) req->data
-+ + (sign * i * req->size),
-+ req->size, &tmp);
-+ do_outp(env, req->addr, req->size, tmp);
-+ }
-+ }
-+ }
-+}
-+
-+void cpu_ioreq_move(CPUState *env, ioreq_t *req)
-+{
-+ int i, sign;
-+
-+ sign = req->df ? -1 : 1;
-+
-+ if (!req->data_is_ptr) {
-+ if (req->dir == IOREQ_READ) {
-+ for (i = 0; i < req->count; i++) {
-+ read_physical(req->addr
-+ + (sign * i * req->size),
-+ req->size, &req->data);
-+ }
-+ } else if (req->dir == IOREQ_WRITE) {
-+ for (i = 0; i < req->count; i++) {
-+ write_physical(req->addr
-+ + (sign * i * req->size),
-+ req->size, &req->data);
-+ }
-+ }
-+ } else {
-+ unsigned long tmp;
-+
-+ if (req->dir == IOREQ_READ) {
-+ for (i = 0; i < req->count; i++) {
-+ read_physical(req->addr
-+ + (sign * i * req->size),
-+ req->size, &tmp);
-+ write_physical((target_phys_addr_t )req->data
-+ + (sign * i * req->size),
-+ req->size, &tmp);
-+ }
-+ } else if (req->dir == IOREQ_WRITE) {
-+ for (i = 0; i < req->count; i++) {
-+ read_physical((target_phys_addr_t) req->data
-+ + (sign * i * req->size),
-+ req->size, &tmp);
-+ write_physical(req->addr
-+ + (sign * i * req->size),
-+ req->size, &tmp);
-+ }
-+ }
-+ }
-+}
-+
-+void cpu_ioreq_and(CPUState *env, ioreq_t *req)
-+{
-+ unsigned long tmp1, tmp2;
-+
-+ if (req->data_is_ptr != 0)
-+ hw_error("expected scalar value");
-+
-+ read_physical(req->addr, req->size, &tmp1);
-+ if (req->dir == IOREQ_WRITE) {
-+ tmp2 = tmp1 & (unsigned long) req->data;
-+ write_physical(req->addr, req->size, &tmp2);
-+ }
-+ req->data = tmp1;
-+}
-+
-+void cpu_ioreq_add(CPUState *env, ioreq_t *req)
-+{
-+ unsigned long tmp1, tmp2;
-+
-+ if (req->data_is_ptr != 0)
-+ hw_error("expected scalar value");
-+
-+ read_physical(req->addr, req->size, &tmp1);
-+ if (req->dir == IOREQ_WRITE) {
-+ tmp2 = tmp1 + (unsigned long) req->data;
-+ write_physical(req->addr, req->size, &tmp2);
-+ }
-+ req->data = tmp1;
-+}
-+
-+void cpu_ioreq_sub(CPUState *env, ioreq_t *req)
-+{
-+ unsigned long tmp1, tmp2;
-+
-+ if (req->data_is_ptr != 0)
-+ hw_error("expected scalar value");
-+
-+ read_physical(req->addr, req->size, &tmp1);
-+ if (req->dir == IOREQ_WRITE) {
-+ tmp2 = tmp1 - (unsigned long) req->data;
-+ write_physical(req->addr, req->size, &tmp2);
-+ }
-+ req->data = tmp1;
-+}
-+
-+void cpu_ioreq_or(CPUState *env, ioreq_t *req)
-+{
-+ unsigned long tmp1, tmp2;
-+
-+ if (req->data_is_ptr != 0)
-+ hw_error("expected scalar value");
-+
-+ read_physical(req->addr, req->size, &tmp1);
-+ if (req->dir == IOREQ_WRITE) {
-+ tmp2 = tmp1 | (unsigned long) req->data;
-+ write_physical(req->addr, req->size, &tmp2);
-+ }
-+ req->data = tmp1;
-+}
-+
-+void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
-+{
-+ unsigned long tmp1, tmp2;
-+
-+ if (req->data_is_ptr != 0)
-+ hw_error("expected scalar value");
-+
-+ read_physical(req->addr, req->size, &tmp1);
-+ if (req->dir == IOREQ_WRITE) {
-+ tmp2 = tmp1 ^ (unsigned long) req->data;
-+ write_physical(req->addr, req->size, &tmp2);
-+ }
-+ req->data = tmp1;
-+}
-+
-+void cpu_ioreq_xchg(CPUState *env, ioreq_t *req)
-+{
-+ unsigned long tmp1;
-+
-+ if (req->data_is_ptr != 0)
-+ hw_error("expected scalar value");
-+
-+ read_physical(req->addr, req->size, &tmp1);
-+ write_physical(req->addr, req->size, &req->data);
-+ req->data = tmp1;
-+}
-+
-+void cpu_handle_ioreq(void *opaque)
-+{
-+ extern int vm_running;
-+ extern int shutdown_requested;
-+ CPUState *env = opaque;
-+ ioreq_t *req = cpu_get_ioreq();
-+
-+ if (req) {
-+ if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) {
-+ if (req->size != 4)
-+ req->data &= (1UL << (8 * req->size))-1;
-+ }
-+
-+ switch (req->type) {
-+ case IOREQ_TYPE_PIO:
-+ cpu_ioreq_pio(env, req);
-+ break;
-+ case IOREQ_TYPE_COPY:
-+ cpu_ioreq_move(env, req);
-+ break;
-+ case IOREQ_TYPE_AND:
-+ cpu_ioreq_and(env, req);
-+ break;
-+ case IOREQ_TYPE_ADD:
-+ cpu_ioreq_add(env, req);
-+ break;
-+ case IOREQ_TYPE_SUB:
-+ cpu_ioreq_sub(env, req);
-+ break;
-+ case IOREQ_TYPE_OR:
-+ cpu_ioreq_or(env, req);
-+ break;
-+ case IOREQ_TYPE_XOR:
-+ cpu_ioreq_xor(env, req);
-+ break;
-+ case IOREQ_TYPE_XCHG:
-+ cpu_ioreq_xchg(env, req);
-+ break;
-+ default:
-+ hw_error("Invalid ioreq type 0x%x\n", req->type);
-+ }
-+
-+ if (req->state != STATE_IOREQ_INPROCESS) {
-+ fprintf(logfile, "Badness in I/O request ... not in service?!: "
-+ "%x, ptr: %x, port: %"PRIx64", "
-+ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
-+ req->state, req->data_is_ptr, req->addr,
-+ req->data, req->count, req->size);
-+ destroy_hvm_domain();
-+ return;
-+ }
-+
-+ wmb(); /* Update ioreq contents /then/ update state. */
-+
-+ /*
-+ * We do this before we send the response so that the tools
-+ * have the opportunity to pick up on the reset before the
-+ * guest resumes and does a hlt with interrupts disabled which
-+ * causes Xen to powerdown the domain.
-+ */
-+ if (vm_running) {
-+ if (shutdown_requested) {
-+ fprintf(logfile, "shutdown requested in cpu_handle_ioreq\n");
-+ destroy_hvm_domain();
-+ }
-+ if (reset_requested) {
-+ fprintf(logfile, "reset requested in cpu_handle_ioreq.\n");
-+ qemu_system_reset();
-+ reset_requested = 0;
-+ }
-+ }
-+
-+ req->state = STATE_IORESP_READY;
-+ xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
-+ }
-+}
-+
-+int main_loop(void)
-+{
-+ extern int vm_running;
-+ extern int shutdown_requested;
-+ CPUState *env = cpu_single_env;
-+ int evtchn_fd = xc_evtchn_fd(xce_handle);
-+
-+ qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
-+
-+ while (1) {
-+ if (vm_running) {
-+ if (shutdown_requested)
-+ break;
-+ }
-+
-+ /* Wait up to 10 msec. */
-+ main_loop_wait(10);
-+ }
-+ return 0;
-+}
-Index: ioemu/target-i386-dm/i8259-dm.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/i8259-dm.c 2007-05-11 10:04:04.000000000 +0100
-@@ -0,0 +1,67 @@
-+/* Xen 8259 stub for interrupt controller emulation
-+ *
-+ * Copyright (c) 2003-2004 Fabrice Bellard
-+ * Copyright (c) 2005 Intel corperation
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+#include "vl.h"
-+#include "xenctrl.h"
-+#include <xen/hvm/ioreq.h>
-+#include <stdio.h>
-+#include "cpu.h"
-+#include "cpu-all.h"
-+
-+struct PicState2 {
-+};
-+
-+void pic_set_irq_new(void *opaque, int irq, int level)
-+{
-+ xc_hvm_set_irq_level(xc_handle, domid, irq, level);
-+}
-+
-+/* obsolete function */
-+void pic_set_irq(int irq, int level)
-+{
-+ pic_set_irq_new(isa_pic, irq, level);
-+}
-+
-+void irq_info(void)
-+{
-+ term_printf("irq statistic code not compiled.\n");
-+}
-+
-+void pic_info(void)
-+{
-+ term_printf("pic_info code not compiled.\n");
-+}
-+
-+PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque)
-+{
-+ PicState2 *s;
-+ s = qemu_mallocz(sizeof(PicState2));
-+ if (!s)
-+ return NULL;
-+ return s;
-+}
-+
-+void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
-+ void *alt_irq_opaque)
-+{
-+}
-Index: ioemu/target-i386-dm/qemu-dm.debug
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/qemu-dm.debug 2007-05-11 10:01:09.000000000 +0100
-@@ -0,0 +1,10 @@
-+#!/bin/sh
-+
-+if [ "`arch`" = "x86_64" ]; then
-+ LIBDIR="lib64"
-+else
-+ LIBDIR="lib"
-+fi
-+echo $* > /tmp/args
-+echo $DISPLAY >> /tmp/args
-+exec /usr/$LIBDIR/xen/bin/qemu-dm $*
-Index: ioemu/target-i386-dm/qemu-ifup
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/qemu-ifup 2007-06-03 11:50:25.000000000 +1000
-@@ -0,0 +1,37 @@
-+#!/bin/sh
-+
-+#. /etc/rc.d/init.d/functions
-+#ulimit -c unlimited
-+
-+echo 'config qemu network with xen bridge for ' $*
-+
-+bridge=$2
-+
-+#
-+# Old style bridge setup with netloop, used to have a bridge name
-+# of xenbrX, enslaving pethX and vif0.X, and then configuring
-+# eth0.
-+#
-+# New style bridge setup does not use netloop, so the bridge name
-+# is ethX and the physical device is enslaved pethX
-+#
-+# So if...
-+#
-+# - User asks for xenbrX
-+# - AND xenbrX doesn't exist
-+# - AND there is a ethX device which is a bridge
-+#
-+# ..then we translate xenbrX to ethX
-+#
-+# This lets old config files work without modification
-+#
-+if [ ! -e "/sys/class/net/$bridge" ] && [ -z "${bridge##xenbr*}" ]
-+then
-+ if [ -e "/sys/class/net/eth${bridge#xenbr}/bridge" ]
-+ then
-+ bridge="eth${bridge#xenbr}"
-+ fi
-+fi
-+
-+ifconfig $1 0.0.0.0 up
-+brctl addif $bridge $1
diff --git a/tools/ioemu/patches/qemu-timer b/tools/ioemu/patches/qemu-timer
deleted file mode 100644
index cfb659c746..0000000000
--- a/tools/ioemu/patches/qemu-timer
+++ /dev/null
@@ -1,54 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:11:56.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:11:59.000000000 +0100
-@@ -912,6 +912,16 @@
- }
- }
-
-+#ifdef CONFIG_DM
-+static void timer_save(QEMUFile *f, void *opaque)
-+{
-+}
-+
-+static int timer_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ return 0;
-+}
-+#else /* !CONFIG_DM */
- static void timer_save(QEMUFile *f, void *opaque)
- {
- if (cpu_ticks_enabled) {
-@@ -1032,6 +1042,8 @@
-
- #endif /* !defined(_WIN32) */
-
-+#endif /* !CONFIG_DM */
-+
- static void init_timer_alarm(void)
- {
- #ifdef _WIN32
-@@ -1063,12 +1075,15 @@
- pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
- #else
- {
-+#ifndef CONFIG_DM
- struct sigaction act;
- struct itimerval itv;
-+#endif
-
- /* get times() syscall frequency */
- timer_freq = sysconf(_SC_CLK_TCK);
-
-+#ifndef CONFIG_DM
- /* timer signal */
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
-@@ -1114,6 +1129,7 @@
- pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
- PIT_FREQ) / 1000000;
- }
-+#endif /* CONFIG_DM */
- }
- #endif
- }
diff --git a/tools/ioemu/patches/qemu-tunable-ide-write-cache b/tools/ioemu/patches/qemu-tunable-ide-write-cache
deleted file mode 100644
index b1742245b9..0000000000
--- a/tools/ioemu/patches/qemu-tunable-ide-write-cache
+++ /dev/null
@@ -1,56 +0,0 @@
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-10 15:04:31.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-10 15:05:02.000000000 +0100
-@@ -306,6 +306,7 @@
- PCIDevice *pci_dev;
- struct BMDMAState *bmdma;
- int drive_serial;
-+ int write_cache;
- /* ide regs */
- uint8_t feature;
- uint8_t error;
-@@ -921,6 +922,9 @@
- }
- ide_set_sector(s, sector_num + n);
-
-+ if (!s->write_cache)
-+ bdrv_flush(s->bs);
-+
- #ifdef TARGET_I386
- if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
- /* It seems there is a bug in the Windows 2000 installer HDD
-@@ -956,6 +960,9 @@
-
- /* end of transfer ? */
- if (s->nsector == 0) {
-+ /* Ensure the data hit disk before telling the guest OS so. */
-+ if (!s->write_cache)
-+ bdrv_flush(s->bs);
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- eot:
-@@ -1849,7 +1856,15 @@
- /* XXX: valid for CDROM ? */
- switch(s->feature) {
- case 0x02: /* write cache enable */
-+ s->write_cache = 1;
-+ s->status = READY_STAT | SEEK_STAT;
-+ ide_set_irq(s);
-+ break;
- case 0x82: /* write cache disable */
-+ s->write_cache = 0;
-+ s->status = READY_STAT | SEEK_STAT;
-+ ide_set_irq(s);
-+ break;
- case 0xaa: /* read look-ahead enable */
- case 0x55: /* read look-ahead disable */
- s->status = READY_STAT | SEEK_STAT;
-@@ -2282,6 +2297,7 @@
- s->irq = irq;
- s->sector_write_timer = qemu_new_timer(vm_clock,
- ide_sector_write_timer_cb, s);
-+ s->write_cache = 0;
- ide_reset(s);
- }
- }
diff --git a/tools/ioemu/patches/remove-pci-bridge-setup b/tools/ioemu/patches/remove-pci-bridge-setup
deleted file mode 100644
index d3a49f542a..0000000000
--- a/tools/ioemu/patches/remove-pci-bridge-setup
+++ /dev/null
@@ -1,240 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID a8d31d5ce2589762c3226185deeca3afca47a698
-# Parent b8cc9ffda0a3dc449b026c72c97f78dea2e6f114
-[HVM] Move PCI and PCI-ISA bridge setup to hvmloader.
-Signed-off-by: Keir Fraser <keir@xensource.com>
-
-Index: ioemu/target-i386-dm/piix_pci-dm.c
-===================================================================
---- ioemu.orig/target-i386-dm/piix_pci-dm.c 2007-05-09 14:07:46.000000000 +0100
-+++ ioemu/target-i386-dm/piix_pci-dm.c 2007-05-09 14:07:56.000000000 +0100
-@@ -220,228 +220,3 @@
- piix3_reset(d);
- return d->devfn;
- }
--
--/***********************************************************/
--/* XXX: the following should be moved to the PC BIOS */
--
--static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
--{
-- return cpu_inb(NULL, addr);
--}
--
--static void isa_outb(uint32_t val, uint32_t addr)
--{
-- cpu_outb(NULL, addr, val);
--}
--
--static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
--{
-- return cpu_inw(NULL, addr);
--}
--
--static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
--{
-- cpu_outw(NULL, addr, val);
--}
--
--static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
--{
-- return cpu_inl(NULL, addr);
--}
--
--static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
--{
-- cpu_outl(NULL, addr, val);
--}
--
--static uint32_t pci_bios_io_addr;
--static uint32_t pci_bios_mem_addr;
--/* host irqs corresponding to PCI irqs A-D */
--static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
--
--static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
--{
-- PCIBus *s = d->bus;
-- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-- pci_data_write(s, addr, val, 4);
--}
--
--static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
--{
-- PCIBus *s = d->bus;
-- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-- pci_data_write(s, addr, val, 2);
--}
--
--static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
--{
-- PCIBus *s = d->bus;
-- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-- pci_data_write(s, addr, val, 1);
--}
--
--static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
--{
-- PCIBus *s = d->bus;
-- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-- return pci_data_read(s, addr, 4);
--}
--
--static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
--{
-- PCIBus *s = d->bus;
-- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-- return pci_data_read(s, addr, 2);
--}
--
--static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
--{
-- PCIBus *s = d->bus;
-- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
-- return pci_data_read(s, addr, 1);
--}
--
--static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
--{
-- PCIIORegion *r;
-- uint16_t cmd;
-- uint32_t ofs;
--
-- if ( region_num == PCI_ROM_SLOT ) {
-- ofs = 0x30;
-- }else{
-- ofs = 0x10 + region_num * 4;
-- }
--
-- pci_config_writel(d, ofs, addr);
-- r = &d->io_regions[region_num];
--
-- /* enable memory mappings */
-- cmd = pci_config_readw(d, PCI_COMMAND);
-- if ( region_num == PCI_ROM_SLOT )
-- cmd |= 2;
-- else if (r->type & PCI_ADDRESS_SPACE_IO)
-- cmd |= 1;
-- else
-- cmd |= 2;
-- pci_config_writew(d, PCI_COMMAND, cmd);
--}
--
--static void pci_bios_init_device(PCIDevice *d)
--{
-- int class;
-- PCIIORegion *r;
-- uint32_t *paddr;
-- int i, pin, pic_irq, vendor_id, device_id;
--
-- class = pci_config_readw(d, PCI_CLASS_DEVICE);
-- vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
-- device_id = pci_config_readw(d, PCI_DEVICE_ID);
-- switch(class) {
-- case 0x0101:
-- if (vendor_id == 0x8086 && device_id == 0x7010) {
-- /* PIIX3 IDE */
-- pci_config_writew(d, 0x40, 0x8000); // enable IDE0
-- pci_config_writew(d, 0x42, 0x8000); // enable IDE1
-- goto default_map;
-- } else {
-- /* IDE: we map it as in ISA mode */
-- pci_set_io_region_addr(d, 0, 0x1f0);
-- pci_set_io_region_addr(d, 1, 0x3f4);
-- pci_set_io_region_addr(d, 2, 0x170);
-- pci_set_io_region_addr(d, 3, 0x374);
-- }
-- break;
-- case 0x0680:
-- if (vendor_id == 0x8086 && device_id == 0x7113) {
-- /*
-- * PIIX4 ACPI PM.
-- * Special device with special PCI config space. No ordinary BARs.
-- */
-- pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
-- pci_config_writew(d, 0x22, 0x0000);
-- pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
-- pci_config_writew(d, 0x3d, 0x0001);
-- }
-- break;
-- case 0x0300:
-- if (vendor_id != 0x1234)
-- goto default_map;
-- /* VGA: map frame buffer to default Bochs VBE address */
-- pci_set_io_region_addr(d, 0, 0xE0000000);
-- break;
-- case 0x0800:
-- /* PIC */
-- vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
-- device_id = pci_config_readw(d, PCI_DEVICE_ID);
-- if (vendor_id == 0x1014) {
-- /* IBM */
-- if (device_id == 0x0046 || device_id == 0xFFFF) {
-- /* MPIC & MPIC2 */
-- pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
-- }
-- }
-- break;
-- case 0xff00:
-- if (vendor_id == 0x0106b &&
-- (device_id == 0x0017 || device_id == 0x0022)) {
-- /* macio bridge */
-- pci_set_io_region_addr(d, 0, 0x80800000);
-- }
-- break;
-- default:
-- default_map:
-- /* default memory mappings */
-- for(i = 0; i < PCI_NUM_REGIONS; i++) {
-- r = &d->io_regions[i];
-- if (r->size) {
-- if (r->type & PCI_ADDRESS_SPACE_IO)
-- paddr = &pci_bios_io_addr;
-- else
-- paddr = &pci_bios_mem_addr;
-- *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
-- pci_set_io_region_addr(d, i, *paddr);
-- *paddr += r->size;
-- }
-- }
-- break;
-- }
--
-- /* map the interrupt */
-- pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
-- if (pin != 0) {
-- pin = pci_slot_get_pirq(d, pin - 1);
-- pic_irq = pci_irqs[pin];
-- pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
-- }
--}
--
--/*
-- * This function initializes the PCI devices as a normal PCI BIOS
-- * would do. It is provided just in case the BIOS has no support for
-- * PCI.
-- */
--void pci_bios_init(void)
--{
-- int i, irq;
-- uint8_t elcr[2];
--
-- pci_bios_io_addr = 0xc000;
-- pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START;
--
-- /* activate IRQ mappings */
-- elcr[0] = 0x00;
-- elcr[1] = 0x00;
-- for(i = 0; i < 4; i++) {
-- irq = pci_irqs[i];
-- /* set to trigger level */
-- elcr[irq >> 3] |= (1 << (irq & 7));
-- /* activate irq remapping in PIIX */
-- pci_config_writeb(piix3_dev, 0x60 + i, irq);
-- }
-- isa_outb(elcr[0], 0x4d0);
-- isa_outb(elcr[1], 0x4d1);
--
-- pci_for_each_device(pci_bios_init_device);
--}
--
diff --git a/tools/ioemu/patches/rtl8139-bound-chaining b/tools/ioemu/patches/rtl8139-bound-chaining
deleted file mode 100644
index 2ff2b208b9..0000000000
--- a/tools/ioemu/patches/rtl8139-bound-chaining
+++ /dev/null
@@ -1,36 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID 075f4ffdbbce5527ba525a515abe320703d17a0e
-# Parent 51edd3c6a4d861db6ce1c9a02251ed49213c3002
-[QEMU] rtl8139: Disallow chaining above 64K
-
-As it stands the 8139C+ TX chaining is only bounded by realloc failure.
-This is contrary to how the real hardware operates. It also has DoS
-potential when ioemu runs in dom0.
-
-This patch makes any attempt to chain a frame beyond 64K fail
-immediately.
-
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-
-Index: ioemu/hw/rtl8139.c
-===================================================================
---- ioemu.orig/hw/rtl8139.c 2007-05-03 20:36:50.000000000 +0100
-+++ ioemu/hw/rtl8139.c 2007-05-03 20:39:45.000000000 +0100
-@@ -1999,12 +1999,12 @@
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len));
- }
-
-- while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
-+ if (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
- {
-- s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
-- s->cplus_txbuffer = realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
-+ free(s->cplus_txbuffer);
-+ s->cplus_txbuffer = NULL;
-
-- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len));
-+ DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space exceeded: %d\n", s->cplus_txbuffer_offset + txsize));
- }
-
- if (!s->cplus_txbuffer)
diff --git a/tools/ioemu/patches/scsi b/tools/ioemu/patches/scsi
deleted file mode 100644
index 8c83bb22c4..0000000000
--- a/tools/ioemu/patches/scsi
+++ /dev/null
@@ -1,194 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:35:25.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:35:25.000000000 +0100
-@@ -124,7 +124,7 @@
- IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
- /* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
- to store the VM snapshots */
--BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
-+BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS + 1], *fd_table[MAX_FD];
- /* point to the block driver where the snapshots are managed */
- BlockDriverState *bs_snapshots;
- int vga_ram_size;
-@@ -1526,7 +1526,7 @@
- case 's':
- {
- int i;
-- for (i = 0; i < MAX_DISKS; i++) {
-+ for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (bs_table[i])
- bdrv_commit(bs_table[i]);
- }
-@@ -6954,7 +6954,7 @@
- int snapshot, linux_boot;
- const char *initrd_filename;
- #ifndef CONFIG_DM
-- const char *hd_filename[MAX_DISKS];
-+ const char *hd_filename[MAX_DISKS + MAX_SCSI_DISKS];
- #endif /* !CONFIG_DM */
- const char *fd_filename[MAX_FD];
- const char *kernel_filename, *kernel_cmdline;
-@@ -7023,7 +7023,7 @@
- for(i = 0; i < MAX_FD; i++)
- fd_filename[i] = NULL;
- #ifndef CONFIG_DM
-- for(i = 0; i < MAX_DISKS; i++)
-+ for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
- hd_filename[i] = NULL;
- #endif /* !CONFIG_DM */
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
-@@ -7714,7 +7714,7 @@
- }
-
- /* open the virtual block devices */
-- for(i = 0; i < MAX_DISKS; i++) {
-+ for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (hd_filename[i]) {
- if (!bs_table[i]) {
- char buf[64];
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:35:25.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:35:25.000000000 +0100
-@@ -963,8 +963,9 @@
-
- /* ide.c */
- #define MAX_DISKS 4
-+#define MAX_SCSI_DISKS 7
-
--extern BlockDriverState *bs_table[MAX_DISKS + 1];
-+extern BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS + 1];
-
- void isa_ide_init(int iobase, int iobase2, int irq,
- BlockDriverState *hd0, BlockDriverState *hd1);
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-10 15:35:25.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-10 15:35:25.000000000 +0100
-@@ -761,7 +761,6 @@
- piix4_smbus_register_device(eeprom, 0x50 + i);
- }
- }
--#endif /* !CONFIG_DM */
-
- if (i440fx_state) {
- i440fx_init_memory_mappings(i440fx_state);
-@@ -783,6 +782,18 @@
- lsi_scsi_attach(scsi, bdrv, -1);
- }
- #endif
-+#else
-+ if (pci_enabled) {
-+ void *scsi = NULL;
-+ for (i = 0; i < MAX_SCSI_DISKS ; i++) {
-+ if (!bs_table[i + MAX_DISKS])
-+ continue;
-+ if (!scsi)
-+ scsi = lsi_scsi_init(pci_bus, -1);
-+ lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1);
-+ }
-+ }
-+#endif /* !CONFIG_DM */
- }
-
- static void pc_init_pci(uint64_t ram_size, int vga_ram_size, char *boot_device,
-Index: ioemu/xenstore.c
-===================================================================
---- ioemu.orig/xenstore.c 2007-05-10 15:35:25.000000000 +0100
-+++ ioemu/xenstore.c 2007-05-10 15:35:25.000000000 +0100
-@@ -18,7 +18,7 @@
- #include <fcntl.h>
-
- static struct xs_handle *xsh = NULL;
--static char *media_filename[MAX_DISKS];
-+static char *media_filename[MAX_DISKS + MAX_SCSI_DISKS];
- static QEMUTimer *insert_timer = NULL;
-
- #define UWAIT_MAX (30*1000000) /* thirty seconds */
-@@ -44,7 +44,7 @@
- {
- int i;
-
-- for (i = 0; i < MAX_DISKS; i++) {
-+ for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (media_filename[i] && bs_table[i]) {
- do_change(bs_table[i]->device_name, media_filename[i]);
- free(media_filename[i]);
-@@ -83,10 +83,10 @@
- char *buf = NULL, *path;
- char *fpath = NULL, *bpath = NULL,
- *dev = NULL, *params = NULL, *type = NULL;
-- int i;
-+ int i, is_scsi;
- unsigned int len, num, hd_index;
-
-- for(i = 0; i < MAX_DISKS; i++)
-+ for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
- media_filename[i] = NULL;
-
- xsh = xs_daemon_open();
-@@ -123,10 +123,11 @@
- dev = xs_read(xsh, XBT_NULL, buf, &len);
- if (dev == NULL)
- continue;
-- if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
-+ is_scsi = !strncmp(dev, "sd", 2);
-+ if ((strncmp(dev, "hd", 2) && !is_scsi) || strlen(dev) != 3 )
- continue;
- hd_index = dev[2] - 'a';
-- if (hd_index >= MAX_DISKS)
-+ if (hd_index >= (is_scsi ? MAX_SCSI_DISKS : MAX_DISKS))
- continue;
- /* read the type of the device */
- if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
-@@ -163,7 +164,7 @@
- }
- }
-
-- bs_table[hd_index] = bdrv_new(dev);
-+ bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)] = bdrv_new(dev);
- /* check if it is a cdrom */
- if (type && !strcmp(type, "cdrom")) {
- bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
-@@ -172,7 +173,8 @@
- }
- /* open device now if media present */
- if (params[0]) {
-- if (bdrv_open(bs_table[hd_index], params, 0 /* snapshot */) < 0)
-+ if (bdrv_open(bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)],
-+ params, 0 /* snapshot */) < 0)
- fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
- params);
- }
-Index: ioemu/monitor.c
-===================================================================
---- ioemu.orig/monitor.c 2007-05-10 15:32:53.000000000 +0100
-+++ ioemu/monitor.c 2007-05-10 15:35:25.000000000 +0100
-@@ -209,7 +209,7 @@
- int i, all_devices;
-
- all_devices = !strcmp(device, "all");
-- for (i = 0; i < MAX_DISKS; i++) {
-+ for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (bs_table[i]) {
- if (all_devices ||
- !strcmp(bdrv_get_device_name(bs_table[i]), device))
-Index: ioemu/hw/lsi53c895a.c
-===================================================================
---- ioemu.orig/hw/lsi53c895a.c 2007-05-10 15:32:53.000000000 +0100
-+++ ioemu/hw/lsi53c895a.c 2007-05-10 15:35:25.000000000 +0100
-@@ -1351,8 +1351,13 @@
- shift = (offset & 3) * 8;
- return (s->scratch[n] >> shift) & 0xff;
- }
-+#ifndef CONFIG_DM
- BADF("readb 0x%x\n", offset);
- exit(1);
-+#else
-+ /* XEN: This path can be triggered (e.g. ASPI8DOS.SYS reads 0x8). */
-+ return 0;
-+#endif
- #undef CASE_GET_REG32
- }
-
diff --git a/tools/ioemu/patches/sdl-mouse-invisible-wall b/tools/ioemu/patches/sdl-mouse-invisible-wall
deleted file mode 100644
index c0d7eef028..0000000000
--- a/tools/ioemu/patches/sdl-mouse-invisible-wall
+++ /dev/null
@@ -1,25 +0,0 @@
-Index: ioemu/sdl.c
-===================================================================
---- ioemu.orig/sdl.c 2006-07-12 11:35:01.450735012 +0100
-+++ ioemu/sdl.c 2006-07-12 11:35:03.377493622 +0100
-@@ -280,13 +280,18 @@
-
- static void sdl_hide_cursor(void)
- {
-- SDL_SetCursor(sdl_cursor_hidden);
-+ if (kbd_mouse_is_absolute()) {
-+ SDL_ShowCursor(1);
-+ SDL_SetCursor(sdl_cursor_hidden);
-+ } else {
-+ SDL_ShowCursor(0);
-+ }
- }
-
- static void sdl_show_cursor(void)
- {
- if (!kbd_mouse_is_absolute()) {
-- SDL_SetCursor(sdl_cursor_normal);
-+ SDL_ShowCursor(1);
- }
- }
-
diff --git a/tools/ioemu/patches/serial-non-block b/tools/ioemu/patches/serial-non-block
deleted file mode 100644
index a8bbf68d0c..0000000000
--- a/tools/ioemu/patches/serial-non-block
+++ /dev/null
@@ -1,48 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:15:06.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:15:58.000000000 +0100
-@@ -1298,19 +1298,34 @@
-
- static int unix_write(int fd, const uint8_t *buf, int len1)
- {
-- int ret, len;
-+ int ret, sel_ret, len;
-+ int max_fd;
-+ fd_set writefds;
-+ struct timeval timeout;
-+
-+ max_fd = fd;
-
- len = len1;
- while (len > 0) {
-- ret = write(fd, buf, len);
-- if (ret < 0) {
-- if (errno != EINTR && errno != EAGAIN)
-- return -1;
-- } else if (ret == 0) {
-- break;
-+ FD_ZERO(&writefds);
-+ FD_SET(fd, &writefds);
-+ timeout.tv_sec = 0;
-+ timeout.tv_usec = 0;
-+ sel_ret = select(max_fd + 1, NULL, &writefds, 0, &timeout);
-+ if (sel_ret <= 0) {
-+ /* Timeout or select error */
-+ return -1;
- } else {
-- buf += ret;
-- len -= ret;
-+ ret = write(fd, buf, len);
-+ if (ret < 0) {
-+ if (errno != EINTR && errno != EAGAIN)
-+ return -1;
-+ } else if (ret == 0) {
-+ break;
-+ } else {
-+ buf += ret;
-+ len -= ret;
-+ }
- }
- }
- return len1 - len;
diff --git a/tools/ioemu/patches/serial-port-rate-limit b/tools/ioemu/patches/serial-port-rate-limit
deleted file mode 100644
index 755bbbf980..0000000000
--- a/tools/ioemu/patches/serial-port-rate-limit
+++ /dev/null
@@ -1,118 +0,0 @@
-# HG changeset patch
-# User Steven Smith <ssmith@xensource.com>
-# Node ID 1d3f52eb256e3522edc12daca91039b319dbbbe5
-# Parent b7b653e36d20811831f26bb951ea66dca5854b17
-[HVM] Rate limit guest accesses to the qemu virtual serial port. This stops
-grub's boot menu from hammering dom0.
-
-Signed-off-by: Steven Smith <sos22@cam.ac.uk>
-
-Index: ioemu/hw/serial.c
-===================================================================
---- ioemu.orig/hw/serial.c 2007-05-03 18:18:01.000000000 +0100
-+++ ioemu/hw/serial.c 2007-05-03 20:36:58.000000000 +0100
-@@ -22,6 +22,9 @@
- * THE SOFTWARE.
- */
- #include "vl.h"
-+#include <sys/time.h>
-+#include <time.h>
-+#include <assert.h>
-
- //#define DEBUG_SERIAL
-
-@@ -140,6 +143,67 @@
- #endif
- }
-
-+/* Rate limit serial requests so that e.g. grub on a serial console
-+ doesn't kill dom0. Simple token bucket. If we get some actual
-+ data from the user, instantly refil the bucket. */
-+
-+/* How long it takes to generate a token, in microseconds. */
-+#define TOKEN_PERIOD 1000
-+/* Maximum and initial size of token bucket */
-+#define TOKENS_MAX 100000
-+
-+static int tokens_avail;
-+
-+static void serial_get_token(void)
-+{
-+ static struct timeval last_refil_time;
-+ static int started;
-+
-+ assert(tokens_avail >= 0);
-+ if (!tokens_avail) {
-+ struct timeval delta, now;
-+ int generated;
-+
-+ if (!started) {
-+ gettimeofday(&last_refil_time, NULL);
-+ tokens_avail = TOKENS_MAX;
-+ started = 1;
-+ return;
-+ }
-+ retry:
-+ gettimeofday(&now, NULL);
-+ delta.tv_sec = now.tv_sec - last_refil_time.tv_sec;
-+ delta.tv_usec = now.tv_usec - last_refil_time.tv_usec;
-+ if (delta.tv_usec < 0) {
-+ delta.tv_usec += 1000000;
-+ delta.tv_sec--;
-+ }
-+ assert(delta.tv_usec >= 0 && delta.tv_sec >= 0);
-+ if (delta.tv_usec < TOKEN_PERIOD) {
-+ struct timespec ts;
-+ /* Wait until at least one token is available. */
-+ ts.tv_sec = TOKEN_PERIOD / 1000000;
-+ ts.tv_nsec = (TOKEN_PERIOD % 1000000) * 1000;
-+ while (nanosleep(&ts, &ts) < 0 && errno == EINTR)
-+ ;
-+ goto retry;
-+ }
-+ generated = (delta.tv_sec * 1000000) / TOKEN_PERIOD;
-+ generated +=
-+ ((delta.tv_sec * 1000000) % TOKEN_PERIOD + delta.tv_usec) / TOKEN_PERIOD;
-+ assert(generated > 0);
-+
-+ last_refil_time.tv_usec += (generated * TOKEN_PERIOD) % 1000000;
-+ last_refil_time.tv_sec += last_refil_time.tv_usec / 1000000;
-+ last_refil_time.tv_usec %= 1000000;
-+ last_refil_time.tv_sec += (generated * TOKEN_PERIOD) / 1000000;
-+ if (generated > TOKENS_MAX)
-+ generated = TOKENS_MAX;
-+ tokens_avail = generated;
-+ }
-+ tokens_avail--;
-+}
-+
- static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- {
- SerialState *s = opaque;
-@@ -245,9 +309,11 @@
- ret = s->mcr;
- break;
- case 5:
-+ serial_get_token();
- ret = s->lsr;
- break;
- case 6:
-+ serial_get_token();
- if (s->mcr & UART_MCR_LOOP) {
- /* in loopback, the modem output pins are connected to the
- inputs */
-@@ -296,12 +362,14 @@
- static void serial_receive1(void *opaque, const uint8_t *buf, int size)
- {
- SerialState *s = opaque;
-+ tokens_avail = TOKENS_MAX;
- serial_receive_byte(s, buf[0]);
- }
-
- static void serial_event(void *opaque, int event)
- {
- SerialState *s = opaque;
-+ tokens_avail = TOKENS_MAX;
- if (event == CHR_EVENT_BREAK)
- serial_receive_break(s);
- }
diff --git a/tools/ioemu/patches/series b/tools/ioemu/patches/series
deleted file mode 100644
index 06691f4abb..0000000000
--- a/tools/ioemu/patches/series
+++ /dev/null
@@ -1,80 +0,0 @@
-xen-build
-qemu-dm
-qemu-target-i386-dm
-qemu-cleanup
-qemu-64bit
-qemu-bugfixes
-qemu-logging
-qemu-hvm-banner
-xen-domain-name
-xen-domid
-xen-mm
-ioemu-ia64
-qemu-smp
-qemu-no-apic
-qemu-nobios
-qemu-init-vgabios
-xen-network
-qemu-timer
-domain-reset
-domain-destroy
-support-xm-console
-hypervisor-pit
-shared-vram
-shadow-vram
-serial-non-block
-ioemu-save-restore
-ioemu-save-restore-usb
-ioemu-save-restore-timer
-ioemu-save-restore-rtl8139
-ioemu-save-restore-pcnet
-ioemu-save-restore-ne2000
-#ide-hd-multithread
-acpi-support
-acpi-timer-support
-acpi-poweroff-support
-ioemu-save-restore-acpi
-fix-vga-scanning-code-overflow
-vnc-cleanup
-vnc-fixes
-vnc-protocol-fixes
-vnc-start-vncviewer
-vnc-title-domain-name
-vnc-display-find-unused
-vnc-backoff-screen-scan
-xenstore
-xenstore-block-device-config
-xenstore-write-vnc-port
-domain-timeoffset
-qemu-allow-disable-sdl
-xen-support-buffered-ioreqs
-ioemu-buffer-pio-ia64
-qemu-daemonize
-xen-platform-device
-qemu-bootorder
-qemu-tunable-ide-write-cache
-qemu-pci
-qemu-pci-vendor-ids
-serial-port-rate-limit
-hypervisor-rtc
-vnc-password
-ne2000-bounds-checks
-xenstore-device-info-functions
-tpm-tis-device
-qemu-serial-fixes
-rtl8139-bound-chaining
-fix-interrupt-routing
-remove-pci-bridge-setup
-ide-error-reporting
-vnc-altgr-keysym
-xen-mapcache
-ioemu-save-restore-logdirty
-usb-mouse-tablet-status-check
-vnc-fix-signedness
-vnc-fix-version-check
-scsi
-qemu-cirrus-bounds-checks
-qemu-block-device-bounds-checks
-qemu-dma-null-pointer-check
-vnc-fix-text-display-shift-key
-vnc-keypad-handling
diff --git a/tools/ioemu/patches/shadow-vram b/tools/ioemu/patches/shadow-vram
deleted file mode 100644
index e4420c3a6d..0000000000
--- a/tools/ioemu/patches/shadow-vram
+++ /dev/null
@@ -1,177 +0,0 @@
-Index: ioemu/hw/vga.c
-===================================================================
---- ioemu.orig/hw/vga.c 2007-05-03 19:15:06.000000000 +0100
-+++ ioemu/hw/vga.c 2007-05-03 19:15:57.000000000 +0100
-@@ -1373,6 +1373,105 @@
- }
- }
-
-+static inline int cmp_vram(VGAState *s, int offset, int n)
-+{
-+ long *vp, *sp;
-+
-+ if (s->vram_shadow == NULL)
-+ return 1;
-+ vp = (long *)(s->vram_ptr + offset);
-+ sp = (long *)(s->vram_shadow + offset);
-+ while ((n -= sizeof(*vp)) >= 0) {
-+ if (*vp++ != *sp++) {
-+ memcpy(sp - 1, vp - 1, n + sizeof(*vp));
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+#ifdef USE_SSE2
-+
-+#include <signal.h>
-+#include <setjmp.h>
-+#include <emmintrin.h>
-+
-+int sse2_ok = 1;
-+
-+static inline unsigned int cpuid_edx(unsigned int op)
-+{
-+ unsigned int eax, edx;
-+
-+#ifdef __x86_64__
-+#define __bx "rbx"
-+#else
-+#define __bx "ebx"
-+#endif
-+ __asm__("push %%"__bx"; cpuid; pop %%"__bx
-+ : "=a" (eax), "=d" (edx)
-+ : "0" (op)
-+ : "cx");
-+#undef __bx
-+
-+ return edx;
-+}
-+
-+jmp_buf sse_jbuf;
-+
-+void intr(int sig)
-+{
-+ sse2_ok = 0;
-+ longjmp(sse_jbuf, 1);
-+}
-+
-+void check_sse2(void)
-+{
-+ /* Check 1: What does CPUID say? */
-+ if ((cpuid_edx(1) & 0x4000000) == 0) {
-+ sse2_ok = 0;
-+ return;
-+ }
-+
-+ /* Check 2: Can we use SSE2 in anger? */
-+ signal(SIGILL, intr);
-+ if (setjmp(sse_jbuf) == 0)
-+ __asm__("xorps %xmm0,%xmm0\n");
-+}
-+
-+int vram_dirty(VGAState *s, int offset, int n)
-+{
-+ __m128i *sp, *vp;
-+
-+ if (s->vram_shadow == NULL)
-+ return 1;
-+ if (sse2_ok == 0)
-+ return cmp_vram(s, offset, n);
-+ vp = (__m128i *)(s->vram_ptr + offset);
-+ sp = (__m128i *)(s->vram_shadow + offset);
-+ while ((n -= sizeof(*vp)) >= 0) {
-+ if (_mm_movemask_epi8(_mm_cmpeq_epi8(*sp, *vp)) != 0xffff) {
-+ while (n >= 0) {
-+ _mm_store_si128(sp++, _mm_load_si128(vp++));
-+ n -= sizeof(*vp);
-+ }
-+ return 1;
-+ }
-+ sp++;
-+ vp++;
-+ }
-+ return 0;
-+}
-+#else /* !USE_SSE2 */
-+int vram_dirty(VGAState *s, int offset, int n)
-+{
-+ return cmp_vram(s, offset, n);
-+}
-+
-+void check_sse2(void)
-+{
-+}
-+#endif /* !USE_SSE2 */
-+
- /*
- * graphic modes
- */
-@@ -1468,6 +1567,11 @@
- printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
- width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
- #endif
-+
-+ for (y = 0; y < s->vram_size; y += TARGET_PAGE_SIZE)
-+ if (vram_dirty(s, y, TARGET_PAGE_SIZE))
-+ cpu_physical_memory_set_dirty(s->vram_offset + y);
-+
- addr1 = (s->start_addr * 4);
- bwidth = width * 4;
- y_start = -1;
-@@ -1918,7 +2022,18 @@
-
- vga_reset(s);
-
-- s->vram_ptr = qemu_malloc(vga_ram_size);
-+ check_sse2();
-+ s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
-+ if (s->vram_shadow == NULL)
-+ fprintf(stderr, "Cannot allocate %d bytes for VRAM shadow, "
-+ "mouse will be slow\n", vga_ram_size);
-+ s->vram_shadow = (uint8_t *)((long)(s->vram_shadow + TARGET_PAGE_SIZE - 1)
-+ & ~(TARGET_PAGE_SIZE - 1));
-+
-+ /* Video RAM must be 128-bit aligned for SSE optimizations later */
-+ s->vram_alloc = qemu_malloc(vga_ram_size + 15);
-+ s->vram_ptr = (uint8_t *)((long)(s->vram_alloc + 15) & ~15L);
-+
- s->vram_offset = vga_ram_offset;
- s->vram_size = vga_ram_size;
- s->ds = ds;
-@@ -2058,7 +2173,7 @@
- }
-
- if (!vga_ram_base) {
-- vga_ram_base = qemu_malloc(vga_ram_size);
-+ vga_ram_base = qemu_malloc(vga_ram_size + TARGET_PAGE_SIZE + 1);
- if (!vga_ram_base) {
- fprintf(stderr, "reallocate error\n");
- return NULL;
-@@ -2066,8 +2181,10 @@
- }
-
- /* XXX lock needed? */
-+ old_pointer = s->vram_alloc;
-+ s->vram_alloc = vga_ram_base;
-+ vga_ram_base = (uint8_t *)((long)(vga_ram_base + 15) & ~15L);
- memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
-- old_pointer = s->vram_ptr;
- s->vram_ptr = vga_ram_base;
-
- return old_pointer;
-Index: ioemu/hw/vga_int.h
-===================================================================
---- ioemu.orig/hw/vga_int.h 2007-05-03 19:15:06.000000000 +0100
-+++ ioemu/hw/vga_int.h 2007-05-03 19:15:57.000000000 +0100
-@@ -80,7 +80,9 @@
- #define VGA_MAX_HEIGHT 2048
-
- #define VGA_STATE_COMMON \
-+ uint8_t *vram_alloc; \
- uint8_t *vram_ptr; \
-+ uint8_t *vram_shadow; \
- unsigned long vram_offset; \
- unsigned int vram_size; \
- unsigned long bios_offset; \
diff --git a/tools/ioemu/patches/shared-vram b/tools/ioemu/patches/shared-vram
deleted file mode 100644
index 0dba12d11c..0000000000
--- a/tools/ioemu/patches/shared-vram
+++ /dev/null
@@ -1,353 +0,0 @@
-Index: ioemu/hw/cirrus_vga.c
-===================================================================
---- ioemu.orig/hw/cirrus_vga.c 2007-05-03 18:18:00.000000000 +0100
-+++ ioemu/hw/cirrus_vga.c 2007-05-03 19:15:06.000000000 +0100
-@@ -28,6 +28,9 @@
- */
- #include "vl.h"
- #include "vga_int.h"
-+#ifndef _WIN32
-+#include <sys/mman.h>
-+#endif
-
- /*
- * TODO:
-@@ -231,6 +234,8 @@
- int cirrus_linear_io_addr;
- int cirrus_linear_bitblt_io_addr;
- int cirrus_mmio_io_addr;
-+ unsigned long cirrus_lfb_addr;
-+ unsigned long cirrus_lfb_end;
- uint32_t cirrus_addr_mask;
- uint32_t linear_mmio_mask;
- uint8_t cirrus_shadow_gr0;
-@@ -267,6 +272,8 @@
- int last_hw_cursor_y_end;
- int real_vram_size; /* XXX: suppress that */
- CPUWriteMemoryFunc **cirrus_linear_write;
-+ unsigned long map_addr;
-+ unsigned long map_end;
- } CirrusVGAState;
-
- typedef struct PCICirrusVGAState {
-@@ -276,6 +283,8 @@
-
- static uint8_t rop_to_index[256];
-
-+void *shared_vram;
-+
- /***************************************
- *
- * prototypes.
-@@ -2525,6 +2534,83 @@
- cirrus_linear_bitblt_writel,
- };
-
-+static void *set_vram_mapping(unsigned long begin, unsigned long end)
-+{
-+ xen_pfn_t *extent_start = NULL;
-+ unsigned long nr_extents;
-+ void *vram_pointer = NULL;
-+ int i;
-+
-+ /* align begin and end address */
-+ begin = begin & TARGET_PAGE_MASK;
-+ end = begin + VGA_RAM_SIZE;
-+ end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
-+ nr_extents = (end - begin) >> TARGET_PAGE_BITS;
-+
-+ extent_start = malloc(sizeof(xen_pfn_t) * nr_extents);
-+ if (extent_start == NULL) {
-+ fprintf(stderr, "Failed malloc on set_vram_mapping\n");
-+ return NULL;
-+ }
-+
-+ memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
-+
-+ for (i = 0; i < nr_extents; i++)
-+ extent_start[i] = (begin + i * TARGET_PAGE_SIZE) >> TARGET_PAGE_BITS;
-+
-+ set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
-+
-+ vram_pointer = xc_map_foreign_batch(xc_handle, domid,
-+ PROT_READ|PROT_WRITE,
-+ extent_start, nr_extents);
-+ if (vram_pointer == NULL) {
-+ fprintf(logfile, "xc_map_foreign_batch vgaram returned error %d\n",
-+ errno);
-+ return NULL;
-+ }
-+
-+ memset(vram_pointer, 0, nr_extents * TARGET_PAGE_SIZE);
-+
-+ free(extent_start);
-+
-+ return vram_pointer;
-+}
-+
-+static int unset_vram_mapping(unsigned long begin, unsigned long end,
-+ void *mapping)
-+{
-+ xen_pfn_t *extent_start = NULL;
-+ unsigned long nr_extents;
-+ int i;
-+
-+ /* align begin and end address */
-+
-+ end = begin + VGA_RAM_SIZE;
-+ begin = begin & TARGET_PAGE_MASK;
-+ end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
-+ nr_extents = (end - begin) >> TARGET_PAGE_BITS;
-+
-+ extent_start = malloc(sizeof(xen_pfn_t) * nr_extents);
-+
-+ if (extent_start == NULL) {
-+ fprintf(stderr, "Failed malloc on set_mm_mapping\n");
-+ return -1;
-+ }
-+
-+ /* Drop our own references to the vram pages */
-+ munmap(mapping, nr_extents * TARGET_PAGE_SIZE);
-+
-+ /* Now drop the guest's mappings */
-+ memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
-+ for (i = 0; i < nr_extents; i++)
-+ extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS;
-+ unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
-+
-+ free(extent_start);
-+
-+ return 0;
-+}
-+
- /* Compute the memory access functions */
- static void cirrus_update_memory_access(CirrusVGAState *s)
- {
-@@ -2543,11 +2629,37 @@
-
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
-+ if (s->cirrus_lfb_addr && s->cirrus_lfb_end && !s->map_addr) {
-+ void *vram_pointer, *old_vram;
-+
-+ vram_pointer = set_vram_mapping(s->cirrus_lfb_addr,
-+ s->cirrus_lfb_end);
-+ if (!vram_pointer)
-+ fprintf(stderr, "NULL vram_pointer\n");
-+ else {
-+ old_vram = vga_update_vram((VGAState *)s, vram_pointer,
-+ VGA_RAM_SIZE);
-+ qemu_free(old_vram);
-+ }
-+ s->map_addr = s->cirrus_lfb_addr;
-+ s->map_end = s->cirrus_lfb_end;
-+ }
- s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
- s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
- s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
- } else {
- generic_io:
-+ if (s->cirrus_lfb_addr && s->cirrus_lfb_end && s->map_addr) {
-+ void *old_vram;
-+
-+ old_vram = vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
-+
-+ unset_vram_mapping(s->cirrus_lfb_addr,
-+ s->cirrus_lfb_end,
-+ old_vram);
-+
-+ s->map_addr = s->map_end = 0;
-+ }
- s->cirrus_linear_write[0] = cirrus_linear_writeb;
- s->cirrus_linear_write[1] = cirrus_linear_writew;
- s->cirrus_linear_write[2] = cirrus_linear_writel;
-@@ -3151,6 +3263,13 @@
- /* XXX: add byte swapping apertures */
- cpu_register_physical_memory(addr, s->vram_size,
- s->cirrus_linear_io_addr);
-+ s->cirrus_lfb_addr = addr;
-+ s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
-+
-+ if (s->map_addr && (s->cirrus_lfb_addr != s->map_addr) &&
-+ (s->cirrus_lfb_end != s->map_end))
-+ fprintf(logfile, "cirrus vga map change while on lfb mode\n");
-+
- cpu_register_physical_memory(addr + 0x1000000, 0x400000,
- s->cirrus_linear_bitblt_io_addr);
- }
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-03 19:15:05.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-03 19:15:51.000000000 +0100
-@@ -639,18 +639,18 @@
- if (cirrus_vga_enabled) {
- if (pci_enabled) {
- pci_cirrus_vga_init(pci_bus,
-- ds, phys_ram_base + ram_size, ram_size,
-+ ds, NULL, ram_size,
- vga_ram_size);
- } else {
-- isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size,
-+ isa_cirrus_vga_init(ds, NULL, ram_size,
- vga_ram_size);
- }
- } else {
- if (pci_enabled) {
-- pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
-+ pci_vga_init(pci_bus, ds, NULL, ram_size,
- vga_ram_size, 0, 0);
- } else {
-- isa_vga_init(ds, phys_ram_base + ram_size, ram_size,
-+ isa_vga_init(ds, NULL, ram_size,
- vga_ram_size);
- }
- }
-Index: ioemu/hw/vga.c
-===================================================================
---- ioemu.orig/hw/vga.c 2007-05-03 19:11:39.000000000 +0100
-+++ ioemu/hw/vga.c 2007-05-03 19:15:06.000000000 +0100
-@@ -1887,6 +1887,7 @@
- /* TODO: add vbe support if enabled */
- }
-
-+/* when used on xen environment, the vga_ram_base is not used */
- void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
- {
-@@ -1917,7 +1918,7 @@
-
- vga_reset(s);
-
-- s->vram_ptr = vga_ram_base;
-+ s->vram_ptr = qemu_malloc(vga_ram_size);
- s->vram_offset = vga_ram_offset;
- s->vram_size = vga_ram_size;
- s->ds = ds;
-@@ -2047,6 +2048,31 @@
- return 0;
- }
-
-+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
-+{
-+ uint8_t *old_pointer;
-+
-+ if (s->vram_size != vga_ram_size) {
-+ fprintf(stderr, "No support to change vga_ram_size\n");
-+ return NULL;
-+ }
-+
-+ if (!vga_ram_base) {
-+ vga_ram_base = qemu_malloc(vga_ram_size);
-+ if (!vga_ram_base) {
-+ fprintf(stderr, "reallocate error\n");
-+ return NULL;
-+ }
-+ }
-+
-+ /* XXX lock needed? */
-+ memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
-+ old_pointer = s->vram_ptr;
-+ s->vram_ptr = vga_ram_base;
-+
-+ return old_pointer;
-+}
-+
- /********************************************************/
- /* vga screen dump */
-
-Index: ioemu/hw/vga_int.h
-===================================================================
---- ioemu.orig/hw/vga_int.h 2007-05-03 18:38:09.000000000 +0100
-+++ ioemu/hw/vga_int.h 2007-05-03 19:15:06.000000000 +0100
-@@ -174,5 +174,6 @@
- unsigned int color0, unsigned int color1,
- unsigned int color_xor);
-
-+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
- extern const uint8_t sr_mask[8];
- extern const uint8_t gr_mask[16];
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:15:05.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:15:06.000000000 +0100
-@@ -6660,6 +6660,62 @@
-
- #define MAX_NET_CLIENTS 32
-
-+#include <xg_private.h>
-+
-+/* FIXME Flush the shadow page */
-+int unset_mm_mapping(int xc_handle, uint32_t domid,
-+ unsigned long nr_pages, unsigned int address_bits,
-+ xen_pfn_t *extent_start)
-+{
-+ int err = 0;
-+ xc_dominfo_t info;
-+
-+ xc_domain_getinfo(xc_handle, domid, 1, &info);
-+ if ((info.nr_pages - nr_pages) <= 0) {
-+ fprintf(stderr, "unset_mm_mapping: error nr_pages\n");
-+ err = -1;
-+ }
-+
-+ err = xc_domain_memory_decrease_reservation(xc_handle, domid,
-+ nr_pages, 0, extent_start);
-+ if (err)
-+ fprintf(stderr, "Failed to decrease physmap\n");
-+
-+
-+ if (xc_domain_setmaxmem(xc_handle, domid, (info.nr_pages - nr_pages) *
-+ PAGE_SIZE/1024) != 0) {
-+ fprintf(logfile, "set maxmem returned error %d\n", errno);
-+ err = -1;
-+ }
-+
-+ return err;
-+}
-+
-+int set_mm_mapping(int xc_handle, uint32_t domid,
-+ unsigned long nr_pages, unsigned int address_bits,
-+ xen_pfn_t *extent_start)
-+{
-+ xc_dominfo_t info;
-+ int err = 0;
-+
-+ xc_domain_getinfo(xc_handle, domid, 1, &info);
-+
-+ if (xc_domain_setmaxmem(xc_handle, domid, info.max_memkb +
-+ nr_pages * PAGE_SIZE/1024) != 0) {
-+ fprintf(logfile, "set maxmem returned error %d\n", errno);
-+ return -1;
-+ }
-+
-+ err = xc_domain_memory_populate_physmap(xc_handle, domid, nr_pages, 0,
-+ address_bits, extent_start);
-+ if (err) {
-+ fprintf(stderr, "Failed to populate physmap\n");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
- int main(int argc, char **argv)
- {
- #ifdef CONFIG_GDBSTUB
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 19:12:02.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 19:15:06.000000000 +0100
-@@ -150,6 +150,13 @@
-
- void main_loop_wait(int timeout);
-
-+int unset_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages,
-+ unsigned int address_bits, unsigned long *extent_start);
-+int set_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages,
-+ unsigned int address_bits, unsigned long *extent_start);
-+
-+extern void *shared_vram;
-+
- extern FILE *logfile;
-
- extern int xc_handle;
diff --git a/tools/ioemu/patches/support-xm-console b/tools/ioemu/patches/support-xm-console
deleted file mode 100644
index 82f0b21fcb..0000000000
--- a/tools/ioemu/patches/support-xm-console
+++ /dev/null
@@ -1,174 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:12:00.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:14:57.000000000 +0100
-@@ -1671,26 +1671,108 @@
- return chr;
- }
-
-+/*
-+ * Create a store entry for a device (e.g., monitor, serial/parallel lines).
-+ * The entry is <domain-path><storeString>/tty and the value is the name
-+ * of the pty associated with the device.
-+ */
-+static int store_dev_info(char *devName, int domid,
-+ CharDriverState *cState, char *storeString)
-+{
-+ int xc_handle;
-+ struct xs_handle *xs;
-+ char *path;
-+ char *newpath;
-+ FDCharDriver *s;
-+ char *pts;
-+
-+ /* Check for valid arguments (at least, prevent segfaults). */
-+ if ((devName == NULL) || (cState == NULL) || (storeString == NULL)) {
-+ fprintf(logfile, "%s - invalid arguments\n", __FUNCTION__);
-+ return EINVAL;
-+ }
-+
-+ /*
-+ * Only continue if we're talking to a pty
-+ * Actually, the following code works for any CharDriverState using
-+ * FDCharDriver, but we really only care about pty's here
-+ */
-+ if (strcmp(devName, "pty"))
-+ return 0;
-+
-+ s = cState->opaque;
-+ if (s == NULL) {
-+ fprintf(logfile, "%s - unable to retrieve fd for '%s'/'%s'\n",
-+ __FUNCTION__, storeString, devName);
-+ return EBADF;
-+ }
-+
-+ pts = ptsname(s->fd_in);
-+ if (pts == NULL) {
-+ fprintf(logfile, "%s - unable to determine ptsname '%s'/'%s', "
-+ "error %d (%s)\n",
-+ __FUNCTION__, storeString, devName, errno, strerror(errno));
-+ return errno;
-+ }
-+
-+ /* We now have everything we need to set the xenstore entry. */
-+ xs = xs_daemon_open();
-+ if (xs == NULL) {
-+ fprintf(logfile, "Could not contact XenStore\n");
-+ return -1;
-+ }
-+
-+ xc_handle = xc_interface_open();
-+ if (xc_handle == -1) {
-+ fprintf(logfile, "xc_interface_open() error\n");
-+ return -1;
-+ }
-+
-+ path = xs_get_domain_path(xs, domid);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_get_domain_path() error\n");
-+ return -1;
-+ }
-+ newpath = realloc(path, (strlen(path) + strlen(storeString) +
-+ strlen("/tty") + 1));
-+ if (newpath == NULL) {
-+ free(path); /* realloc errors leave old block */
-+ fprintf(logfile, "realloc error\n");
-+ return -1;
-+ }
-+ path = newpath;
-+
-+ strcat(path, storeString);
-+ strcat(path, "/tty");
-+ if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
-+ fprintf(logfile, "xs_write for '%s' fail", storeString);
-+ return -1;
-+ }
-+
-+ free(path);
-+ xs_daemon_close(xs);
-+ close(xc_handle);
-+
-+ return 0;
-+}
-+
- #if defined(__linux__)
- static CharDriverState *qemu_chr_open_pty(void)
- {
- struct termios tty;
-- char slave_name[1024];
- int master_fd, slave_fd;
-
- /* Not satisfying */
-- if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
-+ if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
- return NULL;
- }
-
-- /* Disabling local echo and line-buffered output */
-- tcgetattr (master_fd, &tty);
-- tty.c_lflag &= ~(ECHO|ICANON|ISIG);
-- tty.c_cc[VMIN] = 1;
-- tty.c_cc[VTIME] = 0;
-- tcsetattr (master_fd, TCSAFLUSH, &tty);
-+ /* Set raw attributes on the pty. */
-+ cfmakeraw(&tty);
-+ tcsetattr(slave_fd, TCSAFLUSH, &tty);
-+
-+ fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-
-- fprintf(stderr, "char device redirected to %s\n", slave_name);
- return qemu_chr_open_fd(master_fd, master_fd);
- }
-
-@@ -6799,7 +6881,9 @@
- break;
- case QEMU_OPTION_nographic:
- pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
-- pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
-+ if(!strcmp(serial_devices[0], "vc"))
-+ pstrcpy(serial_devices[0], sizeof(serial_devices[0]),
-+ "stdio");
- nographic = 1;
- break;
- case QEMU_OPTION_kernel:
-@@ -7365,17 +7449,24 @@
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
- }
-+ store_dev_info(monitor_device, domid, monitor_hd, "/monitor");
- monitor_init(monitor_hd, !nographic);
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- const char *devname = serial_devices[i];
- if (devname[0] != '\0' && strcmp(devname, "none")) {
-+ char buf[16];
- serial_hds[i] = qemu_chr_open(devname);
- if (!serial_hds[i]) {
- fprintf(stderr, "qemu: could not open serial device '%s'\n",
- devname);
- exit(1);
- }
-+ snprintf(buf, sizeof(buf), "/serial/%d", i);
-+ store_dev_info(serial_devices[i], domid, serial_hds[i], buf);
-+ if (i == 0) /* serial 0 is also called the console */
-+ store_dev_info(serial_devices[i], domid,
-+ serial_hds[i], "/console");
- if (!strcmp(devname, "vc"))
- qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
- }
-@@ -7384,12 +7475,15 @@
- for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
- const char *devname = parallel_devices[i];
- if (devname[0] != '\0' && strcmp(devname, "none")) {
-+ char buf[16];
- parallel_hds[i] = qemu_chr_open(devname);
- if (!parallel_hds[i]) {
- fprintf(stderr, "qemu: could not open parallel device '%s'\n",
- devname);
- exit(1);
- }
-+ snprintf(buf, sizeof(buf), "/parallel/%d", i);
-+ store_dev_info(parallel_devices[i], domid, parallel_hds[i], buf);
- if (!strcmp(devname, "vc"))
- qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
- }
diff --git a/tools/ioemu/patches/tpm-tis-device b/tools/ioemu/patches/tpm-tis-device
deleted file mode 100644
index c43f1d64e6..0000000000
--- a/tools/ioemu/patches/tpm-tis-device
+++ /dev/null
@@ -1,1196 +0,0 @@
-# HG changeset patch
-# User kaf24@localhost.localdomain
-# Node ID d60b709724f48397b95da3d56299213cae391789
-# Parent bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2
-[QEMU] Add a TIS device model compliant to the 1.2 TPM specification.
-It implements all registers necessary to make the Linux TIS driver
-work (tpm_tis.c). All of the basic registers supported by this type of
-device are implemented. Also the locality selection has been
-implemented, but has not been tested. The legacy registers as
-described in the specification are not supported.
-
-Current caveat: The device has so far not yet been integrated with the
-virtual TPM available in the repository. It will require changes to
-the virtual TPM spawned by the vTPM manager to offer an additional message
-interface. The TIS interface itself then needs to have an additional
-transport implemented. (see vTPMTransmit array).
-
-The relevant specification for the device model can be found here:
-https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
-
-Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
-
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-10 15:19:29.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-10 15:19:29.000000000 +0100
-@@ -400,6 +400,7 @@
- VL_OBJS+= piix4acpi.o
- VL_OBJS+= xenstore.o
- VL_OBJS+= xen_platform.o
-+VL_OBJS+= tpm_tis.o
- CPPFLAGS += -DHAS_AUDIO
- endif
- ifeq ($(TARGET_BASE_ARCH), ppc)
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-10 15:19:28.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-10 15:19:29.000000000 +0100
-@@ -730,6 +730,9 @@
- }
- }
-
-+ if (has_tpm_device())
-+ tpm_tis_init(&pic_set_irq_new, isa_pic, 11);
-+
- kbd_init();
- DMA_init(0);
- #ifdef HAS_AUDIO
-Index: ioemu/hw/tpm_tis.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/hw/tpm_tis.c 2007-05-10 15:19:29.000000000 +0100
-@@ -0,0 +1,1128 @@
-+/*
-+ * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
-+ *
-+ * Copyright (C) 2006 IBM Corporation
-+ *
-+ * Author: Stefan Berger <stefanb@us.ibm.com>
-+ * David Safford <safford@us.ibm.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ *
-+ *
-+ * Implementation of the TIS interface according to specs at
-+ * https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
-+ *
-+ */
-+
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+#include "vl.h"
-+
-+//#define DEBUG_TPM
-+
-+#define TPM_MAX_PKT 4096
-+
-+#define VTPM_BAD_INSTANCE (uint32_t)0xffffffff
-+
-+#define TIS_ADDR_BASE 0xFED40000
-+
-+/* tis registers */
-+#define TPM_REG_ACCESS 0x00
-+#define TPM_REG_INT_ENABLE 0x08
-+#define TPM_REG_INT_VECTOR 0x0c
-+#define TPM_REG_INT_STATUS 0x10
-+#define TPM_REG_INTF_CAPABILITY 0x14
-+#define TPM_REG_STS 0x18
-+#define TPM_REG_DATA_FIFO 0x24
-+#define TPM_REG_DID_VID 0xf00
-+#define TPM_REG_RID 0xf04
-+
-+#define STS_VALID (1 << 7)
-+#define STS_COMMAND_READY (1 << 6)
-+#define STS_TPM_GO (1 << 5)
-+#define STS_DATA_AVAILABLE (1 << 4)
-+#define STS_EXPECT (1 << 3)
-+#define STS_RESPONSE_RETRY (1 << 1)
-+
-+#define ACCESS_TPM_REG_VALID_STS (1 << 7)
-+#define ACCESS_ACTIVE_LOCALITY (1 << 5)
-+#define ACCESS_BEEN_SEIZED (1 << 4)
-+#define ACCESS_SEIZE (1 << 3)
-+#define ACCESS_PENDING_REQUEST (1 << 2)
-+#define ACCESS_REQUEST_USE (1 << 1)
-+#define ACCESS_TPM_ESTABLISHMENT (1 << 0)
-+
-+#define INT_ENABLED (1 << 31)
-+#define INT_DATA_AVAILABLE (1 << 0)
-+#define INT_LOCALITY_CHANGED (1 << 2)
-+#define INT_COMMAND_READY (1 << 7)
-+
-+#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \
-+ INT_DATA_AVAILABLE | \
-+ INT_COMMAND_READY)
-+#define CAPABILITIES_SUPPORTED ((1 << 4) | \
-+ INTERRUPTS_SUPPORTED)
-+
-+enum {
-+ STATE_IDLE = 0,
-+ STATE_READY,
-+ STATE_COMPLETION,
-+ STATE_EXECUTION,
-+ STATE_RECEPTION
-+};
-+
-+#define NUM_LOCALITIES 5
-+#define NO_LOCALITY 0xff
-+
-+#define IS_VALID_LOC(x) ((x) < NUM_LOCALITIES)
-+
-+#define TPM_DID 0x0001
-+#define TPM_VID 0x0001
-+#define TPM_RID 0x0001
-+
-+/* if the connection to the vTPM should be closed after a successfully
-+ received response; set to '0' to allow keeping the connection */
-+#define FORCE_CLOSE 0
-+
-+/* local data structures */
-+
-+typedef struct TPMTx {
-+ int fd[2];
-+} tpmTx;
-+
-+typedef struct TPMBuffer {
-+ uint8_t instance[4]; /* instance number in network byte order */
-+ uint8_t buf[TPM_MAX_PKT];
-+} __attribute__((packed)) tpmBuffer;
-+
-+/* locality data */
-+typedef struct TPMLocal {
-+ uint32_t state;
-+ uint8_t access;
-+ uint8_t sts;
-+ uint32_t inte;
-+ uint32_t ints;
-+} tpmLoc;
-+
-+/* overall state of the TPM interface; 's' marks as save upon suspension */
-+typedef struct TPMState {
-+ uint32_t offset; /* s */
-+ tpmBuffer buffer; /* s */
-+ uint8_t active_loc; /* s */
-+ uint8_t aborting_locty;
-+ uint8_t next_locty;
-+ uint8_t irq_pending; /* s */
-+ tpmLoc loc[NUM_LOCALITIES]; /* s */
-+ QEMUTimer *poll_timer;
-+ SetIRQFunc *set_irq;
-+ void *irq_opaque;
-+ int irq;
-+ int poll_attempts;
-+ uint32_t vtpm_instance; /* vtpm inst. number; determined from xenstore*/
-+ int Transmitlayer;
-+ tpmTx tpmTx;
-+} tpmState;
-+
-+
-+/* local prototypes */
-+static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg);
-+static int TPM_Receive(tpmState *s, tpmBuffer *buffer);
-+static uint32_t vtpm_instance_from_xenstore(void);
-+static void tis_poll_timer(void *opaque);
-+static void tis_prep_next_interrupt(tpmState *s);
-+static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask);
-+static void close_vtpm_channel(tpmState *s, int force);
-+static void open_vtpm_channel(tpmState *s);
-+static void tis_attempt_receive(tpmState *s, uint8_t locty);
-+
-+/* transport layer functions: local sockets */
-+static int create_local_socket(tpmState *s, uint32_t vtpm_instance);
-+static int write_local_socket(tpmState *s, const tpmBuffer *);
-+static int read_local_socket(tpmState *s, tpmBuffer *);
-+static int close_local_socket(tpmState *s, int force);
-+static int has_channel_local_socket(tpmState *s);
-+#define LOCAL_SOCKET_PATH "/var/vtpm/vtpm_all.socket"
-+
-+
-+#define NUM_TRANSPORTS 1
-+
-+struct vTPM_transmit {
-+ int (*open) (tpmState *s, uint32_t vtpm_instance);
-+ int (*write) (tpmState *s, const tpmBuffer *);
-+ int (*read) (tpmState *s, tpmBuffer *);
-+ int (*close) (tpmState *s, int);
-+ int (*has_channel) (tpmState *s);
-+} vTPMTransmit[NUM_TRANSPORTS] = {
-+ { .open = create_local_socket,
-+ .write = write_local_socket,
-+ .read = read_local_socket,
-+ .close = close_local_socket,
-+ .has_channel = has_channel_local_socket,
-+ }
-+};
-+
-+
-+#define IS_COMM_WITH_VTPM(s) \
-+ ((s)->Transmitlayer >= 0 && \
-+ vTPMTransmit[(s)->Transmitlayer].has_channel(s))
-+
-+
-+/**********************************************************************
-+ helper functions
-+ *********************************************************************/
-+
-+static inline uint32_t tpm_get_size_from_buffer(const uint8_t *buffer)
-+{
-+ uint32_t len = (buffer[4] << 8) + buffer[5];
-+ return len;
-+}
-+
-+static inline void tpm_initialize_instance(tpmState *s, uint32_t instance)
-+{
-+ s->buffer.instance[0] = (instance >> 24) & 0xff;
-+ s->buffer.instance[1] = (instance >> 16) & 0xff;
-+ s->buffer.instance[2] = (instance >> 8) & 0xff;
-+ s->buffer.instance[3] = (instance >> 0) & 0xff;
-+}
-+
-+/*
-+ * open communication channel with a vTPM
-+ */
-+static void open_vtpm_channel(tpmState *s)
-+{
-+ int idx;
-+ /* search a usable transmit layer */
-+ for (idx = 0; idx < NUM_TRANSPORTS; idx++) {
-+ if (1 == vTPMTransmit[idx].open(s, s->vtpm_instance)) {
-+ /* found one */
-+ s->Transmitlayer = idx;
-+ break;
-+ }
-+ }
-+}
-+
-+/*
-+ * close the communication channel with the vTPM
-+ */
-+static inline void close_vtpm_channel(tpmState *s, int force)
-+{
-+ if (1 == vTPMTransmit[s->Transmitlayer].close(s, force)) {
-+ s->Transmitlayer = -1;
-+ }
-+}
-+
-+static inline uint8_t locality_from_addr(target_phys_addr_t addr)
-+{
-+ return (uint8_t)((addr >> 12) & 0x7);
-+}
-+
-+
-+/**********************************************************************
-+ low-level transmission layer methods
-+ *********************************************************************/
-+
-+/*
-+ * the 'open' method that creates the filedescriptor for communicating
-+ * only one is needed for reading and writing
-+ */
-+static int create_local_socket(tpmState *s, uint32_t vtpm_instance)
-+{
-+ int success = 1;
-+ if (s->tpmTx.fd[0] < 0) {
-+ s->tpmTx.fd[0] = socket(PF_LOCAL, SOCK_STREAM, 0);
-+
-+ if (has_channel_local_socket(s)) {
-+ struct sockaddr_un addr;
-+ memset(&addr, 0x0, sizeof(addr));
-+ addr.sun_family = AF_LOCAL;
-+ strcpy(addr.sun_path, LOCAL_SOCKET_PATH);
-+ if (connect(s->tpmTx.fd[0],
-+ (struct sockaddr *)&addr,
-+ sizeof(addr)) != 0) {
-+ close_local_socket(s, 1);
-+ success = 0;
-+ } else {
-+ /* put filedescriptor in non-blocking mode for polling */
-+ int flags = fcntl(s->tpmTx.fd[0], F_GETFL);
-+ fcntl(s->tpmTx.fd[0], F_SETFL, flags | O_NONBLOCK);
-+ }
-+#ifdef DEBUG_TPM
-+ if (success)
-+ fprintf(logfile,"Successfully connected using local socket "
-+ LOCAL_SOCKET_PATH ".\n");
-+ else
-+ fprintf(logfile,"Could not connect to local socket "
-+ LOCAL_SOCKET_PATH ".\n");
-+#endif
-+ } else {
-+ success = 0;
-+ }
-+ }
-+ return success;
-+}
-+
-+/*
-+ * the 'write' method for sending requests to the vTPM
-+ * four bytes with the vTPM instance number are prepended to each request
-+ * the locality in which the command was sent is transmitted in the
-+ * highest 3 bits
-+ */
-+static int write_local_socket(tpmState *s, const tpmBuffer *buffer)
-+{
-+ uint32_t size = tpm_get_size_from_buffer(buffer->buf);
-+ int len;
-+
-+ len = write(s->tpmTx.fd[0],
-+ buffer->instance,
-+ sizeof(buffer->instance) + size);
-+ if (len == sizeof(buffer->instance) + size) {
-+ return len;
-+ } else {
-+ return -1;
-+ }
-+}
-+
-+/*
-+ * the 'read' method for receiving of responses from the TPM
-+ * this function expects that four bytes with the instance number
-+ * are received from the vTPM
-+ */
-+static int read_local_socket(tpmState *s, tpmBuffer *buffer)
-+{
-+ int off;
-+#ifdef DEBUG_TPM
-+ fprintf(logfile, "Reading from fd %d\n", s->tpmTx.fd[0]);
-+#endif
-+ off = read(s->tpmTx.fd[0],
-+ buffer->instance,
-+ sizeof(buffer->instance)+TPM_MAX_PKT);
-+#ifdef DEBUG_TPM
-+ fprintf(logfile, "Read %d bytes\n", off);
-+#endif
-+ return off;
-+}
-+
-+/*
-+ * the 'close' method
-+ * shut down communication with the vTPM
-+ * 'force' = 1 indicates that the socket *must* be closed
-+ * 'force' = 0 indicates that a connection may be maintained
-+ */
-+static int close_local_socket(tpmState *s, int force)
-+{
-+ if (force) {
-+ close(s->tpmTx.fd[0]);
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"Closed connection with fd %d\n",s->tpmTx.fd[0]);
-+#endif
-+ s->tpmTx.fd[0] = -1;
-+ return 1; /* socket was closed */
-+ }
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"Keeping connection with fd %d\n",s->tpmTx.fd[0]);
-+#endif
-+ return 0;
-+}
-+
-+/*
-+ * the 'has_channel' method that checks whether there's a communication
-+ * channel with the vTPM
-+ */
-+static int has_channel_local_socket(tpmState *s)
-+{
-+ return (s->tpmTx.fd[0] > 0);
-+}
-+
-+/**********************************************************************/
-+
-+/*
-+ * read a byte of response data
-+ */
-+static uint32_t tpm_data_read(tpmState *s, uint8_t locty)
-+{
-+ uint32_t ret, len;
-+
-+ /* try to receive data, if none are there it is ok */
-+ tis_attempt_receive(s, locty);
-+
-+ if (s->loc[locty].state != STATE_COMPLETION) {
-+ return 0xff;
-+ }
-+
-+ len = tpm_get_size_from_buffer(s->buffer.buf);
-+ ret = s->buffer.buf[s->offset++];
-+ if (s->offset >= len) {
-+ s->loc[locty].sts = STS_VALID ;
-+ s->offset = 0;
-+ }
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"tpm_data_read byte x%02x [%d]\n",ret,s->offset-1);
-+#endif
-+ return ret;
-+}
-+
-+
-+
-+/* raise an interrupt if allowed */
-+static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask)
-+{
-+ if (!s->irq_pending &&
-+ (s->loc[locty].inte & INT_ENABLED) &&
-+ (s->loc[locty].inte & irqmask)) {
-+ if ((irqmask & s->loc[locty].ints) == 0) {
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"Raising IRQ for flag %08x\n",irqmask);
-+#endif
-+ s->set_irq(s->irq_opaque, s->irq, 1);
-+ s->irq_pending = 1;
-+ s->loc[locty].ints |= irqmask;
-+ }
-+ }
-+}
-+
-+/* abort execution of command */
-+static void tis_abort(tpmState *s)
-+{
-+ s->offset = 0;
-+ s->active_loc = s->next_locty;
-+
-+ /*
-+ * Need to react differently depending on who's aborting now and
-+ * which locality will become active afterwards.
-+ */
-+ if (s->aborting_locty == s->next_locty) {
-+ s->loc[s->aborting_locty].state = STATE_READY;
-+ s->loc[s->aborting_locty].sts = STS_COMMAND_READY;
-+ tis_raise_irq(s, s->aborting_locty, INT_COMMAND_READY);
-+ }
-+
-+ /* locality after abort is another one than the current one */
-+ if (s->aborting_locty != s->next_locty && s->next_locty != NO_LOCALITY) {
-+ s->loc[s->aborting_locty].access &= ~ACCESS_ACTIVE_LOCALITY;
-+ s->loc[s->next_locty].access |= ACCESS_ACTIVE_LOCALITY;
-+ tis_raise_irq(s, s->next_locty, INT_LOCALITY_CHANGED);
-+ }
-+
-+ s->aborting_locty = NO_LOCALITY; /* nobody's aborting a command anymore */
-+
-+ qemu_del_timer(s->poll_timer);
-+}
-+
-+/* abort current command */
-+static void tis_prep_abort(tpmState *s, uint8_t locty, uint8_t newlocty)
-+{
-+ s->aborting_locty = locty; /* current locality */
-+ s->next_locty = newlocty; /* locality after successful abort */
-+
-+ /*
-+ * only abort a command using an interrupt if currently executing
-+ * a command AND if there's a valid connection to the vTPM.
-+ */
-+ if (s->loc[locty].state == STATE_EXECUTION &&
-+ IS_COMM_WITH_VTPM(s)) {
-+ /* start timer and inside the timer wait for the result */
-+ s->poll_attempts = 0;
-+ tis_prep_next_interrupt(s);
-+ } else {
-+ tis_abort(s);
-+ }
-+}
-+
-+
-+/*
-+ * Try to receive a response from the vTPM
-+ */
-+static void tis_attempt_receive(tpmState *s, uint8_t locty)
-+{
-+ /*
-+ * Attempt to read from the vTPM here if
-+ * - not aborting a command
-+ * - command has been sent and state is 'EXECUTION' now
-+ * - no data are already available (data have already been read)
-+ * - there's a communication path to the vTPM established
-+ */
-+ if (!IS_VALID_LOC(s->aborting_locty)) {
-+ if (s->loc[locty].state == STATE_EXECUTION) {
-+ if (0 == (s->loc[locty].sts & STS_DATA_AVAILABLE)){
-+ if (IS_COMM_WITH_VTPM(s)) {
-+ int n = TPM_Receive(s, &s->buffer);
-+ if (n > 0) {
-+ s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
-+ s->loc[locty].state = STATE_COMPLETION;
-+ close_vtpm_channel(s, FORCE_CLOSE);
-+ tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
-+ }
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+/*
-+ * Read a register of the TIS interface
-+ * See specs pages 33-63 for description of the registers
-+ */
-+static uint32_t tis_mem_readl(void *opaque, target_phys_addr_t addr)
-+{
-+ tpmState *s = (tpmState *)opaque;
-+ uint16_t offset = addr & 0xffc;
-+ uint8_t shift = (addr & 0x3) * 8;
-+ uint32_t val = 0;
-+ uint8_t locty = locality_from_addr(addr);
-+
-+ if (offset == TPM_REG_ACCESS) {
-+ if (s->active_loc == locty) {
-+ s->loc[locty].access |= (1 << 5);
-+ } else {
-+ s->loc[locty].access &= ~(1 << 5);
-+ }
-+ val = s->loc[locty].access;
-+ } else
-+ if (offset == TPM_REG_INT_ENABLE) {
-+ val = s->loc[locty].inte;
-+ } else
-+ if (offset == TPM_REG_INT_VECTOR) {
-+ val = s->irq;
-+ } else
-+ if (offset == TPM_REG_INT_STATUS) {
-+ tis_attempt_receive(s, locty);
-+ val = s->loc[locty].ints;
-+ } else
-+ if (offset == TPM_REG_INTF_CAPABILITY) {
-+ val = CAPABILITIES_SUPPORTED;
-+ } else
-+ if (offset == TPM_REG_STS) { /* status register */
-+ tis_attempt_receive(s, locty);
-+ val = (sizeof(s->buffer.buf) - s->offset) << 8 | s->loc[locty].sts;
-+ } else
-+ if (offset == TPM_REG_DATA_FIFO) {
-+ val = tpm_data_read(s, locty);
-+ } else
-+ if (offset == TPM_REG_DID_VID) {
-+ val = (TPM_DID << 16) | TPM_VID;
-+ } else
-+ if (offset == TPM_REG_RID) {
-+ val = TPM_RID;
-+ }
-+
-+ if (shift)
-+ val >>= shift;
-+
-+#ifdef DEBUG_TPM
-+ fprintf(logfile," read(%08x) = %08x\n",
-+ (int)addr,
-+ val);
-+#endif
-+
-+ return val;
-+}
-+
-+/*
-+ * Write a value to a register of the TIS interface
-+ * See specs pages 33-63 for description of the registers
-+ */
-+static void tis_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-+{
-+ tpmState* s=(tpmState*)opaque;
-+ uint16_t off = addr & 0xfff;
-+ uint8_t locty = locality_from_addr(addr);
-+ int n, c;
-+ uint32_t len;
-+
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"write(%08x) = %08x\n",
-+ (int)addr,
-+ val);
-+#endif
-+
-+ if (off == TPM_REG_ACCESS) {
-+ if (val & ACCESS_ACTIVE_LOCALITY) {
-+ /* give up locality if currently owned */
-+ if (s->active_loc == locty) {
-+ uint8_t newlocty = NO_LOCALITY;
-+ s->loc[locty].access &= ~(ACCESS_PENDING_REQUEST);
-+ /* anybody wants the locality ? */
-+ for (c = NUM_LOCALITIES - 1; c >= 0; c--) {
-+ if (s->loc[c].access & ACCESS_REQUEST_USE) {
-+ s->loc[c].access |= ACCESS_TPM_REG_VALID_STS;
-+ s->loc[c].access &= ~ACCESS_REQUEST_USE;
-+ newlocty = c;
-+ break;
-+ }
-+ }
-+ tis_prep_abort(s, locty, newlocty);
-+ }
-+ }
-+ if (val & ACCESS_BEEN_SEIZED) {
-+ /* clear the flag */
-+ s->loc[locty].access &= ~ACCESS_BEEN_SEIZED;
-+ }
-+ if (val & ACCESS_SEIZE) {
-+ if (locty > s->active_loc && IS_VALID_LOC(s->active_loc)) {
-+ s->loc[s->active_loc].access |= ACCESS_BEEN_SEIZED;
-+ s->loc[locty].access = ACCESS_TPM_REG_VALID_STS;
-+ tis_prep_abort(s, s->active_loc, locty);
-+ }
-+ }
-+ if (val & ACCESS_REQUEST_USE) {
-+ if (IS_VALID_LOC(s->active_loc)) {
-+ /* locality election */
-+ s->loc[s->active_loc].access |= ACCESS_PENDING_REQUEST;
-+ } else {
-+ /* no locality active -> make this one active now */
-+ s->loc[locty].access |= ACCESS_ACTIVE_LOCALITY;
-+ s->active_loc = locty;
-+ tis_raise_irq(s, locty, INT_LOCALITY_CHANGED);
-+ }
-+ }
-+ } else
-+ if (off == TPM_REG_INT_ENABLE) {
-+ s->loc[locty].inte = (val & (INT_ENABLED | (0x3 << 3) |
-+ INTERRUPTS_SUPPORTED));
-+ } else
-+ if (off == TPM_REG_INT_STATUS) {
-+ /* clearing of interrupt flags */
-+ if ((val & INTERRUPTS_SUPPORTED) &&
-+ (s->loc[locty].ints & INTERRUPTS_SUPPORTED)) {
-+ s->set_irq(s->irq_opaque, s->irq, 0);
-+ s->irq_pending = 0;
-+ }
-+ s->loc[locty].ints &= ~(val & INTERRUPTS_SUPPORTED);
-+ } else
-+ if (off == TPM_REG_STS) {
-+ if (val & STS_COMMAND_READY) {
-+ if (s->loc[locty].state == STATE_IDLE) {
-+ s->loc[locty].sts = STS_COMMAND_READY;
-+ s->loc[locty].state = STATE_READY;
-+ tis_raise_irq(s, locty, INT_COMMAND_READY);
-+ } else if (s->loc[locty].state == STATE_COMPLETION ||
-+ s->loc[locty].state == STATE_EXECUTION ||
-+ s->loc[locty].state == STATE_RECEPTION) {
-+ /* abort currently running command */
-+ tis_prep_abort(s, locty, locty);
-+ }
-+ }
-+ if (val & STS_TPM_GO) {
-+ n = TPM_Send(s, &s->buffer, locty, "tpm_data_write");
-+ if (n > 0) {
-+ /* sending of data was successful */
-+ s->offset = 0;
-+ s->loc[locty].state = STATE_EXECUTION;
-+ if (s->loc[locty].inte & (INT_ENABLED | INT_DATA_AVAILABLE)) {
-+ s->poll_attempts = 0;
-+ tis_prep_next_interrupt(s);
-+ }
-+ }
-+ }
-+ if (val & STS_RESPONSE_RETRY) {
-+ s->offset = 0;
-+ }
-+ } else if (off == TPM_REG_DATA_FIFO) {
-+ /* data fifo */
-+ if (s->loc[locty].state == STATE_IDLE ||
-+ s->loc[locty].state == STATE_EXECUTION ||
-+ s->loc[locty].state == STATE_COMPLETION) {
-+ /* drop the byte */
-+ } else {
-+#ifdef TPM_DEBUG
-+ fprintf(logfile,"Byte to send to TPM: %02x\n", val);
-+#endif
-+ s->loc[locty].state = STATE_RECEPTION;
-+
-+ if (s->offset < sizeof(s->buffer.buf))
-+ s->buffer.buf[s->offset++] = (uint8_t)val;
-+
-+ if (s->offset > 5) {
-+ /* we have a packet length - see if we have all of it */
-+ len = tpm_get_size_from_buffer(s->buffer.buf);
-+ if (len > s->offset) {
-+ s->loc[locty].sts = STS_EXPECT | STS_VALID;
-+ } else {
-+ s->loc[locty].sts = STS_VALID;
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+/*
-+ * Prepare the next interrupt for example after a command has
-+ * been sent out for the purpose of receiving the response.
-+ * Depending on how many interrupts (used for polling on the fd) have
-+ * already been schedule, this function determines the delta in time
-+ * to the next interrupt. This accomodates for commands that finish
-+ * quickly.
-+ */
-+static void tis_prep_next_interrupt(tpmState *s)
-+{
-+ int64_t expiration;
-+ int rate = 5; /* 5 times per second */
-+
-+ /*
-+ poll often at the beginning for quickly finished commands,
-+ then back off
-+ */
-+ if (s->poll_attempts < 5) {
-+ rate = 20;
-+ } else if (s->poll_attempts < 10) {
-+ rate = 10;
-+ }
-+
-+ expiration = qemu_get_clock(vm_clock) + (ticks_per_sec / rate);
-+ qemu_mod_timer(s->poll_timer, expiration);
-+ s->poll_attempts++;
-+}
-+
-+
-+/*
-+ * The polling routine called when the 'timer interrupt' fires.
-+ * Tries to receive a command from the vTPM.
-+ */
-+static void tis_poll_timer(void *opaque)
-+{
-+ tpmState* s=(tpmState*)opaque;
-+ uint8_t locty = s->active_loc;
-+
-+ if (!IS_VALID_LOC(locty) ||
-+ (!(s->loc[locty].inte & INT_ENABLED) &&
-+ (s->aborting_locty != NO_LOCALITY)) ||
-+ !IS_COMM_WITH_VTPM(s)) {
-+ /* no more interrupts requested, so no more polling needed */
-+ qemu_del_timer(s->poll_timer);
-+ }
-+
-+ if (!IS_COMM_WITH_VTPM(s)) {
-+ if (s->aborting_locty != NO_LOCALITY) {
-+ tis_abort(s);
-+ }
-+ return;
-+ }
-+
-+ if (s->aborting_locty != NO_LOCALITY) {
-+ int n = TPM_Receive(s, &s->buffer);
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"Receiving for abort.\n");
-+#endif
-+ if (n > 0) {
-+ close_vtpm_channel(s, FORCE_CLOSE);
-+ tis_abort(s);
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"Abort is complete.\n");
-+#endif
-+ } else {
-+ tis_prep_next_interrupt(s);
-+ }
-+ } else if (IS_VALID_LOC(locty)) {
-+ if (s->loc[locty].state == STATE_EXECUTION) {
-+ /* poll for result */
-+ int n = TPM_Receive(s, &s->buffer);
-+ if (n > 0) {
-+ s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
-+ s->loc[locty].state = STATE_COMPLETION;
-+ close_vtpm_channel(s, FORCE_CLOSE);
-+ tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
-+ } else {
-+ /* nothing received */
-+ tis_prep_next_interrupt(s);
-+ }
-+ }
-+ }
-+}
-+
-+
-+static CPUReadMemoryFunc *tis_readfn[3]={
-+ tis_mem_readl,
-+ tis_mem_readl,
-+ tis_mem_readl
-+};
-+
-+static CPUWriteMemoryFunc *tis_writefn[3]={
-+ tis_mem_writel,
-+ tis_mem_writel,
-+ tis_mem_writel
-+};
-+
-+/*
-+ * Save the internal state of this interface for later resumption.
-+ * Need to get any outstanding responses from the vTPM back, so
-+ * this might delay the suspend for a while.
-+ */
-+static void tpm_save(QEMUFile* f,void* opaque)
-+{
-+ tpmState* s=(tpmState*)opaque;
-+ uint8_t locty = s->active_loc;
-+ int c;
-+
-+ /* need to wait for outstanding requests to complete */
-+ if (s->loc[locty].state == STATE_EXECUTION) {
-+ int repeats = 30; /* 30 seconds; really should be infty */
-+ while (repeats > 0 &&
-+ !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) {
-+ int n = TPM_Receive(s, &s->buffer);
-+ if (n > 0) {
-+ if (IS_VALID_LOC(s->active_loc)) {
-+ s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
-+ s->loc[s->active_loc].state = STATE_COMPLETION;
-+ tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
-+ }
-+ /* close the connection with the vTPM for good */
-+ close_vtpm_channel(s, 1);
-+ break;
-+ }
-+ sleep(1);
-+ }
-+ }
-+
-+ if (IS_COMM_WITH_VTPM(s)) {
-+ close_vtpm_channel(s, 1);
-+ }
-+
-+ qemu_put_be32s(f,&s->offset);
-+ qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT);
-+ qemu_put_8s(f, &s->active_loc);
-+ qemu_put_8s(f, &s->irq_pending);
-+ for (c = 0; c < NUM_LOCALITIES; c++) {
-+ qemu_put_be32s(f, &s->loc[c].state);
-+ qemu_put_8s(f, &s->loc[c].access);
-+ qemu_put_8s(f, &s->loc[c].sts);
-+ qemu_put_be32s(f, &s->loc[c].inte);
-+ qemu_put_be32s(f, &s->loc[c].ints);
-+ }
-+}
-+
-+/*
-+ * load TIS interface state
-+ */
-+static int tpm_load(QEMUFile* f,void* opaque,int version_id)
-+{
-+ tpmState* s=(tpmState*)opaque;
-+ int c;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+
-+ qemu_get_be32s(f,&s->offset);
-+ qemu_get_buffer(f, s->buffer.buf, TPM_MAX_PKT);
-+ qemu_get_8s(f, &s->active_loc);
-+ qemu_get_8s(f, &s->irq_pending);
-+ for (c = 0; c < NUM_LOCALITIES; c++) {
-+ qemu_get_be32s(f, &s->loc[c].state);
-+ qemu_get_8s(f, &s->loc[c].access);
-+ qemu_get_8s(f, &s->loc[c].sts);
-+ qemu_get_be32s(f, &s->loc[c].inte);
-+ qemu_get_be32s(f, &s->loc[c].ints);
-+ }
-+
-+ /* need to be able to get the instance number from the xenstore */
-+ s->vtpm_instance = vtpm_instance_from_xenstore();
-+ if (s->vtpm_instance == VTPM_BAD_INSTANCE)
-+ return -EINVAL;
-+ tpm_initialize_instance(s, s->vtpm_instance);
-+
-+ return 0;
-+}
-+
-+
-+typedef struct LPCtpmState {
-+ tpmState tpm;
-+ int mem;
-+} LPCtpmState;
-+
-+
-+/*
-+ * initialize TIS interface
-+ */
-+void tpm_tis_init(SetIRQFunc *set_irq, void *opaque, int irq)
-+{
-+ LPCtpmState *d;
-+ tpmState *s;
-+ int c = 0;
-+ uint32_t vtpm_in;
-+
-+ vtpm_in = vtpm_instance_from_xenstore();
-+ /* no valid vtpm instance -> no device */
-+ if (vtpm_in == VTPM_BAD_INSTANCE)
-+ return;
-+
-+ d = qemu_mallocz(sizeof(LPCtpmState));
-+ d->mem = cpu_register_io_memory(0, tis_readfn, tis_writefn, d);
-+
-+ if (d->mem == -1) {
-+ return;
-+ }
-+
-+ cpu_register_physical_memory(TIS_ADDR_BASE,
-+ 0x1000 * NUM_LOCALITIES, d->mem);
-+
-+ /* initialize tpmState */
-+ s = &d->tpm;
-+
-+ s->offset = 0;
-+ s->active_loc = NO_LOCALITY;
-+
-+ while (c < NUM_LOCALITIES) {
-+ s->loc[c].access = (1 << 7);
-+ s->loc[c].sts = 0;
-+ s->loc[c].inte = (1 << 3);
-+ s->loc[c].ints = 0;
-+ s->loc[c].state = STATE_IDLE;
-+ c++;
-+ }
-+ s->poll_timer = qemu_new_timer(vm_clock, tis_poll_timer, s);
-+ s->set_irq = set_irq;
-+ s->irq_opaque = opaque;
-+ s->irq = irq;
-+ s->vtpm_instance = vtpm_in;
-+ s->Transmitlayer = -1;
-+ s->tpmTx.fd[0] = -1;
-+ s->tpmTx.fd[1] = -1;
-+ s->aborting_locty = NO_LOCALITY;
-+
-+ tpm_initialize_instance(s, s->vtpm_instance);
-+ memset(s->buffer.buf,0,sizeof(s->buffer.buf));
-+
-+ register_savevm("tpm-tis", 0, 1, tpm_save, tpm_load, s);
-+}
-+
-+/****************************************************************************/
-+/* optional verbose logging of data to/from vtpm */
-+/****************************************************************************/
-+#ifdef DEBUG_TPM
-+static void showBuff(unsigned char *buff, char *string)
-+{
-+ uint32_t i, len;
-+
-+ len = tpm_get_size_from_buffer(buff);
-+ fprintf(logfile,"%s length = %d\n", string, len);
-+ for (i = 0; i < len; i++) {
-+ if (i && !(i % 16)) {
-+ fprintf(logfile,"\n");
-+ }
-+ fprintf(logfile,"%.2X ", buff[i]);
-+ }
-+ fprintf(logfile,"\n");
-+}
-+#endif
-+
-+/****************************************************************************/
-+/* Transmit request to TPM and read Response */
-+/****************************************************************************/
-+
-+const static unsigned char tpm_failure[] = {
-+ 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x0a,
-+ 0x00, 0x00, 0x00, 0x09
-+};
-+
-+
-+/*
-+ * Send a TPM request.
-+ */
-+static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg)
-+{
-+ int len;
-+ uint32_t size = tpm_get_size_from_buffer(buffer->buf);
-+
-+ /* try to establish a connection to the vTPM */
-+ if ( !IS_COMM_WITH_VTPM(s)) {
-+ open_vtpm_channel(s);
-+ }
-+
-+ if ( !IS_COMM_WITH_VTPM(s)) {
-+ unsigned char tag = buffer->buf[1];
-+
-+ /* there's a failure response from the TPM */
-+ memcpy(buffer->buf, tpm_failure, sizeof(tpm_failure));
-+ buffer->buf[1] = tag + 3;
-+ if (IS_VALID_LOC(s->active_loc)) {
-+ s->loc[s->active_loc].sts = STS_DATA_AVAILABLE | STS_VALID;
-+ }
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"No TPM running!\n");
-+#endif
-+ /* the request went out ok. */
-+ return sizeof(buffer->instance) + size;
-+ }
-+
-+#ifdef DEBUG_TPM
-+ showBuff(buffer->buf, "To TPM");
-+#endif
-+
-+ /* transmit the locality in the highest 3 bits */
-+ buffer->instance[0] &= 0x1f;
-+ buffer->instance[0] |= (locty << 5);
-+
-+ len = vTPMTransmit[s->Transmitlayer].write(s, buffer);
-+ if (len < 0) {
-+ s->Transmitlayer = -1;
-+ }
-+ return len;
-+}
-+
-+/*
-+ * Try to receive data from the file descriptor. Since it is in
-+ * non-blocking mode it is possible that no data are actually received -
-+ * whatever calls this function needs to try again later.
-+ */
-+static int TPM_Receive(tpmState *s, tpmBuffer *buffer)
-+{
-+ int off;
-+
-+ off = vTPMTransmit[s->Transmitlayer].read(s, buffer);
-+
-+ if (off < 0) {
-+ /* EAGAIN is set in errno due to non-blocking mode */
-+ return -1;
-+ }
-+
-+ if (off == 0) {
-+#ifdef DEBUG_TPM
-+ fprintf(logfile,"TPM GONE? errno=%d\n",errno);
-+#endif
-+ close_vtpm_channel(s, 1);
-+ /* pretend that data are available */
-+ if (IS_VALID_LOC(s->active_loc)) {
-+ s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
-+ s->loc[s->active_loc].state = STATE_COMPLETION;
-+ tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
-+ }
-+ return -1;
-+ }
-+
-+#ifdef DEBUG_TPM
-+ if (off > sizeof(buffer->instance ) + 6) {
-+ uint32_t size = tpm_get_size_from_buffer(buffer->buf);
-+ if (size + sizeof(buffer->instance) != off) {
-+ fprintf(logfile,"TPM: Packet size is bad! %d != %d\n",
-+ (int)(size + sizeof(buffer->instance)),
-+ off);
-+ } else {
-+ uint32_t ret;
-+ showBuff(buffer->buf, "From TPM");
-+ ret = (buffer->buf[8])*256 + buffer->buf[9];
-+ if (ret)
-+ fprintf(logfile,"Receive failed with error %d\n", ret);
-+ else
-+ fprintf(logfile,"Receive succeeded. Got response of length %d (=%d)\n",
-+ size, off);
-+ }
-+ }
-+#endif
-+
-+ /* assuming reading in one chunk for now */
-+ return off;
-+}
-+
-+
-+/****************************************************************************
-+ Helper functions for reading data from the xenstore such as
-+ reading virtual TPM instance information
-+ ****************************************************************************/
-+int has_tpm_device(void)
-+{
-+ int ret = 0;
-+ struct xs_handle *handle = xs_daemon_open();
-+ if (handle) {
-+ ret = xenstore_domain_has_devtype(handle, "vtpm");
-+ xs_daemon_close(handle);
-+ }
-+ return ret;
-+}
-+
-+
-+/*
-+ * Wait until hotplug scripts have finished then read the vTPM instance
-+ * number from the xenstore.
-+ */
-+static uint32_t vtpm_instance_from_xenstore(void)
-+{
-+ unsigned int num;
-+ uint32_t number = VTPM_BAD_INSTANCE;
-+ int end = 0;
-+ char *token = "tok";
-+ int subscribed = 0;
-+ int ctr = 0;
-+ fd_set readfds;
-+
-+ struct xs_handle *handle = xs_daemon_open();
-+
-+ FD_ZERO(&readfds);
-+
-+ if (handle) {
-+ char **e = xenstore_domain_get_devices(handle, "vtpm", &num);
-+ int fd = xs_fileno(handle);
-+ FD_SET(fd, &readfds);
-+ if (e) {
-+ do {
-+ struct timeval tv = {
-+ .tv_sec = 30,
-+ .tv_usec = 0,
-+ };
-+ /* need to make sure that the hotplug scripts have finished */
-+ char *status = xenstore_read_hotplug_status(handle,
-+ "vtpm",
-+ e[0]);
-+ if (status) {
-+ if (!strcmp(status, "connected")) {
-+ char *inst = xenstore_backend_read_variable(handle,
-+ "vtpm",
-+ e[0],
-+ "instance");
-+ if (1 != (sscanf(inst,"%d",&number)))
-+ number = VTPM_BAD_INSTANCE;
-+ free(inst);
-+ } else {
-+ fprintf(logfile,
-+ "bad status '%s' from vtpm hotplug\n",
-+ status);
-+ }
-+ free(status);
-+ end = 1;
-+ } else {
-+ /* no status, yet */
-+ int rc;
-+ unsigned int nr;
-+ char **f;
-+
-+ if (!subscribed) {
-+ rc = xenstore_subscribe_to_hotplug_status(handle,
-+ "vtpm",
-+ e[0],
-+ token);
-+ if (rc != 0)
-+ break;
-+ subscribed = 1;
-+ }
-+ rc = select(fd+1, &readfds, NULL, NULL, &tv);
-+ /* get what's available -- drain the fd */
-+ f = xs_read_watch(handle, &nr);
-+ ctr++;
-+ free(f);
-+ if (ctr > 2)
-+ end = 1;
-+ }
-+ } while (end == 0);
-+ free(e);
-+ }
-+ if (subscribed) {
-+ /* clean up */
-+ xenstore_unsubscribe_from_hotplug_status(handle,
-+ "vtpm",
-+ e[0],
-+ token);
-+ }
-+ xs_daemon_close(handle);
-+ }
-+ if (number == VTPM_BAD_INSTANCE)
-+ fprintf(logfile, "no valid vtpm instance");
-+ else
-+ fprintf(logfile,"vtpm instance:%d\n",number);
-+ return number;
-+}
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:19:29.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:19:29.000000000 +0100
-@@ -1086,6 +1086,10 @@
- /* smbus_eeprom.c */
- SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
-
-+/* tpm_tis.c */
-+int has_tpm_device(void);
-+void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
-+
- /* piix4acpi.c */
- extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
-
diff --git a/tools/ioemu/patches/usb-mouse-tablet-status-check b/tools/ioemu/patches/usb-mouse-tablet-status-check
deleted file mode 100644
index d5e9b28ccf..0000000000
--- a/tools/ioemu/patches/usb-mouse-tablet-status-check
+++ /dev/null
@@ -1,193 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID 60bbcf799384d779c2a561b9d9ba30f28e31d970
-# Parent fb3cb6f52a2905be938559529ae43b6ba990c878
-[HVM] qemu mouse: Adds support for USB mouse/tablet status check and
-restricts Universal Host Controller interrupt generating when received
-NAK in interrupt transfer.
-
-According to usb spec, USB mouse/tablet device returns NAK to host
-controller if its status does not alter in interrupt transfer.
-And UHC should leave a TD active when receiving NAK and execute this
-incompleted TD in a subseqent frame. UHC only generates an interrupt
-on complete after the TD with ICO bit is completed.
-
-This patch make UHC & USB mouse/tablet behave consistently with spec.
-
-Signed-off-by: Xinmei Huang <xinmei.huang@intel.com>
-
-Index: ioemu/hw/usb-hid.c
-===================================================================
---- ioemu.orig/hw/usb-hid.c 2007-05-09 14:11:27.000000000 +0100
-+++ ioemu/hw/usb-hid.c 2007-05-09 14:12:06.000000000 +0100
-@@ -39,6 +39,7 @@
- int x, y;
- int kind;
- int mouse_grabbed;
-+ int status_changed;
- QEMUPutMouseEntry *eh_entry;
- } USBMouseState;
-
-@@ -232,6 +233,7 @@
- s->dy += dy1;
- s->dz += dz1;
- s->buttons_state = buttons_state;
-+ s->status_changed = 1;
- }
-
- static void usb_tablet_event(void *opaque,
-@@ -243,6 +245,7 @@
- s->y = y;
- s->dz += dz;
- s->buttons_state = buttons_state;
-+ s->status_changed = 1;
- }
-
- static inline int int_clamp(int val, int vmin, int vmax)
-@@ -485,10 +488,16 @@
- switch(p->pid) {
- case USB_TOKEN_IN:
- if (p->devep == 1) {
-- if (s->kind == USB_MOUSE)
-- ret = usb_mouse_poll(s, p->data, p->len);
-- else if (s->kind == USB_TABLET)
-- ret = usb_tablet_poll(s, p->data, p->len);
-+ if (s->kind == USB_MOUSE)
-+ ret = usb_mouse_poll(s, p->data, p->len);
-+ else if (s->kind == USB_TABLET)
-+ ret = usb_tablet_poll(s, p->data, p->len);
-+
-+ if (!s->status_changed)
-+ ret = USB_RET_NAK;
-+ else
-+ s->status_changed = 0;
-+
- } else {
- goto fail;
- }
-@@ -570,6 +579,7 @@
- s->dev.handle_data = usb_mouse_handle_data;
- s->dev.handle_destroy = usb_mouse_handle_destroy;
- s->kind = USB_TABLET;
-+ s->status_changed = 0;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
-
-@@ -593,6 +603,7 @@
- s->dev.handle_data = usb_mouse_handle_data;
- s->dev.handle_destroy = usb_mouse_handle_destroy;
- s->kind = USB_MOUSE;
-+ s->status_changed = 0;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
-
-Index: ioemu/hw/usb-uhci.c
-===================================================================
---- ioemu.orig/hw/usb-uhci.c 2007-05-09 14:12:05.000000000 +0100
-+++ ioemu/hw/usb-uhci.c 2007-05-09 14:12:06.000000000 +0100
-@@ -43,9 +43,15 @@
- #define TD_CTRL_IOC (1 << 24)
- #define TD_CTRL_ACTIVE (1 << 23)
- #define TD_CTRL_STALL (1 << 22)
-+#define TD_CTRL_BUFFER (1 << 21)
- #define TD_CTRL_BABBLE (1 << 20)
- #define TD_CTRL_NAK (1 << 19)
- #define TD_CTRL_TIMEOUT (1 << 18)
-+#define TD_CTRL_BITSTUFF \
-+ (1 << 17)
-+#define TD_CTRL_MASK \
-+ (TD_CTRL_BITSTUFF | TD_CTRL_TIMEOUT | TD_CTRL_NAK \
-+ | TD_CTRL_BABBLE | TD_CTRL_BUFFER | TD_CTRL_STALL)
-
- #define UHCI_PORT_RESET (1 << 9)
- #define UHCI_PORT_LSDA (1 << 8)
-@@ -431,13 +437,13 @@
- uint8_t pid;
- int len, max_len, err, ret;
-
-- /* ??? This is wrong for async completion. */
-- if (td->ctrl & TD_CTRL_IOC) {
-- *int_mask |= 0x01;
-+ if (!(td->ctrl & TD_CTRL_ACTIVE)) {
-+ ret = 1;
-+ goto out;
- }
--
-- if (!(td->ctrl & TD_CTRL_ACTIVE))
-- return 1;
-+
-+ /* Clear TD's status field explicitly */
-+ td->ctrl = td->ctrl & (~TD_CTRL_MASK);
-
- /* TD is active */
- max_len = ((td->token >> 21) + 1) & 0x7ff;
-@@ -493,11 +499,13 @@
- /* invalid pid : frame interrupted */
- s->status |= UHCI_STS_HCPERR;
- uhci_update_irq(s);
-- return -1;
-+ ret = -1;
-+ goto out;
- }
- }
- if (ret == USB_RET_ASYNC) {
-- return 2;
-+ ret = 2;
-+ goto out;
- }
- if (td->ctrl & TD_CTRL_IOS)
- td->ctrl &= ~TD_CTRL_ACTIVE;
-@@ -509,10 +517,12 @@
- len < max_len) {
- *int_mask |= 0x02;
- /* short packet: do not update QH */
-- return 1;
-+ ret = 1;
-+ goto out;
- } else {
- /* success */
-- return 0;
-+ ret = 0;
-+ goto out;
- }
- } else {
- switch(ret) {
-@@ -531,23 +541,34 @@
- }
- td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
- (err << TD_CTRL_ERROR_SHIFT);
-- return 1;
-+ ret = 1;
-+ goto out;
- case USB_RET_NAK:
- td->ctrl |= TD_CTRL_NAK;
- if (pid == USB_TOKEN_SETUP)
- goto do_timeout;
-- return 1;
-+ ret = 1;
-+ goto out;
- case USB_RET_STALL:
- td->ctrl |= TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
-- return 1;
-+ ret = 1;
-+ goto out;
- case USB_RET_BABBLE:
- td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
- /* frame interrupted */
-- return -1;
-+ ret = -1;
-+ goto out;
- }
- }
-+
-+out:
-+ /* If TD is inactive and IOC bit set to 1 then update int_mask */
-+ if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {
-+ *int_mask |= 0x01;
-+ }
-+ return ret;
- }
-
- static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
diff --git a/tools/ioemu/patches/usb-uhci-buffer-size b/tools/ioemu/patches/usb-uhci-buffer-size
deleted file mode 100644
index 785692ff47..0000000000
--- a/tools/ioemu/patches/usb-uhci-buffer-size
+++ /dev/null
@@ -1,25 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID f19ddc0ee3e68d5d8a250ba0a20ab7d90ae9a36a
-# Parent f66f7c3a82a7420d80714b0d349ee9a24b50ec28
-[QEMU] usb-uhci: Data buffer is too small
-
-The data buffer is only 1280 bytes long but the user-supplied length
-can be as large as 0x7ff. This patch extends the buffer to 2048
-bytes.
-
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-
-Index: ioemu/hw/usb-uhci.c
-===================================================================
---- ioemu.orig/hw/usb-uhci.c 2006-12-08 18:21:36.000000000 +0000
-+++ ioemu/hw/usb-uhci.c 2006-12-08 18:23:06.000000000 +0000
-@@ -421,7 +421,7 @@
- static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
- {
- uint8_t pid;
-- uint8_t buf[1280];
-+ uint8_t buf[2048];
- int len, max_len, err, ret;
-
- if (td->ctrl & TD_CTRL_IOC) {
diff --git a/tools/ioemu/patches/vnc-altgr-keysym b/tools/ioemu/patches/vnc-altgr-keysym
deleted file mode 100644
index 3bf4240faa..0000000000
--- a/tools/ioemu/patches/vnc-altgr-keysym
+++ /dev/null
@@ -1,24 +0,0 @@
-Index: ioemu/keymaps/modifiers
-===================================================================
---- ioemu.orig/keymaps/modifiers 2007-05-08 10:35:13.000000000 +0100
-+++ ioemu/keymaps/modifiers 2007-05-08 10:35:57.000000000 +0100
-@@ -3,6 +3,7 @@
-
- Alt_R 0xb8
- Mode_switch 0xb8
-+ISO_Level3_Shift 0xb8
- Alt_L 0x38
-
- Control_R 0x9d
-Index: ioemu/vnc_keysym.h
-===================================================================
---- ioemu.orig/vnc_keysym.h 2007-05-08 10:35:14.000000000 +0100
-+++ ioemu/vnc_keysym.h 2007-05-08 10:35:14.000000000 +0100
-@@ -215,6 +215,7 @@
- {"Shift_R", 0xffe2}, /* XK_Shift_R */
- {"Super_L", 0xffeb}, /* XK_Super_L */
- {"Super_R", 0xffec}, /* XK_Super_R */
-+{"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
-
- /* special keys */
- {"BackSpace", 0xff08}, /* XK_BackSpace */
diff --git a/tools/ioemu/patches/vnc-backoff-screen-scan b/tools/ioemu/patches/vnc-backoff-screen-scan
deleted file mode 100644
index 817fe31806..0000000000
--- a/tools/ioemu/patches/vnc-backoff-screen-scan
+++ /dev/null
@@ -1,385 +0,0 @@
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-10 15:18:01.000000000 +0100
-+++ ioemu/vnc.c 2007-05-10 15:18:58.000000000 +0100
-@@ -28,7 +28,19 @@
- #include "qemu_socket.h"
- #include <assert.h>
-
--#define VNC_REFRESH_INTERVAL (1000 / 30)
-+/* The refresh interval starts at BASE. If we scan the buffer and
-+ find no change, we increase by INC, up to MAX. If the mouse moves
-+ or we get a keypress, the interval is set back to BASE. If we find
-+ an update, halve the interval.
-+
-+ All times in milliseconds. */
-+#define VNC_REFRESH_INTERVAL_BASE 30
-+#define VNC_REFRESH_INTERVAL_INC 50
-+#define VNC_REFRESH_INTERVAL_MAX 2000
-+
-+/* Wait at most one second between updates, so that we can detect a
-+ minimised vncviewer reasonably quickly. */
-+#define VNC_MAX_UPDATE_INTERVAL 5000
-
- #include "vnc_keysym.h"
- #include "keymaps.c"
-@@ -61,10 +73,11 @@
- struct VncState
- {
- QEMUTimer *timer;
-+ int timer_interval;
-+ int64_t last_update_time;
- int lsock;
- int csock;
- DisplayState *ds;
-- int need_update;
- int width;
- int height;
- uint64_t *dirty_row; /* screen regions which are possibly dirty */
-@@ -102,8 +115,6 @@
- int visible_w;
- int visible_h;
-
-- int slow_client;
--
- /* input */
- uint8_t modifiers_state[256];
- };
-@@ -408,7 +419,7 @@
- int y = 0;
- int pitch = ds->linesize;
- VncState *vs = ds->opaque;
-- int updating_client = !vs->slow_client;
-+ int updating_client = 1;
-
- if (src_x < vs->visible_x || src_y < vs->visible_y ||
- dst_x < vs->visible_x || dst_y < vs->visible_y ||
-@@ -418,10 +429,8 @@
- (dst_y + h) > (vs->visible_y + vs->visible_h))
- updating_client = 0;
-
-- if (updating_client) {
-- vs->need_update = 1;
-+ if (updating_client)
- _vnc_update_client(vs);
-- }
-
- if (dst_y > src_y) {
- y = h - 1;
-@@ -473,110 +482,149 @@
- static void _vnc_update_client(void *opaque)
- {
- VncState *vs = opaque;
-- int64_t now = qemu_get_clock(rt_clock);
--
-- if (vs->need_update && vs->csock != -1) {
-- int y;
-- char *row;
-- char *old_row;
-- uint64_t width_mask;
-- int n_rectangles;
-- int saved_offset;
-- int maxx, maxy;
-- int tile_bytes = vs->depth * DP2X(vs, 1);
-+ int64_t now;
-+ int y;
-+ char *row;
-+ char *old_row;
-+ uint64_t width_mask;
-+ int n_rectangles;
-+ int saved_offset;
-+ int maxx, maxy;
-+ int tile_bytes = vs->depth * DP2X(vs, 1);
-
-- qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
-+ if (vs->csock == -1)
-+ return;
-
-- if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
-- width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
-- else
-- width_mask = ~(0ULL);
-+ now = qemu_get_clock(rt_clock);
-
-- /* Walk through the dirty map and eliminate tiles that
-- really aren't dirty */
-- row = vs->ds->data;
-- old_row = vs->old_data;
--
-- for (y = 0; y < vs->ds->height; y++) {
-- if (vs->dirty_row[y] & width_mask) {
-- int x;
-- char *ptr, *old_ptr;
--
-- ptr = row;
-- old_ptr = old_row;
--
-- for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
-- if (vs->dirty_row[y] & (1ULL << x)) {
-- if (memcmp(old_ptr, ptr, tile_bytes)) {
-- vs->has_update = 1;
-- vs->update_row[y] |= (1ULL << x);
-- memcpy(old_ptr, ptr, tile_bytes);
-- }
-- vs->dirty_row[y] &= ~(1ULL << x);
-- }
-+ if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
-+ width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
-+ else
-+ width_mask = ~(0ULL);
-
-- ptr += tile_bytes;
-- old_ptr += tile_bytes;
-- }
-- }
-+ /* Walk through the dirty map and eliminate tiles that really
-+ aren't dirty */
-+ row = vs->ds->data;
-+ old_row = vs->old_data;
-
-- row += vs->ds->linesize;
-- old_row += vs->ds->linesize;
-- }
-+ for (y = 0; y < vs->ds->height; y++) {
-+ if (vs->dirty_row[y] & width_mask) {
-+ int x;
-+ char *ptr, *old_ptr;
-
-- if (!vs->has_update || vs->visible_y >= vs->ds->height ||
-- vs->visible_x >= vs->ds->width)
-- return;
-+ ptr = row;
-+ old_ptr = old_row;
-
-- /* Count rectangles */
-- n_rectangles = 0;
-- vnc_write_u8(vs, 0); /* msg id */
-- vnc_write_u8(vs, 0);
-- saved_offset = vs->output.offset;
-- vnc_write_u16(vs, 0);
-+ for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
-+ if (vs->dirty_row[y] & (1ULL << x)) {
-+ if (memcmp(old_ptr, ptr, tile_bytes)) {
-+ vs->has_update = 1;
-+ vs->update_row[y] |= (1ULL << x);
-+ memcpy(old_ptr, ptr, tile_bytes);
-+ }
-+ vs->dirty_row[y] &= ~(1ULL << x);
-+ }
-
-- maxy = vs->visible_y + vs->visible_h;
-- if (maxy > vs->ds->height)
-- maxy = vs->ds->height;
-- maxx = vs->visible_x + vs->visible_w;
-- if (maxx > vs->ds->width)
-- maxx = vs->ds->width;
-+ ptr += tile_bytes;
-+ old_ptr += tile_bytes;
-+ }
-+ }
-+
-+ row += vs->ds->linesize;
-+ old_row += vs->ds->linesize;
-+ }
-
-- for (y = vs->visible_y; y < maxy; y++) {
-- int x;
-- int last_x = -1;
-- for (x = X2DP_DOWN(vs, vs->visible_x);
-- x < X2DP_UP(vs, maxx); x++) {
-- if (vs->update_row[y] & (1ULL << x)) {
-- if (last_x == -1)
-- last_x = x;
-- vs->update_row[y] &= ~(1ULL << x);
-- } else {
-- if (last_x != -1) {
-- int h = find_update_height(vs, y, maxy, last_x, x);
-+ if (!vs->has_update || vs->visible_y >= vs->ds->height ||
-+ vs->visible_x >= vs->ds->width)
-+ goto backoff;
-+
-+ /* Count rectangles */
-+ n_rectangles = 0;
-+ vnc_write_u8(vs, 0); /* msg id */
-+ vnc_write_u8(vs, 0);
-+ saved_offset = vs->output.offset;
-+ vnc_write_u16(vs, 0);
-+
-+ maxy = vs->visible_y + vs->visible_h;
-+ if (maxy > vs->ds->height)
-+ maxy = vs->ds->height;
-+ maxx = vs->visible_x + vs->visible_w;
-+ if (maxx > vs->ds->width)
-+ maxx = vs->ds->width;
-+
-+ for (y = vs->visible_y; y < maxy; y++) {
-+ int x;
-+ int last_x = -1;
-+ for (x = X2DP_DOWN(vs, vs->visible_x);
-+ x < X2DP_UP(vs, maxx); x++) {
-+ if (vs->update_row[y] & (1ULL << x)) {
-+ if (last_x == -1)
-+ last_x = x;
-+ vs->update_row[y] &= ~(1ULL << x);
-+ } else {
-+ if (last_x != -1) {
-+ int h = find_update_height(vs, y, maxy, last_x, x);
-+ if (h != 0) {
- send_framebuffer_update(vs, DP2X(vs, last_x), y,
- DP2X(vs, (x - last_x)), h);
- n_rectangles++;
- }
-- last_x = -1;
- }
-+ last_x = -1;
- }
-- if (last_x != -1) {
-- int h = find_update_height(vs, y, maxy, last_x, x);
-+ }
-+ if (last_x != -1) {
-+ int h = find_update_height(vs, y, maxy, last_x, x);
-+ if (h != 0) {
- send_framebuffer_update(vs, DP2X(vs, last_x), y,
- DP2X(vs, (x - last_x)), h);
- n_rectangles++;
- }
- }
-- vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
-- vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-+ }
-+ vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
-+ vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-
-- vs->has_update = 0;
-- vs->need_update = 0;
-- vnc_flush(vs);
-- vs->slow_client = 0;
-- } else
-- vs->slow_client = 1;
-+ if (n_rectangles == 0)
-+ goto backoff;
-+
-+ vs->has_update = 0;
-+ vnc_flush(vs);
-+ vs->last_update_time = now;
-+
-+ vs->timer_interval /= 2;
-+ if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE)
-+ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-+
-+ return;
-+
-+ backoff:
-+ /* No update -> back off a bit */
-+ vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
-+ if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
-+ vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
-+ if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
-+ /* Send a null update. If the client is no longer
-+ interested (e.g. minimised) it'll ignore this, and we
-+ can stop scanning the buffer until it sends another
-+ update request. */
-+ /* It turns out that there's a bug in realvncviewer 4.1.2
-+ which means that if you send a proper null update (with
-+ no update rectangles), it gets a bit out of sync and
-+ never sends any further requests, regardless of whether
-+ it needs one or not. Fix this by sending a single 1x1
-+ update rectangle instead. */
-+ vnc_write_u8(vs, 0);
-+ vnc_write_u8(vs, 0);
-+ vnc_write_u16(vs, 1);
-+ send_framebuffer_update(vs, 0, 0, 1, 1);
-+ vnc_flush(vs);
-+ vs->last_update_time = now;
-+ return;
-+ }
-+ }
-+ qemu_mod_timer(vs->timer, now + vs->timer_interval);
-+ return;
- }
-
- static void vnc_update_client(void *opaque)
-@@ -589,8 +637,10 @@
-
- static void vnc_timer_init(VncState *vs)
- {
-- if (vs->timer == NULL)
-+ if (vs->timer == NULL) {
- vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
-+ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-+ }
- }
-
- static void vnc_dpy_refresh(DisplayState *ds)
-@@ -650,7 +700,6 @@
- vs->csock = -1;
- buffer_reset(&vs->input);
- buffer_reset(&vs->output);
-- vs->need_update = 0;
- return 0;
- }
- return ret;
-@@ -957,7 +1006,6 @@
- int x_position, int y_position,
- int w, int h)
- {
-- vs->need_update = 1;
- if (!incremental)
- framebuffer_set_updated(vs, x_position, y_position, w, h);
- vs->visible_x = x_position;
-@@ -1087,6 +1135,7 @@
- {
- int i;
- uint16_t limit;
-+ int64_t now;
-
- switch (data[0]) {
- case 0:
-@@ -1130,12 +1179,18 @@
- if (len == 1)
- return 8;
-
-+ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-+ qemu_advance_timer(vs->timer,
-+ qemu_get_clock(rt_clock) + vs->timer_interval);
- key_event(vs, read_u8(data, 1), read_u32(data, 4));
- break;
- case 5:
- if (len == 1)
- return 6;
-
-+ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-+ qemu_advance_timer(vs->timer,
-+ qemu_get_clock(rt_clock) + vs->timer_interval);
- pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
- break;
- case 6:
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:18:01.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:18:58.000000000 +0100
-@@ -811,6 +811,12 @@
- }
- }
-
-+void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time)
-+{
-+ if (ts->expire_time > expire_time || !qemu_timer_pending(ts))
-+ qemu_mod_timer(ts, expire_time);
-+}
-+
- /* modify the current timer so that it will be fired when current_time
- >= expire_time. The corresponding callback will be called. */
- void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:18:01.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:18:58.000000000 +0100
-@@ -441,6 +441,7 @@
- void qemu_free_timer(QEMUTimer *ts);
- void qemu_del_timer(QEMUTimer *ts);
- void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-+void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time);
- int qemu_timer_pending(QEMUTimer *ts);
-
- extern int64_t ticks_per_sec;
diff --git a/tools/ioemu/patches/vnc-cleanup b/tools/ioemu/patches/vnc-cleanup
deleted file mode 100644
index db44e06f63..0000000000
--- a/tools/ioemu/patches/vnc-cleanup
+++ /dev/null
@@ -1,107 +0,0 @@
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-03 18:17:59.000000000 +0100
-+++ ioemu/vnc.c 2007-05-03 19:46:19.000000000 +0100
-@@ -170,13 +170,16 @@
- static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
- {
- VncState *vs = ds->opaque;
-- int i;
-+ uint64_t mask;
-
- h += y;
-+ if (w != 1024)
-+ mask = ((1ULL << (w / 16)) - 1) << (x / 16);
-+ else
-+ mask = ~(0ULL);
-
- for (; y < h; y++)
-- for (i = 0; i < w; i += 16)
-- vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
-+ vs->dirty_row[y] |= mask;
- }
-
- static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
-@@ -402,6 +405,7 @@
- static void vnc_update_client(void *opaque)
- {
- VncState *vs = opaque;
-+ int64_t now = qemu_get_clock(rt_clock);
-
- if (vs->need_update && vs->csock != -1) {
- int y;
-@@ -412,6 +416,8 @@
- int saved_offset;
- int has_dirty = 0;
-
-+ qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
-+
- vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
-
- /* Walk through the dirty map and eliminate tiles that
-@@ -419,7 +425,7 @@
- row = vs->ds->data;
- old_row = vs->old_data;
-
-- for (y = 0; y < vs->height; y++) {
-+ for (y = 0; y < vs->ds->height; y++) {
- if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
- int x;
- char *ptr, *old_ptr;
-@@ -444,10 +450,8 @@
- old_row += vs->ds->linesize;
- }
-
-- if (!has_dirty) {
-- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
-+ if (!has_dirty)
- return;
-- }
-
- /* Count rectangles */
- n_rectangles = 0;
-@@ -483,17 +487,13 @@
- vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
- vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
- vnc_flush(vs);
--
- }
-- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
- }
-
- static void vnc_timer_init(VncState *vs)
- {
-- if (vs->timer == NULL) {
-+ if (vs->timer == NULL)
- vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
-- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
-- }
- }
-
- static void vnc_dpy_refresh(DisplayState *ds)
-@@ -864,6 +864,8 @@
- old_row += vs->ds->linesize;
- }
- }
-+
-+ qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
- }
-
- static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:44:49.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:46:19.000000000 +0100
-@@ -6085,10 +6085,10 @@
- /* XXX: better handling of removal */
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
- ioh_next = ioh->next;
-- if (FD_ISSET(ioh->fd, &rfds)) {
-+ if (ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
- ioh->fd_read(ioh->opaque);
- }
-- if (FD_ISSET(ioh->fd, &wfds)) {
-+ if (ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
- ioh->fd_write(ioh->opaque);
- }
- }
diff --git a/tools/ioemu/patches/vnc-display-find-unused b/tools/ioemu/patches/vnc-display-find-unused
deleted file mode 100644
index f150b92f2e..0000000000
--- a/tools/ioemu/patches/vnc-display-find-unused
+++ /dev/null
@@ -1,143 +0,0 @@
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-10 15:11:41.000000000 +0100
-+++ ioemu/vnc.c 2007-05-10 15:11:41.000000000 +0100
-@@ -1266,7 +1266,7 @@
-
- extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
-
--void vnc_display_init(DisplayState *ds, const char *arg)
-+int vnc_display_init(DisplayState *ds, const char *arg, int find_unused)
- {
- struct sockaddr *addr;
- struct sockaddr_in iaddr;
-@@ -1308,6 +1308,9 @@
-
- vnc_dpy_resize(vs->ds, 640, 400);
-
-+ if (arg == NULL)
-+ arg = "localhost:0";
-+
- #ifndef _WIN32
- if (strstart(arg, "unix:", &p)) {
- addr = (struct sockaddr *)&uaddr;
-@@ -1352,7 +1355,11 @@
- }
- }
-
-- if (bind(vs->lsock, addr, addrlen) == -1) {
-+ while (bind(vs->lsock, addr, addrlen) == -1) {
-+ if (find_unused && errno == EADDRINUSE) {
-+ iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 1);
-+ continue;
-+ }
- fprintf(stderr, "bind() failed\n");
- exit(1);
- }
-@@ -1366,6 +1373,8 @@
- if (ret == -1) {
- exit(1);
- }
-+
-+ return ntohs(iaddr.sin_port);
- }
-
- int vnc_start_viewer(int port)
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:11:41.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:11:41.000000000 +0100
-@@ -132,6 +132,7 @@
- static DisplayState display_state;
- int nographic;
- int vncviewer;
-+int vncunused;
- const char* keyboard_layout = NULL;
- int64_t ticks_per_sec;
- int boot_device = 'c';
-@@ -6311,6 +6312,7 @@
- "-loadvm file start right away with a saved state (loadvm in monitor)\n"
- "-vnc display start a VNC server on display\n"
- "-vncviewer start a vncviewer process for this domain\n"
-+ "-vncunused bind the VNC server to an unused port\n"
- #ifndef _WIN32
- "-daemonize daemonize QEMU after initializing\n"
- #endif
-@@ -6407,6 +6409,7 @@
- QEMU_OPTION_vcpus,
- QEMU_OPTION_acpi,
- QEMU_OPTION_vncviewer,
-+ QEMU_OPTION_vncunused,
- };
-
- typedef struct QEMUOption {
-@@ -6486,6 +6489,7 @@
- { "smp", HAS_ARG, QEMU_OPTION_smp },
- { "vnc", HAS_ARG, QEMU_OPTION_vnc },
- { "vncviewer", 0, QEMU_OPTION_vncviewer },
-+ { "vncunused", 0, QEMU_OPTION_vncunused },
-
- /* temporary options */
- { "usb", 0, QEMU_OPTION_usb },
-@@ -6853,6 +6857,7 @@
- snapshot = 0;
- nographic = 0;
- vncviewer = 0;
-+ vncunused = 0;
- kernel_filename = NULL;
- kernel_cmdline = "";
- #ifdef TARGET_PPC
-@@ -7272,12 +7277,15 @@
- case QEMU_OPTION_vncviewer:
- vncviewer++;
- break;
-+ case QEMU_OPTION_vncunused:
-+ vncunused++;
-+ break;
- }
- }
- }
-
- #ifndef _WIN32
-- if (daemonize && !nographic && vnc_display == NULL) {
-+ if (daemonize && !nographic && vnc_display == NULL && vncunused == 0) {
- fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
- daemonize = 0;
- }
-@@ -7553,10 +7561,11 @@
- /* terminal init */
- if (nographic) {
- dumb_display_init(ds);
-- } else if (vnc_display != NULL) {
-- vnc_display_init(ds, vnc_display);
-+ } else if (vnc_display != NULL || vncunused != 0) {
-+ int vnc_display_port;
-+ vnc_display_port = vnc_display_init(ds, vnc_display, vncunused);
- if (vncviewer)
-- vnc_start_viewer(vnc_display);
-+ vnc_start_viewer(vnc_display_port);
- } else {
- #if defined(CONFIG_SDL)
- sdl_display_init(ds, full_screen);
-@@ -7626,7 +7635,7 @@
- }
- }
-
-- if (vnc_display == -1) {
-+ if (vnc_display == NULL && vncunused == 0) {
- gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
- qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
- }
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:11:41.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:11:41.000000000 +0100
-@@ -928,7 +928,7 @@
- void cocoa_display_init(DisplayState *ds, int full_screen);
-
- /* vnc.c */
--void vnc_display_init(DisplayState *ds, const char *display);
-+int vnc_display_init(DisplayState *ds, const char *display, int find_unused);
- void do_info_vnc(void);
- int vnc_start_viewer(int port);
-
diff --git a/tools/ioemu/patches/vnc-fix-signedness b/tools/ioemu/patches/vnc-fix-signedness
deleted file mode 100644
index d5d7777822..0000000000
--- a/tools/ioemu/patches/vnc-fix-signedness
+++ /dev/null
@@ -1,176 +0,0 @@
-# HG changeset patch
-# User kaf24@localhost.localdomain
-# Date 1167325891 0
-# Node ID ede2f5280810789c3cb37603cf2e6b34c60982b1
-# Parent a138fabc2120376cfb4bf72596a334a1edf8adb0
-[QEMU] Fix a number of signedness issues plus a typo in the version checking in vnc.c.
-Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-10 15:19:29.000000000 +0100
-+++ ioemu/vnc.c 2007-05-10 15:19:30.000000000 +0100
-@@ -50,12 +50,12 @@
- {
- size_t capacity;
- size_t offset;
-- char *buffer;
-+ uint8_t *buffer;
- } Buffer;
-
- typedef struct VncState VncState;
-
--typedef int VncReadEvent(VncState *vs, char *data, size_t len);
-+typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
-
- typedef void VncWritePixels(VncState *vs, void *data, int size);
-
-@@ -86,7 +86,7 @@
- uint64_t *update_row; /* outstanding updates */
- int has_update; /* there's outstanding updates in the
- * visible area */
-- char *old_data;
-+ uint8_t *old_data;
- int depth; /* internal VNC frame buffer byte per pixel */
- int has_resize;
- int has_hextile;
-@@ -161,7 +161,7 @@
- static void vnc_update_client(void *opaque);
- static void vnc_client_read(void *opaque);
- static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
--static int make_challenge(char *random, int size);
-+static int make_challenge(unsigned char *random, int size);
- static void set_seed(unsigned int *seedp);
- static void get_random(int len, unsigned char *buf);
-
-@@ -353,7 +353,7 @@
- static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
- {
- int i;
-- char *row;
-+ uint8_t *row;
-
- vnc_framebuffer_update(vs, x, y, w, h, 0);
-
-@@ -417,9 +417,9 @@
- static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
- {
- int src, dst;
-- char *src_row;
-- char *dst_row;
-- char *old_row;
-+ uint8_t *src_row;
-+ uint8_t *dst_row;
-+ uint8_t *old_row;
- int y = 0;
- int pitch = ds->linesize;
- VncState *vs = ds->opaque;
-@@ -488,8 +488,8 @@
- VncState *vs = opaque;
- int64_t now;
- int y;
-- char *row;
-- char *old_row;
-+ uint8_t *row;
-+ uint8_t *old_row;
- uint64_t width_mask;
- int n_rectangles;
- int saved_offset;
-@@ -514,7 +514,7 @@
- for (y = 0; y < vs->ds->height; y++) {
- if (vs->dirty_row[y] & width_mask) {
- int x;
-- char *ptr, *old_ptr;
-+ uint8_t *ptr, *old_ptr;
-
- ptr = row;
- old_ptr = old_row;
-@@ -677,7 +677,7 @@
- return buffer->offset == 0;
- }
-
--static char *buffer_end(Buffer *buffer)
-+static uint8_t *buffer_end(Buffer *buffer)
- {
- return buffer->buffer + buffer->offset;
- }
-@@ -811,7 +811,7 @@
-
- static void vnc_write_u8(VncState *vs, uint8_t value)
- {
-- vnc_write(vs, (char *)&value, 1);
-+ vnc_write(vs, &value, 1);
- }
-
- static void vnc_flush(VncState *vs)
-@@ -1135,11 +1135,10 @@
- vga_hw_update();
- }
-
--static int protocol_client_msg(VncState *vs, char *data, size_t len)
-+static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
- {
- int i;
- uint16_t limit;
-- int64_t now;
-
- switch (data[0]) {
- case 0:
-@@ -1208,7 +1207,7 @@
- return 8 + v;
- }
-
-- client_cut_text(vs, read_u32(data, 4), data + 8);
-+ client_cut_text(vs, read_u32(data, 4), (char *)(data + 8));
- break;
- default:
- printf("Msg: %d\n", data[0]);
-@@ -1220,7 +1219,7 @@
- return 0;
- }
-
--static int protocol_client_init(VncState *vs, char *data, size_t len)
-+static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
- {
- size_t l;
- char pad[3] = { 0, 0, 0 };
-@@ -1281,7 +1280,7 @@
- return 0;
- }
-
--static int protocol_response(VncState *vs, char *client_response, size_t len)
-+static int protocol_response(VncState *vs, uint8_t *client_response, size_t len)
- {
- extern char vncpasswd[64];
- extern unsigned char challenge[AUTHCHALLENGESIZE];
-@@ -1319,7 +1318,7 @@
- return 0;
- }
-
--static int protocol_version(VncState *vs, char *version, size_t len)
-+static int protocol_version(VncState *vs, uint8_t *version, size_t len)
- {
- extern char vncpasswd[64];
- extern unsigned char challenge[AUTHCHALLENGESIZE];
-@@ -1535,7 +1534,7 @@
-
- unsigned int seed;
-
--static int make_challenge(char *random, int size)
-+static int make_challenge(unsigned char *random, int size)
- {
-
- set_seed(&seed);
-Index: ioemu/vnchextile.h
-===================================================================
---- ioemu.orig/vnchextile.h 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/vnchextile.h 2007-05-10 15:19:30.000000000 +0100
-@@ -13,7 +13,7 @@
- uint32_t *last_fg32,
- int *has_bg, int *has_fg)
- {
-- char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
-+ uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
- pixel_t *irow = (pixel_t *)row;
- int j, i;
- pixel_t *last_bg = (pixel_t *)last_bg32;
diff --git a/tools/ioemu/patches/vnc-fix-text-display-shift-key b/tools/ioemu/patches/vnc-fix-text-display-shift-key
deleted file mode 100644
index c659b105db..0000000000
--- a/tools/ioemu/patches/vnc-fix-text-display-shift-key
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-10 15:11:44.000000000 +0100
-+++ ioemu/vnc.c 2007-05-10 15:11:44.000000000 +0100
-@@ -993,7 +993,7 @@
-
- static void key_event(VncState *vs, int down, uint32_t sym)
- {
-- if (sym >= 'A' && sym <= 'Z')
-+ if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
- sym = sym - 'A' + 'a';
- do_key_event(vs, down, sym);
- }
diff --git a/tools/ioemu/patches/vnc-fix-version-check b/tools/ioemu/patches/vnc-fix-version-check
deleted file mode 100644
index e0769d1b00..0000000000
--- a/tools/ioemu/patches/vnc-fix-version-check
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-10 15:11:44.000000000 +0100
-+++ ioemu/vnc.c 2007-05-10 15:11:44.000000000 +0100
-@@ -1337,7 +1337,7 @@
-
-
- support = 0;
-- if (maj = 3) {
-+ if (maj == 3) {
- if (min == 3 || min ==4) {
- support = 1;
- }
diff --git a/tools/ioemu/patches/vnc-fixes b/tools/ioemu/patches/vnc-fixes
deleted file mode 100644
index 65447d066a..0000000000
--- a/tools/ioemu/patches/vnc-fixes
+++ /dev/null
@@ -1,531 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:46:19.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:46:21.000000000 +0100
-@@ -7616,8 +7616,10 @@
- }
- }
-
-- gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
-- qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
-+ if (vnc_display == -1) {
-+ gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
-+ qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
-+ }
-
- #ifdef CONFIG_GDBSTUB
- if (use_gdbstub) {
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-03 19:46:19.000000000 +0100
-+++ ioemu/vnc.c 2007-05-03 19:49:33.000000000 +0100
-@@ -3,6 +3,7 @@
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
-+ * Copyright (C) 2006 Christian Limpach <Christian.Limpach@xensource.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
-@@ -50,9 +51,11 @@
- uint32_t *last_fg,
- int *has_bg, int *has_fg);
-
-+#if 0
- #define VNC_MAX_WIDTH 2048
- #define VNC_MAX_HEIGHT 2048
- #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
-+#endif
-
- struct VncState
- {
-@@ -63,7 +66,11 @@
- int need_update;
- int width;
- int height;
-- uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
-+ uint64_t *dirty_row; /* screen regions which are possibly dirty */
-+ int dirty_pixel_shift;
-+ uint64_t *update_row; /* outstanding updates */
-+ int has_update; /* there's outstanding updates in the
-+ * visible area */
- char *old_data;
- int depth; /* internal VNC frame buffer byte per pixel */
- int has_resize;
-@@ -88,12 +95,26 @@
-
- VncReadEvent *read_handler;
- size_t read_handler_expect;
-+
-+ int visible_x;
-+ int visible_y;
-+ int visible_w;
-+ int visible_h;
-+
-+ int slow_client;
-+
- /* input */
- uint8_t modifiers_state[256];
- };
-
- static VncState *vnc_state; /* needed for info vnc */
-
-+#define DIRTY_PIXEL_BITS 64
-+#define X2DP_DOWN(vs, x) ((x) >> (vs)->dirty_pixel_shift)
-+#define X2DP_UP(vs, x) \
-+ (((x) + (1ULL << (vs)->dirty_pixel_shift) - 1) >> (vs)->dirty_pixel_shift)
-+#define DP2X(vs, x) ((x) << (vs)->dirty_pixel_shift)
-+
- void do_info_vnc(void)
- {
- if (vnc_state == NULL)
-@@ -123,9 +144,12 @@
- static void vnc_write_u16(VncState *vs, uint16_t value);
- static void vnc_write_u8(VncState *vs, uint8_t value);
- static void vnc_flush(VncState *vs);
-+static void _vnc_update_client(void *opaque);
- static void vnc_update_client(void *opaque);
- static void vnc_client_read(void *opaque);
-+static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
-
-+#if 0
- static inline void vnc_set_bit(uint32_t *d, int k)
- {
- d[k >> 5] |= 1 << (k & 0x1f);
-@@ -166,20 +190,37 @@
- }
- return 0;
- }
-+#endif
-
--static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
-+static void set_bits_in_row(VncState *vs, uint64_t *row,
-+ int x, int y, int w, int h)
- {
-- VncState *vs = ds->opaque;
-+ int x1, x2;
- uint64_t mask;
-
-- h += y;
-- if (w != 1024)
-- mask = ((1ULL << (w / 16)) - 1) << (x / 16);
-+ if (w == 0)
-+ return;
-+
-+ x1 = X2DP_DOWN(vs, x);
-+ x2 = X2DP_UP(vs, x + w);
-+
-+ if (X2DP_UP(vs, w) != DIRTY_PIXEL_BITS)
-+ mask = ((1ULL << (x2 - x1)) - 1) << x1;
- else
- mask = ~(0ULL);
-
-+ h += y;
-+ if (h > vs->ds->height)
-+ h = vs->ds->height;
- for (; y < h; y++)
-- vs->dirty_row[y] |= mask;
-+ row[y] |= mask;
-+}
-+
-+static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
-+{
-+ VncState *vs = ds->opaque;
-+
-+ set_bits_in_row(vs, vs->dirty_row, x, y, w, h);
- }
-
- static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
-@@ -197,16 +238,23 @@
- {
- int size_changed;
- VncState *vs = ds->opaque;
-+ int o;
-
- ds->data = realloc(ds->data, w * h * vs->depth);
- vs->old_data = realloc(vs->old_data, w * h * vs->depth);
-+ vs->dirty_row = realloc(vs->dirty_row, h * sizeof(vs->dirty_row[0]));
-+ vs->update_row = realloc(vs->update_row, h * sizeof(vs->dirty_row[0]));
-
-- if (ds->data == NULL || vs->old_data == NULL) {
-+ if (ds->data == NULL || vs->old_data == NULL ||
-+ vs->dirty_row == NULL || vs->update_row == NULL) {
- fprintf(stderr, "vnc: memory allocation failed\n");
- exit(1);
- }
-
-- ds->depth = vs->depth * 8;
-+ if (ds->depth != vs->depth * 8) {
-+ ds->depth = vs->depth * 8;
-+ set_color_table(ds);
-+ }
- size_changed = ds->width != w || ds->height != h;
- ds->width = w;
- ds->height = h;
-@@ -220,6 +268,10 @@
- vs->width = ds->width;
- vs->height = ds->height;
- }
-+ vs->dirty_pixel_shift = 0;
-+ for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
-+ vs->dirty_pixel_shift++;
-+ framebuffer_set_updated(vs, 0, 0, ds->width, ds->height);
- }
-
- /* fastest code */
-@@ -355,8 +407,20 @@
- int y = 0;
- int pitch = ds->linesize;
- VncState *vs = ds->opaque;
-+ int updating_client = !vs->slow_client;
-
-- vnc_update_client(vs);
-+ if (src_x < vs->visible_x || src_y < vs->visible_y ||
-+ dst_x < vs->visible_x || dst_y < vs->visible_y ||
-+ (src_x + w) > (vs->visible_x + vs->visible_w) ||
-+ (src_y + h) > (vs->visible_y + vs->visible_h) ||
-+ (dst_x + w) > (vs->visible_x + vs->visible_w) ||
-+ (dst_y + h) > (vs->visible_y + vs->visible_h))
-+ updating_client = 0;
-+
-+ if (updating_client) {
-+ vs->need_update = 1;
-+ _vnc_update_client(vs);
-+ }
-
- if (dst_y > src_y) {
- y = h - 1;
-@@ -378,31 +442,34 @@
- old_row += pitch;
- }
-
-- vnc_write_u8(vs, 0); /* msg id */
-- vnc_write_u8(vs, 0);
-- vnc_write_u16(vs, 1); /* number of rects */
-- vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
-- vnc_write_u16(vs, src_x);
-- vnc_write_u16(vs, src_y);
-- vnc_flush(vs);
-+ if (updating_client && vs->csock != -1 && !vs->has_update) {
-+ vnc_write_u8(vs, 0); /* msg id */
-+ vnc_write_u8(vs, 0);
-+ vnc_write_u16(vs, 1); /* number of rects */
-+ vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
-+ vnc_write_u16(vs, src_x);
-+ vnc_write_u16(vs, src_y);
-+ vnc_flush(vs);
-+ } else
-+ framebuffer_set_updated(vs, dst_x, dst_y, w, h);
- }
-
--static int find_dirty_height(VncState *vs, int y, int last_x, int x)
-+static int find_update_height(VncState *vs, int y, int maxy, int last_x, int x)
- {
- int h;
-
-- for (h = 1; h < (vs->height - y); h++) {
-+ for (h = 1; y + h < maxy; h++) {
- int tmp_x;
-- if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
-+ if (!(vs->update_row[y + h] & (1ULL << last_x)))
- break;
- for (tmp_x = last_x; tmp_x < x; tmp_x++)
-- vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
-+ vs->update_row[y + h] &= ~(1ULL << tmp_x);
- }
-
- return h;
- }
-
--static void vnc_update_client(void *opaque)
-+static void _vnc_update_client(void *opaque)
- {
- VncState *vs = opaque;
- int64_t now = qemu_get_clock(rt_clock);
-@@ -411,14 +478,18 @@
- int y;
- char *row;
- char *old_row;
-- uint32_t width_mask[VNC_DIRTY_WORDS];
-+ uint64_t width_mask;
- int n_rectangles;
- int saved_offset;
-- int has_dirty = 0;
-+ int maxx, maxy;
-+ int tile_bytes = vs->depth * DP2X(vs, 1);
-
- qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
-
-- vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
-+ if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
-+ width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
-+ else
-+ width_mask = ~(0ULL);
-
- /* Walk through the dirty map and eliminate tiles that
- really aren't dirty */
-@@ -426,23 +497,25 @@
- old_row = vs->old_data;
-
- for (y = 0; y < vs->ds->height; y++) {
-- if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
-+ if (vs->dirty_row[y] & width_mask) {
- int x;
- char *ptr, *old_ptr;
-
- ptr = row;
- old_ptr = old_row;
-
-- for (x = 0; x < vs->ds->width; x += 16) {
-- if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
-- vnc_clear_bit(vs->dirty_row[y], (x / 16));
-- } else {
-- has_dirty = 1;
-- memcpy(old_ptr, ptr, 16 * vs->depth);
-+ for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
-+ if (vs->dirty_row[y] & (1ULL << x)) {
-+ if (memcmp(old_ptr, ptr, tile_bytes)) {
-+ vs->has_update = 1;
-+ vs->update_row[y] |= (1ULL << x);
-+ memcpy(old_ptr, ptr, tile_bytes);
-+ }
-+ vs->dirty_row[y] &= ~(1ULL << x);
- }
-
-- ptr += 16 * vs->depth;
-- old_ptr += 16 * vs->depth;
-+ ptr += tile_bytes;
-+ old_ptr += tile_bytes;
- }
- }
-
-@@ -450,7 +523,8 @@
- old_row += vs->ds->linesize;
- }
-
-- if (!has_dirty)
-+ if (!vs->has_update || vs->visible_y >= vs->ds->height ||
-+ vs->visible_x >= vs->ds->width)
- return;
-
- /* Count rectangles */
-@@ -460,34 +534,56 @@
- saved_offset = vs->output.offset;
- vnc_write_u16(vs, 0);
-
-- for (y = 0; y < vs->height; y++) {
-+ maxy = vs->visible_y + vs->visible_h;
-+ if (maxy > vs->ds->height)
-+ maxy = vs->ds->height;
-+ maxx = vs->visible_x + vs->visible_w;
-+ if (maxx > vs->ds->width)
-+ maxx = vs->ds->width;
-+
-+ for (y = vs->visible_y; y < maxy; y++) {
- int x;
- int last_x = -1;
-- for (x = 0; x < vs->width / 16; x++) {
-- if (vnc_get_bit(vs->dirty_row[y], x)) {
-- if (last_x == -1) {
-+ for (x = X2DP_DOWN(vs, vs->visible_x);
-+ x < X2DP_UP(vs, maxx); x++) {
-+ if (vs->update_row[y] & (1ULL << x)) {
-+ if (last_x == -1)
- last_x = x;
-- }
-- vnc_clear_bit(vs->dirty_row[y], x);
-+ vs->update_row[y] &= ~(1ULL << x);
- } else {
- if (last_x != -1) {
-- int h = find_dirty_height(vs, y, last_x, x);
-- send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
-+ int h = find_update_height(vs, y, maxy, last_x, x);
-+ send_framebuffer_update(vs, DP2X(vs, last_x), y,
-+ DP2X(vs, (x - last_x)), h);
- n_rectangles++;
- }
- last_x = -1;
- }
- }
- if (last_x != -1) {
-- int h = find_dirty_height(vs, y, last_x, x);
-- send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
-+ int h = find_update_height(vs, y, maxy, last_x, x);
-+ send_framebuffer_update(vs, DP2X(vs, last_x), y,
-+ DP2X(vs, (x - last_x)), h);
- n_rectangles++;
- }
- }
- vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
- vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-+
-+ vs->has_update = 0;
-+ vs->need_update = 0;
- vnc_flush(vs);
-- }
-+ vs->slow_client = 0;
-+ } else
-+ vs->slow_client = 1;
-+}
-+
-+static void vnc_update_client(void *opaque)
-+{
-+ VncState *vs = opaque;
-+
-+ vs->ds->dpy_refresh(vs->ds);
-+ _vnc_update_client(vs);
- }
-
- static void vnc_timer_init(VncState *vs)
-@@ -498,8 +594,6 @@
-
- static void vnc_dpy_refresh(DisplayState *ds)
- {
-- VncState *vs = ds->opaque;
-- vnc_timer_init(vs);
- vga_hw_update();
- }
-
-@@ -535,7 +629,7 @@
-
- static void buffer_reset(Buffer *buffer)
- {
-- buffer->offset = 0;
-+ buffer->offset = 0;
- }
-
- static void buffer_append(Buffer *buffer, const void *data, size_t len)
-@@ -576,12 +670,12 @@
- if (!ret)
- return;
-
-- memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
-+ memmove(vs->output.buffer, vs->output.buffer + ret,
-+ vs->output.offset - ret);
- vs->output.offset -= ret;
-
-- if (vs->output.offset == 0) {
-+ if (vs->output.offset == 0)
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
-- }
- }
-
- static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-@@ -613,11 +707,11 @@
- return;
-
- if (!ret) {
-- memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
-+ memmove(vs->input.buffer, vs->input.buffer + len,
-+ vs->input.offset - len);
- vs->input.offset -= len;
-- } else {
-+ } else
- vs->read_handler_expect = ret;
-- }
- }
- }
-
-@@ -625,9 +719,9 @@
- {
- buffer_reserve(&vs->output, len);
-
-- if (buffer_empty(&vs->output)) {
-- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
-- }
-+ if (buffer_empty(&vs->output))
-+ qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read,
-+ vnc_client_write, vs);
-
- buffer_append(&vs->output, data, len);
- }
-@@ -848,22 +942,25 @@
- do_key_event(vs, down, sym);
- }
-
-+static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h)
-+{
-+
-+ set_bits_in_row(vs, vs->update_row, x, y, w, h);
-+
-+ vs->has_update = 1;
-+}
-+
- static void framebuffer_update_request(VncState *vs, int incremental,
- int x_position, int y_position,
- int w, int h)
- {
-- int i;
- vs->need_update = 1;
-- if (!incremental) {
-- char *old_row = vs->old_data + y_position * vs->ds->linesize;
--
-- for (i = 0; i < h; i++) {
-- vnc_set_bits(vs->dirty_row[y_position + i],
-- (vs->ds->width / 16), VNC_DIRTY_WORDS);
-- memset(old_row, 42, vs->ds->width * vs->depth);
-- old_row += vs->ds->linesize;
-- }
-- }
-+ if (!incremental)
-+ framebuffer_set_updated(vs, x_position, y_position, w, h);
-+ vs->visible_x = x_position;
-+ vs->visible_y = y_position;
-+ vs->visible_w = w;
-+ vs->visible_h = h;
-
- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
- }
-@@ -978,8 +1075,6 @@
- }
-
- vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
-- memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
-- memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
-
- vga_hw_invalidate();
- vga_hw_update();
-@@ -1059,6 +1154,8 @@
- {
- char pad[3] = { 0, 0, 0 };
-
-+ vga_hw_update();
-+
- vs->width = vs->ds->width;
- vs->height = vs->ds->height;
- vnc_write_u16(vs, vs->ds->width);
-@@ -1145,11 +1242,11 @@
- vnc_write(vs, "RFB 003.003\n", 12);
- vnc_flush(vs);
- vnc_read_when(vs, protocol_version, 12);
-- memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
-- memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
-+ framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height);
- vs->has_resize = 0;
- vs->has_hextile = 0;
- vs->ds->dpy_copy = NULL;
-+ vnc_timer_init(vs);
- }
- }
-
-@@ -1195,8 +1292,6 @@
- vs->ds->dpy_resize = vnc_dpy_resize;
- vs->ds->dpy_refresh = vnc_dpy_refresh;
-
-- memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
--
- vnc_dpy_resize(vs->ds, 640, 400);
-
- #ifndef _WIN32
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 19:36:00.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 19:46:21.000000000 +0100
-@@ -356,6 +356,7 @@
- int is_graphic_console(void);
- CharDriverState *text_console_init(DisplayState *ds);
- void console_select(unsigned int index);
-+void set_color_table(DisplayState *ds);
-
- /* serial ports */
-
diff --git a/tools/ioemu/patches/vnc-japan-keymap b/tools/ioemu/patches/vnc-japan-keymap
deleted file mode 100644
index 86135a9b22..0000000000
--- a/tools/ioemu/patches/vnc-japan-keymap
+++ /dev/null
@@ -1,39 +0,0 @@
-# HG changeset patch
-# User kasai.takanori@jp.fujitsu.com
-# Node ID ea1ffa51b4121d36cffdc90276378a6ed334c2cc
-# Parent edd592c823a520d4072a95ac39beb2012c05321e
-Add the Japanese keymap for VNC Server.
-
-Signed-off-by: Takanori Kasai < kasai.takanori@jp.fujitsu.com >
-
-Index: ioemu/keymaps/ja
-===================================================================
---- ioemu.orig/keymaps/ja 2006-12-08 18:21:36.000000000 +0000
-+++ ioemu/keymaps/ja 2006-12-08 18:21:56.000000000 +0000
-@@ -102,3 +102,6 @@
- Henkan_Mode 0x79
- Katakana 0x70
- Muhenkan 0x7b
-+Henkan_Mode_Real 0x79
-+Henkan_Mode_Ultra 0x79
-+backslash_ja 0x73
-Index: ioemu/vnc_keysym.h
-===================================================================
---- ioemu.orig/vnc_keysym.h 2006-12-08 18:21:36.000000000 +0000
-+++ ioemu/vnc_keysym.h 2006-12-08 18:21:56.000000000 +0000
-@@ -271,5 +271,15 @@
- {"Num_Lock", 0xff7f}, /* XK_Num_Lock */
- {"Pause", 0xff13}, /* XK_Pause */
- {"Escape", 0xff1b}, /* XK_Escape */
-+
-+ /* localized keys */
-+{"BackApostrophe", 0xff21},
-+{"Muhenkan", 0xff22},
-+{"Katakana", 0xff25},
-+{"Zenkaku_Hankaku", 0xff29},
-+{"Henkan_Mode_Real", 0xff23},
-+{"Henkan_Mode_Ultra", 0xff3e},
-+{"backslash_ja", 0xffa5},
-+
- {0,0},
- };
diff --git a/tools/ioemu/patches/vnc-keypad-handling b/tools/ioemu/patches/vnc-keypad-handling
deleted file mode 100644
index 23c18a52b1..0000000000
--- a/tools/ioemu/patches/vnc-keypad-handling
+++ /dev/null
@@ -1,190 +0,0 @@
-# HG changeset patch
-# User Christian Limpach <Christian.Limpach@xensource.com>
-# Date 1178821985 -3600
-# Node ID dfbbb4d3b0dd2107cfee2b07fab6f33cefc4719c
-# Parent 23c4790512dbc889c4deed8ae1f8d54813c4b474
-[qemu] Fix keypad handling for VNC.
-
-Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
-
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-10 19:34:49.000000000 +0100
-+++ ioemu/vnc.c 2007-05-10 19:34:51.000000000 +0100
-@@ -909,6 +909,12 @@
- }
- }
-
-+static void press_key(VncState *vs, int keysym)
-+{
-+ kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
-+ kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
-+}
-+
- static void do_key_event(VncState *vs, int down, uint32_t sym)
- {
- int keycode;
-@@ -936,6 +942,28 @@
- return;
- }
- break;
-+ case 0x45: /* NumLock */
-+ if (!down)
-+ vs->modifiers_state[keycode] ^= 1;
-+ break;
-+ }
-+
-+ if (keycodeIsKeypad(vs->kbd_layout, keycode)) {
-+ /* If the numlock state needs to change then simulate an additional
-+ keypress before sending this one. This will happen if the user
-+ toggles numlock away from the VNC window.
-+ */
-+ if (keysymIsNumlock(vs->kbd_layout, sym & 0xFFFF)) {
-+ if (!vs->modifiers_state[0x45]) {
-+ vs->modifiers_state[0x45] = 1;
-+ press_key(vs, 0xff7f);
-+ }
-+ } else {
-+ if (vs->modifiers_state[0x45]) {
-+ vs->modifiers_state[0x45] = 0;
-+ press_key(vs, 0xff7f);
-+ }
-+ }
- }
-
- if (is_graphic_console()) {
-@@ -1427,6 +1455,7 @@
- vs->kbd_layout = init_keyboard_layout(keyboard_layout);
- if (!vs->kbd_layout)
- exit(1);
-+ vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
-
- vs->ds->data = NULL;
- vs->ds->dpy_update = vnc_dpy_update;
-Index: ioemu/keymaps.c
-===================================================================
---- ioemu.orig/keymaps.c 2007-05-10 19:34:49.000000000 +0100
-+++ ioemu/keymaps.c 2007-05-10 19:34:51.000000000 +0100
-@@ -32,6 +32,12 @@
- return 0;
- }
-
-+struct key_range {
-+ int start;
-+ int end;
-+ struct key_range *next;
-+};
-+
- #define MAX_NORMAL_KEYCODE 512
- #define MAX_EXTRA_COUNT 256
- typedef struct {
-@@ -41,8 +47,34 @@
- uint16_t keycode;
- } keysym2keycode_extra[MAX_EXTRA_COUNT];
- int extra_count;
-+ struct key_range *keypad_range;
-+ struct key_range *numlock_range;
- } kbd_layout_t;
-
-+static void add_to_key_range(struct key_range **krp, int code) {
-+ struct key_range *kr;
-+ for (kr = *krp; kr; kr = kr->next) {
-+ if (code >= kr->start && code <= kr->end)
-+ break;
-+ if (code == kr->start - 1) {
-+ kr->start--;
-+ break;
-+ }
-+ if (code == kr->end + 1) {
-+ kr->end++;
-+ break;
-+ }
-+ }
-+ if (kr == NULL) {
-+ kr = qemu_mallocz(sizeof(*kr));
-+ if (kr) {
-+ kr->start = kr->end = code;
-+ kr->next = *krp;
-+ *krp = kr;
-+ }
-+ }
-+}
-+
- static kbd_layout_t *parse_keyboard_layout(const char *language,
- kbd_layout_t * k)
- {
-@@ -87,7 +119,15 @@
- // fprintf(stderr, "Warning: unknown keysym %s\n", line);
- } else {
- const char *rest = end_of_keysym + 1;
-- int keycode = strtol(rest, NULL, 0);
-+ char *rest2;
-+ int keycode = strtol(rest, &rest2, 0);
-+
-+ if (rest && strstr(rest, "numlock")) {
-+ add_to_key_range(&k->keypad_range, keycode);
-+ add_to_key_range(&k->numlock_range, keysym);
-+ fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
-+ }
-+
- /* if(keycode&0x80)
- keycode=(keycode<<8)^0x80e0; */
- if (keysym < MAX_NORMAL_KEYCODE) {
-@@ -143,3 +183,25 @@
- }
- return 0;
- }
-+
-+static int keycodeIsKeypad(void *kbd_layout, int keycode)
-+{
-+ kbd_layout_t *k = kbd_layout;
-+ struct key_range *kr;
-+
-+ for (kr = k->keypad_range; kr; kr = kr->next)
-+ if (keycode >= kr->start && keycode <= kr->end)
-+ return 1;
-+ return 0;
-+}
-+
-+static int keysymIsNumlock(void *kbd_layout, int keysym)
-+{
-+ kbd_layout_t *k = kbd_layout;
-+ struct key_range *kr;
-+
-+ for (kr = k->numlock_range; kr; kr = kr->next)
-+ if (keysym >= kr->start && keysym <= kr->end)
-+ return 1;
-+ return 0;
-+}
-Index: ioemu/vnc_keysym.h
-===================================================================
---- ioemu.orig/vnc_keysym.h 2007-05-10 19:34:49.000000000 +0100
-+++ ioemu/vnc_keysym.h 2007-05-10 19:34:51.000000000 +0100
-@@ -232,6 +232,19 @@
- {"Home", 0xff50}, /* XK_Home */
- {"End", 0xff57}, /* XK_End */
- {"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
-+{"KP_Home", 0xff95},
-+{"KP_Left", 0xff96},
-+{"KP_Up", 0xff97},
-+{"KP_Right", 0xff98},
-+{"KP_Down", 0xff99},
-+{"KP_Prior", 0xff9a},
-+{"KP_Page_Up", 0xff9a},
-+{"KP_Next", 0xff9b},
-+{"KP_Page_Down", 0xff9b},
-+{"KP_End", 0xff9c},
-+{"KP_Begin", 0xff9d},
-+{"KP_Insert", 0xff9e},
-+{"KP_Delete", 0xff9f},
- {"F1", 0xffbe}, /* XK_F1 */
- {"F2", 0xffbf}, /* XK_F2 */
- {"F3", 0xffc0}, /* XK_F3 */
-@@ -259,6 +272,7 @@
- {"KP_8", 0xffb8}, /* XK_KP_8 */
- {"KP_9", 0xffb9}, /* XK_KP_9 */
- {"KP_Add", 0xffab}, /* XK_KP_Add */
-+{"KP_Separator", 0xffac},/* XK_KP_Separator */
- {"KP_Decimal", 0xffae}, /* XK_KP_Decimal */
- {"KP_Divide", 0xffaf}, /* XK_KP_Divide */
- {"KP_Enter", 0xff8d}, /* XK_KP_Enter */
diff --git a/tools/ioemu/patches/vnc-monitor-shift-key-processing b/tools/ioemu/patches/vnc-monitor-shift-key-processing
deleted file mode 100644
index afd164ad94..0000000000
--- a/tools/ioemu/patches/vnc-monitor-shift-key-processing
+++ /dev/null
@@ -1,60 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID 582d21e2d3cd12a13ad4debee9af8bb0f1be413a
-# Parent b7095209e31ae1f52cd4b196225a360543e37a80
-[QEMU] Do shift-key processing in QEMU monitor terminal when connected via VNC.
-Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2006-12-08 18:21:36.000000000 +0000
-+++ ioemu/vnc.c 2006-12-08 18:23:12.000000000 +0000
-@@ -114,6 +114,7 @@
- int visible_h;
-
- int ctl_keys; /* Ctrl+Alt starts calibration */
-+ int shift_keys; /* Shift / CapsLock keys */
- };
-
- #define DIRTY_PIXEL_BITS 64
-@@ -870,9 +871,12 @@
- } else if (down) {
- int qemu_keysym = 0;
-
-- if (sym <= 128) /* normal ascii */
-+ if (sym <= 128) { /* normal ascii */
-+ int shifted = vs->shift_keys == 1 || vs->shift_keys == 2;
- qemu_keysym = sym;
-- else {
-+ if (sym >= 'a' && sym <= 'z' && shifted)
-+ qemu_keysym -= 'a' - 'A';
-+ } else {
- switch (sym) {
- case XK_Up: qemu_keysym = QEMU_KEY_UP; break;
- case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break;
-@@ -903,6 +907,10 @@
- vs->ctl_keys |= 2;
- break;
-
-+ case XK_Shift_L:
-+ vs->shift_keys |= 1;
-+ break;
-+
- default:
- break;
- }
-@@ -916,6 +924,14 @@
- vs->ctl_keys &= ~2;
- break;
-
-+ case XK_Shift_L:
-+ vs->shift_keys &= ~1;
-+ break;
-+
-+ case XK_Caps_Lock:
-+ vs->shift_keys ^= 2;
-+ break;
-+
- case XK_1 ... XK_9:
- if ((vs->ctl_keys & 3) != 3)
- break;
diff --git a/tools/ioemu/patches/vnc-password b/tools/ioemu/patches/vnc-password
deleted file mode 100644
index 6f54403095..0000000000
--- a/tools/ioemu/patches/vnc-password
+++ /dev/null
@@ -1,801 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID 02506a7443155611d6bbf03e49fbf193e96d24db
-# Parent 328606e0705f0341bebda14cdd17962e463868e8
-[HVM] Implement password authentication of VNC connections.
-
-The specification is as mentioned at
-http://lists.xensource.com/archives/html/xen-devel/2006-09/msg00666.html
-(However, password came to describe plain text)
-
-The difference is follows.
-- protocol_authtype() without the necessity was deleted.
-- The check on the protocol version was added.
-- And, some small modification.
-
-Signed-off-by: Masami Watanabe <masami.watanabe@jp.fujitsu.com>
-
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-10 15:35:24.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-10 15:35:24.000000000 +0100
-@@ -443,6 +443,7 @@
- VL_OBJS+=sdl.o x_keymap.o
- endif
- VL_OBJS+=vnc.o
-+VL_OBJS+=d3des.o
- ifdef CONFIG_COCOA
- VL_OBJS+=cocoa.o
- COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
-@@ -503,6 +504,9 @@
- vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h
- $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-+d3des.o: d3des.c d3des.h
-+ $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
-+
- sdlaudio.o: sdlaudio.c
- $(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:35:16.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:35:24.000000000 +0100
-@@ -186,6 +186,9 @@
- char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
- extern int domid;
-
-+char vncpasswd[64];
-+unsigned char challenge[AUTHCHALLENGESIZE];
-+
- /***********************************************************/
- /* x86 ISA bus support */
-
-@@ -6882,6 +6885,7 @@
- vncunused = 0;
- kernel_filename = NULL;
- kernel_cmdline = "";
-+ *vncpasswd = '\0';
- #ifndef CONFIG_DM
- #ifdef TARGET_PPC
- cdrom_index = 1;
-@@ -7621,6 +7625,10 @@
-
- init_ioports();
-
-+ /* read vncpasswd from xenstore */
-+ if (0 > xenstore_read_vncpasswd(domid))
-+ exit(1);
-+
- /* terminal init */
- if (nographic) {
- dumb_display_init(ds);
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:35:24.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:35:24.000000000 +0100
-@@ -1432,6 +1432,7 @@
- void xenstore_process_event(void *opaque);
- void xenstore_check_new_media_present(int timeout);
- void xenstore_write_vncport(int vnc_display);
-+int xenstore_read_vncpasswd(int domid);
-
- int xenstore_vm_write(int domid, char *key, char *val);
- char *xenstore_vm_read(int domid, char *key, int *len);
-@@ -1450,4 +1451,7 @@
-
- void destroy_hvm_domain(void);
-
-+/* VNC Authentication */
-+#define AUTHCHALLENGESIZE 16
-+
- #endif /* VL_H */
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-10 15:32:53.000000000 +0100
-+++ ioemu/vnc.c 2007-05-10 15:35:24.000000000 +0100
-@@ -44,6 +44,7 @@
-
- #include "vnc_keysym.h"
- #include "keymaps.c"
-+#include "d3des.h"
-
- typedef struct Buffer
- {
-@@ -160,6 +161,9 @@
- static void vnc_update_client(void *opaque);
- static void vnc_client_read(void *opaque);
- static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
-+static int make_challenge(char *random, int size);
-+static void set_seed(unsigned int *seedp);
-+static void get_random(int len, unsigned char *buf);
-
- #if 0
- static inline void vnc_set_bit(uint32_t *d, int k)
-@@ -1277,23 +1281,92 @@
- return 0;
- }
-
-+static int protocol_response(VncState *vs, char *client_response, size_t len)
-+{
-+ extern char vncpasswd[64];
-+ extern unsigned char challenge[AUTHCHALLENGESIZE];
-+ unsigned char cryptchallenge[AUTHCHALLENGESIZE];
-+ unsigned char key[8];
-+ int passwdlen, i, j;
-+
-+ memcpy(cryptchallenge, challenge, AUTHCHALLENGESIZE);
-+
-+ /* Calculate the sent challenge */
-+ passwdlen = strlen(vncpasswd);
-+ for (i=0; i<8; i++)
-+ key[i] = i<passwdlen ? vncpasswd[i] : 0;
-+ deskey(key, EN0);
-+ for (j = 0; j < AUTHCHALLENGESIZE; j += 8)
-+ des(cryptchallenge+j, cryptchallenge+j);
-+
-+ /* Check the actual response */
-+ if (memcmp(cryptchallenge, client_response, AUTHCHALLENGESIZE) != 0) {
-+ /* password error */
-+ vnc_write_u32(vs, 1);
-+ vnc_write_u32(vs, 22);
-+ vnc_write(vs, "Authentication failure", 22);
-+ vnc_flush(vs);
-+ fprintf(stderr, "VNC Password error.\n");
-+ vnc_client_error(vs);
-+ return 0;
-+ }
-+
-+ vnc_write_u32(vs, 0);
-+ vnc_flush(vs);
-+
-+ vnc_read_when(vs, protocol_client_init, 1);
-+
-+ return 0;
-+}
-+
- static int protocol_version(VncState *vs, char *version, size_t len)
- {
-+ extern char vncpasswd[64];
-+ extern unsigned char challenge[AUTHCHALLENGESIZE];
- char local[13];
-- int maj, min;
-+ int support, maj, min;
-
- memcpy(local, version, 12);
- local[12] = 0;
-
-+ /* protocol version check */
- if (sscanf(local, "RFB %03d.%03d\n", &maj, &min) != 2) {
-+ fprintf(stderr, "Protocol version error.\n");
- vnc_client_error(vs);
- return 0;
- }
-
-- vnc_write_u32(vs, 1); /* None */
-- vnc_flush(vs);
-
-- vnc_read_when(vs, protocol_client_init, 1);
-+ support = 0;
-+ if (maj = 3) {
-+ if (min == 3 || min ==4) {
-+ support = 1;
-+ }
-+ }
-+
-+ if (! support) {
-+ fprintf(stderr, "Client uses unsupported protocol version %d.%d.\n",
-+ maj, min);
-+ vnc_client_error(vs);
-+ return 0;
-+ }
-+
-+ if (*vncpasswd == '\0') {
-+ /* AuthType is None */
-+ vnc_write_u32(vs, 1);
-+ vnc_flush(vs);
-+ vnc_read_when(vs, protocol_client_init, 1);
-+ } else {
-+ /* AuthType is VncAuth */
-+ vnc_write_u32(vs, 2);
-+
-+ /* Challenge-Responce authentication */
-+ /* Send Challenge */
-+ make_challenge(challenge, AUTHCHALLENGESIZE);
-+ vnc_write(vs, challenge, AUTHCHALLENGESIZE);
-+ vnc_flush(vs);
-+ vnc_read_when(vs, protocol_response, AUTHCHALLENGESIZE);
-+ }
-
- return 0;
- }
-@@ -1459,3 +1532,32 @@
- return pid;
- }
- }
-+
-+unsigned int seed;
-+
-+static int make_challenge(char *random, int size)
-+{
-+
-+ set_seed(&seed);
-+ get_random(size, random);
-+
-+ return 0;
-+}
-+
-+static void set_seed(unsigned int *seedp)
-+{
-+ *seedp += (unsigned int)(time(NULL)+getpid()+getpid()*987654+rand());
-+ srand(*seedp);
-+
-+ return;
-+}
-+
-+static void get_random(int len, unsigned char *buf)
-+{
-+ int i;
-+
-+ for (i=0; i<len; i++)
-+ buf[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-+
-+ return;
-+}
-Index: ioemu/xenstore.c
-===================================================================
---- ioemu.orig/xenstore.c 2007-05-10 15:32:53.000000000 +0100
-+++ ioemu/xenstore.c 2007-05-10 15:35:24.000000000 +0100
-@@ -253,6 +253,57 @@
- free(buf);
- }
-
-+int xenstore_read_vncpasswd(int domid)
-+{
-+ extern char vncpasswd[64];
-+ char *buf = NULL, *path, *uuid = NULL, *passwd = NULL;
-+ unsigned int i, len, rc = 0;
-+
-+ if (xsh == NULL) {
-+ return -1;
-+ }
-+
-+ path = xs_get_domain_path(xsh, domid);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_get_domain_path() error. domid %d.\n", domid);
-+ return -1;
-+ }
-+
-+ pasprintf(&buf, "%s/vm", path);
-+ uuid = xs_read(xsh, XBT_NULL, buf, &len);
-+ if (uuid == NULL) {
-+ fprintf(logfile, "xs_read(): uuid get error. %s.\n", buf);
-+ free(path);
-+ return -1;
-+ }
-+
-+ pasprintf(&buf, "%s/vncpasswd", uuid);
-+ passwd = xs_read(xsh, XBT_NULL, buf, &len);
-+ if (passwd == NULL) {
-+ fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf);
-+ free(uuid);
-+ free(path);
-+ return rc;
-+ }
-+
-+ for (i=0; i<len && i<63; i++) {
-+ vncpasswd[i] = passwd[i];
-+ passwd[i] = '\0';
-+ }
-+ vncpasswd[len] = '\0';
-+ pasprintf(&buf, "%s/vncpasswd", uuid);
-+ if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
-+ fprintf(logfile, "xs_write() vncpasswd failed.\n");
-+ rc = -1;
-+ }
-+
-+ free(passwd);
-+ free(uuid);
-+ free(path);
-+
-+ return rc;
-+}
-+
- char *xenstore_vm_read(int domid, char *key, int *len)
- {
- char *buf = NULL, *path = NULL, *value = NULL;
-Index: ioemu/d3des.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/d3des.c 2007-05-10 15:35:24.000000000 +0100
-@@ -0,0 +1,434 @@
-+/*
-+ * This is D3DES (V5.09) by Richard Outerbridge with the double and
-+ * triple-length support removed for use in VNC. Also the bytebit[] array
-+ * has been reversed so that the most significant bit in each byte of the
-+ * key is ignored, not the least significant.
-+ *
-+ * These changes are:
-+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+ */
-+
-+/* D3DES (V5.09) -
-+ *
-+ * A portable, public domain, version of the Data Encryption Standard.
-+ *
-+ * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
-+ * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
-+ * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
-+ * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
-+ * for humouring me on.
-+ *
-+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
-+ * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
-+ */
-+
-+#include "d3des.h"
-+
-+static void scrunch(unsigned char *, unsigned long *);
-+static void unscrun(unsigned long *, unsigned char *);
-+static void desfunc(unsigned long *, unsigned long *);
-+static void cookey(unsigned long *);
-+
-+static unsigned long KnL[32] = { 0L };
-+
-+static unsigned short bytebit[8] = {
-+ 01, 02, 04, 010, 020, 040, 0100, 0200 };
-+
-+static unsigned long bigbyte[24] = {
-+ 0x800000L, 0x400000L, 0x200000L, 0x100000L,
-+ 0x80000L, 0x40000L, 0x20000L, 0x10000L,
-+ 0x8000L, 0x4000L, 0x2000L, 0x1000L,
-+ 0x800L, 0x400L, 0x200L, 0x100L,
-+ 0x80L, 0x40L, 0x20L, 0x10L,
-+ 0x8L, 0x4L, 0x2L, 0x1L };
-+
-+/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
-+
-+static unsigned char pc1[56] = {
-+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
-+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
-+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
-+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
-+
-+static unsigned char totrot[16] = {
-+ 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
-+
-+static unsigned char pc2[48] = {
-+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
-+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
-+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
-+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
-+
-+void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */
-+unsigned char *key;
-+int edf;
-+{
-+ register int i, j, l, m, n;
-+ unsigned char pc1m[56], pcr[56];
-+ unsigned long kn[32];
-+
-+ for ( j = 0; j < 56; j++ ) {
-+ l = pc1[j];
-+ m = l & 07;
-+ pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
-+ }
-+ for( i = 0; i < 16; i++ ) {
-+ if( edf == DE1 ) m = (15 - i) << 1;
-+ else m = i << 1;
-+ n = m + 1;
-+ kn[m] = kn[n] = 0L;
-+ for( j = 0; j < 28; j++ ) {
-+ l = j + totrot[i];
-+ if( l < 28 ) pcr[j] = pc1m[l];
-+ else pcr[j] = pc1m[l - 28];
-+ }
-+ for( j = 28; j < 56; j++ ) {
-+ l = j + totrot[i];
-+ if( l < 56 ) pcr[j] = pc1m[l];
-+ else pcr[j] = pc1m[l - 28];
-+ }
-+ for( j = 0; j < 24; j++ ) {
-+ if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
-+ if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
-+ }
-+ }
-+ cookey(kn);
-+ return;
-+ }
-+
-+static void cookey(raw1)
-+register unsigned long *raw1;
-+{
-+ register unsigned long *cook, *raw0;
-+ unsigned long dough[32];
-+ register int i;
-+
-+ cook = dough;
-+ for( i = 0; i < 16; i++, raw1++ ) {
-+ raw0 = raw1++;
-+ *cook = (*raw0 & 0x00fc0000L) << 6;
-+ *cook |= (*raw0 & 0x00000fc0L) << 10;
-+ *cook |= (*raw1 & 0x00fc0000L) >> 10;
-+ *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
-+ *cook = (*raw0 & 0x0003f000L) << 12;
-+ *cook |= (*raw0 & 0x0000003fL) << 16;
-+ *cook |= (*raw1 & 0x0003f000L) >> 4;
-+ *cook++ |= (*raw1 & 0x0000003fL);
-+ }
-+ usekey(dough);
-+ return;
-+ }
-+
-+void cpkey(into)
-+register unsigned long *into;
-+{
-+ register unsigned long *from, *endp;
-+
-+ from = KnL, endp = &KnL[32];
-+ while( from < endp ) *into++ = *from++;
-+ return;
-+ }
-+
-+void usekey(from)
-+register unsigned long *from;
-+{
-+ register unsigned long *to, *endp;
-+
-+ to = KnL, endp = &KnL[32];
-+ while( to < endp ) *to++ = *from++;
-+ return;
-+ }
-+
-+void des(inblock, outblock)
-+unsigned char *inblock, *outblock;
-+{
-+ unsigned long work[2];
-+
-+ scrunch(inblock, work);
-+ desfunc(work, KnL);
-+ unscrun(work, outblock);
-+ return;
-+ }
-+
-+static void scrunch(outof, into)
-+register unsigned char *outof;
-+register unsigned long *into;
-+{
-+ *into = (*outof++ & 0xffL) << 24;
-+ *into |= (*outof++ & 0xffL) << 16;
-+ *into |= (*outof++ & 0xffL) << 8;
-+ *into++ |= (*outof++ & 0xffL);
-+ *into = (*outof++ & 0xffL) << 24;
-+ *into |= (*outof++ & 0xffL) << 16;
-+ *into |= (*outof++ & 0xffL) << 8;
-+ *into |= (*outof & 0xffL);
-+ return;
-+ }
-+
-+static void unscrun(outof, into)
-+register unsigned long *outof;
-+register unsigned char *into;
-+{
-+ *into++ = (unsigned char)((*outof >> 24) & 0xffL);
-+ *into++ = (unsigned char)((*outof >> 16) & 0xffL);
-+ *into++ = (unsigned char)((*outof >> 8) & 0xffL);
-+ *into++ = (unsigned char)(*outof++ & 0xffL);
-+ *into++ = (unsigned char)((*outof >> 24) & 0xffL);
-+ *into++ = (unsigned char)((*outof >> 16) & 0xffL);
-+ *into++ = (unsigned char)((*outof >> 8) & 0xffL);
-+ *into = (unsigned char)(*outof & 0xffL);
-+ return;
-+ }
-+
-+static unsigned long SP1[64] = {
-+ 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
-+ 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
-+ 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
-+ 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
-+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
-+ 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
-+ 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
-+ 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
-+ 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
-+ 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
-+ 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
-+ 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
-+ 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
-+ 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
-+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
-+ 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
-+
-+static unsigned long SP2[64] = {
-+ 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
-+ 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
-+ 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
-+ 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
-+ 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
-+ 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
-+ 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
-+ 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
-+ 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
-+ 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
-+ 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
-+ 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
-+ 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
-+ 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
-+ 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
-+ 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
-+
-+static unsigned long SP3[64] = {
-+ 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
-+ 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
-+ 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
-+ 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
-+ 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
-+ 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
-+ 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
-+ 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
-+ 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
-+ 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
-+ 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
-+ 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
-+ 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
-+ 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
-+ 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
-+ 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
-+
-+static unsigned long SP4[64] = {
-+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
-+ 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
-+ 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
-+ 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
-+ 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
-+ 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
-+ 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
-+ 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
-+ 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
-+ 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
-+ 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
-+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
-+ 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
-+ 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
-+ 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
-+ 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
-+
-+static unsigned long SP5[64] = {
-+ 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
-+ 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
-+ 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
-+ 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
-+ 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
-+ 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
-+ 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
-+ 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
-+ 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
-+ 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
-+ 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
-+ 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
-+ 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
-+ 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
-+ 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
-+ 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
-+
-+static unsigned long SP6[64] = {
-+ 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
-+ 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
-+ 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
-+ 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
-+ 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
-+ 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
-+ 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
-+ 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
-+ 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
-+ 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
-+ 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
-+ 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
-+ 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
-+ 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
-+ 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
-+ 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
-+
-+static unsigned long SP7[64] = {
-+ 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
-+ 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
-+ 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
-+ 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
-+ 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
-+ 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
-+ 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
-+ 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
-+ 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
-+ 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
-+ 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
-+ 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
-+ 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
-+ 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
-+ 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
-+ 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
-+
-+static unsigned long SP8[64] = {
-+ 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
-+ 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
-+ 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
-+ 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
-+ 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
-+ 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
-+ 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
-+ 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
-+ 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
-+ 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
-+ 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
-+ 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
-+ 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
-+ 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
-+ 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
-+ 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
-+
-+static void desfunc(block, keys)
-+register unsigned long *block, *keys;
-+{
-+ register unsigned long fval, work, right, leftt;
-+ register int round;
-+
-+ leftt = block[0];
-+ right = block[1];
-+ work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
-+ right ^= work;
-+ leftt ^= (work << 4);
-+ work = ((leftt >> 16) ^ right) & 0x0000ffffL;
-+ right ^= work;
-+ leftt ^= (work << 16);
-+ work = ((right >> 2) ^ leftt) & 0x33333333L;
-+ leftt ^= work;
-+ right ^= (work << 2);
-+ work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
-+ leftt ^= work;
-+ right ^= (work << 8);
-+ right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
-+ work = (leftt ^ right) & 0xaaaaaaaaL;
-+ leftt ^= work;
-+ right ^= work;
-+ leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
-+
-+ for( round = 0; round < 8; round++ ) {
-+ work = (right << 28) | (right >> 4);
-+ work ^= *keys++;
-+ fval = SP7[ work & 0x3fL];
-+ fval |= SP5[(work >> 8) & 0x3fL];
-+ fval |= SP3[(work >> 16) & 0x3fL];
-+ fval |= SP1[(work >> 24) & 0x3fL];
-+ work = right ^ *keys++;
-+ fval |= SP8[ work & 0x3fL];
-+ fval |= SP6[(work >> 8) & 0x3fL];
-+ fval |= SP4[(work >> 16) & 0x3fL];
-+ fval |= SP2[(work >> 24) & 0x3fL];
-+ leftt ^= fval;
-+ work = (leftt << 28) | (leftt >> 4);
-+ work ^= *keys++;
-+ fval = SP7[ work & 0x3fL];
-+ fval |= SP5[(work >> 8) & 0x3fL];
-+ fval |= SP3[(work >> 16) & 0x3fL];
-+ fval |= SP1[(work >> 24) & 0x3fL];
-+ work = leftt ^ *keys++;
-+ fval |= SP8[ work & 0x3fL];
-+ fval |= SP6[(work >> 8) & 0x3fL];
-+ fval |= SP4[(work >> 16) & 0x3fL];
-+ fval |= SP2[(work >> 24) & 0x3fL];
-+ right ^= fval;
-+ }
-+
-+ right = (right << 31) | (right >> 1);
-+ work = (leftt ^ right) & 0xaaaaaaaaL;
-+ leftt ^= work;
-+ right ^= work;
-+ leftt = (leftt << 31) | (leftt >> 1);
-+ work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
-+ right ^= work;
-+ leftt ^= (work << 8);
-+ work = ((leftt >> 2) ^ right) & 0x33333333L;
-+ right ^= work;
-+ leftt ^= (work << 2);
-+ work = ((right >> 16) ^ leftt) & 0x0000ffffL;
-+ leftt ^= work;
-+ right ^= (work << 16);
-+ work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
-+ leftt ^= work;
-+ right ^= (work << 4);
-+ *block++ = right;
-+ *block = leftt;
-+ return;
-+ }
-+
-+/* Validation sets:
-+ *
-+ * Single-length key, single-length plaintext -
-+ * Key : 0123 4567 89ab cdef
-+ * Plain : 0123 4567 89ab cde7
-+ * Cipher : c957 4425 6a5e d31d
-+ *
-+ * Double-length key, single-length plaintext -
-+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
-+ * Plain : 0123 4567 89ab cde7
-+ * Cipher : 7f1d 0a77 826b 8aff
-+ *
-+ * Double-length key, double-length plaintext -
-+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
-+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
-+ * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
-+ *
-+ * Triple-length key, single-length plaintext -
-+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
-+ * Plain : 0123 4567 89ab cde7
-+ * Cipher : de0b 7c06 ae5e 0ed5
-+ *
-+ * Triple-length key, double-length plaintext -
-+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
-+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
-+ * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
-+ *
-+ * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
-+ **********************************************************************/
-Index: ioemu/d3des.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/d3des.h 2007-05-10 15:35:24.000000000 +0100
-@@ -0,0 +1,51 @@
-+/*
-+ * This is D3DES (V5.09) by Richard Outerbridge with the double and
-+ * triple-length support removed for use in VNC.
-+ *
-+ * These changes are:
-+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+ */
-+
-+/* d3des.h -
-+ *
-+ * Headers and defines for d3des.c
-+ * Graven Imagery, 1992.
-+ *
-+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
-+ * (GEnie : OUTER; CIS : [71755,204])
-+ */
-+
-+#define EN0 0 /* MODE == encrypt */
-+#define DE1 1 /* MODE == decrypt */
-+
-+extern void deskey(unsigned char *, int);
-+/* hexkey[8] MODE
-+ * Sets the internal key register according to the hexadecimal
-+ * key contained in the 8 bytes of hexkey, according to the DES,
-+ * for encryption or decryption according to MODE.
-+ */
-+
-+extern void usekey(unsigned long *);
-+/* cookedkey[32]
-+ * Loads the internal key register with the data in cookedkey.
-+ */
-+
-+extern void cpkey(unsigned long *);
-+/* cookedkey[32]
-+ * Copies the contents of the internal key register into the storage
-+ * located at &cookedkey[0].
-+ */
-+
-+extern void des(unsigned char *, unsigned char *);
-+/* from[8] to[8]
-+ * Encrypts/Decrypts (according to the key currently loaded in the
-+ * internal key register) one block of eight bytes at address 'from'
-+ * into the block at address 'to'. They can be the same.
-+ */
-+
-+/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
-+ ********************************************************************/
diff --git a/tools/ioemu/patches/vnc-protocol-fixes b/tools/ioemu/patches/vnc-protocol-fixes
deleted file mode 100644
index 82ef000973..0000000000
--- a/tools/ioemu/patches/vnc-protocol-fixes
+++ /dev/null
@@ -1,63 +0,0 @@
-# HG changeset patch
-# User Steven Smith <ssmith@xensource.com>
-# Node ID ca3abb3804f4400b24037a4366cb2ca5e51ed742
-# Parent 7fca81d456b2cb40d4effe2492f7ed1aafd32f52
-[HVM][VNC] Make sure that qemu doesn't go into an infinite loop when
-it receives certain invalid requests from the viewer.
-
-Signed-off-by: Steven Smith <sos22@cam.ac.uk>
-
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-03 19:49:33.000000000 +0100
-+++ ioemu/vnc.c 2007-05-03 19:49:43.000000000 +0100
-@@ -26,6 +26,7 @@
-
- #include "vl.h"
- #include "qemu_socket.h"
-+#include <assert.h>
-
- #define VNC_REFRESH_INTERVAL (1000 / 30)
-
-@@ -710,8 +711,10 @@
- memmove(vs->input.buffer, vs->input.buffer + len,
- vs->input.offset - len);
- vs->input.offset -= len;
-- } else
-+ } else {
-+ assert(ret > vs->read_handler_expect);
- vs->read_handler_expect = ret;
-+ }
- }
- }
-
-@@ -1100,8 +1103,12 @@
- if (len == 1)
- return 4;
-
-- if (len == 4)
-- return 4 + (read_u16(data, 2) * 4);
-+ if (len == 4) {
-+ uint16_t v;
-+ v = read_u16(data, 2);
-+ if (v)
-+ return 4 + v * 4;
-+ }
-
- limit = read_u16(data, 2);
- for (i = 0; i < limit; i++) {
-@@ -1135,8 +1142,12 @@
- if (len == 1)
- return 8;
-
-- if (len == 8)
-- return 8 + read_u32(data, 4);
-+ if (len == 8) {
-+ uint32_t v;
-+ v = read_u32(data, 4);
-+ if (v)
-+ return 8 + v;
-+ }
-
- client_cut_text(vs, read_u32(data, 4), data + 8);
- break;
diff --git a/tools/ioemu/patches/vnc-start-vncviewer b/tools/ioemu/patches/vnc-start-vncviewer
deleted file mode 100644
index 21d4343047..0000000000
--- a/tools/ioemu/patches/vnc-start-vncviewer
+++ /dev/null
@@ -1,111 +0,0 @@
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-03 19:49:43.000000000 +0100
-+++ ioemu/vnc.c 2007-05-03 19:49:46.000000000 +0100
-@@ -1364,3 +1364,31 @@
- exit(1);
- }
- }
-+
-+int vnc_start_viewer(int port)
-+{
-+ int pid, i, open_max;
-+ char s[16];
-+
-+ sprintf(s, ":%d", port);
-+
-+ switch (pid = fork()) {
-+ case -1:
-+ fprintf(stderr, "vncviewer failed fork\n");
-+ exit(1);
-+
-+ case 0: /* child */
-+ open_max = sysconf(_SC_OPEN_MAX);
-+ for (i = 0; i < open_max; i++)
-+ if (i != STDIN_FILENO &&
-+ i != STDOUT_FILENO &&
-+ i != STDERR_FILENO)
-+ close(i);
-+ execlp("vncviewer", "vncviewer", s, NULL);
-+ fprintf(stderr, "vncviewer execlp failed\n");
-+ exit(1);
-+
-+ default:
-+ return pid;
-+ }
-+}
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:46:21.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:50:04.000000000 +0100
-@@ -131,6 +131,7 @@
- int bios_size;
- static DisplayState display_state;
- int nographic;
-+int vncviewer;
- const char* keyboard_layout = NULL;
- int64_t ticks_per_sec;
- int boot_device = 'c';
-@@ -6309,6 +6310,7 @@
- "-no-reboot exit instead of rebooting\n"
- "-loadvm file start right away with a saved state (loadvm in monitor)\n"
- "-vnc display start a VNC server on display\n"
-+ "-vncviewer start a vncviewer process for this domain\n"
- #ifndef _WIN32
- "-daemonize daemonize QEMU after initializing\n"
- #endif
-@@ -6404,6 +6406,7 @@
- QEMU_OPTION_d,
- QEMU_OPTION_vcpus,
- QEMU_OPTION_acpi,
-+ QEMU_OPTION_vncviewer,
- };
-
- typedef struct QEMUOption {
-@@ -6482,6 +6485,7 @@
- { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
- { "smp", HAS_ARG, QEMU_OPTION_smp },
- { "vnc", HAS_ARG, QEMU_OPTION_vnc },
-+ { "vncviewer", 0, QEMU_OPTION_vncviewer },
-
- /* temporary options */
- { "usb", 0, QEMU_OPTION_usb },
-@@ -6848,6 +6852,7 @@
- #endif
- snapshot = 0;
- nographic = 0;
-+ vncviewer = 0;
- kernel_filename = NULL;
- kernel_cmdline = "";
- #ifdef TARGET_PPC
-@@ -7264,6 +7269,9 @@
- case QEMU_OPTION_acpi:
- acpi_enabled = 1;
- break;
-+ case QEMU_OPTION_vncviewer:
-+ vncviewer++;
-+ break;
- }
- }
- }
-@@ -7547,6 +7555,8 @@
- dumb_display_init(ds);
- } else if (vnc_display != NULL) {
- vnc_display_init(ds, vnc_display);
-+ if (vncviewer)
-+ vnc_start_viewer(vnc_display);
- } else {
- #if defined(CONFIG_SDL)
- sdl_display_init(ds, full_screen);
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 19:46:21.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 19:50:15.000000000 +0100
-@@ -930,6 +930,7 @@
- /* vnc.c */
- void vnc_display_init(DisplayState *ds, const char *display);
- void do_info_vnc(void);
-+int vnc_start_viewer(int port);
-
- /* x_keymap.c */
- extern uint8_t _translate_keycode(const int key);
diff --git a/tools/ioemu/patches/vnc-title-domain-name b/tools/ioemu/patches/vnc-title-domain-name
deleted file mode 100644
index 42c0108608..0000000000
--- a/tools/ioemu/patches/vnc-title-domain-name
+++ /dev/null
@@ -1,25 +0,0 @@
-Index: ioemu/vnc.c
-===================================================================
---- ioemu.orig/vnc.c 2007-05-03 19:49:46.000000000 +0100
-+++ ioemu/vnc.c 2007-05-03 19:50:17.000000000 +0100
-@@ -1163,6 +1163,7 @@
-
- static int protocol_client_init(VncState *vs, char *data, size_t len)
- {
-+ size_t l;
- char pad[3] = { 0, 0, 0 };
-
- vga_hw_update();
-@@ -1210,8 +1211,10 @@
-
- vnc_write(vs, pad, 3); /* padding */
-
-- vnc_write_u32(vs, 4);
-- vnc_write(vs, "QEMU", 4);
-+ l = strlen(domain_name);
-+ vnc_write_u32(vs, l);
-+ vnc_write(vs, domain_name, l);
-+
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_msg, 1);
diff --git a/tools/ioemu/patches/xen-build b/tools/ioemu/patches/xen-build
deleted file mode 100644
index e83b1e81f9..0000000000
--- a/tools/ioemu/patches/xen-build
+++ /dev/null
@@ -1,274 +0,0 @@
-Index: ioemu/Makefile
-===================================================================
---- ioemu.orig/Makefile 2007-05-09 13:42:55.000000000 +0100
-+++ ioemu/Makefile 2007-05-09 13:42:58.000000000 +0100
-@@ -1,6 +1,9 @@
- # Makefile for QEMU.
-
--include config-host.mak
-+XEN_ROOT=../..
-+include $(XEN_ROOT)/tools/Rules.mk
-+
-+-include config-host.mak
-
- .PHONY: all clean distclean dvi info install install-doc tar tarbin \
- speed test test2 html dvi info
-@@ -32,9 +35,11 @@
- endif
- endif
-
-+TOOLS=
-+
- all: $(TOOLS) $(DOCS) recurse-all
-
--subdir-%: dyngen$(EXESUF)
-+subdir-%:
- $(MAKE) -C $(subst subdir-,,$@) all
-
- recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))
-@@ -51,7 +56,7 @@
- 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
-
- distclean: clean
-@@ -67,25 +72,25 @@
-
- install-doc: $(DOCS)
- mkdir -p "$(DESTDIR)$(docdir)"
-- $(INSTALL) -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)"
-+ $(INSTALL_DATA) -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"
-+ $(INSTALL_DATA) 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 openbios-sparc32 linux_boot.bin pxe-ne2k_pci.bin \
-- pxe-rtl8139.bin pxe-pcnet.bin; do \
-- $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
-- done
-+# $(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 openbios-sparc32 linux_boot.bin pxe-ne2k_pci.bin \
-+# pxe-rtl8139.bin pxe-pcnet.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"; \
-+ $(INSTALL_DATA) -m 644 $(SRC_PATH)/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps"; \
- done
- endif
- for d in $(TARGET_DIRS); do \
-@@ -97,7 +102,7 @@
- $(MAKE) -C tests $@
-
- TAGS:
-- etags *.[ch] tests/*.[ch]
-+ etags *.[ch] target-i386-dm/*.[ch] hw/*.[ch]
-
- cscope:
- rm -f ./cscope.*
-@@ -115,11 +120,11 @@
- texi2dvi $<
-
- qemu.1: qemu-doc.texi
-- $(SRC_PATH)/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
-- $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
-+ perl -w $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
- pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@
-
- info: qemu-doc.info qemu-tech.info
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-09 13:42:55.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-09 13:42:58.000000000 +0100
-@@ -1,5 +1,8 @@
- include config.mak
-
-+XEN_ROOT=../../..
-+include $(XEN_ROOT)/tools/Rules.mk
-+
- TARGET_BASE_ARCH:=$(TARGET_ARCH)
- ifeq ($(TARGET_ARCH), x86_64)
- TARGET_BASE_ARCH:=i386
-@@ -10,9 +13,11 @@
- ifeq ($(TARGET_ARCH), sparc64)
- TARGET_BASE_ARCH:=sparc
- endif
--TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
-+TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)$(TARGET_SUB)
- VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
- CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
-+CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc
-+CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore
- ifdef CONFIG_DARWIN_USER
- VPATH+=:$(SRC_PATH)/darwin-user
- CPPFLAGS+=-I$(SRC_PATH)/darwin-user -I$(SRC_PATH)/darwin-user/$(TARGET_ARCH)
-@@ -23,6 +28,10 @@
- endif
- BASE_CFLAGS=
- BASE_LDFLAGS=
-+SSE2 := $(call cc-option,$(CC),-msse2,)
-+ifeq ($(SSE2),-msse2)
-+CFLAGS += -DUSE_SSE2=1 -msse2
-+endif
- #CFLAGS+=-Werror
- LIBS=
- HELPER_CFLAGS=$(CFLAGS)
-@@ -181,8 +190,12 @@
-
- #########################################################
-
--CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-+CPPFLAGS+=-D_GNU_SOURCE
-+# -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
- LIBS+=-lm
-+LIBS+=-L../../libxc -lxenctrl -lxenguest
-+LIBS+=-L../../xenstore -lxenstore
-+LIBS+=-lpthread
- ifndef CONFIG_USER_ONLY
- LIBS+=-lz
- endif
-@@ -311,7 +324,7 @@
- all: $(PROGS)
-
- $(QEMU_USER): $(OBJS)
-- $(CC) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ $(LIBS)
-+ $(CC) $(CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ $(LIBS)
- ifeq ($(ARCH),alpha)
- # Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
- # the address space (31 bit so sign extending doesn't matter)
-@@ -574,10 +587,16 @@
- clean:
- rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o
-
-+distclean: clean
-+ rm -rf config.mak config.h
-+
- install: all
-+ mkdir -p "$(DESTDIR)$(bindir)" "$(DESTDIR)$(configdir)"
- ifneq ($(PROGS),)
-- $(INSTALL) -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)"
-+ $(INSTALL_PROG) $(PROGS) "$(DESTDIR)$(bindir)"
- endif
-+ $(INSTALL_PROG) $(TARGET_PATH)/qemu-dm.debug "$(DESTDIR)$(bindir)"
-+ $(INSTALL_PROG) $(TARGET_PATH)/qemu-ifup "$(DESTDIR)$(configdir)"
-
- ifneq ($(wildcard .depend),)
- include .depend
-Index: ioemu/configure
-===================================================================
---- ioemu.orig/configure 2007-05-09 13:42:55.000000000 +0100
-+++ ioemu/configure 2007-05-09 13:42:58.000000000 +0100
-@@ -18,8 +18,8 @@
-
- # default parameters
- prefix=""
--interp_prefix="/usr/gnemul/qemu-%M"
- static="no"
-+libdir="lib"
- cross_prefix=""
- cc="gcc"
- gcc3_search="yes"
-@@ -67,6 +67,7 @@
- ;;
- x86_64|amd64)
- cpu="x86_64"
-+ libdir="lib64"
- ;;
- *)
- cpu="unknown"
-@@ -92,7 +93,7 @@
- profiler="no"
- cocoa="no"
- check_gfx="yes"
--check_gcc="yes"
-+check_gcc="no"
- softmmu="yes"
- linux_user="no"
- darwin_user="no"
-@@ -433,6 +434,8 @@
- exit 1
- fi
-
-+kqemu="no"
-+
- if test -z "$cross_prefix" ; then
-
- # ---
-@@ -569,14 +572,16 @@
- datadir="$prefix"
- docdir="$prefix"
- bindir="$prefix"
-+configdir=""
- else
- if test -z "$prefix" ; then
- prefix="/usr/local"
- fi
- mandir="$prefix/share/man"
--datadir="$prefix/share/qemu"
-+datadir="$prefix/share/xen/qemu"
- docdir="$prefix/share/doc/qemu"
--bindir="$prefix/bin"
-+bindir="$prefix/$libdir/xen/bin"
-+configdir="/etc/xen"
- fi
-
- echo "Install prefix $prefix"
-@@ -647,6 +652,8 @@
- echo "mandir=$mandir" >> $config_mak
- echo "datadir=$datadir" >> $config_mak
- echo "docdir=$docdir" >> $config_mak
-+echo "configdir=$configdir" >> $config_mak
-+echo "LIBDIR=$libdir" >> $config_mak
- echo "#define CONFIG_QEMU_SHAREDIR \"$datadir\"" >> $config_h
- echo "MAKE=$make" >> $config_mak
- echo "INSTALL=$install" >> $config_mak
-@@ -843,7 +850,7 @@
- # don't use ln -sf as not all "ln -sf" over write the file/link
- #
- rm -f $target_dir/Makefile
--ln -s $source_path/Makefile.target $target_dir/Makefile
-+ln -s ../Makefile.target $target_dir/Makefile
-
-
- echo "# Automatically generated by configure - do not modify" > $config_mak
-@@ -857,6 +864,12 @@
- 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
-@@ -935,6 +948,9 @@
- echo "CONFIG_DARWIN_USER=yes" >> $config_mak
- echo "#define CONFIG_DARWIN_USER 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" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64" -o "$target_cpu" = "m68k"; then
- echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
diff --git a/tools/ioemu/patches/xen-domain-name b/tools/ioemu/patches/xen-domain-name
deleted file mode 100644
index b7ec42ed73..0000000000
--- a/tools/ioemu/patches/xen-domain-name
+++ /dev/null
@@ -1,78 +0,0 @@
-Index: ioemu/sdl.c
-===================================================================
---- ioemu.orig/sdl.c 2007-05-03 18:17:58.000000000 +0100
-+++ ioemu/sdl.c 2007-05-03 19:01:57.000000000 +0100
-@@ -213,14 +213,14 @@
- static void sdl_update_caption(void)
- {
- char buf[1024];
-- strcpy(buf, "QEMU");
-+ strcpy(buf, domain_name);
- if (!vm_running) {
- strcat(buf, " [Stopped]");
- }
- if (gui_grab) {
- strcat(buf, " - Press Ctrl-Alt to exit grab");
- }
-- SDL_WM_SetCaption(buf, "QEMU");
-+ SDL_WM_SetCaption(buf, domain_name);
- }
-
- static void sdl_hide_cursor(void)
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:00:51.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:01:57.000000000 +0100
-@@ -175,6 +175,8 @@
- int semihosting_enabled = 0;
- int autostart = 1;
-
-+char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
-+
- /***********************************************************/
- /* x86 ISA bus support */
-
-@@ -6128,6 +6130,7 @@
- "-s wait gdb connection to port %d\n"
- "-p port change gdb connection port\n"
- "-l item1,... output log to %s (use -d ? for a list of log items)\n"
-+ "-domain-name domain name that we're serving\n"
- "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
- " translation (t=none or lba) (usually qemu can guess them)\n"
- "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
-@@ -6217,6 +6220,7 @@
- QEMU_OPTION_g,
- QEMU_OPTION_std_vga,
- QEMU_OPTION_monitor,
-+ QEMU_OPTION_domainname,
- QEMU_OPTION_serial,
- QEMU_OPTION_parallel,
- QEMU_OPTION_loadvm,
-@@ -6300,6 +6304,7 @@
- { "localtime", 0, QEMU_OPTION_localtime },
- { "std-vga", 0, QEMU_OPTION_std_vga },
- { "monitor", 1, QEMU_OPTION_monitor },
-+ { "domain-name", 1, QEMU_OPTION_domainname },
- { "serial", 1, QEMU_OPTION_serial },
- { "parallel", 1, QEMU_OPTION_parallel },
- { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
-@@ -7002,6 +7007,9 @@
- case QEMU_OPTION_semihosting:
- semihosting_enabled = 1;
- break;
-+ case QEMU_OPTION_domainname:
-+ strncat(domain_name, optarg, sizeof(domain_name) - 20);
-+ break;
- }
- }
- }
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 19:00:05.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 19:01:57.000000000 +0100
-@@ -1405,4 +1405,5 @@
-
- void kqemu_record_dump(void);
-
-+extern char domain_name[];
- #endif /* VL_H */
diff --git a/tools/ioemu/patches/xen-domid b/tools/ioemu/patches/xen-domid
deleted file mode 100644
index 933afb7e7c..0000000000
--- a/tools/ioemu/patches/xen-domid
+++ /dev/null
@@ -1,49 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:01:57.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:02:49.000000000 +0100
-@@ -176,6 +176,7 @@
- int autostart = 1;
-
- char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
-+extern int domid;
-
- /***********************************************************/
- /* x86 ISA bus support */
-@@ -6130,6 +6131,7 @@
- "-s wait gdb connection to port %d\n"
- "-p port change gdb connection port\n"
- "-l item1,... output log to %s (use -d ? for a list of log items)\n"
-+ "-d domain domain that we're serving\n"
- "-domain-name domain name that we're serving\n"
- "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
- " translation (t=none or lba) (usually qemu can guess them)\n"
-@@ -6239,6 +6241,8 @@
- QEMU_OPTION_daemonize,
- QEMU_OPTION_option_rom,
- QEMU_OPTION_semihosting
-+ ,
-+ QEMU_OPTION_d,
- };
-
- typedef struct QEMUOption {
-@@ -6328,6 +6332,8 @@
- #if defined(TARGET_ARM)
- { "semihosting", 0, QEMU_OPTION_semihosting },
- #endif
-+
-+ { "d", HAS_ARG, QEMU_OPTION_d },
- { NULL },
- };
-
-@@ -7010,6 +7016,10 @@
- case QEMU_OPTION_domainname:
- strncat(domain_name, optarg, sizeof(domain_name) - 20);
- break;
-+ case QEMU_OPTION_d:
-+ domid = atoi(optarg);
-+ fprintf(logfile, "domid: %d\n", domid);
-+ break;
- }
- }
- }
diff --git a/tools/ioemu/patches/xen-mapcache b/tools/ioemu/patches/xen-mapcache
deleted file mode 100644
index 44f493175f..0000000000
--- a/tools/ioemu/patches/xen-mapcache
+++ /dev/null
@@ -1,441 +0,0 @@
-# HG changeset patch
-# User kfraser@localhost.localdomain
-# Node ID 67a06a9b7b1dca707e1cd3b08ae0a341d6e97b3d
-# Parent 3f0ca90351e268084fbdb733d70fc596cb46537d
-[HVM] qemu: Add guest address-space mapping cache.
-
-On IA32 host or IA32 PAE host, at present, generally, we can't create
-an HVM guest with more than 2G memory, because generally it's almost
-impossible for Qemu to find a large enough and consecutive virtual
-address space to map an HVM guest's whole physical address space.
-The attached patch fixes this issue using dynamic mapping based on
-little blocks of memory.
-
-Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
-Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
-Signed-off-by: Keir Fraser <keir@xensource.com>
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-11 10:04:51.000000000 +0100
-+++ ioemu/vl.c 2007-05-11 10:04:52.000000000 +0100
-@@ -275,7 +275,7 @@
- for(i = start; i < start + length; i += size) {
- ioport_read_table[bsize][i] = func;
- if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
-- hw_error("register_ioport_read: invalid opaque");
-+ hw_error("register_ioport_write: invalid opaque");
- ioport_opaque[i] = opaque;
- }
- return 0;
-@@ -6791,6 +6791,157 @@
- suspend_requested = 1;
- }
-
-+#if defined(MAPCACHE)
-+
-+#if defined(__i386__)
-+#define MAX_MCACHE_SIZE 0x40000000 /* 1GB max for x86 */
-+#define MCACHE_BUCKET_SHIFT 16
-+#elif defined(__x86_64__)
-+#define MAX_MCACHE_SIZE 0x1000000000 /* 64GB max for x86_64 */
-+#define MCACHE_BUCKET_SHIFT 20
-+#endif
-+
-+#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
-+
-+#define BITS_PER_LONG (sizeof(long)*8)
-+#define BITS_TO_LONGS(bits) \
-+ (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-+#define DECLARE_BITMAP(name,bits) \
-+ unsigned long name[BITS_TO_LONGS(bits)]
-+#define test_bit(bit,map) \
-+ (!!((map)[(bit)/BITS_PER_LONG] & (1UL << ((bit)%BITS_PER_LONG))))
-+
-+struct map_cache {
-+ unsigned long paddr_index;
-+ uint8_t *vaddr_base;
-+ DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>PAGE_SHIFT);
-+};
-+
-+static struct map_cache *mapcache_entry;
-+static unsigned long nr_buckets;
-+
-+/* For most cases (>99.9%), the page address is the same. */
-+static unsigned long last_address_index = ~0UL;
-+static uint8_t *last_address_vaddr;
-+
-+static int qemu_map_cache_init(void)
-+{
-+ unsigned long size;
-+
-+ nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
-+ (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
-+ (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
-+ fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
-+
-+ /*
-+ * Use mmap() directly: lets us allocate a big hash table with no up-front
-+ * cost in storage space. The OS will allocate memory only for the buckets
-+ * that we actually use. All others will contain all zeroes.
-+ */
-+ size = nr_buckets * sizeof(struct map_cache);
-+ size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
-+ mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
-+ MAP_SHARED|MAP_ANONYMOUS, 0, 0);
-+ if (mapcache_entry == MAP_FAILED) {
-+ errno = ENOMEM;
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static void qemu_remap_bucket(struct map_cache *entry,
-+ unsigned long address_index)
-+{
-+ uint8_t *vaddr_base;
-+ unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
-+ unsigned int i, j;
-+
-+ if (entry->vaddr_base != NULL) {
-+ errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
-+ if (errno) {
-+ fprintf(logfile, "unmap fails %d\n", errno);
-+ exit(-1);
-+ }
-+ }
-+
-+ for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++)
-+ pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i;
-+
-+ vaddr_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE,
-+ pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT);
-+ if (vaddr_base == NULL) {
-+ fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
-+ exit(-1);
-+ }
-+
-+ entry->vaddr_base = vaddr_base;
-+ entry->paddr_index = address_index;
-+
-+ for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i += BITS_PER_LONG) {
-+ unsigned long word = 0;
-+ j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
-+ (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
-+ while (j > 0)
-+ word = (word << 1) | !(pfns[i + --j] & 0xF0000000UL);
-+ entry->valid_mapping[i / BITS_PER_LONG] = word;
-+ }
-+}
-+
-+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
-+{
-+ struct map_cache *entry;
-+ unsigned long address_index = phys_addr >> MCACHE_BUCKET_SHIFT;
-+ unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
-+
-+ if (address_index == last_address_index)
-+ return last_address_vaddr + address_offset;
-+
-+ entry = &mapcache_entry[address_index % nr_buckets];
-+
-+ if (entry->vaddr_base == NULL || entry->paddr_index != address_index ||
-+ !test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
-+ qemu_remap_bucket(entry, address_index);
-+
-+ if (!test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
-+ return NULL;
-+
-+ last_address_index = address_index;
-+ last_address_vaddr = entry->vaddr_base;
-+
-+ return last_address_vaddr + address_offset;
-+}
-+
-+void qemu_invalidate_map_cache(void)
-+{
-+ unsigned long i;
-+
-+ mapcache_lock();
-+
-+ for (i = 0; i < nr_buckets; i++) {
-+ struct map_cache *entry = &mapcache_entry[i];
-+
-+ if (entry->vaddr_base == NULL)
-+ continue;
-+
-+ errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
-+ if (errno) {
-+ fprintf(logfile, "unmap fails %d\n", errno);
-+ exit(-1);
-+ }
-+
-+ entry->paddr_index = 0;
-+ entry->vaddr_base = NULL;
-+ }
-+
-+ last_address_index = ~0UL;
-+ last_address_vaddr = NULL;
-+
-+ mapcache_unlock();
-+}
-+
-+#endif /* defined(MAPCACHE) */
-+
- int main(int argc, char **argv)
- {
- #ifdef CONFIG_GDBSTUB
-@@ -6827,8 +6978,11 @@
- unsigned long ioreq_pfn;
- extern void *shared_page;
- extern void *buffered_io_page;
-- extern void *buffered_pio_page;
-+#ifdef __ia64__
- unsigned long nr_pages;
-+ xen_pfn_t *page_array;
-+ extern void *buffered_pio_page;
-+#endif
-
- char qemu_dm_logfilename[64];
-
-@@ -7119,6 +7273,7 @@
- break;
- case QEMU_OPTION_m:
- ram_size = atol(optarg) * 1024 * 1024;
-+ ram_size = (uint64_t)atol(optarg) * 1024 * 1024;
- if (ram_size <= 0)
- help();
- #ifndef CONFIG_DM
-@@ -7472,30 +7627,15 @@
-
- #if defined(__i386__) || defined(__x86_64__)
-
-- nr_pages = ram_size/PAGE_SIZE;
--
-- page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
-- if (page_array == NULL) {
-- fprintf(logfile, "malloc returned error %d\n", errno);
-- exit(-1);
-- }
--
-- for ( i = 0; i < nr_pages; i++)
-- page_array[i] = i;
--
-- phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
-- PROT_READ|PROT_WRITE, page_array,
-- nr_pages);
-- if (phys_ram_base == NULL) {
-- fprintf(logfile, "batch map guest memory returned error %d\n", errno);
-+ if (qemu_map_cache_init()) {
-+ fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
- exit(-1);
- }
-
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
- fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
- shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-- PROT_READ|PROT_WRITE,
-- page_array[ioreq_pfn]);
-+ PROT_READ|PROT_WRITE, ioreq_pfn);
- if (shared_page == NULL) {
- fprintf(logfile, "map shared IO page returned error %d\n", errno);
- exit(-1);
-@@ -7504,15 +7644,12 @@
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
- fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
- buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-- PROT_READ|PROT_WRITE,
-- page_array[ioreq_pfn]);
-+ PROT_READ|PROT_WRITE, ioreq_pfn);
- if (buffered_io_page == NULL) {
- fprintf(logfile, "map buffered IO page returned error %d\n", errno);
- exit(-1);
- }
-
-- free(page_array);
--
- #elif defined(__ia64__)
-
- nr_pages = ram_size/PAGE_SIZE;
-Index: ioemu/target-i386-dm/exec-dm.c
-===================================================================
---- ioemu.orig/target-i386-dm/exec-dm.c 2007-05-11 10:04:46.000000000 +0100
-+++ ioemu/target-i386-dm/exec-dm.c 2007-05-11 10:04:52.000000000 +0100
-@@ -36,6 +36,7 @@
-
- #include "cpu.h"
- #include "exec-all.h"
-+#include "vl.h"
-
- //#define DEBUG_TB_INVALIDATE
- //#define DEBUG_FLUSH
-@@ -127,10 +128,17 @@
- FILE *logfile;
- int loglevel;
-
-+#ifdef MAPCACHE
-+pthread_mutex_t mapcache_mutex;
-+#endif
-+
- void cpu_exec_init(CPUState *env)
- {
- CPUState **penv;
- int cpu_index;
-+#ifdef MAPCACHE
-+ pthread_mutexattr_t mxattr;
-+#endif
-
- env->next_cpu = NULL;
- penv = &first_cpu;
-@@ -144,6 +152,14 @@
-
- /* alloc dirty bits array */
- phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
-+
-+#ifdef MAPCACHE
-+ /* setup memory access mutex to protect mapcache */
-+ pthread_mutexattr_init(&mxattr);
-+ pthread_mutexattr_settype(&mxattr, PTHREAD_MUTEX_RECURSIVE);
-+ pthread_mutex_init(&mapcache_mutex, &mxattr);
-+ pthread_mutexattr_destroy(&mxattr);
-+#endif
- }
-
- /* enable or disable low levels log */
-@@ -414,16 +430,11 @@
- return 0;
- }
-
--static inline int paddr_is_ram(target_phys_addr_t addr)
--{
-- /* Is this guest physical address RAM-backed? */
--#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__))
-- return ((addr < HVM_BELOW_4G_MMIO_START) ||
-- (addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH));
--#else
-- return (addr < ram_size);
-+#if defined(__i386__) || defined(__x86_64__)
-+#define phys_ram_addr(x) (qemu_map_cache(x))
-+#elif defined(__ia64__)
-+#define phys_ram_addr(x) ((addr < ram_size) ? (phys_ram_base + (x)) : NULL)
- #endif
--}
-
- void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-@@ -431,13 +442,15 @@
- int l, io_index;
- uint8_t *ptr;
- uint32_t val;
--
-+
-+ mapcache_lock();
-+
- while (len > 0) {
- /* How much can we copy before the next page boundary? */
- l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
- if (l > len)
- l = len;
--
-+
- io_index = iomem_index(addr);
- if (is_write) {
- if (io_index) {
-@@ -457,11 +470,11 @@
- io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
- l = 1;
- }
-- } else if (paddr_is_ram(addr)) {
-+ } else if ((ptr = phys_ram_addr(addr)) != NULL) {
- /* Reading from RAM */
-- memcpy(phys_ram_base + addr, buf, l);
-+ memcpy(ptr, buf, l);
- #ifdef __ia64__
-- sync_icache((unsigned long)(phys_ram_base + addr), l);
-+ sync_icache(ptr, l);
- #endif
- }
- } else {
-@@ -482,9 +495,9 @@
- stb_raw(buf, val);
- l = 1;
- }
-- } else if (paddr_is_ram(addr)) {
-+ } else if ((ptr = phys_ram_addr(addr)) != NULL) {
- /* Reading from RAM */
-- memcpy(buf, phys_ram_base + addr, l);
-+ memcpy(buf, ptr, l);
- } else {
- /* Neither RAM nor known MMIO space */
- memset(buf, 0xff, len);
-@@ -494,6 +507,8 @@
- buf += l;
- addr += l;
- }
-+
-+ mapcache_unlock();
- }
- #endif
-
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-11 10:04:51.000000000 +0100
-+++ ioemu/vl.h 2007-05-11 10:04:52.000000000 +0100
-@@ -159,6 +159,28 @@
-
- extern FILE *logfile;
-
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+
-+#define MAPCACHE
-+
-+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
-+void qemu_invalidate_map_cache(void);
-+
-+#include <pthread.h>
-+extern pthread_mutex_t mapcache_mutex;
-+#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
-+#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
-+
-+#else
-+
-+#define qemu_invalidate_map_cache() ((void)0)
-+
-+#define mapcache_lock() ((void)0)
-+#define mapcache_unlock() ((void)0)
-+
-+#endif
-+
- extern int xc_handle;
- extern int domid;
-
-Index: ioemu/target-i386-dm/cpu.h
-===================================================================
---- ioemu.orig/target-i386-dm/cpu.h 2007-05-11 10:04:47.000000000 +0100
-+++ ioemu/target-i386-dm/cpu.h 2007-05-11 10:04:52.000000000 +0100
-@@ -25,7 +25,8 @@
- #ifdef TARGET_X86_64
- #define TARGET_LONG_BITS 64
- #else
--#define TARGET_LONG_BITS 32
-+/* #define TARGET_LONG_BITS 32 */
-+#define TARGET_LONG_BITS 64 /* for Qemu map cache */
- #endif
-
- /* target supports implicit self modifying code */
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- ioemu.orig/target-i386-dm/helper2.c 2007-05-11 10:04:50.000000000 +0100
-+++ ioemu/target-i386-dm/helper2.c 2007-05-11 10:04:52.000000000 +0100
-@@ -526,6 +526,9 @@
- case IOREQ_TYPE_TIMEOFFSET:
- cpu_ioreq_timeoffset(env, req);
- break;
-+ case IOREQ_TYPE_INVALIDATE:
-+ qemu_invalidate_map_cache();
-+ break;
- default:
- hw_error("Invalid ioreq type 0x%x\n", req->type);
- }
diff --git a/tools/ioemu/patches/xen-mm b/tools/ioemu/patches/xen-mm
deleted file mode 100644
index b1d36608e0..0000000000
--- a/tools/ioemu/patches/xen-mm
+++ /dev/null
@@ -1,136 +0,0 @@
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-03 19:08:13.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-03 19:08:19.000000000 +0100
-@@ -481,7 +481,9 @@
- }
-
- /* allocate RAM */
-+#ifndef CONFIG_DM /* HVM domain owns memory */
- cpu_register_physical_memory(0, ram_size, 0);
-+#endif
-
- /* BIOS load */
- bios_offset = ram_size + vga_ram_size;
-@@ -510,8 +512,10 @@
- ret = load_image(buf, phys_ram_base + vga_bios_offset);
-
- /* setup basic memory access */
-+#ifndef CONFIG_DM /* HVM domain owns memory */
- cpu_register_physical_memory(0xc0000, 0x10000,
- vga_bios_offset | IO_MEM_ROM);
-+#endif
-
- /* map the last 128KB of the BIOS in ISA space */
- isa_bios_size = bios_size;
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:08:13.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:08:57.000000000 +0100
-@@ -89,6 +89,7 @@
-
- #include "exec-all.h"
-
-+#include <xen/hvm/params.h>
- #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
- #ifdef __sun__
- #define SMBD_COMMAND "/usr/sfw/sbin/smbd"
-@@ -175,6 +176,8 @@
- int semihosting_enabled = 0;
- int autostart = 1;
-
-+int xc_handle;
-+
- char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
- extern int domid;
-
-@@ -6565,6 +6568,9 @@
- char usb_devices[MAX_USB_CMDLINE][128];
- int usb_devices_index;
- int fds[2];
-+ unsigned long ioreq_pfn;
-+ extern void *shared_page;
-+ unsigned long nr_pages;
-
- char qemu_dm_logfilename[64];
-
-@@ -6839,11 +6845,13 @@
- ram_size = atol(optarg) * 1024 * 1024;
- if (ram_size <= 0)
- help();
-+#ifndef CONFIG_DM
- if (ram_size > PHYS_RAM_MAX_SIZE) {
- fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
- PHYS_RAM_MAX_SIZE / (1024 * 1024));
- exit(1);
- }
-+#endif /* !CONFIG_DM */
- break;
- case QEMU_OPTION_l:
- {
-@@ -7153,12 +7161,53 @@
- phys_ram_size += ret;
- }
-
-+#ifdef CONFIG_DM
-+
-+ xc_handle = xc_interface_open();
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+
-+ nr_pages = ram_size/PAGE_SIZE;
-+
-+ page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
-+ if (page_array == NULL) {
-+ fprintf(logfile, "malloc returned error %d\n", errno);
-+ exit(-1);
-+ }
-+
-+ for ( i = 0; i < nr_pages; i++)
-+ page_array[i] = i;
-+
-+ phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
-+ PROT_READ|PROT_WRITE, page_array,
-+ nr_pages);
-+ if (phys_ram_base == NULL) {
-+ fprintf(logfile, "batch map guest memory returned error %d\n", errno);
-+ exit(-1);
-+ }
-+
-+ xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
-+ fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
-+ shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-+ PROT_READ|PROT_WRITE,
-+ page_array[ioreq_pfn]);
-+ if (shared_page == NULL) {
-+ fprintf(logfile, "map shared IO page returned error %d\n", errno);
-+ exit(-1);
-+ }
-+
-+ free(page_array);
-+
-+#else /* !CONFIG_DM */
-+
- phys_ram_base = qemu_vmalloc(phys_ram_size);
- if (!phys_ram_base) {
- fprintf(stderr, "Could not allocate physical memory\n");
- exit(1);
- }
-
-+#endif /* !CONFIG_DM */
-+
- /* we always create the cdrom drive, even if no disk is there */
- bdrv_init();
- if (cdrom_index >= 0) {
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-03 19:08:13.000000000 +0100
-+++ ioemu/vl.h 2007-05-03 19:08:19.000000000 +0100
-@@ -39,6 +39,7 @@
- #include <sys/stat.h>
- #include "xenctrl.h"
- #include "xs.h"
-+#include <xen/hvm/e820.h>
-
- #ifndef O_LARGEFILE
- #define O_LARGEFILE 0
diff --git a/tools/ioemu/patches/xen-network b/tools/ioemu/patches/xen-network
deleted file mode 100644
index 8aad7eaaa8..0000000000
--- a/tools/ioemu/patches/xen-network
+++ /dev/null
@@ -1,74 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-03 19:09:18.000000000 +0100
-+++ ioemu/vl.c 2007-05-03 19:11:56.000000000 +0100
-@@ -91,6 +91,7 @@
-
- #include <xen/hvm/params.h>
- #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
-+#define DEFAULT_BRIDGE "xenbr0"
- #ifdef __sun__
- #define SMBD_COMMAND "/usr/sfw/sbin/smbd"
- #else
-@@ -3288,11 +3289,11 @@
- #endif
-
- static int net_tap_init(VLANState *vlan, const char *ifname1,
-- const char *setup_script)
-+ const char *setup_script, const char *bridge)
- {
- TAPState *s;
- int pid, status, fd;
-- char *args[3];
-+ char *args[4];
- char **parg;
- char ifname[128];
-
-@@ -3311,9 +3312,18 @@
- pid = fork();
- if (pid >= 0) {
- if (pid == 0) {
-+ int open_max = sysconf(_SC_OPEN_MAX), i;
-+ for (i = 0; i < open_max; i++)
-+ if (i != STDIN_FILENO &&
-+ i != STDOUT_FILENO &&
-+ i != STDERR_FILENO &&
-+ i != fd)
-+ close(i);
-+
- parg = args;
- *parg++ = (char *)setup_script;
- *parg++ = ifname;
-+ *parg++ = (char *)bridge;
- *parg++ = NULL;
- execv(setup_script, args);
- _exit(1);
-@@ -3869,6 +3879,7 @@
- if (!strcmp(device, "tap")) {
- char ifname[64];
- char setup_script[1024];
-+ char bridge[16];
- int fd;
- if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
- fd = strtol(buf, NULL, 0);
-@@ -3882,7 +3893,10 @@
- if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
- pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
- }
-- ret = net_tap_init(vlan, ifname, setup_script);
-+ if (get_param_value(bridge, sizeof(bridge), "bridge", p) == 0) {
-+ pstrcpy(bridge, sizeof(bridge), DEFAULT_BRIDGE);
-+ }
-+ ret = net_tap_init(vlan, ifname, setup_script, bridge);
- }
- } else
- #endif
-@@ -6101,7 +6115,7 @@
- "-net tap[,vlan=n],ifname=name\n"
- " connect the host TAP network interface to VLAN 'n'\n"
- #else
-- "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
-+ "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,bridge=br]\n"
- " connect the host TAP network interface to VLAN 'n' and use\n"
- " the network script 'file' (default=%s);\n"
- " use 'script=no' to disable script execution;\n"
diff --git a/tools/ioemu/patches/xen-platform-device b/tools/ioemu/patches/xen-platform-device
deleted file mode 100644
index 272b8e6693..0000000000
--- a/tools/ioemu/patches/xen-platform-device
+++ /dev/null
@@ -1,199 +0,0 @@
-Add the xen platform device to the qemu PCI bus. Useful functionality
-will come later.
-
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-10 15:19:05.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-10 15:19:28.000000000 +0100
-@@ -391,6 +391,7 @@
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
- VL_OBJS+= piix4acpi.o
- VL_OBJS+= xenstore.o
-+VL_OBJS+= xen_platform.o
- CPPFLAGS += -DHAS_AUDIO
- endif
- ifeq ($(TARGET_BASE_ARCH), ppc)
-Index: ioemu/hw/pc.c
-===================================================================
---- ioemu.orig/hw/pc.c 2007-05-10 15:19:11.000000000 +0100
-+++ ioemu/hw/pc.c 2007-05-10 15:19:28.000000000 +0100
-@@ -676,6 +676,9 @@
- }
- #endif /* !CONFIG_DM */
-
-+ if (pci_enabled)
-+ pci_xen_platform_init(pci_bus);
-+
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_hds[i]) {
- serial_init(&pic_set_irq_new, isa_pic,
-Index: ioemu/hw/xen_platform.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/hw/xen_platform.c 2007-05-10 15:19:28.000000000 +0100
-@@ -0,0 +1,150 @@
-+/*
-+ * XEN platform fake pci device, formerly known as the event channel device
-+ *
-+ * Copyright (c) 2003-2004 Intel Corp.
-+ * Copyright (c) 2006 XenSource
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+#include "vl.h"
-+
-+#include <xenguest.h>
-+#include <xc_private.h>
-+
-+extern FILE *logfile;
-+
-+static void platform_ioport_map(PCIDevice *pci_dev, int region_num,
-+ uint32_t addr, uint32_t size, int type)
-+{
-+ /* nothing yet */
-+}
-+
-+static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
-+{
-+ fprintf(logfile, "Warning: try read from xen platform mmio space\n");
-+ return 0;
-+}
-+
-+static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
-+ uint32_t val)
-+{
-+ fprintf(logfile, "Warning: try write to xen platform mmio space\n");
-+ return;
-+}
-+
-+static CPUReadMemoryFunc *platform_mmio_read_funcs[3] = {
-+ platform_mmio_read,
-+ platform_mmio_read,
-+ platform_mmio_read,
-+};
-+
-+static CPUWriteMemoryFunc *platform_mmio_write_funcs[3] = {
-+ platform_mmio_write,
-+ platform_mmio_write,
-+ platform_mmio_write,
-+};
-+
-+static void platform_mmio_map(PCIDevice *d, int region_num,
-+ uint32_t addr, uint32_t size, int type)
-+{
-+ int mmio_io_addr;
-+
-+ mmio_io_addr = cpu_register_io_memory(0, platform_mmio_read_funcs,
-+ platform_mmio_write_funcs, NULL);
-+
-+ cpu_register_physical_memory(addr, 0x1000000, mmio_io_addr);
-+}
-+
-+struct pci_config_header {
-+ uint16_t vendor_id;
-+ uint16_t device_id;
-+ uint16_t command;
-+ uint16_t status;
-+ uint8_t revision;
-+ uint8_t api;
-+ uint8_t subclass;
-+ uint8_t class;
-+ uint8_t cache_line_size; /* Units of 32 bit words */
-+ uint8_t latency_timer; /* In units of bus cycles */
-+ uint8_t header_type; /* Should be 0 */
-+ uint8_t bist; /* Built in self test */
-+ uint32_t base_address_regs[6];
-+ uint32_t reserved1;
-+ uint16_t subsystem_vendor_id;
-+ uint16_t subsystem_id;
-+ uint32_t rom_addr;
-+ uint32_t reserved3;
-+ uint32_t reserved4;
-+ uint8_t interrupt_line;
-+ uint8_t interrupt_pin;
-+ uint8_t min_gnt;
-+ uint8_t max_lat;
-+};
-+
-+void xen_pci_save(QEMUFile *f, void *opaque)
-+{
-+ PCIDevice *d = opaque;
-+
-+ pci_device_save(d, f);
-+}
-+
-+int xen_pci_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+ PCIDevice *d = opaque;
-+
-+ if (version_id != 1)
-+ return -EINVAL;
-+
-+ return pci_device_load(d, f);
-+}
-+
-+void pci_xen_platform_init(PCIBus *bus)
-+{
-+ PCIDevice *d;
-+ struct pci_config_header *pch;
-+
-+ printf("Register xen platform.\n");
-+ d = pci_register_device(bus, "xen-platform", sizeof(PCIDevice), -1, NULL,
-+ NULL);
-+ pch = (struct pci_config_header *)d->config;
-+ pch->vendor_id = 0x5853;
-+ pch->device_id = 0x0001;
-+ pch->command = 3; /* IO and memory access */
-+ pch->revision = 1;
-+ pch->api = 0;
-+ pch->subclass = 0x80; /* Other */
-+ pch->class = 0xff; /* Unclassified device class */
-+ pch->header_type = 0;
-+ pch->interrupt_pin = 1;
-+
-+ /* Microsoft WHQL requires non-zero subsystem IDs. */
-+ /* http://www.pcisig.com/reflector/msg02205.html. */
-+ pch->subsystem_vendor_id = pch->vendor_id; /* Duplicate vendor id. */
-+ pch->subsystem_id = 0x0001; /* Hardcode sub-id as 1. */
-+
-+ pci_register_io_region(d, 0, 0x100, PCI_ADDRESS_SPACE_IO,
-+ platform_ioport_map);
-+
-+ /* reserve 16MB mmio address for share memory*/
-+ pci_register_io_region(d, 1, 0x1000000, PCI_ADDRESS_SPACE_MEM_PREFETCH,
-+ platform_mmio_map);
-+
-+ register_savevm("platform", 0, 1, xen_pci_save, xen_pci_load, d);
-+ printf("Done register platform.\n");
-+}
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:19:11.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:19:28.000000000 +0100
-@@ -1437,6 +1437,10 @@
- extern long time_offset;
- void timeoffset_get(void);
-
-+/* xen_platform.c */
-+void pci_xen_platform_init(PCIBus *bus);
-+
-+
- void kqemu_record_dump(void);
-
- extern char domain_name[];
diff --git a/tools/ioemu/patches/xen-support-buffered-ioreqs b/tools/ioemu/patches/xen-support-buffered-ioreqs
deleted file mode 100644
index 9280546126..0000000000
--- a/tools/ioemu/patches/xen-support-buffered-ioreqs
+++ /dev/null
@@ -1,182 +0,0 @@
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:34:19.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:34:24.000000000 +0100
-@@ -6823,6 +6823,7 @@
- int fds[2];
- unsigned long ioreq_pfn;
- extern void *shared_page;
-+ extern void *buffered_io_page;
- unsigned long nr_pages;
-
- char qemu_dm_logfilename[64];
-@@ -7490,6 +7491,16 @@
- exit(-1);
- }
-
-+ xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
-+ fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
-+ buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-+ PROT_READ|PROT_WRITE,
-+ page_array[ioreq_pfn]);
-+ if (buffered_io_page == NULL) {
-+ fprintf(logfile, "map buffered IO page returned error %d\n", errno);
-+ exit(-1);
-+ }
-+
- free(page_array);
-
- #elif defined(__ia64__)
-Index: ioemu/target-i386-dm/helper2.c
-===================================================================
---- ioemu.orig/target-i386-dm/helper2.c 2007-05-10 15:34:19.000000000 +0100
-+++ ioemu/target-i386-dm/helper2.c 2007-05-10 15:34:24.000000000 +0100
-@@ -78,6 +78,10 @@
-
- shared_iopage_t *shared_page = NULL;
-
-+#define BUFFER_IO_MAX_DELAY 100
-+buffered_iopage_t *buffered_io_page = NULL;
-+QEMUTimer *buffered_io_timer;
-+
- /* the evtchn fd for polling */
- int xce_handle = -1;
-
-@@ -489,6 +493,72 @@
- req->data = tmp1;
- }
-
-+void __handle_ioreq(CPUState *env, ioreq_t *req)
-+{
-+ if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
-+ req->data &= (1UL << (8 * req->size)) - 1;
-+
-+ switch (req->type) {
-+ case IOREQ_TYPE_PIO:
-+ cpu_ioreq_pio(env, req);
-+ break;
-+ case IOREQ_TYPE_COPY:
-+ cpu_ioreq_move(env, req);
-+ break;
-+ case IOREQ_TYPE_AND:
-+ cpu_ioreq_and(env, req);
-+ break;
-+ case IOREQ_TYPE_ADD:
-+ cpu_ioreq_add(env, req);
-+ break;
-+ case IOREQ_TYPE_SUB:
-+ cpu_ioreq_sub(env, req);
-+ break;
-+ case IOREQ_TYPE_OR:
-+ cpu_ioreq_or(env, req);
-+ break;
-+ case IOREQ_TYPE_XOR:
-+ cpu_ioreq_xor(env, req);
-+ break;
-+ case IOREQ_TYPE_XCHG:
-+ cpu_ioreq_xchg(env, req);
-+ break;
-+ case IOREQ_TYPE_TIMEOFFSET:
-+ cpu_ioreq_timeoffset(env, req);
-+ break;
-+ default:
-+ hw_error("Invalid ioreq type 0x%x\n", req->type);
-+ }
-+}
-+
-+void __handle_buffered_iopage(CPUState *env)
-+{
-+ ioreq_t *req = NULL;
-+
-+ if (!buffered_io_page)
-+ return;
-+
-+ while (buffered_io_page->read_pointer !=
-+ buffered_io_page->write_pointer) {
-+ req = &buffered_io_page->ioreq[buffered_io_page->read_pointer %
-+ IOREQ_BUFFER_SLOT_NUM];
-+
-+ __handle_ioreq(env, req);
-+
-+ mb();
-+ buffered_io_page->read_pointer++;
-+ }
-+}
-+
-+void handle_buffered_io(void *opaque)
-+{
-+ CPUState *env = opaque;
-+
-+ __handle_buffered_iopage(env);
-+ qemu_mod_timer(buffered_io_timer, BUFFER_IO_MAX_DELAY +
-+ qemu_get_clock(rt_clock));
-+}
-+
- void cpu_handle_ioreq(void *opaque)
- {
- extern int vm_running;
-@@ -496,43 +566,9 @@
- CPUState *env = opaque;
- ioreq_t *req = cpu_get_ioreq();
-
-+ handle_buffered_io(env);
- if (req) {
-- if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) {
-- if (req->size != 4)
-- req->data &= (1UL << (8 * req->size))-1;
-- }
--
-- switch (req->type) {
-- case IOREQ_TYPE_PIO:
-- cpu_ioreq_pio(env, req);
-- break;
-- case IOREQ_TYPE_COPY:
-- cpu_ioreq_move(env, req);
-- break;
-- case IOREQ_TYPE_AND:
-- cpu_ioreq_and(env, req);
-- break;
-- case IOREQ_TYPE_ADD:
-- cpu_ioreq_add(env, req);
-- break;
-- case IOREQ_TYPE_SUB:
-- cpu_ioreq_sub(env, req);
-- break;
-- case IOREQ_TYPE_OR:
-- cpu_ioreq_or(env, req);
-- break;
-- case IOREQ_TYPE_XOR:
-- cpu_ioreq_xor(env, req);
-- break;
-- case IOREQ_TYPE_XCHG:
-- cpu_ioreq_xchg(env, req);
-- break;
-- case IOREQ_TYPE_TIMEOFFSET:
-- cpu_ioreq_timeoffset(env, req);
-- break;
-- default:
-- hw_error("Invalid ioreq type 0x%x\n", req->type);
-- }
-+ __handle_ioreq(env, req);
-
- if (req->state != STATE_IOREQ_INPROCESS) {
- fprintf(logfile, "Badness in I/O request ... not in service?!: "
-@@ -578,6 +614,10 @@
- int evtchn_fd = xc_evtchn_fd(xce_handle);
- char qemu_file[20];
-
-+ buffered_io_timer = qemu_new_timer(rt_clock, handle_buffered_io,
-+ cpu_single_env);
-+ qemu_mod_timer(buffered_io_timer, qemu_get_clock(rt_clock));
-+
- qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
-
- while (!(vm_running && suspend_requested))
-@@ -587,6 +627,7 @@
- fprintf(logfile, "device model received suspend signal!\n");
-
- /* Pull all outstanding ioreqs through the system */
-+ handle_buffered_io(env);
- main_loop_wait(1); /* For the select() on events */
-
- /* Save the device state */
diff --git a/tools/ioemu/patches/xenstore b/tools/ioemu/patches/xenstore
deleted file mode 100644
index c3a679d650..0000000000
--- a/tools/ioemu/patches/xenstore
+++ /dev/null
@@ -1,197 +0,0 @@
-Index: ioemu/xenstore.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/xenstore.c 2007-05-10 15:19:05.000000000 +0100
-@@ -0,0 +1,139 @@
-+/*
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License. See the file "COPYING" in the main directory of
-+ * this archive for more details.
-+ *
-+ * Copyright (C) 2006 Christian Limpach
-+ * Copyright (C) 2006 XenSource Ltd.
-+ *
-+ */
-+
-+#include "vl.h"
-+
-+static struct xs_handle *xsh = NULL;
-+
-+static int pasprintf(char **buf, const char *fmt, ...)
-+{
-+ va_list ap;
-+ int ret = 0;
-+
-+ if (*buf)
-+ free(*buf);
-+ va_start(ap, fmt);
-+ if (vasprintf(buf, fmt, ap) == -1) {
-+ buf = NULL;
-+ ret = -1;
-+ }
-+ va_end(ap);
-+ return ret;
-+}
-+
-+void xenstore_parse_domain_config(int domid)
-+{
-+ char *path;
-+
-+ xsh = xs_daemon_open();
-+ if (xsh == NULL) {
-+ fprintf(logfile, "Could not contact xenstore for domain config\n");
-+ return;
-+ }
-+
-+ path = xs_get_domain_path(xsh, domid);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_get_domain_path() error\n");
-+ goto out;
-+ }
-+
-+ out:
-+ free(path);
-+ return;
-+}
-+
-+int xenstore_fd(void)
-+{
-+ if (xsh)
-+ return xs_fileno(xsh);
-+ return -1;
-+}
-+
-+void xenstore_process_event(void *opaque)
-+{
-+ char **vec;
-+ unsigned int num;
-+
-+ vec = xs_read_watch(xsh, &num);
-+ if (!vec)
-+ return;
-+
-+ out:
-+ free(vec);
-+}
-+
-+char *xenstore_vm_read(int domid, char *key, int *len)
-+{
-+ char *buf = NULL, *path = NULL, *value = NULL;
-+
-+ if (xsh == NULL)
-+ goto out;
-+
-+ path = xs_get_domain_path(xsh, domid);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_get_domain_path(%d): error\n", domid);
-+ goto out;
-+ }
-+
-+ pasprintf(&buf, "%s/vm", path);
-+ free(path);
-+ path = xs_read(xsh, XBT_NULL, buf, NULL);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_read(%s): read error\n", buf);
-+ goto out;
-+ }
-+
-+ pasprintf(&buf, "%s/%s", path, key);
-+ value = xs_read(xsh, XBT_NULL, buf, len);
-+ if (value == NULL) {
-+ fprintf(logfile, "xs_read(%s): read error\n", buf);
-+ goto out;
-+ }
-+
-+ out:
-+ free(path);
-+ free(buf);
-+ return value;
-+}
-+
-+int xenstore_vm_write(int domid, char *key, char *value)
-+{
-+ char *buf = NULL, *path = NULL;
-+ int rc = -1;
-+
-+ if (xsh == NULL)
-+ goto out;
-+
-+ path = xs_get_domain_path(xsh, domid);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_get_domain_path: error\n");
-+ goto out;
-+ }
-+
-+ pasprintf(&buf, "%s/vm", path);
-+ free(path);
-+ path = xs_read(xsh, XBT_NULL, buf, NULL);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_read(%s): read error\n", buf);
-+ goto out;
-+ }
-+
-+ pasprintf(&buf, "%s/%s", path, key);
-+ rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value));
-+ if (rc) {
-+ fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key);
-+ goto out;
-+ }
-+
-+ out:
-+ free(path);
-+ free(buf);
-+ return rc;
-+}
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:18:58.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:19:05.000000000 +0100
-@@ -1421,6 +1421,12 @@
- void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque);
-
-+/* xenstore.c */
-+void xenstore_parse_domain_config(int domid);
-+
-+int xenstore_vm_write(int domid, char *key, char *val);
-+char *xenstore_vm_read(int domid, char *key, int *len);
-+
- void kqemu_record_dump(void);
-
- extern char domain_name[];
-Index: ioemu/Makefile.target
-===================================================================
---- ioemu.orig/Makefile.target 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/Makefile.target 2007-05-10 15:19:05.000000000 +0100
-@@ -390,6 +390,7 @@
- VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
- VL_OBJS+= usb-uhci.o smbus_eeprom.o
- VL_OBJS+= piix4acpi.o
-+VL_OBJS+= xenstore.o
- CPPFLAGS += -DHAS_AUDIO
- endif
- ifeq ($(TARGET_BASE_ARCH), ppc)
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:18:58.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:19:05.000000000 +0100
-@@ -7338,6 +7338,10 @@
- }
- #endif
-
-+#ifdef CONFIG_DM
-+ xenstore_parse_domain_config(domid);
-+#endif /* CONFIG_DM */
-+
- #ifdef USE_KQEMU
- if (smp_cpus > 1)
- kqemu_allowed = 0;
-@@ -7627,6 +7631,8 @@
- }
- }
-
-+ qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL);
-+
- machine->init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename);
diff --git a/tools/ioemu/patches/xenstore-block-device-config b/tools/ioemu/patches/xenstore-block-device-config
deleted file mode 100644
index 2dd5e08386..0000000000
--- a/tools/ioemu/patches/xenstore-block-device-config
+++ /dev/null
@@ -1,453 +0,0 @@
-Index: ioemu/xenstore.c
-===================================================================
---- ioemu.orig/xenstore.c 2007-05-10 15:19:05.000000000 +0100
-+++ ioemu/xenstore.c 2007-05-10 15:19:05.000000000 +0100
-@@ -9,8 +9,15 @@
- */
-
- #include "vl.h"
-+#include "block_int.h"
-+#include <unistd.h>
-
- static struct xs_handle *xsh = NULL;
-+static char *media_filename[MAX_DISKS];
-+static QEMUTimer *insert_timer = NULL;
-+
-+#define UWAIT_MAX (30*1000000) /* thirty seconds */
-+#define UWAIT (100000) /* 1/10th second */
-
- static int pasprintf(char **buf, const char *fmt, ...)
- {
-@@ -28,9 +35,54 @@
- return ret;
- }
-
-+static void insert_media(void *opaque)
-+{
-+ int i;
-+
-+ for (i = 0; i < MAX_DISKS; i++) {
-+ if (media_filename[i] && bs_table[i]) {
-+ do_change(bs_table[i]->device_name, media_filename[i]);
-+ free(media_filename[i]);
-+ media_filename[i] = NULL;
-+ }
-+ }
-+}
-+
-+void xenstore_check_new_media_present(int timeout)
-+{
-+
-+ if (insert_timer == NULL)
-+ insert_timer = qemu_new_timer(rt_clock, insert_media, NULL);
-+ qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
-+}
-+
-+static void waitForDevice(char *fn)
-+{
-+ struct stat sbuf;
-+ int status;
-+ int uwait = UWAIT_MAX;
-+
-+ do {
-+ status = stat(fn, &sbuf);
-+ if (!status) break;
-+ usleep(UWAIT);
-+ uwait -= UWAIT;
-+ } while (uwait > 0);
-+
-+ return;
-+}
-+
- void xenstore_parse_domain_config(int domid)
- {
-- char *path;
-+ char **e = NULL;
-+ char *buf = NULL, *path;
-+ char *fpath = NULL, *bpath = NULL,
-+ *dev = NULL, *params = NULL, *type = NULL;
-+ int i;
-+ unsigned int len, num, hd_index;
-+
-+ for(i = 0; i < MAX_DISKS; i++)
-+ media_filename[i] = NULL;
-
- xsh = xs_daemon_open();
- if (xsh == NULL) {
-@@ -44,8 +96,91 @@
- goto out;
- }
-
-+ if (pasprintf(&buf, "%s/device/vbd", path) == -1)
-+ goto out;
-+
-+ e = xs_directory(xsh, XBT_NULL, buf, &num);
-+ if (e == NULL)
-+ goto out;
-+
-+ for (i = 0; i < num; i++) {
-+ /* read the backend path */
-+ if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
-+ continue;
-+ free(bpath);
-+ bpath = xs_read(xsh, XBT_NULL, buf, &len);
-+ if (bpath == NULL)
-+ continue;
-+ /* read the name of the device */
-+ if (pasprintf(&buf, "%s/dev", bpath) == -1)
-+ continue;
-+ free(dev);
-+ dev = xs_read(xsh, XBT_NULL, buf, &len);
-+ if (dev == NULL)
-+ continue;
-+ if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
-+ continue;
-+ hd_index = dev[2] - 'a';
-+ if (hd_index >= MAX_DISKS)
-+ continue;
-+ /* read the type of the device */
-+ if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
-+ continue;
-+ free(type);
-+ type = xs_read(xsh, XBT_NULL, buf, &len);
-+ if (pasprintf(&buf, "%s/params", bpath) == -1)
-+ continue;
-+ free(params);
-+ params = xs_read(xsh, XBT_NULL, buf, &len);
-+ if (params == NULL)
-+ continue;
-+ /*
-+ * check if device has a phantom vbd; the phantom is hooked
-+ * to the frontend device (for ease of cleanup), so lookup
-+ * the frontend device, and see if there is a phantom_vbd
-+ * if there is, we will use resolution as the filename
-+ */
-+ if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
-+ continue;
-+ free(fpath);
-+ fpath = xs_read(xsh, XBT_NULL, buf, &len);
-+ if (fpath) {
-+ if (pasprintf(&buf, "%s/dev", fpath) == -1)
-+ continue;
-+ free(params);
-+ params = xs_read(xsh, XBT_NULL, buf , &len);
-+ if (params) {
-+ /*
-+ * wait for device, on timeout silently fail because we will
-+ * fail to open below
-+ */
-+ waitForDevice(params);
-+ }
-+ }
-+
-+ bs_table[hd_index] = bdrv_new(dev);
-+ /* check if it is a cdrom */
-+ if (type && !strcmp(type, "cdrom")) {
-+ bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
-+ if (pasprintf(&buf, "%s/params", bpath) != -1)
-+ xs_watch(xsh, buf, dev);
-+ }
-+ /* open device now if media present */
-+ if (params[0]) {
-+ if (bdrv_open(bs_table[hd_index], params, 0 /* snapshot */) < 0)
-+ fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
-+ params);
-+ }
-+ }
-+
- out:
-+ free(type);
-+ free(params);
-+ free(dev);
-+ free(bpath);
-+ free(buf);
- free(path);
-+ free(e);
- return;
- }
-
-@@ -58,14 +193,35 @@
-
- void xenstore_process_event(void *opaque)
- {
-- char **vec;
-- unsigned int num;
-+ char **vec, *image = NULL;
-+ unsigned int len, num, hd_index;
-
- vec = xs_read_watch(xsh, &num);
- if (!vec)
- return;
-
-+ if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
-+ strlen(vec[XS_WATCH_TOKEN]) != 3)
-+ goto out;
-+ hd_index = vec[XS_WATCH_TOKEN][2] - 'a';
-+ image = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
-+ if (image == NULL || !strcmp(image, bs_table[hd_index]->filename))
-+ goto out; /* gone or identical */
-+
-+ do_eject(0, vec[XS_WATCH_TOKEN]);
-+ bs_table[hd_index]->filename[0] = 0;
-+ if (media_filename[hd_index]) {
-+ free(media_filename[hd_index]);
-+ media_filename[hd_index] = NULL;
-+ }
-+
-+ if (image[0]) {
-+ media_filename[hd_index] = strdup(image);
-+ xenstore_check_new_media_present(5000);
-+ }
-+
- out:
-+ free(image);
- free(vec);
- }
-
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:19:05.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:19:05.000000000 +0100
-@@ -6213,9 +6213,11 @@
- "Standard options:\n"
- "-M machine select emulated machine (-M ? for list)\n"
- "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
-+#ifndef CONFIG_DM
- "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
- "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
- "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
-+#endif /* !CONFIG_DM */
- "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
- "-snapshot write to temporary files instead of disk image files\n"
- #ifdef CONFIG_SDL
-@@ -6350,11 +6352,13 @@
- QEMU_OPTION_M,
- QEMU_OPTION_fda,
- QEMU_OPTION_fdb,
-+#ifndef CONFIG_DM
- QEMU_OPTION_hda,
- QEMU_OPTION_hdb,
- QEMU_OPTION_hdc,
- QEMU_OPTION_hdd,
- QEMU_OPTION_cdrom,
-+#endif /* !CONFIG_DM */
- QEMU_OPTION_boot,
- QEMU_OPTION_snapshot,
- #ifdef TARGET_I386
-@@ -6431,11 +6435,13 @@
- { "M", HAS_ARG, QEMU_OPTION_M },
- { "fda", HAS_ARG, QEMU_OPTION_fda },
- { "fdb", HAS_ARG, QEMU_OPTION_fdb },
-+#ifndef CONFIG_DM
- { "hda", HAS_ARG, QEMU_OPTION_hda },
- { "hdb", HAS_ARG, QEMU_OPTION_hdb },
- { "hdc", HAS_ARG, QEMU_OPTION_hdc },
- { "hdd", HAS_ARG, QEMU_OPTION_hdd },
- { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
-+#endif /* !CONFIG_DM */
- { "boot", HAS_ARG, QEMU_OPTION_boot },
- { "snapshot", 0, QEMU_OPTION_snapshot },
- #ifdef TARGET_I386
-@@ -6787,10 +6793,16 @@
- #ifdef CONFIG_GDBSTUB
- int use_gdbstub, gdbstub_port;
- #endif
-- int i, cdrom_index;
-+ int i;
-+#ifndef CONFIG_DM
-+ int cdrom_index;
-+#endif /* !CONFIG_DM */
- int snapshot, linux_boot;
- const char *initrd_filename;
-- const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
-+#ifndef CONFIG_DM
-+ const char *hd_filename[MAX_DISKS];
-+#endif /* !CONFIG_DM */
-+ const char *fd_filename[MAX_FD];
- const char *kernel_filename, *kernel_cmdline;
- DisplayState *ds = &display_state;
- int cyls, heads, secs, translation;
-@@ -6851,8 +6863,10 @@
- initrd_filename = NULL;
- for(i = 0; i < MAX_FD; i++)
- fd_filename[i] = NULL;
-+#ifndef CONFIG_DM
- for(i = 0; i < MAX_DISKS; i++)
- hd_filename[i] = NULL;
-+#endif /* !CONFIG_DM */
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
- vga_ram_size = VGA_RAM_SIZE;
- bios_size = BIOS_SIZE;
-@@ -6866,11 +6880,13 @@
- vncunused = 0;
- kernel_filename = NULL;
- kernel_cmdline = "";
-+#ifndef CONFIG_DM
- #ifdef TARGET_PPC
- cdrom_index = 1;
- #else
- cdrom_index = 2;
- #endif
-+#endif /* !CONFIG_DM */
- cyls = heads = secs = 0;
- translation = BIOS_ATA_TRANSLATION_AUTO;
- pstrcpy(monitor_device, sizeof(monitor_device), "null");
-@@ -6907,7 +6923,11 @@
- break;
- r = argv[optind];
- if (r[0] != '-') {
-+#ifndef CONFIG_DM
- hd_filename[0] = argv[optind++];
-+#else
-+ help();
-+#endif /* !CONFIG_DM */
- } else {
- const QEMUOption *popt;
-
-@@ -6954,6 +6974,7 @@
- case QEMU_OPTION_initrd:
- initrd_filename = optarg;
- break;
-+#ifndef CONFIG_DM
- case QEMU_OPTION_hda:
- case QEMU_OPTION_hdb:
- case QEMU_OPTION_hdc:
-@@ -6966,6 +6987,7 @@
- cdrom_index = -1;
- }
- break;
-+#endif /* !CONFIG_DM */
- case QEMU_OPTION_snapshot:
- snapshot = 1;
- break;
-@@ -7018,11 +7040,13 @@
- case QEMU_OPTION_append:
- kernel_cmdline = optarg;
- break;
-+#ifndef CONFIG_DM
- case QEMU_OPTION_cdrom:
- if (cdrom_index >= 0) {
- hd_filename[cdrom_index] = optarg;
- }
- break;
-+#endif /* !CONFIG_DM */
- case QEMU_OPTION_boot:
- boot_device = optarg[0];
- if (boot_device != 'a' &&
-@@ -7339,6 +7363,7 @@
- #endif
-
- #ifdef CONFIG_DM
-+ bdrv_init();
- xenstore_parse_domain_config(domid);
- #endif /* CONFIG_DM */
-
-@@ -7348,6 +7373,7 @@
- #endif
- linux_boot = (kernel_filename != NULL);
-
-+#ifndef CONFIG_DM
- if (!linux_boot &&
- hd_filename[0] == '\0' &&
- (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
-@@ -7361,6 +7387,7 @@
- else
- boot_device = 'd';
- }
-+#endif /* !CONFIG_DM */
-
- setvbuf(stdout, NULL, _IOLBF, 0);
-
-@@ -7513,6 +7540,7 @@
-
- #endif /* !CONFIG_DM */
-
-+#ifndef CONFIG_DM
- /* we always create the cdrom drive, even if no disk is there */
- bdrv_init();
- if (cdrom_index >= 0) {
-@@ -7539,6 +7567,7 @@
- }
- }
- }
-+#endif /* !CONFIG_DM */
-
- /* we always create at least one floppy disk */
- fd_table[0] = bdrv_new("fda");
-Index: ioemu/monitor.c
-===================================================================
---- ioemu.orig/monitor.c 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/monitor.c 2007-05-10 15:19:05.000000000 +0100
-@@ -24,6 +24,7 @@
- #include "vl.h"
- #include "disas.h"
- #include <dirent.h>
-+#include "block_int.h"
-
- //#define DEBUG
- //#define DEBUG_COMPLETION
-@@ -361,7 +362,7 @@
- return 0;
- }
-
--static void do_eject(int force, const char *filename)
-+void do_eject(int force, const char *filename)
- {
- BlockDriverState *bs;
-
-@@ -373,7 +374,7 @@
- eject_device(bs, force);
- }
-
--static void do_change(const char *device, const char *filename)
-+void do_change(const char *device, const char *filename)
- {
- BlockDriverState *bs;
- int i;
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:19:05.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:19:05.000000000 +0100
-@@ -1409,6 +1409,8 @@
- void term_print_help(void);
- void monitor_readline(const char *prompt, int is_password,
- char *buf, int buf_size);
-+void do_eject(int force, const char *filename);
-+void do_change(const char *device, const char *filename);
-
- /* readline.c */
- typedef void ReadLineFunc(void *opaque, const char *str);
-@@ -1423,6 +1425,9 @@
-
- /* xenstore.c */
- void xenstore_parse_domain_config(int domid);
-+int xenstore_fd(void);
-+void xenstore_process_event(void *opaque);
-+void xenstore_check_new_media_present(int timeout);
-
- int xenstore_vm_write(int domid, char *key, char *val);
- char *xenstore_vm_read(int domid, char *key, int *len);
-Index: ioemu/hw/ide.c
-===================================================================
---- ioemu.orig/hw/ide.c 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/hw/ide.c 2007-05-10 15:19:05.000000000 +0100
-@@ -1221,6 +1221,7 @@
- } else {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
-+ xenstore_check_new_media_present(1000);
- }
- break;
- case GPCMD_MODE_SENSE_10:
-Index: ioemu/block-raw.c
-===================================================================
---- ioemu.orig/block-raw.c 2007-05-10 15:17:54.000000000 +0100
-+++ ioemu/block-raw.c 2007-05-10 15:19:05.000000000 +0100
-@@ -383,6 +383,7 @@
- static void raw_close(BlockDriverState *bs)
- {
- BDRVRawState *s = bs->opaque;
-+ bs->total_sectors = 0;
- if (s->fd >= 0) {
- close(s->fd);
- s->fd = -1;
diff --git a/tools/ioemu/patches/xenstore-device-info-functions b/tools/ioemu/patches/xenstore-device-info-functions
deleted file mode 100644
index 2e09b8e0d9..0000000000
--- a/tools/ioemu/patches/xenstore-device-info-functions
+++ /dev/null
@@ -1,192 +0,0 @@
-# HG changeset patch
-# User kaf24@localhost.localdomain
-# Node ID bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2
-# Parent dc973fe5633386547ce5bc8fd4cf5f2bb5b55174
-[QEMU] Helper functions to interface with the xenstore and read device information from it.
-
- - detect what types of devices a domain has or whether a domain has a
- device of a certain type
- - read the content of a variable related to a device, i.e.,
- hotplug-status
- - subscribe to changes of the hotplug status of a device for not
- having to poll the status
-
-Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
-
-Index: ioemu/xenstore.c
-===================================================================
---- ioemu.orig/xenstore.c 2007-05-10 15:19:29.000000000 +0100
-+++ ioemu/xenstore.c 2007-05-10 15:19:29.000000000 +0100
-@@ -304,6 +304,143 @@
- return rc;
- }
-
-+
-+/*
-+ * get all device instances of a certain type
-+ */
-+char **xenstore_domain_get_devices(struct xs_handle *handle,
-+ const char *devtype, unsigned int *num)
-+{
-+ char *path;
-+ char *buf = NULL;
-+ char **e = NULL;
-+
-+ path = xs_get_domain_path(handle, domid);
-+ if (path == NULL)
-+ goto out;
-+
-+ if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
-+ goto out;
-+
-+ e = xs_directory(handle, XBT_NULL, buf, num);
-+
-+ out:
-+ free(path);
-+ free(buf);
-+ return e;
-+}
-+
-+/*
-+ * Check whether a domain has devices of the given type
-+ */
-+int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype)
-+{
-+ int rc = 0;
-+ unsigned int num;
-+ char **e = xenstore_domain_get_devices(handle, devtype, &num);
-+ if (e)
-+ rc = 1;
-+ free(e);
-+ return rc;
-+}
-+
-+/*
-+ * Function that creates a path to a variable of an instance of a
-+ * certain device
-+ */
-+static char *get_device_variable_path(const char *devtype, const char *inst,
-+ const char *var)
-+{
-+ char *buf = NULL;
-+ if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s",
-+ devtype,
-+ domid,
-+ inst,
-+ var) == -1) {
-+ free(buf);
-+ buf = NULL;
-+ }
-+ return buf;
-+}
-+
-+char *xenstore_backend_read_variable(struct xs_handle *handle,
-+ const char *devtype, const char *inst,
-+ const char *var)
-+{
-+ char *value = NULL;
-+ char *buf = NULL;
-+ unsigned int len;
-+
-+ buf = get_device_variable_path(devtype, inst, var);
-+ if (NULL == buf)
-+ goto out;
-+
-+ value = xs_read(handle, XBT_NULL, buf, &len);
-+
-+ free(buf);
-+
-+ out:
-+ return value;
-+}
-+
-+/*
-+ Read the hotplug status variable from the backend given the type
-+ of device and its instance.
-+*/
-+char *xenstore_read_hotplug_status(struct xs_handle *handle,
-+ const char *devtype, const char *inst)
-+{
-+ return xenstore_backend_read_variable(handle, devtype, inst,
-+ "hotplug-status");
-+}
-+
-+/*
-+ Subscribe to the hotplug status of a device given the type of device and
-+ its instance.
-+ In case an error occurrs, a negative number is returned.
-+ */
-+int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
-+ const char *devtype,
-+ const char *inst,
-+ const char *token)
-+{
-+ int rc = 0;
-+ char *path = get_device_variable_path(devtype, inst, "hotplug-status");
-+
-+ if (path == NULL)
-+ return -1;
-+
-+ if (0 == xs_watch(handle, path, token))
-+ rc = -2;
-+
-+ free(path);
-+
-+ return rc;
-+}
-+
-+/*
-+ * Unsubscribe from a subscription to the status of a hotplug variable of
-+ * a device.
-+ */
-+int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
-+ const char *devtype,
-+ const char *inst,
-+ const char *token)
-+{
-+ int rc = 0;
-+ char *path;
-+ path = get_device_variable_path(devtype, inst, "hotplug-status");
-+ if (path == NULL)
-+ return -1;
-+
-+ if (0 == xs_unwatch(handle, path, token))
-+ rc = -2;
-+
-+ free(path);
-+
-+ return rc;
-+}
-+
- char *xenstore_vm_read(int domid, char *key, int *len)
- {
- char *buf = NULL, *path = NULL, *value = NULL;
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:19:29.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:19:29.000000000 +0100
-@@ -1434,6 +1434,24 @@
- void xenstore_write_vncport(int vnc_display);
- int xenstore_read_vncpasswd(int domid);
-
-+int xenstore_domain_has_devtype(struct xs_handle *handle,
-+ const char *devtype);
-+char **xenstore_domain_get_devices(struct xs_handle *handle,
-+ const char *devtype, unsigned int *num);
-+char *xenstore_read_hotplug_status(struct xs_handle *handle,
-+ const char *devtype, const char *inst);
-+char *xenstore_backend_read_variable(struct xs_handle *,
-+ const char *devtype, const char *inst,
-+ const char *var);
-+int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
-+ const char *devtype,
-+ const char *inst,
-+ const char *token);
-+int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
-+ const char *devtype,
-+ const char *inst,
-+ const char *token);
-+
- int xenstore_vm_write(int domid, char *key, char *val);
- char *xenstore_vm_read(int domid, char *key, int *len);
-
diff --git a/tools/ioemu/patches/xenstore-write-vnc-port b/tools/ioemu/patches/xenstore-write-vnc-port
deleted file mode 100644
index 581724f7eb..0000000000
--- a/tools/ioemu/patches/xenstore-write-vnc-port
+++ /dev/null
@@ -1,63 +0,0 @@
-Index: ioemu/xenstore.c
-===================================================================
---- ioemu.orig/xenstore.c 2007-05-10 15:19:05.000000000 +0100
-+++ ioemu/xenstore.c 2007-05-10 15:19:05.000000000 +0100
-@@ -225,6 +225,34 @@
- free(vec);
- }
-
-+void xenstore_write_vncport(int display)
-+{
-+ char *buf = NULL, *path;
-+ char *portstr = NULL;
-+
-+ if (xsh == NULL)
-+ return;
-+
-+ path = xs_get_domain_path(xsh, domid);
-+ if (path == NULL) {
-+ fprintf(logfile, "xs_get_domain_path() error\n");
-+ goto out;
-+ }
-+
-+ if (pasprintf(&buf, "%s/console/vnc-port", path) == -1)
-+ goto out;
-+
-+ if (pasprintf(&portstr, "%d", 5900 + display) == -1)
-+ goto out;
-+
-+ if (xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)) == 0)
-+ fprintf(logfile, "xs_write() vncport failed\n");
-+
-+ out:
-+ free(portstr);
-+ free(buf);
-+}
-+
- char *xenstore_vm_read(int domid, char *key, int *len)
- {
- char *buf = NULL, *path = NULL, *value = NULL;
-Index: ioemu/vl.c
-===================================================================
---- ioemu.orig/vl.c 2007-05-10 15:19:05.000000000 +0100
-+++ ioemu/vl.c 2007-05-10 15:19:05.000000000 +0100
-@@ -7605,6 +7605,7 @@
- vnc_display_port = vnc_display_init(ds, vnc_display, vncunused);
- if (vncviewer)
- vnc_start_viewer(vnc_display_port);
-+ xenstore_write_vncport(vnc_display_port);
- } else {
- #if defined(CONFIG_SDL)
- sdl_display_init(ds, full_screen);
-Index: ioemu/vl.h
-===================================================================
---- ioemu.orig/vl.h 2007-05-10 15:19:05.000000000 +0100
-+++ ioemu/vl.h 2007-05-10 15:19:05.000000000 +0100
-@@ -1428,6 +1428,7 @@
- int xenstore_fd(void);
- void xenstore_process_event(void *opaque);
- void xenstore_check_new_media_present(int timeout);
-+void xenstore_write_vncport(int vnc_display);
-
- int xenstore_vm_write(int domid, char *key, char *val);
- char *xenstore_vm_read(int domid, char *key, int *len);
diff --git a/tools/ioemu/pc-bios/.CVS/Entries b/tools/ioemu/pc-bios/.CVS/Entries
deleted file mode 100644
index 47d7697c18..0000000000
--- a/tools/ioemu/pc-bios/.CVS/Entries
+++ /dev/null
@@ -1,17 +0,0 @@
-/Makefile/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/README/1.9/Thu May 3 17:18:04 2007//Trelease_0_9_0
-/bios.bin/1.19/Thu May 3 17:18:05 2007/-kb/Trelease_0_9_0
-/bios.diff/1.17/Thu May 3 17:18:05 2007//Trelease_0_9_0
-/linux_boot.S/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/linux_boot.bin/1.1/Thu May 3 17:18:05 2007/-kb/Trelease_0_9_0
-/ohw.diff/1.2/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/openbios-sparc32/1.3/Thu May 3 17:18:06 2007/-kb/Trelease_0_9_0
-/ppc_rom.bin/1.6/Thu May 3 17:18:09 2007/-kb/Trelease_0_9_0
-/pxe-ne2k_pci.bin/1.1/Fri Jan 5 23:48:51 2007//Trelease_0_9_0
-/pxe-pcnet.bin/1.1/Fri Jan 5 23:48:51 2007//Trelease_0_9_0
-/pxe-rtl8139.bin/1.1/Fri Jan 5 23:48:51 2007//Trelease_0_9_0
-/vgabios-cirrus.bin/1.8/Thu May 3 17:18:09 2007/-kb/Trelease_0_9_0
-/vgabios.bin/1.8/Thu May 3 17:18:10 2007/-kb/Trelease_0_9_0
-/vgabios.diff/1.5/Fri Jan 5 14:34:35 2007//Trelease_0_9_0
-/video.x/1.1/Fri Jan 5 14:34:35 2007/-kb/Trelease_0_9_0
-D
diff --git a/tools/ioemu/pc-bios/.CVS/Repository b/tools/ioemu/pc-bios/.CVS/Repository
deleted file mode 100644
index de93946755..0000000000
--- a/tools/ioemu/pc-bios/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu/pc-bios
diff --git a/tools/ioemu/pc-bios/.CVS/Root b/tools/ioemu/pc-bios/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/pc-bios/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/pc-bios/.CVS/Tag b/tools/ioemu/pc-bios/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/pc-bios/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/pc-bios/Makefile b/tools/ioemu/pc-bios/Makefile
deleted file mode 100644
index 7ae0ff02a0..0000000000
--- a/tools/ioemu/pc-bios/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# NOTE: only compilable with x86 cross compile tools
-#
-include ../config-host.mak
-
-DEFINES=
-
-TARGETS=
-ifeq ($(ARCH),i386)
-TARGETS+=linux_boot.bin
-endif
-
-all: $(TARGETS)
-
-linux_boot.bin: linux_boot.o
- ld --oformat binary -Ttext 0 -o $@ $<
- chmod a-x $@
-
-%.o: %.S
- $(CC) $(DEFINES) -c -o $@ $<
-
-clean:
- rm -f $(TARGETS) *.o *~
-
diff --git a/tools/ioemu/pc-bios/README b/tools/ioemu/pc-bios/README
deleted file mode 100644
index 45e4b7cba2..0000000000
--- a/tools/ioemu/pc-bios/README
+++ /dev/null
@@ -1,22 +0,0 @@
-- The PC BIOS comes from the Bochs project
- (http://bochs.sourceforge.net/). A patch from bios.diff was applied.
-
-- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios
- project (http://www.nongnu.org/vgabios/).
-
-- The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is
- available at http://perso.magic.fr/l_indien/OpenHackWare/index.htm.
-
-- video.x is a PowerMac NDRV compatible driver for a VGA frame
- buffer. It comes from the Mac-on-Linux project
- (http://www.maconlinux.org/).
-
-- OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable
- firmware implementation. The goal is to implement a 100% IEEE
- 1275-1994 (referred to as Open Firmware) compliant firmware.
-
-- The PXE roms come from Rom-o-Matic etherboot 5.4.2.
- pcnet32:pcnet32 -- [0x1022,0x2000]
- ns8390:winbond940 -- [0x1050,0x0940]
- rtl8139:rtl8139 -- [0x10ec,0x8139]
- http://rom-o-matic.net/
diff --git a/tools/ioemu/pc-bios/bios.diff b/tools/ioemu/pc-bios/bios.diff
deleted file mode 100644
index 86c36c11d1..0000000000
--- a/tools/ioemu/pc-bios/bios.diff
+++ /dev/null
@@ -1,35 +0,0 @@
-Index: rombios.h
-===================================================================
-RCS file: /cvsroot/bochs/bochs/bios/rombios.h,v
-retrieving revision 1.3
-diff -u -w -r1.3 rombios.h
---- rombios.h 3 Oct 2006 20:27:30 -0000 1.3
-+++ rombios.h 1 Nov 2006 19:16:34 -0000
-@@ -19,7 +19,7 @@
- // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- /* define it to include QEMU specific code */
--//#define BX_QEMU
-+#define BX_QEMU
-
- #ifndef LEGACY
- # define BX_ROMBIOS32 1
-Index: rombios32.c
-===================================================================
-RCS file: /cvsroot/bochs/bochs/bios/rombios32.c,v
-retrieving revision 1.8
-diff -u -w -r1.8 rombios32.c
---- rombios32.c 3 Oct 2006 20:27:30 -0000 1.8
-+++ rombios32.c 1 Nov 2006 19:16:34 -0000
-@@ -852,6 +852,11 @@
- int ioapic_id, i, len;
- int mp_config_table_size;
-
-+#ifdef BX_QEMU
-+ if (smp_cpus <= 1)
-+ return;
-+#endif
-+
- #ifdef BX_USE_EBDA_TABLES
- mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
- #else
diff --git a/tools/ioemu/pc-bios/linux_boot.S b/tools/ioemu/pc-bios/linux_boot.S
deleted file mode 100644
index 22fcd4be80..0000000000
--- a/tools/ioemu/pc-bios/linux_boot.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QEMU Boot sector to launch a preloaded Linux kernel
- * Copyright (c) 2004 Fabrice Bellard
- */
-
-#define LOAD_SEG 0x9000
-
-.code16
-.text
- .globl _start
-
-_start:
- cli
- cld
- mov $LOAD_SEG, %ax
- mov %ax, %ds
- mov %ax, %es
- mov %ax, %fs
- mov %ax, %gs
- mov %ax, %ss
- mov $0x8ffe, %sp
- ljmp $LOAD_SEG + 0x20, $0
-
-1:
- .fill 510 - (1b - _start), 1, 0
-
- /* boot sector signature */
- .byte 0x55
- .byte 0xaa
diff --git a/tools/ioemu/pc-bios/ohw.diff b/tools/ioemu/pc-bios/ohw.diff
deleted file mode 100644
index 4fb542274d..0000000000
--- a/tools/ioemu/pc-bios/ohw.diff
+++ /dev/null
@@ -1,1843 +0,0 @@
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bios.h OpenHackWare-release-0.4/src/bios.h
---- OpenHackWare-release-0.4.org/src/bios.h 2005-04-06 23:20:22.000000000 +0200
-+++ OpenHackWare-release-0.4/src/bios.h 2005-07-07 01:10:20.000000000 +0200
-@@ -64,6 +64,7 @@
- ARCH_CHRP,
- ARCH_MAC99,
- ARCH_POP,
-+ ARCH_HEATHROW,
- };
-
- /* Hardware definition(s) */
-@@ -174,6 +175,7 @@
- int bd_ioctl (bloc_device_t *bd, int func, void *args);
- uint32_t bd_seclen (bloc_device_t *bd);
- void bd_close (bloc_device_t *bd);
-+void bd_reset_all(void);
- uint32_t bd_seclen (bloc_device_t *bd);
- uint32_t bd_maxbloc (bloc_device_t *bd);
- void bd_sect2CHS (bloc_device_t *bd, uint32_t secnum,
-@@ -183,12 +185,12 @@
- part_t *bd_probe (int boot_device);
- bloc_device_t *bd_get (int device);
- void bd_put (bloc_device_t *bd);
--void bd_set_boot_part (bloc_device_t *bd, part_t *partition);
-+void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum);
- part_t **_bd_parts (bloc_device_t *bd);
-
- void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
- uint32_t io_base2, uint32_t io_base3,
-- void *OF_private);
-+ void *OF_private0, void *OF_private1);
- void ide_pci_pmac_register (uint32_t io_base0, uint32_t io_base1,
- void *OF_private);
-
-@@ -399,17 +401,23 @@
- uint16_t min_grant, uint16_t max_latency);
- void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses);
- void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
-- uint32_t *regions, uint32_t *sizes);
-+ uint32_t *regions, uint32_t *sizes,
-+ int irq_line);
- void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
- void *private_data);
-+void OF_finalize_pci_ide (void *dev,
-+ uint32_t io_base0, uint32_t io_base1,
-+ uint32_t io_base2, uint32_t io_base3);
- int OF_register_bus (const unsigned char *name, uint32_t address,
- const unsigned char *type);
- int OF_register_serial (const unsigned char *bus, const unsigned char *name,
- uint32_t io_base, int irq);
- int OF_register_stdio (const unsigned char *dev_in,
- const unsigned char *dev_out);
--void OF_vga_register (const unsigned char *name, uint32_t address,
-- int width, int height, int depth);
-+void OF_vga_register (const unsigned char *name, unused uint32_t address,
-+ int width, int height, int depth,
-+ unsigned long vga_bios_addr,
-+ unsigned long vga_bios_size);
- void *OF_blockdev_register (void *parent, void *private,
- const unsigned char *type,
- const unsigned char *name, int devnum,
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bloc.c OpenHackWare-release-0.4/src/bloc.c
---- OpenHackWare-release-0.4.org/src/bloc.c 2005-04-06 23:21:00.000000000 +0200
-+++ OpenHackWare-release-0.4/src/bloc.c 2005-07-08 00:28:26.000000000 +0200
-@@ -55,6 +55,7 @@
- /* Partitions */
- part_t *parts, *bparts;
- part_t *boot_part;
-+ int bpartnum;
- /* Chain */
- bloc_device_t *next;
- };
-@@ -66,6 +67,7 @@
-
- static int ide_initialize (bloc_device_t *bd, int device);
- static int ide_read_sector (bloc_device_t *bd, void *buffer, int secnum);
-+static int ide_reset (bloc_device_t *bd);
-
- static int mem_initialize (bloc_device_t *bd, int device);
- static int mem_read_sector (bloc_device_t *bd, void *buffer, int secnum);
-@@ -212,6 +214,17 @@
- {
- }
-
-+void bd_reset_all(void)
-+{
-+ bloc_device_t *bd;
-+ for (bd = bd_list; bd != NULL; bd = bd->next) {
-+ if (bd->init == &ide_initialize) {
-+ /* reset IDE drive because Darwin wants all IDE devices to be reset */
-+ ide_reset(bd);
-+ }
-+ }
-+}
-+
- uint32_t bd_seclen (bloc_device_t *bd)
- {
- return bd->seclen;
-@@ -223,10 +236,12 @@
- }
-
- /* XXX: to be suppressed */
--void bd_set_boot_part (bloc_device_t *bd, part_t *partition)
-+void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum)
- {
-+ dprintf("%s: part %p (%p) %d\n", __func__, partition, bd->boot_part, partnum);
- if (bd->boot_part == NULL) {
- bd->boot_part = partition;
-+ bd->bpartnum = partnum;
- }
- }
-
-@@ -240,6 +255,13 @@
- return &bd->bparts;
- }
-
-+void bd_set_boot_device (bloc_device_t *bd)
-+{
-+#if defined (USE_OPENFIRMWARE)
-+ OF_blockdev_set_boot_device(bd->OF_private, bd->bpartnum, "\\\\ofwboot");
-+#endif
-+}
-+
- part_t *bd_probe (int boot_device)
- {
- char devices[] = { /*'a', 'b',*/ 'c', 'd', 'e', 'f', 'm', '\0', };
-@@ -272,9 +294,7 @@
- tmp = part_probe(bd, force_raw);
- if (boot_device == bd->device) {
- boot_part = tmp;
--#if defined (USE_OPENFIRMWARE)
-- OF_blockdev_set_boot_device(bd->OF_private, 2, "\\\\ofwboot");
--#endif
-+ bd_set_boot_device(bd);
- }
- }
-
-@@ -717,34 +737,29 @@
- /* IDE PCI access for pc */
- static uint8_t ide_pci_port_read (bloc_device_t *bd, int port)
- {
-- eieio();
--
-- return *(uint8_t *)(bd->io_base + port);
-+ uint8_t value;
-+ value = inb(bd->io_base + port);
-+ return value;
- }
-
- static void ide_pci_port_write (bloc_device_t *bd, int port, uint8_t value)
- {
-- *(uint8_t *)(bd->io_base + port) = value;
-- eieio();
-+ outb(bd->io_base + port, value);
- }
-
- static uint32_t ide_pci_data_readl (bloc_device_t *bd)
- {
-- eieio();
--
-- return *((uint32_t *)bd->io_base);
-+ return inl(bd->io_base);
- }
-
- static void ide_pci_data_writel (bloc_device_t *bd, uint32_t val)
- {
-- *(uint32_t *)(bd->io_base) = val;
-- eieio();
-+ outl(bd->io_base, val);
- }
-
- static void ide_pci_control_write (bloc_device_t *bd, uint32_t val)
- {
-- *((uint8_t *)bd->tmp) = val;
-- eieio();
-+ outb(bd->tmp + 2, val);
- }
-
- static ide_ops_t ide_pci_pc_ops = {
-@@ -761,7 +776,7 @@
-
- void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
- uint32_t io_base2, uint32_t io_base3,
-- unused void *OF_private)
-+ void *OF_private0, void *OF_private1)
- {
- if (ide_pci_ops == NULL) {
- ide_pci_ops = malloc(sizeof(ide_ops_t));
-@@ -770,19 +785,19 @@
- memcpy(ide_pci_ops, &ide_pci_pc_ops, sizeof(ide_ops_t));
- }
- if ((io_base0 != 0 || io_base1 != 0) &&
-- ide_pci_ops->base[0] == 0 && ide_pci_ops->base[1] == 0) {
-+ ide_pci_ops->base[0] == 0 && ide_pci_ops->base[2] == 0) {
- ide_pci_ops->base[0] = io_base0;
-- ide_pci_ops->base[1] = io_base1;
-+ ide_pci_ops->base[2] = io_base1;
- #ifdef USE_OPENFIRMWARE
-- ide_pci_ops->OF_private[0] = OF_private;
-+ ide_pci_ops->OF_private[0] = OF_private0;
- #endif
- }
- if ((io_base2 != 0 || io_base3 != 0) &&
-- ide_pci_ops->base[2] == 0 && ide_pci_ops->base[3] == 0) {
-- ide_pci_ops->base[2] = io_base2;
-+ ide_pci_ops->base[1] == 0 && ide_pci_ops->base[3] == 0) {
-+ ide_pci_ops->base[1] = io_base2;
- ide_pci_ops->base[3] = io_base3;
- #ifdef USE_OPENFIRMWARE
-- ide_pci_ops->OF_private[1] = OF_private;
-+ ide_pci_ops->OF_private[1] = OF_private1;
- #endif
- }
- }
-@@ -935,6 +950,8 @@
- }
-
- static void atapi_pad_req (void *buffer, int len);
-+static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer,
-+ int maxlen);
- static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum);
-
- static int ide_initialize (bloc_device_t *bd, int device)
-@@ -1035,9 +1052,7 @@
- DPRINTF("INQUIRY\n");
- len = spc_inquiry_req(&atapi_buffer, 36);
- atapi_pad_req(&atapi_buffer, len);
-- ide_port_write(bd, 0x07, 0xA0);
-- for (i = 0; i < 3; i++)
-- ide_data_writel(bd, ldswap32(&atapi_buffer[i]));
-+ atapi_make_req(bd, atapi_buffer, 36);
- status = ide_port_read(bd, 0x07);
- if (status != 0x48) {
- ERROR("ATAPI INQUIRY : status %0x != 0x48\n", status);
-@@ -1053,9 +1068,7 @@
- DPRINTF("READ_CAPACITY\n");
- len = mmc_read_capacity_req(&atapi_buffer);
- atapi_pad_req(&atapi_buffer, len);
-- ide_port_write(bd, 0x07, 0xA0);
-- for (i = 0; i < 3; i++)
-- ide_data_writel(bd, ldswap32(&atapi_buffer[i]));
-+ atapi_make_req(bd, atapi_buffer, 8);
- status = ide_port_read(bd, 0x07);
- if (status != 0x48) {
- ERROR("ATAPI READ_CAPACITY : status %0x != 0x48\n", status);
-@@ -1105,6 +1118,22 @@
- memset(p + len, 0, 12 - len);
- }
-
-+static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer,
-+ int maxlen)
-+{
-+ int i;
-+ /* select drive */
-+ if (bd->drv == 0)
-+ ide_port_write(bd, 0x06, 0x40);
-+ else
-+ ide_port_write(bd, 0x06, 0x50);
-+ ide_port_write(bd, 0x04, maxlen & 0xff);
-+ ide_port_write(bd, 0x05, (maxlen >> 8) & 0xff);
-+ ide_port_write(bd, 0x07, 0xA0);
-+ for (i = 0; i < 3; i++)
-+ ide_data_writel(bd, ldswap32(&buffer[i]));
-+}
-+
- static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum)
- {
- uint32_t atapi_buffer[4];
-@@ -1112,16 +1141,9 @@
- uint32_t status, value;
- int i, len;
-
-- /* select drive */
-- if (bd->drv == 0)
-- ide_port_write(bd, 0x06, 0x40);
-- else
-- ide_port_write(bd, 0x06, 0x50);
- len = mmc_read12_req(atapi_buffer, secnum, 1);
- atapi_pad_req(&atapi_buffer, len);
-- ide_port_write(bd, 0x07, 0xA0);
-- for (i = 0; i < 3; i++)
-- ide_data_writel(bd, ldswap32(&atapi_buffer[i]));
-+ atapi_make_req(bd, atapi_buffer, bd->seclen);
- status = ide_port_read(bd, 0x07);
- if (status != 0x48) {
- ERROR("ATAPI READ12 : status %0x != 0x48\n", status);
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/apple.c OpenHackWare-release-0.4/src/libpart/apple.c
---- OpenHackWare-release-0.4.org/src/libpart/apple.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/apple.c 2005-07-03 16:17:41.000000000 +0200
-@@ -199,14 +199,18 @@
- if (len == 0) {
- /* Place holder. Skip it */
- DPRINTF("%s placeholder part\t%d\n", __func__, i);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Void", type, 32) == 0) {
- /* Void partition. Skip it */
- DPRINTF("%s Void part\t%d [%s]\n", __func__, i, type);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Free", type, 32) == 0) {
- /* Free space. Skip it */
- DPRINTF("%s Free part (%d)\n", __func__, i);
- part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_partition_map", type, 32) == 0 ||
- strncmp("Apple_Partition_Map", type, 32) == 0
- #if 0 // Is this really used or is it just a mistake ?
-@@ -226,7 +230,7 @@
- */
- }
- part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Driver", type, 32) == 0 ||
- strncmp("Apple_Driver43", type, 32) == 0 ||
- strncmp("Apple_Driver43_CD", type, 32) == 0 ||
-@@ -236,8 +240,12 @@
- strncmp("Apple_Driver_IOKit", type, 32) == 0) {
- /* Drivers. don't care for now */
- DPRINTF("%s Drivers part\t%d [%s]\n", __func__, i, type);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DRIVER;
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Patches", type, 32) == 0) {
- /* Patches: don't care for now */
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_PATCH;
-+ part_register(bd, part, name, i);
- DPRINTF("%s Patches part\t%d [%s]\n", __func__, i, type);
- } else if (strncmp("Apple_HFS", type, 32) == 0 ||
- strncmp("Apple_MFS", type, 32) == 0 ||
-@@ -256,9 +264,8 @@
- count = partmap->bloc_cnt * HFS_BLOCSIZE;
- if (partmap->boot_size == 0 || partmap->boot_load == 0) {
- printf("Not a bootable partition %d %d (%p %p)\n",
-- partmap->boot_size, partmap->boot_load,boot_part, part);
-- if (boot_part == NULL)
-- boot_part = part;
-+ partmap->boot_size, partmap->boot_load,
-+ boot_part, part);
- part->flags = PART_TYPE_APPLE | PART_FLAG_FS;
- } else {
- part->boot_start.bloc = partmap->boot_start;
-@@ -278,8 +285,8 @@
- boot_part = part;
- part->flags = PART_TYPE_APPLE | PART_FLAG_FS | PART_FLAG_BOOT;
- }
-- printf("Partition: %d %s st %0x size %0x",
-- i, name, partmap->start_bloc, partmap->bloc_cnt);
-+ printf("Partition: %d '%s' '%s' st %0x size %0x",
-+ i, name, type, partmap->start_bloc, partmap->bloc_cnt);
- #ifndef DEBUG
- printf("\n");
- #endif
-@@ -290,11 +297,13 @@
- part->boot_load, part->boot_entry);
- DPRINTF(" load %0x entry %0x %0x\n",
- partmap->boot_load2, partmap->boot_entry2, HFS_BLOCSIZE);
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i);
- } else {
- memcpy(tmp, type, 32);
- tmp[32] = '\0';
- ERROR("Unknown partition type [%s]\n", tmp);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-+ part_register(bd, part, name, i);
- }
- }
- error:
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/core.c OpenHackWare-release-0.4/src/libpart/core.c
---- OpenHackWare-release-0.4.org/src/libpart/core.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/core.c 2005-07-03 16:17:41.000000000 +0200
-@@ -126,7 +126,7 @@
- }
-
- int part_register (bloc_device_t *bd, part_t *partition,
-- const unsigned char *name)
-+ const unsigned char *name, int partnum)
- {
- part_t **cur;
-
-@@ -134,6 +134,7 @@
- partition->bd = bd;
- partition->next = NULL;
- partition->name = strdup(name);
-+ partition->partnum = partnum;
- for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next)
- continue;
- *cur = partition;
-@@ -141,29 +142,15 @@
- return 0;
- }
-
--static inline int set_boot_part (bloc_device_t *bd, int partnum)
--{
-- part_t *cur;
--
-- cur = part_get(bd, partnum);
-- if (cur == NULL)
-- return -1;
-- bd_set_boot_part(bd, cur);
--
-- return 0;
--}
--
- part_t *part_get (bloc_device_t *bd, int partnum)
- {
- part_t **listp, *cur;
-- int i;
-
- listp = _bd_parts(bd);
-- cur = *listp;
-- for (i = 0; i != partnum; i++) {
-- if (cur == NULL)
-+
-+ for (cur = *listp; cur != NULL; cur = cur->next) {
-+ if (cur->partnum == partnum)
- break;
-- cur = cur->next;
- }
-
- return cur;
-@@ -192,17 +179,20 @@
- part_set_blocsize(bd, part, 512);
- part->bd = bd;
- part->flags = PART_TYPE_RAW | PART_FLAG_BOOT;
-- part_register(bd, part, "Raw");
-+ part_register(bd, part, "Raw", 0);
-
- return part;
- }
-
-+bloc_device_t *part_get_bd (part_t *part)
-+{
-+ return part->bd;
-+}
-+
- part_t *part_probe (bloc_device_t *bd, int set_raw)
- {
-- part_t *part0, *boot_part, **cur;
-+ part_t *part0 = NULL, *boot_part, **cur;
-
-- /* Register the 0 partition: raw partition containing the whole disk */
-- part0 = part_get_raw(bd);
- /* Try to find a valid boot partition */
- boot_part = Apple_probe_partitions(bd);
- if (boot_part == NULL) {
-@@ -210,10 +200,13 @@
- if (boot_part == NULL && arch == ARCH_PREP)
- boot_part = PREP_find_partition(bd);
- if (boot_part == NULL && set_raw != 0) {
-- boot_part = part0;
-- set_boot_part(bd, 0);
-+ dprintf("Use bloc device as raw partition\n");
- }
- }
-+ if (_bd_parts(bd) == NULL) {
-+ /* Register the 0 partition: raw partition containing the whole disk */
-+ part0 = part_get_raw(bd);
-+ }
- /* Probe filesystem on each found partition */
- for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) {
- const unsigned char *map, *type;
-@@ -248,23 +241,28 @@
- type = "unknown";
- break;
- }
-- DPRINTF("Probe filesystem on %s %s partition '%s' %s\n",
-+ dprintf("Probe filesystem on %s %s partition '%s' %s %p\n",
- type, map, (*cur)->name,
-- ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "");
-+ ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "", *cur);
- if (((*cur)->flags) & PART_FLAG_FS) {
- if (((*cur)->flags) & PART_FLAG_BOOT)
- (*cur)->fs = fs_probe(*cur, 1);
- else
- (*cur)->fs = fs_probe(*cur, 0);
-+ } else if (((*cur)->flags) & PART_TYPE_RAW) {
-+ (*cur)->fs = fs_probe(*cur, 2);
- } else {
- (*cur)->fs = fs_probe(*cur, 2);
- }
-- if (((*cur)->flags) & PART_FLAG_BOOT) {
-- bd_set_boot_part(bd, *cur);
- fs_get_bootfile((*cur)->fs);
-+ if (((*cur)->flags) & PART_FLAG_BOOT) {
-+ dprintf("Partition is bootable (%d)\n", (*cur)->partnum);
-+ bd_set_boot_part(bd, *cur, (*cur)->partnum);
-+ if (boot_part == NULL)
-+ boot_part = *cur;
- }
- }
-- DPRINTF("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs,
-+ dprintf("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs,
- part_fs(boot_part), part0);
-
- return boot_part;
-@@ -279,6 +277,7 @@
- part->boot_size.offset = 0;
- part->boot_load = 0;
- part->boot_entry = 0;
-+ part->flags |= PART_FLAG_BOOT;
-
- return 0;
- }
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/isofs.c OpenHackWare-release-0.4/src/libpart/isofs.c
---- OpenHackWare-release-0.4.org/src/libpart/isofs.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/isofs.c 2005-07-03 16:17:41.000000000 +0200
-@@ -242,7 +242,7 @@
- part->boot_start.bloc, part->boot_size.bloc,
- part->boot_load, part->boot_entry);
- part->flags = PART_TYPE_ISO9660 | PART_FLAG_BOOT;
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i + 1);
- fs_raw_set_bootfile(part, part->boot_start.bloc,
- part->boot_start.offset,
- part->boot_size.bloc,
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/libpart.h OpenHackWare-release-0.4/src/libpart/libpart.h
---- OpenHackWare-release-0.4.org/src/libpart/libpart.h 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/libpart.h 2005-07-03 16:17:41.000000000 +0200
-@@ -30,6 +30,7 @@
-
- struct part_t {
- bloc_device_t *bd;
-+ int partnum;
- uint32_t start; /* Partition first bloc */
- uint32_t size; /* Partition size, in blocs */
- uint32_t spb;
-@@ -54,7 +55,7 @@
- };
-
- int part_register (bloc_device_t *bd, part_t *partition,
-- const unsigned char *name);
-+ const unsigned char *name, int partnum);
- void part_set_blocsize (bloc_device_t *bd, part_t *part, uint32_t blocsize);
- void part_private_set (part_t *part, void *private);
- void *part_private_get (part_t *part);
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/prep.c OpenHackWare-release-0.4/src/libpart/prep.c
---- OpenHackWare-release-0.4.org/src/libpart/prep.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/prep.c 2005-07-03 16:17:41.000000000 +0200
-@@ -164,7 +164,7 @@
- part->boot_load = 0;
- part->boot_entry = boot_offset - part->bloc_size;
- part->flags = PART_TYPE_PREP | PART_FLAG_BOOT;
-- part_register(bd, part, "PREP boot");
-+ part_register(bd, part, "PREP boot", i);
- fs_raw_set_bootfile(part, part->boot_start.bloc,
- part->boot_start.offset,
- part->boot_size.bloc,
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/main.c OpenHackWare-release-0.4/src/main.c
---- OpenHackWare-release-0.4.org/src/main.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/main.c 2005-06-07 23:48:39.000000000 +0200
-@@ -364,20 +364,24 @@
- void *load_base, *load_entry, *last_alloc, *load_end;
- uint32_t memsize, boot_image_size, cmdline_size, ramdisk_size;
- uint32_t boot_base, boot_nb;
-- int boot_device;
-+ int boot_device, i;
-+ static const uint32_t isa_base_tab[3] = {
-+ 0x80000000, /* PREP */
-+ 0xFE000000, /* Grackle (Heathrow) */
-+ 0xF2000000, /* UniNorth (Mac99) */
-+ };
-
- /* Retrieve NVRAM configuration */
-- nvram_retry:
-+ for(i = 0; i < 3; i++) {
-+ isa_io_base = isa_base_tab[i];
- nvram = NVRAM_get_config(&memsize, &boot_device,
- &boot_image, &boot_image_size,
- &cmdline, &cmdline_size,
- &ramdisk, &ramdisk_size);
-- if (nvram == NULL) {
-- /* Retry with another isa_io_base */
-- if (isa_io_base == 0x80000000) {
-- isa_io_base = 0xF2000000;
-- goto nvram_retry;
-+ if (nvram)
-+ break;
- }
-+ if (i == 3) {
- ERROR("Unable to load configuration from NVRAM. Aborting...\n");
- return -1;
- }
-@@ -402,7 +406,7 @@
- cpu_name = CPU_get_name(pvr);
- OF_register_cpu(cpu_name, 0, pvr,
- 200 * 1000 * 1000, 200 * 1000 * 1000,
-- 100 * 1000 * 1000, 10 * 1000 * 1000,
-+ 100 * 1000 * 1000, 100 * 1000 * 1000,
- 0x0092);
- }
- OF_register_memory(memsize, 512 * 1024 /* TOFIX */);
-@@ -433,9 +437,12 @@
- vga_puts(copyright);
- vga_puts("\n");
-
-+#if 0
- /* QEMU is quite incoherent: d is cdrom, not second drive */
-+ /* XXX: should probe CD-ROM position */
- if (boot_device == 'd')
- boot_device = 'e';
-+#endif
- /* Open boot device */
- boot_part = bd_probe(boot_device);
- if (boot_device == 'm') {
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/nvram.c OpenHackWare-release-0.4/src/nvram.c
---- OpenHackWare-release-0.4.org/src/nvram.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/nvram.c 2005-06-04 23:44:03.000000000 +0200
-@@ -334,6 +334,7 @@
- ret = NVRAM_chrp_format(nvram);
- break;
- case ARCH_MAC99:
-+ case ARCH_HEATHROW: /* XXX: may be incorrect */
- ret = NVRAM_mac99_format(nvram);
- break;
- case ARCH_POP:
-@@ -409,13 +410,12 @@
- arch = ARCH_MAC99;
- } else if (strcmp(sign, "POP") == 0) {
- arch = ARCH_POP;
-+ } else if (strcmp(sign, "HEATHROW") == 0) {
-+ arch = ARCH_HEATHROW;
- } else {
- ERROR("Unknown PPC architecture: '%s'\n", sign);
- return NULL;
- }
-- /* HACK */
-- if (arch == ARCH_CHRP)
-- arch = ARCH_MAC99;
- lword = NVRAM_get_lword(nvram, 0x30);
- *RAM_size = lword;
- byte = NVRAM_get_byte(nvram, 0x34);
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/of.c OpenHackWare-release-0.4/src/of.c
---- OpenHackWare-release-0.4.org/src/of.c 2005-04-06 23:17:26.000000000 +0200
-+++ OpenHackWare-release-0.4/src/of.c 2005-07-07 23:30:08.000000000 +0200
-@@ -489,7 +489,7 @@
- ERROR("%s can't alloc new node '%s' name\n", __func__, name);
- return NULL;
- }
-- new->prop_address = OF_prop_int_new(env, new, "address", address);
-+ new->prop_address = OF_prop_int_new(env, new, "unit-address", address);
- if (new->prop_address == NULL) {
- free(new->prop_name->value);
- free(new->prop_name);
-@@ -1017,6 +1017,33 @@
- string, strlen(string) + 1);
- }
-
-+/* convert '\1' char to '\0' */
-+static OF_prop_t *OF_prop_string_new1 (OF_env_t *env, OF_node_t *node,
-+ const unsigned char *name,
-+ const unsigned char *string)
-+{
-+ int len, i;
-+ OF_prop_t *ret;
-+ unsigned char *str;
-+
-+ if (strchr(string, '\1') == NULL) {
-+ return OF_prop_string_new(env, node, name, string);
-+ } else {
-+ len = strlen(string) + 1;
-+ str = malloc(len);
-+ if (!str)
-+ return NULL;
-+ memcpy(str, string, len);
-+ for(i = 0; i < len; i++)
-+ if (str[i] == '\1')
-+ str[i] = '\0';
-+ ret = OF_property_new(env, node, name,
-+ str, len);
-+ free(str);
-+ return ret;
-+ }
-+}
-+
- __attribute__ (( section (".OpenFirmware") ))
- static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node,
- const unsigned char *name, uint32_t value)
-@@ -1421,15 +1448,12 @@
- __attribute__ (( section (".OpenFirmware") ))
- int OF_init (void)
- {
-- const unsigned char compat_str[] =
- #if 0
- "PowerMac3,1\0MacRISC\0Power Macintosh\0";
- "PowerMac1,2\0MacRISC\0Power Macintosh\0";
- "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0";
- "AAPL,PowerMac3,0\0MacRISC\0Power Macintosh\0";
- "AAPL,Gossamer\0MacRISC\0Power Macintosh\0";
--#else
-- "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0";
- #endif
- OF_env_t *OF_env;
- OF_node_t *als, *opt, *chs, *pks;
-@@ -1455,15 +1479,21 @@
- return -1;
- }
- OF_prop_string_new(OF_env, OF_node_root, "device_type", "bootrom");
--#if 0
-- OF_prop_string_new(OF_env, OF_node_root,
-- "model", "PPC Open Hack'Ware " BIOS_VERSION);
--#else
-+ if (arch == ARCH_HEATHROW) {
-+ const unsigned char compat_str[] =
-+ "PowerMac1,1\0MacRISC\0Power Macintosh";
-+ OF_property_new(OF_env, OF_node_root, "compatible",
-+ compat_str, sizeof(compat_str));
- OF_prop_string_new(OF_env, OF_node_root,
-- "model", compat_str);
--#endif
-+ "model", "Power Macintosh");
-+ } else {
-+ const unsigned char compat_str[] =
-+ "PowerMac3,1\0MacRISC\0Power Macintosh";
- OF_property_new(OF_env, OF_node_root, "compatible",
- compat_str, sizeof(compat_str));
-+ OF_prop_string_new(OF_env, OF_node_root,
-+ "model", "PowerMac3,1");
-+ }
- #if 0
- OF_prop_string_new(OF_env, OF_node_root, "copyright", copyright);
- #else
-@@ -1561,14 +1591,15 @@
- range.size = 0x00800000;
- OF_property_new(OF_env, rom, "ranges", &range, sizeof(OF_range_t));
- OF_prop_int_new(OF_env, rom, "#address-cells", 1);
-+
- /* "/rom/boot-rom@fff00000" node */
-- brom = OF_node_new(OF_env, OF_node_root, "boot-rom", 0xfff00000);
-+ brom = OF_node_new(OF_env, rom, "boot-rom", 0xfff00000);
- if (brom == NULL) {
- ERROR("Cannot create 'boot-rom'\n");
- return -1;
- }
- regs.address = 0xFFF00000;
-- regs.size = 0x00010000;
-+ regs.size = 0x00100000;
- OF_property_new(OF_env, brom, "reg", &regs, sizeof(OF_regprop_t));
- OF_prop_string_new(OF_env, brom, "write-characteristic", "flash");
- OF_prop_string_new(OF_env, brom, "BootROM-build-date",
-@@ -1577,7 +1608,7 @@
- OF_prop_string_new(OF_env, brom, "copyright", copyright);
- OF_prop_string_new(OF_env, brom, "model", BIOS_str);
- OF_prop_int_new(OF_env, brom, "result", 0);
--#if 0
-+#if 1
- {
- /* Hack taken 'as-is' from PearPC */
- unsigned char info[] = {
-@@ -1596,7 +1627,9 @@
- OF_node_put(OF_env, brom);
- OF_node_put(OF_env, rom);
- }
-+#if 0
- /* From here, hardcoded hacks to get a Mac-like machine */
-+ /* XXX: Core99 does not seem to like this NVRAM tree */
- /* "/nvram@fff04000" node */
- {
- OF_regprop_t regs;
-@@ -1617,6 +1650,7 @@
- OF_prop_int_new(OF_env, chs, "nvram", OF_pack_handle(OF_env, nvr));
- OF_node_put(OF_env, nvr);
- }
-+#endif
- /* "/pseudo-hid" : hid emulation as Apple does */
- {
- OF_node_t *hid;
-@@ -1663,7 +1697,27 @@
- }
- OF_node_put(OF_env, hid);
- }
-+ if (arch == ARCH_MAC99) {
-+ OF_node_t *unin;
-+ OF_regprop_t regs;
-
-+ unin = OF_node_new(OF_env, OF_node_root,
-+ "uni-n", 0xf8000000);
-+ if (unin == NULL) {
-+ ERROR("Cannot create 'uni-n'\n");
-+ return -1;
-+ }
-+ OF_prop_string_new(OF_env, unin, "device-type", "memory-controller");
-+ OF_prop_string_new(OF_env, unin, "model", "AAPL,UniNorth");
-+ OF_prop_string_new(OF_env, unin, "compatible", "uni-north");
-+ regs.address = 0xf8000000;
-+ regs.size = 0x01000000;
-+ OF_property_new(OF_env, unin, "reg", &regs, sizeof(regs));
-+ OF_prop_int_new(OF_env, unin, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, unin, "#size-cells", 1);
-+ OF_prop_int_new(OF_env, unin, "device-rev", 3);
-+ OF_node_put(OF_env, unin);
-+ }
-
- #if 1 /* This is mandatory for claim to work
- * but I don't know where it should really be (in cpu ?)
-@@ -1693,7 +1747,9 @@
-
- /* "/options/boot-args" node */
- {
-- const unsigned char *args = "-v rootdev cdrom";
-+ // const unsigned char *args = "-v rootdev cdrom";
-+ //const unsigned char *args = "-v io=0xffffffff";
-+ const unsigned char *args = "-v";
- /* Ask MacOS X to print debug messages */
- // OF_prop_string_new(OF_env, chs, "machargs", args);
- // OF_prop_string_new(OF_env, opt, "boot-command", args);
-@@ -2013,17 +2069,17 @@
- OF_prop_int_new(OF_env, node, "min-grant", min_grant);
- OF_prop_int_new(OF_env, node, "max-latency", max_latency);
- if (dev->type != NULL)
-- OF_prop_string_new(OF_env, node, "device_type", dev->type);
-+ OF_prop_string_new1(OF_env, node, "device_type", dev->type);
- if (dev->compat != NULL)
-- OF_prop_string_new(OF_env, node, "compatible", dev->compat);
-+ OF_prop_string_new1(OF_env, node, "compatible", dev->compat);
- if (dev->model != NULL)
-- OF_prop_string_new(OF_env, node, "model", dev->model);
-+ OF_prop_string_new1(OF_env, node, "model", dev->model);
- if (dev->acells != 0)
- OF_prop_int_new(OF_env, node, "#address-cells", dev->acells);
- if (dev->scells != 0)
-- OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->acells);
-+ OF_prop_int_new(OF_env, node, "#size-cells", dev->scells);
- if (dev->icells != 0)
-- OF_prop_int_new(OF_env, node, "#size-cells", dev->acells);
-+ OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->icells);
- dprintf("Done %p %p\n", parent, node);
-
- return node;
-@@ -2040,8 +2096,9 @@
- OF_env_t *OF_env;
- pci_range_t ranges[3];
- OF_regprop_t regs[1];
-- OF_node_t *pci_host;
-+ OF_node_t *pci_host, *als;
- int nranges;
-+ unsigned char buffer[OF_NAMELEN_MAX];
-
- OF_env = OF_env_main;
- dprintf("register PCI host '%s' '%s' '%s' '%s'\n",
-@@ -2052,6 +2109,17 @@
- ERROR("Cannot create pci host\n");
- return NULL;
- }
-+
-+ als = OF_node_get(OF_env, "aliases");
-+ if (als == NULL) {
-+ ERROR("Cannot get 'aliases'\n");
-+ return NULL;
-+ }
-+ sprintf(buffer, "/%s", dev->name);
-+ OF_prop_string_set(OF_env, als, "pci", buffer);
-+ OF_node_put(OF_env, als);
-+
-+
- regs[0].address = cfg_base;
- regs[0].size = cfg_len;
- OF_property_new(OF_env, pci_host, "reg", regs, sizeof(OF_regprop_t));
-@@ -2136,6 +2204,11 @@
- return pci_dev;
- }
-
-+/* XXX: suppress that, used for interrupt map init */
-+OF_node_t *pci_host_node;
-+uint32_t pci_host_interrupt_map[7 * 32];
-+int pci_host_interrupt_map_len = 0;
-+
- void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses)
- {
- OF_env_t *OF_env;
-@@ -2145,10 +2218,12 @@
- regs[0].address = first_bus;
- regs[0].size = nb_busses;
- OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t));
-+ pci_host_node = dev;
- }
-
- void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
-- uint32_t *regions, uint32_t *sizes)
-+ uint32_t *regions, uint32_t *sizes,
-+ int irq_line)
- {
- OF_env_t *OF_env;
- pci_reg_prop_t pregs[6], rregs[6];
-@@ -2156,6 +2231,7 @@
- int i, j, k;
-
- OF_env = OF_env_main;
-+ /* XXX: only useful for VGA card in fact */
- if (regions[0] != 0x00000000)
- OF_prop_int_set(OF_env, dev, "address", regions[0] & ~0x0000000F);
- for (i = 0, j = 0, k = 0; i < 6; i++) {
-@@ -2222,7 +2298,22 @@
- } else {
- OF_property_new(OF_env, dev, "assigned-addresses", NULL, 0);
- }
--#if 0
-+ if (irq_line >= 0) {
-+ int i;
-+ OF_prop_int_new(OF_env, dev, "interrupts", 1);
-+ i = pci_host_interrupt_map_len;
-+ pci_host_interrupt_map[i++] = (devfn << 8) & 0xf800;
-+ pci_host_interrupt_map[i++] = 0;
-+ pci_host_interrupt_map[i++] = 0;
-+ pci_host_interrupt_map[i++] = 0;
-+ pci_host_interrupt_map[i++] = 0; /* pic handle will be patched later */
-+ pci_host_interrupt_map[i++] = irq_line;
-+ if (arch != ARCH_HEATHROW) {
-+ pci_host_interrupt_map[i++] = 1;
-+ }
-+ pci_host_interrupt_map_len = i;
-+ }
-+#if 1
- {
- OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name;
-
-@@ -2390,6 +2481,54 @@
- return 0;
- }
-
-+static void keylargo_ata(OF_node_t *mio, uint32_t base_address,
-+ uint32_t base, int irq1, int irq2,
-+ uint16_t pic_phandle)
-+{
-+ OF_env_t *OF_env = OF_env_main;
-+ OF_node_t *ata;
-+ OF_regprop_t regs[2];
-+
-+ ata = OF_node_new(OF_env, mio, "ata-4", base);
-+ if (ata == NULL) {
-+ ERROR("Cannot create 'ata-4'\n");
-+ return;
-+ }
-+ OF_prop_string_new(OF_env, ata, "device_type", "ata");
-+#if 1
-+ OF_prop_string_new(OF_env, ata, "compatible", "key2largo-ata");
-+ OF_prop_string_new(OF_env, ata, "model", "ata-4");
-+ OF_prop_string_new(OF_env, ata, "cable-type", "80-conductor");
-+#else
-+ OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-+ OF_prop_string_new(OF_env, ata, "model", "ata-4");
-+#endif
-+ OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-+ regs[0].address = base;
-+ regs[0].size = 0x00001000;
-+#if 0 // HACK: Don't set up DMA registers
-+ regs[1].address = 0x00008A00;
-+ regs[1].size = 0x00001000;
-+ OF_property_new(OF_env, ata, "reg",
-+ regs, 2 * sizeof(OF_regprop_t));
-+#else
-+ OF_property_new(OF_env, ata, "reg",
-+ regs, sizeof(OF_regprop_t));
-+#endif
-+ OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle);
-+ regs[0].address = irq1;
-+ regs[0].size = 0x00000001;
-+ regs[1].address = irq2;
-+ regs[1].size = 0x00000000;
-+ OF_property_new(OF_env, ata, "interrupts",
-+ regs, 2 * sizeof(OF_regprop_t));
-+ if (base == 0x1f000)
-+ ide_pci_pmac_register(base_address + base, 0x00000000, ata);
-+ else
-+ ide_pci_pmac_register(0x00000000, base_address + base, ata);
-+}
-+
- void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
- void *private_data)
- {
-@@ -2398,6 +2537,8 @@
- pci_reg_prop_t pregs[2];
- OF_node_t *mio, *chs, *als;
- uint16_t pic_phandle;
-+ int rec_len;
-+ OF_prop_t *mio_reg;
-
- OF_DPRINTF("mac-io: %p\n", dev);
- OF_env = OF_env_main;
-@@ -2416,10 +2557,14 @@
- mio = dev;
- mio->private_data = private_data;
- pregs[0].addr.hi = 0x00000000;
-- pregs[0].addr.mid = 0x82013810;
-+ pregs[0].addr.mid = 0x00000000;
- pregs[0].addr.lo = 0x00000000;
- pregs[0].size_hi = base_address;
- pregs[0].size_lo = size;
-+ mio_reg = OF_property_get(OF_env, mio, "reg");
-+ if (mio_reg && mio_reg->vlen >= 5 * 4) {
-+ pregs[0].addr.mid = ((pci_reg_prop_t *)mio_reg->value)->addr.hi;
-+ }
- OF_property_new(OF_env, mio, "ranges",
- &pregs, sizeof(pci_reg_prop_t));
- #if 0
-@@ -2431,8 +2576,32 @@
- OF_property_new(OF_env, mio, "assigned-addresses",
- &pregs, sizeof(pci_reg_prop_t));
- #endif
-+
-+ if (arch == ARCH_HEATHROW) {
-+ /* Heathrow PIC */
-+ OF_regprop_t regs;
-+ OF_node_t *mpic;
-+ const char compat_str[] = "heathrow\0mac-risc";
-+
-+ mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x10);
-+ if (mpic == NULL) {
-+ ERROR("Cannot create 'mpic'\n");
-+ goto out;
-+ }
-+ OF_prop_string_new(OF_env, mpic, "device_type", "interrupt-controller");
-+ OF_property_new(OF_env, mpic, "compatible", compat_str, sizeof(compat_str));
-+ OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 1);
-+ regs.address = 0x10;
-+ regs.size = 0x20;
-+ OF_property_new(OF_env, mpic, "reg",
-+ &regs, sizeof(regs));
-+ OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0);
-+ pic_phandle = OF_pack_handle(OF_env, mpic);
-+ OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle);
-+ OF_node_put(OF_env, mpic);
-+ rec_len = 6;
-+ } else {
- /* OpenPIC */
-- {
- OF_regprop_t regs[4];
- OF_node_t *mpic;
- mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x40000);
-@@ -2455,8 +2624,37 @@
- pic_phandle = OF_pack_handle(OF_env, mpic);
- OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle);
- OF_node_put(OF_env, mpic);
-+ rec_len = 7;
- }
--#if 1
-+
-+ /* patch pci host table */
-+ /* XXX: do it after the PCI init */
-+ {
-+ int i;
-+ uint32_t tab[4];
-+
-+ for(i = 0; i < pci_host_interrupt_map_len; i += rec_len)
-+ pci_host_interrupt_map[i + 4] = pic_phandle;
-+#if 0
-+ dprintf("interrupt-map:\n");
-+ for(i = 0; i < pci_host_interrupt_map_len; i++) {
-+ dprintf(" %08x", pci_host_interrupt_map[i]);
-+ if ((i % rec_len) == (rec_len - 1))
-+ dprintf("\n");
-+ }
-+ dprintf("\n");
-+#endif
-+ OF_property_new(OF_env, pci_host_node, "interrupt-map",
-+ pci_host_interrupt_map,
-+ pci_host_interrupt_map_len * sizeof(uint32_t));
-+ tab[0] = 0xf800;
-+ tab[1] = 0;
-+ tab[2] = 0;
-+ tab[3] = 0;
-+ OF_property_new(OF_env, pci_host_node, "interrupt-map-mask",
-+ tab, 4 * sizeof(uint32_t));
-+ }
-+#if 0
- /* escc is usefull to get MacOS X debug messages */
- {
- OF_regprop_t regs[8];
-@@ -2645,85 +2843,12 @@
- OF_node_put(OF_env, scc);
- }
- #endif
-- /* IDE controller */
-- {
-- OF_node_t *ata;
-- OF_regprop_t regs[2];
-- ata = OF_node_new(OF_env, mio, "ata-4", 0x1f000);
-- if (ata == NULL) {
-- ERROR("Cannot create 'ata-4'\n");
-- goto out;
-- }
-- OF_prop_string_new(OF_env, ata, "device_type", "ata");
--#if 1
-- OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#else
-- OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#endif
-- OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-- OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-- regs[0].address = 0x0001F000;
-- regs[0].size = 0x00001000;
--#if 0 // HACK: Don't set up DMA registers
-- regs[1].address = 0x00008A00;
-- regs[1].size = 0x00001000;
-- OF_property_new(OF_env, ata, "reg",
-- regs, 2 * sizeof(OF_regprop_t));
--#else
-- OF_property_new(OF_env, ata, "reg",
-- regs, sizeof(OF_regprop_t));
--#endif
-- OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle);
-- regs[0].address = 0x00000013;
-- regs[0].size = 0x00000001;
-- regs[1].address = 0x0000000B;
-- regs[1].size = 0x00000000;
-- OF_property_new(OF_env, ata, "interrupts",
-- regs, 2 * sizeof(OF_regprop_t));
-- ide_pci_pmac_register(base_address + 0x1f000, 0x00000000, ata);
--
-- }
-- {
-- OF_node_t *ata;
-- OF_regprop_t regs[2];
-- ata = OF_node_new(OF_env, mio, "ata-4", 0x20000);
-- if (ata == NULL) {
-- ERROR("Cannot create 'ata-4'\n");
-- goto out;
-- }
-- OF_prop_string_new(OF_env, ata, "device_type", "ata");
--#if 1
-- OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#else
-- OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#endif
-- OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-- OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-- regs[0].address = 0x00020000;
-- regs[0].size = 0x00001000;
--#if 0 // HACK: Don't set up DMA registers
-- regs[1].address = 0x00008A00;
-- regs[1].size = 0x00001000;
-- OF_property_new(OF_env, ata, "reg",
-- regs, 2 * sizeof(OF_regprop_t));
--#else
-- OF_property_new(OF_env, ata, "reg",
-- regs, sizeof(OF_regprop_t));
--#endif
-- OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle);
-- regs[0].address = 0x00000014;
-- regs[0].size = 0x00000001;
-- regs[1].address = 0x0000000B;
-- regs[1].size = 0x00000000;
-- OF_property_new(OF_env, ata, "interrupts",
-- regs, 2 * sizeof(OF_regprop_t));
-- ide_pci_pmac_register(0x00000000, base_address + 0x20000, ata);
--
-+ /* Keylargo IDE controller: need some work (DMA problem ?) */
-+ if (arch == ARCH_MAC99) {
-+ keylargo_ata(mio, base_address, 0x1f000, 0x13, 0xb, pic_phandle);
-+ keylargo_ata(mio, base_address, 0x20000, 0x14, 0xb, pic_phandle);
- }
-+#if 0
- /* Timer */
- {
- OF_node_t *tmr;
-@@ -2746,10 +2871,11 @@
- regs, sizeof(OF_regprop_t));
- OF_node_put(OF_env, tmr);
- }
-+#endif
- /* VIA-PMU */
- {
- /* Controls adb, RTC and power-mgt (forget it !) */
-- OF_node_t *via, *adb, *rtc;
-+ OF_node_t *via, *adb;
- OF_regprop_t regs[1];
- #if 0 // THIS IS A HACK AND IS COMPLETELY ABSURD !
- // (but needed has Qemu doesn't emulate via-pmu).
-@@ -2773,14 +2899,21 @@
- regs[0].size = 0x00002000;
- OF_property_new(OF_env, via, "reg", regs, sizeof(OF_regprop_t));
- OF_prop_int_new(OF_env, via, "interrupt-parent", pic_phandle);
-+ if (arch == ARCH_HEATHROW) {
-+ OF_prop_int_new(OF_env, via, "interrupts", 0x12);
-+ } else {
- regs[0].address = 0x00000019;
- regs[0].size = 0x00000001;
- OF_property_new(OF_env, via, "interrupts",
- regs, sizeof(OF_regprop_t));
-+ }
-+ /* force usage of OF bus speeds */
-+ OF_prop_int_new(OF_env, via, "BusSpeedCorrect", 1);
- #if 0
- OF_prop_int_new(OF_env, via, "pmu-version", 0x00D0740C);
- #endif
--#if 1
-+ {
-+ OF_node_t *kbd, *mouse;
- /* ADB pseudo-device */
- adb = OF_node_new(OF_env, via, "adb", OF_ADDRESS_NONE);
- if (adb == NULL) {
-@@ -2797,9 +2930,26 @@
- OF_prop_int_new(OF_env, adb, "#size-cells", 0);
- OF_pack_get_path(OF_env, tmp, 512, adb);
- OF_prop_string_new(OF_env, als, "adb", tmp);
-- /* XXX: add "keyboard@2" and "mouse@3" */
-- OF_node_put(OF_env, adb);
--#endif
-+
-+ kbd = OF_node_new(OF_env, adb, "keyboard", 2);
-+ if (kbd == NULL) {
-+ ERROR("Cannot create 'kbd'\n");
-+ goto out;
-+ }
-+ OF_prop_string_new(OF_env, kbd, "device_type", "keyboard");
-+ OF_prop_int_new(OF_env, kbd, "reg", 2);
-+
-+ mouse = OF_node_new(OF_env, adb, "mouse", 3);
-+ if (mouse == NULL) {
-+ ERROR("Cannot create 'mouse'\n");
-+ goto out;
-+ }
-+ OF_prop_string_new(OF_env, mouse, "device_type", "mouse");
-+ OF_prop_int_new(OF_env, mouse, "reg", 3);
-+ OF_prop_int_new(OF_env, mouse, "#buttons", 3);
-+ }
-+ {
-+ OF_node_t *rtc;
-
- rtc = OF_node_new(OF_env, via, "rtc", OF_ADDRESS_NONE);
- if (rtc == NULL) {
-@@ -2813,14 +2963,68 @@
- OF_prop_string_new(OF_env, rtc, "compatible", "rtc");
- #endif
- OF_node_put(OF_env, rtc);
-- OF_node_put(OF_env, via);
- }
-+ // OF_node_put(OF_env, via);
-+ }
-+ {
-+ OF_node_t *pmgt;
-+ pmgt = OF_node_new(OF_env, mio, "power-mgt", OF_ADDRESS_NONE);
-+ OF_prop_string_new(OF_env, pmgt, "device_type", "power-mgt");
-+ OF_prop_string_new(OF_env, pmgt, "compatible", "cuda");
-+ OF_prop_string_new(OF_env, pmgt, "mgt-kind", "min-consumption-pwm-led");
-+ OF_node_put(OF_env, pmgt);
-+ }
-+
-+ if (arch == ARCH_HEATHROW) {
-+ /* NVRAM */
-+ OF_node_t *nvr;
-+ OF_regprop_t regs;
-+ nvr = OF_node_new(OF_env, mio, "nvram", 0x60000);
-+ OF_prop_string_new(OF_env, nvr, "device_type", "nvram");
-+ regs.address = 0x60000;
-+ regs.size = 0x00020000;
-+ OF_property_new(OF_env, nvr, "reg", &regs, sizeof(regs));
-+ OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000);
-+ OF_node_put(OF_env, nvr);
-+ }
-+
- out:
- // OF_node_put(OF_env, mio);
- OF_node_put(OF_env, chs);
- OF_node_put(OF_env, als);
- }
-
-+void OF_finalize_pci_ide (void *dev,
-+ uint32_t io_base0, uint32_t io_base1,
-+ uint32_t io_base2, uint32_t io_base3)
-+{
-+ OF_env_t *OF_env = OF_env_main;
-+ OF_node_t *pci_ata = dev;
-+ OF_node_t *ata, *atas[2];
-+ int i;
-+
-+ OF_prop_int_new(OF_env, pci_ata, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, pci_ata, "#size-cells", 0);
-+
-+ /* XXX: Darwin handles only one device */
-+ for(i = 0; i < 1; i++) {
-+ ata = OF_node_new(OF_env, pci_ata, "ata-4", i);
-+ if (ata == NULL) {
-+ ERROR("Cannot create 'ata-4'\n");
-+ return;
-+ }
-+ OF_prop_string_new(OF_env, ata, "device_type", "ata");
-+ OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-+ OF_prop_string_new(OF_env, ata, "model", "ata-4");
-+ OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-+ OF_prop_int_new(OF_env, ata, "reg", i);
-+ atas[i] = ata;
-+ }
-+ ide_pci_pc_register(io_base0, io_base1, io_base2, io_base3,
-+ atas[0], atas[1]);
-+}
-+
- /*****************************************************************************/
- /* Fake package */
- static void OF_method_fake (OF_env_t *OF_env)
-@@ -2862,11 +3066,11 @@
- /* As we get a 1:1 mapping, do nothing */
- ihandle = popd(OF_env);
- args = (void *)popd(OF_env);
-- address = popd(OF_env);
-- virt = popd(OF_env);
-- size = popd(OF_env);
- popd(OF_env);
-- OF_DPRINTF("Translate address %0x %0x %0x %0x\n", ihandle, address,
-+ size = popd(OF_env);
-+ virt = popd(OF_env);
-+ address = popd(OF_env);
-+ OF_DPRINTF("Map %0x %0x %0x %0x\n", ihandle, address,
- virt, size);
- pushd(OF_env, 0);
- }
-@@ -3270,7 +3474,7 @@
- OF_prop_string_new(OF_env, dsk, "device_type", "block");
- OF_prop_string_new(OF_env, dsk, "category", type);
- OF_prop_int_new(OF_env, dsk, "device_id", devnum);
-- OF_prop_int_new(OF_env, dsk, "reg", 0);
-+ OF_prop_int_new(OF_env, dsk, "reg", devnum);
- OF_method_new(OF_env, dsk, "open", &OF_blockdev_open);
- OF_method_new(OF_env, dsk, "seek", &OF_blockdev_seek);
- OF_method_new(OF_env, dsk, "read", &OF_blockdev_read);
-@@ -3432,7 +3636,8 @@
- }
-
- void OF_vga_register (const unsigned char *name, unused uint32_t address,
-- int width, int height, int depth)
-+ int width, int height, int depth,
-+ unsigned long vga_bios_addr, unsigned long vga_bios_size)
- {
- OF_env_t *OF_env;
- unsigned char tmp[OF_NAMELEN_MAX];
-@@ -3504,6 +3709,18 @@
- OF_prop_string_new(OF_env, als, "display", tmp);
- OF_node_put(OF_env, als);
- /* XXX: may also need read-rectangle */
-+
-+ if (vga_bios_size >= 8) {
-+ const uint8_t *p;
-+ int size;
-+ /* check the QEMU VGA BIOS header */
-+ p = (const uint8_t *)vga_bios_addr;
-+ if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') {
-+ size = *(uint32_t *)(p + 4);
-+ OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC",
-+ p + 8, size);
-+ }
-+ }
- out:
- OF_node_put(OF_env, disp);
- }
-@@ -4451,7 +4668,10 @@
- break;
- case 0x233441d3: /* MacOS X 10.2 and OpenDarwin 1.41 */
- /* Create "memory-map" pseudo device */
-- popd(OF_env);
-+ {
-+ OF_node_t *map;
-+ uint32_t phandle;
-+
- /* Find "/packages" */
- chs = OF_pack_find_by_name(OF_env, OF_node_root, "/chosen");
- if (chs == NULL) {
-@@ -4459,10 +4679,6 @@
- ERROR("Cannot get '/chosen'\n");
- break;
- }
-- {
--#if 1
-- OF_node_t *map;
-- uint32_t phandle;
- map = OF_node_new(OF_env, chs, "memory-map", OF_ADDRESS_NONE);
- if (map == NULL) {
- pushd(OF_env, -1);
-@@ -4473,11 +4689,8 @@
- OF_node_put(OF_env, map);
- OF_node_put(OF_env, chs);
- pushd(OF_env, phandle);
-- }
--#else
-- pushd(OF_env, 0);
--#endif
- pushd(OF_env, 0);
-+ }
- break;
- case 0x32a2d18e: /* MacOS X 10.2 and OpenDarwin 6.02 */
- /* Return screen ihandle */
-@@ -4540,9 +4753,10 @@
- case 0x4ad41f2d:
- /* Yaboot: wait 10 ms: sure ! */
- break;
-+
- default:
- /* ERROR */
-- printf("Script:\n%s\n", FString);
-+ printf("Script: len=%d\n%s\n", (int)strlen(FString), FString);
- printf("Call %0x NOT IMPLEMENTED !\n", crc);
- bug();
- break;
-@@ -4581,6 +4795,7 @@
- {
- OF_CHECK_NBARGS(OF_env, 0);
- /* Should free all OF resources */
-+ bd_reset_all();
- #if defined (DEBUG_BIOS)
- {
- uint16_t loglevel = 0x02 | 0x10 | 0x80;
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/pci.c OpenHackWare-release-0.4/src/pci.c
---- OpenHackWare-release-0.4.org/src/pci.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/pci.c 2005-07-07 23:27:37.000000000 +0200
-@@ -99,8 +99,8 @@
- uint16_t min_grant;
- uint16_t max_latency;
- uint8_t irq_line;
-- uint32_t regions[6];
-- uint32_t sizes[6];
-+ uint32_t regions[7]; /* the region 6 is the PCI ROM */
-+ uint32_t sizes[7];
- pci_device_t *next;
- };
-
-@@ -158,6 +158,7 @@
-
- /* IRQ numbers assigned to PCI IRQs */
- static uint8_t prep_pci_irqs[4] = { 9, 11, 9, 11 };
-+static uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 };
- static uint8_t pmac_pci_irqs[4] = { 8, 9, 10, 11 };
-
- /* PREP PCI host */
-@@ -399,6 +400,79 @@
- &uninorth_config_readl, &uninorth_config_writel,
- };
-
-+/* Grackle PCI host */
-+
-+static uint32_t grackle_cfg_address (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = 0x80000000 | (bus << 16) | (devfn << 8) | (offset & 0xfc);
-+ stswap32((uint32_t *)bridge->cfg_addr, addr);
-+ return bridge->cfg_data + (offset & 3);
-+}
-+
-+static uint8_t grackle_config_readb (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ return *((uint8_t *)addr);
-+}
-+
-+static void grackle_config_writeb (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset, uint8_t val)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ *((uint8_t *)addr) = val;
-+}
-+
-+static uint16_t grackle_config_readw (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ return ldswap16((uint16_t *)addr);
-+}
-+
-+static void grackle_config_writew (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset, uint16_t val)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ stswap16((uint16_t *)addr, val);
-+}
-+
-+static uint32_t grackle_config_readl (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ return ldswap32((uint32_t *)addr);
-+}
-+
-+static void grackle_config_writel (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset, uint32_t val)
-+{
-+ uint32_t addr;
-+
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ stswap32((uint32_t *)addr, val);
-+}
-+
-+static pci_ops_t grackle_pci_ops = {
-+ &grackle_config_readb, &grackle_config_writeb,
-+ &grackle_config_readw, &grackle_config_writew,
-+ &grackle_config_readl, &grackle_config_writel,
-+};
-+
- static inline uint8_t pci_config_readb (pci_bridge_t *bridge,
- uint8_t bus, uint8_t devfn,
- uint8_t offset)
-@@ -466,12 +540,22 @@
- },
- };
-
-+static int ide_config_cb2 (pci_device_t *device)
-+{
-+ OF_finalize_pci_ide(device->common.OF_private,
-+ device->regions[0] & ~0x0000000F,
-+ device->regions[1] & ~0x0000000F,
-+ device->regions[2] & ~0x0000000F,
-+ device->regions[3] & ~0x0000000F);
-+ return 0;
-+}
-+
- static pci_dev_t ide_devices[] = {
- {
-- 0x8086, 0x0100,
-- NULL, "Qemu IDE", "Qemu IDE", "ide",
-+ 0x1095, 0x0646, /* CMD646 IDE controller */
-+ "pci-ide", "pci-ata", NULL, NULL,
- 0, 0, 0,
-- NULL, NULL,
-+ ide_config_cb2, NULL,
- },
- {
- 0xFFFF, 0xFFFF,
-@@ -481,7 +565,9 @@
- },
- };
-
--static int ide_config_cb (pci_device_t *device)
-+#if 0
-+/* should base it on PCI ID, not on arch */
-+static int ide_config_cb (unused pci_device_t *device)
- {
- printf("Register IDE controller\n");
- switch (arch) {
-@@ -491,14 +577,8 @@
- device->common.OF_private);
- break;
- default:
-- ide_pci_pc_register(device->regions[0] & ~0x0000000F,
-- device->regions[1] & ~0x0000000F,
-- device->regions[2] & ~0x0000000F,
-- device->regions[3] & ~0x0000000F,
-- device->common.OF_private);
- break;
- }
--
- return 0;
- }
-
-@@ -512,16 +592,12 @@
- device->common.OF_private);
- break;
- default:
-- ide_pci_pc_register(device->regions[0] & ~0x0000000F,
-- device->regions[1] & ~0x0000000F,
-- device->regions[2] & ~0x0000000F,
-- device->regions[3] & ~0x0000000F,
-- device->common.OF_private);
- break;
- }
-
- return 0;
- }
-+#endif
-
- static pci_subclass_t mass_subclass[] = {
- {
-@@ -530,7 +606,7 @@
- },
- {
- 0x01, "IDE controller", "ide", ide_devices, NULL,
-- &ide_config_cb, NULL,
-+ NULL, NULL,
- },
- {
- 0x02, "Floppy disk controller", NULL, NULL, NULL,
-@@ -546,7 +622,7 @@
- },
- {
- 0x05, "ATA controller", "ata", NULL, NULL,
-- &ata_config_cb, NULL,
-+ NULL, NULL,
- },
- {
- 0x80, "misc mass-storage controller", NULL, NULL, NULL,
-@@ -646,7 +722,9 @@
- /* VGA 640x480x16 */
- OF_vga_register(device->common.device->name,
- device->regions[0] & ~0x0000000F,
-- vga_width, vga_height, vga_depth);
-+ vga_width, vga_height, vga_depth,
-+ device->regions[6] & ~0x0000000F,
-+ device->sizes[6]);
- }
- vga_console_register();
-
-@@ -750,6 +828,13 @@
- NULL, &PREP_pci_ops,
- };
-
-+pci_dev_t grackle_fake_bridge = {
-+ 0xFFFF, 0xFFFF,
-+ "pci", "pci-bridge", "DEC,21154", "DEC,21154.pci-bridge",
-+ -1, -1, -1,
-+ NULL, &grackle_pci_ops,
-+};
-+
- static pci_dev_t hbrg_devices[] = {
- {
- 0x106B, 0x0020, NULL,
-@@ -758,8 +843,8 @@
- NULL, &uninorth_agp_fake_bridge,
- },
- {
-- 0x106B, 0x001F,
-- NULL, "pci", "AAPL,UniNorth", "uni-north",
-+ 0x106B, 0x001F, NULL,
-+ "pci", "AAPL,UniNorth", "uni-north",
- 3, 2, 1,
- NULL, &uninorth_fake_bridge,
- },
-@@ -770,10 +855,10 @@
- NULL, &uninorth_fake_bridge,
- },
- {
-- 0x1011, 0x0026, NULL,
-- "pci-bridge", NULL, NULL,
-+ 0x1057, 0x0002, "pci",
-+ "pci", "MOT,MPC106", "grackle",
- 3, 2, 1,
-- NULL, &PREP_pci_ops,
-+ NULL, &grackle_fake_bridge,
- },
- {
- 0x1057, 0x4801, NULL,
-@@ -1443,7 +1528,14 @@
- }
-
- static const pci_dev_t misc_pci[] = {
-- /* Apple Mac-io controller */
-+ /* Paddington Mac I/O */
-+ {
-+ 0x106B, 0x0017,
-+ "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow",
-+ 1, 1, 1,
-+ &macio_config_cb, NULL,
-+ },
-+ /* KeyLargo Mac I/O */
- {
- 0x106B, 0x0022,
- "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo",
-@@ -1599,7 +1691,7 @@
- uint8_t min_grant, uint8_t max_latency,
- int irq_line)
- {
-- uint32_t cmd;
-+ uint32_t cmd, addr;
- int i;
-
- device->min_grant = min_grant;
-@@ -1611,22 +1703,28 @@
- printf("MAP PCI device %d:%d to IRQ %d\n",
- device->bus, device->devfn, irq_line);
- }
-- for (i = 0; i < 6; i++) {
-+ for (i = 0; i < 7; i++) {
- if ((device->regions[i] & ~0xF) != 0x00000000 &&
- (device->regions[i] & ~0xF) != 0xFFFFFFF0) {
- printf("Map PCI device %d:%d %d to %0x %0x (%s)\n",
- device->bus, device->devfn, i,
- device->regions[i], device->sizes[i],
-- device->regions[i] & 0x00000001 ? "I/O" : "memory");
-+ (device->regions[i] & 0x00000001) && i != 6 ? "I/O" :
-+ "memory");
-+ if (i != 6) {
- cmd = pci_config_readl(bridge, device->bus, device->devfn, 0x04);
- if (device->regions[i] & 0x00000001)
- cmd |= 0x00000001;
- else
- cmd |= 0x00000002;
- pci_config_writel(bridge, device->bus, device->devfn, 0x04, cmd);
-+ }
-+ if (i == 6)
-+ addr = 0x30; /* PCI ROM */
-+ else
-+ addr = 0x10 + (i * sizeof(uint32_t));
- pci_config_writel(bridge, device->bus, device->devfn,
-- 0x10 + (i * sizeof(uint32_t)),
-- device->regions[i]);
-+ addr, device->regions[i]);
- }
- }
- }
-@@ -1900,7 +1998,7 @@
- goto out;
- }
- ret = (pci_u_t *)newd;
-- max_areas = 6;
-+ max_areas = 7;
- /* register PCI device in OF tree */
- if (bridge->dev.common.type == PCI_FAKE_BRIDGE) {
- newd->common.OF_private =
-@@ -1927,6 +2025,9 @@
- /* Handle 64 bits memory mapping */
- continue;
- }
-+ if (i == 6)
-+ addr = 0x30; /* PCI ROM */
-+ else
- addr = 0x10 + (i * sizeof(uint32_t));
- /* Get region size
- * Note: we assume it's always a power of 2
-@@ -1935,7 +2036,7 @@
- smask = pci_config_readl(bridge, bus, devfn, addr);
- if (smask == 0x00000000 || smask == 0xFFFFFFFF)
- continue;
-- if (smask & 0x00000001) {
-+ if ((smask & 0x00000001) != 0 && i != 6) {
- /* I/O space */
- base = io_base;
- /* Align to a minimum of 256 bytes (arbitrary) */
-@@ -1947,6 +2048,8 @@
- /* Align to a minimum of 64 kB (arbitrary) */
- min_align = 1 << 16;
- amask = 0x0000000F;
-+ if (i == 6)
-+ smask |= 1; /* PCI ROM enable */
- }
- omask = smask & amask;
- smask &= ~amask;
-@@ -1980,7 +2083,10 @@
- if (irq_pin > 0) {
- /* assign the IRQ */
- irq_pin = ((devfn >> 3) + irq_pin - 1) & 3;
-- if (arch == ARCH_PREP) {
-+ /* XXX: should base it on the PCI bridge type, not the arch */
-+ switch(arch) {
-+ case ARCH_PREP:
-+ {
- int elcr_port, val;
- irq_line = prep_pci_irqs[irq_pin];
- /* set the IRQ to level-sensitive */
-@@ -1988,14 +2094,22 @@
- val = inb(elcr_port);
- val |= 1 << (irq_line & 7);
- outb(elcr_port, val);
-- } else {
-+ }
-+ break;
-+ case ARCH_MAC99:
- irq_line = pmac_pci_irqs[irq_pin];
-+ break;
-+ case ARCH_HEATHROW:
-+ irq_line = heathrow_pci_irqs[irq_pin];
-+ break;
-+ default:
-+ break;
- }
- }
- update_device:
- pci_update_device(bridge, newd, min_grant, max_latency, irq_line);
- OF_finalize_pci_device(newd->common.OF_private, bus, devfn,
-- newd->regions, newd->sizes);
-+ newd->regions, newd->sizes, irq_line);
- /* Call special inits if needed */
- if (dev->config_cb != NULL)
- (*dev->config_cb)(newd);
-@@ -2049,6 +2163,32 @@
- case ARCH_CHRP:
- /* TODO */
- break;
-+ case ARCH_HEATHROW:
-+ dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
-+ if (dev == NULL)
-+ return -1;
-+ fake_host = pci_add_host(hostp, dev,
-+ (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
-+ if (fake_host == NULL)
-+ return -1;
-+ fake_host->dev.common.type = PCI_FAKE_HOST;
-+ dev = &grackle_fake_bridge;
-+ if (dev == NULL)
-+ goto free_fake_host;
-+ fake_bridge = pci_add_bridge(fake_host, 0, 0, dev,
-+ (0x06 << 24) | (0x04 << 16) | (0xFF << 8),
-+ cfg_base, cfg_len,
-+ cfg_base + 0x7ec00000,
-+ cfg_base + 0x7ee00000,
-+ mem_base, mem_len,
-+ io_base, io_len,
-+ rbase, rlen,
-+ 0,
-+ &grackle_pci_ops);
-+ if (fake_bridge == NULL)
-+ goto free_fake_host;
-+ fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
-+ break;
- case ARCH_MAC99:
- dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
- if (dev == NULL)
-@@ -2167,6 +2307,30 @@
- case ARCH_CHRP:
- /* TODO */
- break;
-+ case ARCH_HEATHROW:
-+ cfg_base = 0x80000000;
-+ cfg_len = 0x7f000000;
-+ mem_base = 0x80000000;
-+ mem_len = 0x01000000;
-+ io_base = 0xfe000000;
-+ io_len = 0x00800000;
-+#if 1
-+ rbase = 0xfd000000;
-+ rlen = 0x01000000;
-+#else
-+ rbase = 0x00000000;
-+ rlen = 0x01000000;
-+#endif
-+ if (pci_check_host(&pci_main, cfg_base, cfg_len,
-+ mem_base, mem_len, io_base, io_len, rbase, rlen,
-+ 0x1057, 0x0002) == 0) {
-+ isa_io_base = io_base;
-+ busnum++;
-+ }
-+ for (curh = pci_main; curh->next != NULL; curh = curh->next)
-+ continue;
-+ pci_check_devices(curh);
-+ break;
- case ARCH_MAC99:
- /* We are supposed to have 3 host bridges:
- * - the uninorth AGP bridge at 0xF0000000
diff --git a/tools/ioemu/pc-bios/pxe-ne2k_pci.bin b/tools/ioemu/pc-bios/pxe-ne2k_pci.bin
deleted file mode 100644
index 8d8fc02af3..0000000000
--- a/tools/ioemu/pc-bios/pxe-ne2k_pci.bin
+++ /dev/null
Binary files differ
diff --git a/tools/ioemu/pc-bios/pxe-pcnet.bin b/tools/ioemu/pc-bios/pxe-pcnet.bin
deleted file mode 100644
index d127d3378e..0000000000
--- a/tools/ioemu/pc-bios/pxe-pcnet.bin
+++ /dev/null
Binary files differ
diff --git a/tools/ioemu/pc-bios/pxe-rtl8139.bin b/tools/ioemu/pc-bios/pxe-rtl8139.bin
deleted file mode 100644
index 2b5cacbbb5..0000000000
--- a/tools/ioemu/pc-bios/pxe-rtl8139.bin
+++ /dev/null
Binary files differ
diff --git a/tools/ioemu/pc-bios/vgabios.diff b/tools/ioemu/pc-bios/vgabios.diff
deleted file mode 100644
index 661c032e46..0000000000
--- a/tools/ioemu/pc-bios/vgabios.diff
+++ /dev/null
@@ -1,896 +0,0 @@
-Index: Makefile
-===================================================================
-RCS file: /sources/vgabios/vgabios/Makefile,v
-retrieving revision 1.17
-diff -u -w -r1.17 Makefile
---- Makefile 6 Mar 2005 13:06:47 -0000 1.17
-+++ Makefile 14 Jun 2006 00:51:06 -0000
-@@ -22,7 +22,7 @@
- cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin
-
- clean:
-- /bin/rm -f biossums *.o *.s *.ld86 \
-+ /bin/rm -f biossums vbetables-gen vbetables.h *.o *.s *.ld86 \
- temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak
-
- dist-clean: clean
-@@ -79,3 +79,9 @@
-
- biossums: biossums.c
- $(CC) -o biossums biossums.c
-+
-+vbetables-gen: vbetables-gen.c
-+ $(CC) -o vbetables-gen vbetables-gen.c
-+
-+vbetables.h: vbetables-gen
-+ ./vbetables-gen > $@
-Index: clext.c
-===================================================================
-RCS file: /sources/vgabios/vgabios/clext.c,v
-retrieving revision 1.10
-diff -u -w -r1.10 clext.c
---- clext.c 25 Mar 2006 10:19:15 -0000 1.10
-+++ clext.c 14 Jun 2006 00:51:06 -0000
-@@ -544,6 +544,13 @@
- cirrus_set_video_mode_extended:
- call cirrus_switch_mode
- pop ax ;; mode
-+ test al, #0x80
-+ jnz cirrus_set_video_mode_extended_1
-+ push ax
-+ mov ax, #0xffff ; set to 0xff to keep win 2K happy
-+ call cirrus_clear_vram
-+ pop ax
-+cirrus_set_video_mode_extended_1:
- and al, #0x7f
-
- push ds
-@@ -1011,6 +1018,13 @@
- jnz cirrus_vesa_02h_3
- call cirrus_enable_16k_granularity
- cirrus_vesa_02h_3:
-+ test bx, #0x8000 ;; no clear
-+ jnz cirrus_vesa_02h_4
-+ push ax
-+ xor ax,ax
-+ call cirrus_clear_vram
-+ pop ax
-+cirrus_vesa_02h_4:
- pop ax
- push ds
- #ifdef CIRRUS_VESA3_PMINFO
-@@ -1479,6 +1493,38 @@
- pop bx
- ret
-
-+cirrus_clear_vram:
-+ pusha
-+ push es
-+ mov si, ax
-+
-+ call cirrus_enable_16k_granularity
-+ call cirrus_extbios_85h
-+ shl al, #2
-+ mov bl, al
-+ xor ah,ah
-+cirrus_clear_vram_1:
-+ mov al, #0x09
-+ mov dx, #0x3ce
-+ out dx, ax
-+ push ax
-+ mov cx, #0xa000
-+ mov es, cx
-+ xor di, di
-+ mov ax, si
-+ mov cx, #8192
-+ cld
-+ rep
-+ stosw
-+ pop ax
-+ inc ah
-+ cmp ah, bl
-+ jne cirrus_clear_vram_1
-+
-+ pop es
-+ popa
-+ ret
-+
- cirrus_extbios_handlers:
- ;; 80h
- dw cirrus_extbios_80h
-Index: vbe.c
-===================================================================
-RCS file: /sources/vgabios/vgabios/vbe.c,v
-retrieving revision 1.48
-diff -u -w -r1.48 vbe.c
---- vbe.c 26 Dec 2005 19:50:26 -0000 1.48
-+++ vbe.c 14 Jun 2006 00:51:07 -0000
-@@ -118,21 +118,114 @@
- .word VBE_VESA_MODE_END_OF_LIST
- #endif
-
-+ .align 2
- vesa_pm_start:
- dw vesa_pm_set_window - vesa_pm_start
-- dw vesa_pm_set_display_strt - vesa_pm_start
-+ dw vesa_pm_set_display_start - vesa_pm_start
- dw vesa_pm_unimplemented - vesa_pm_start
-- dw 0
-+ dw vesa_pm_io_ports_table - vesa_pm_start
-+vesa_pm_io_ports_table:
-+ dw VBE_DISPI_IOPORT_INDEX
-+ dw VBE_DISPI_IOPORT_INDEX + 1
-+ dw VBE_DISPI_IOPORT_DATA
-+ dw VBE_DISPI_IOPORT_DATA + 1
-+ dw 0xffff
-+ dw 0xffff
-
- USE32
- vesa_pm_set_window:
-- mov ax, #0x4f05
-- int #0x10
-+ cmp bx, #0x00
-+ je vesa_pm_set_display_window1
-+ mov ax, #0x0100
-+ ret
-+vesa_pm_set_display_window1:
-+ mov ax, dx
-+ push dx
-+ push ax
-+ mov dx, # VBE_DISPI_IOPORT_INDEX
-+ mov ax, # VBE_DISPI_INDEX_BANK
-+ out dx, ax
-+ pop ax
-+ mov dx, # VBE_DISPI_IOPORT_DATA
-+ out dx, ax
-+ pop dx
-+ mov ax, #0x004f
- ret
-
- vesa_pm_set_display_start:
-- mov ax, #0x4f07
-- int #0x10
-+ cmp bl, #0x80
-+ je vesa_pm_set_display_start1
-+ cmp bl, #0x00
-+ je vesa_pm_set_display_start1
-+ mov ax, #0x0100
-+ ret
-+vesa_pm_set_display_start1:
-+; convert offset to (X, Y) coordinate
-+; (would be simpler to change Bochs VBE API...)
-+ push eax
-+ push ecx
-+ push edx
-+ push esi
-+ push edi
-+ shl edx, #16
-+ and ecx, #0xffff
-+ or ecx, edx
-+ shl ecx, #2
-+ mov eax, ecx
-+
-+ push eax
-+ mov dx, # VBE_DISPI_IOPORT_INDEX
-+ mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH
-+ out dx, ax
-+ mov dx, # VBE_DISPI_IOPORT_DATA
-+ in ax, dx
-+ movzx ecx, ax
-+
-+ mov dx, # VBE_DISPI_IOPORT_INDEX
-+ mov ax, # VBE_DISPI_INDEX_BPP
-+ out dx, ax
-+ mov dx, # VBE_DISPI_IOPORT_DATA
-+ in ax, dx
-+ movzx esi, ax
-+ pop eax
-+
-+ add esi, #7
-+ shr esi, #3
-+ imul ecx, esi
-+ xor edx, edx
-+ div ecx
-+ mov edi, eax
-+ mov eax, edx
-+ xor edx, edx
-+ div esi
-+
-+ push dx
-+ push ax
-+ mov dx, # VBE_DISPI_IOPORT_INDEX
-+ mov ax, # VBE_DISPI_INDEX_X_OFFSET
-+ out dx, ax
-+ pop ax
-+ mov dx, # VBE_DISPI_IOPORT_DATA
-+ out dx, ax
-+ pop dx
-+
-+ mov ax, di
-+ push dx
-+ push ax
-+ mov dx, # VBE_DISPI_IOPORT_INDEX
-+ mov ax, # VBE_DISPI_INDEX_Y_OFFSET
-+ out dx, ax
-+ pop ax
-+ mov dx, # VBE_DISPI_IOPORT_DATA
-+ out dx, ax
-+ pop dx
-+
-+ pop edi
-+ pop esi
-+ pop edx
-+ pop ecx
-+ pop eax
-+ mov ax, #0x004f
- ret
-
- vesa_pm_unimplemented:
-@@ -835,6 +928,64 @@
- ASM_END
-
-
-+Bit16u vbe_biosfn_read_video_state_size()
-+{
-+ return 9 * 2;
-+}
-+
-+void vbe_biosfn_save_video_state(ES, BX)
-+ Bit16u ES; Bit16u BX;
-+{
-+ Bit16u enable, i;
-+
-+ outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
-+ enable = inw(VBE_DISPI_IOPORT_DATA);
-+ write_word(ES, BX, enable);
-+ BX += 2;
-+ if (!(enable & VBE_DISPI_ENABLED))
-+ return;
-+ for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
-+ if (i != VBE_DISPI_INDEX_ENABLE) {
-+ outw(VBE_DISPI_IOPORT_INDEX, i);
-+ write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA));
-+ BX += 2;
-+ }
-+ }
-+}
-+
-+
-+void vbe_biosfn_restore_video_state(ES, BX)
-+ Bit16u ES; Bit16u BX;
-+{
-+ Bit16u enable, i;
-+
-+ enable = read_word(ES, BX);
-+ BX += 2;
-+
-+ if (!(enable & VBE_DISPI_ENABLED)) {
-+ outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
-+ outw(VBE_DISPI_IOPORT_DATA, enable);
-+ } else {
-+ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
-+ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
-+ BX += 2;
-+ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
-+ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
-+ BX += 2;
-+ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
-+ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
-+ BX += 2;
-+ outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
-+ outw(VBE_DISPI_IOPORT_DATA, enable);
-+
-+ for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
-+ outw(VBE_DISPI_IOPORT_INDEX, i);
-+ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
-+ BX += 2;
-+ }
-+ }
-+}
-+
- /** Function 04h - Save/Restore State
- *
- * Input:
-@@ -849,10 +1000,48 @@
- * BX = Number of 64-byte blocks to hold the state buffer (if DL=00h)
- *
- */
--void vbe_biosfn_save_restore_state(AX, DL, CX, ES, BX)
-+void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX)
-+Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX;
- {
--}
-+ Bit16u ss=get_SS();
-+ Bit16u result, val;
-
-+ result = 0x4f;
-+ switch(GET_DL()) {
-+ case 0x00:
-+ val = biosfn_read_video_state_size2(CX);
-+#ifdef DEBUG
-+ printf("VGA state size=%x\n", val);
-+#endif
-+ if (CX & 8)
-+ val += vbe_biosfn_read_video_state_size();
-+ write_word(ss, BX, val);
-+ break;
-+ case 0x01:
-+ val = read_word(ss, BX);
-+ val = biosfn_save_video_state(CX, ES, val);
-+#ifdef DEBUG
-+ printf("VGA save_state offset=%x\n", val);
-+#endif
-+ if (CX & 8)
-+ vbe_biosfn_save_video_state(ES, val);
-+ break;
-+ case 0x02:
-+ val = read_word(ss, BX);
-+ val = biosfn_restore_video_state(CX, ES, val);
-+#ifdef DEBUG
-+ printf("VGA restore_state offset=%x\n", val);
-+#endif
-+ if (CX & 8)
-+ vbe_biosfn_restore_video_state(ES, val);
-+ break;
-+ default:
-+ // function failed
-+ result = 0x100;
-+ break;
-+ }
-+ write_word(ss, AX, result);
-+}
-
- /** Function 05h - Display Window Control
- *
-@@ -1090,7 +1279,7 @@
- */
- ASM_START
- vbe_biosfn_return_protected_mode_interface:
-- test bx, bx
-+ test bl, bl
- jnz _fail
- mov di, #0xc000
- mov es, di
-Index: vbe.h
-===================================================================
-RCS file: /sources/vgabios/vgabios/vbe.h,v
-retrieving revision 1.24
-diff -u -w -r1.24 vbe.h
---- vbe.h 9 May 2004 20:31:31 -0000 1.24
-+++ vbe.h 14 Jun 2006 00:51:07 -0000
-@@ -14,7 +14,7 @@
- void vbe_biosfn_return_controller_information(AX, ES, DI);
- void vbe_biosfn_return_mode_information(AX, CX, ES, DI);
- void vbe_biosfn_set_mode(AX, BX, ES, DI);
--void vbe_biosfn_save_restore_state(AX, DL, CX, ES, BX);
-+void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX);
- void vbe_biosfn_set_get_palette_data(AX);
- void vbe_biosfn_return_protected_mode_interface(AX);
-
-@@ -151,6 +151,12 @@
- Bit8u Reserved[189];
- } ModeInfoBlock;
-
-+typedef struct ModeInfoListItem
-+{
-+ Bit16u mode;
-+ ModeInfoBlockCompact info;
-+} ModeInfoListItem;
-+
- // VBE Return Status Info
- // AL
- #define VBE_RETURN_STATUS_SUPPORTED 0x4F
-@@ -193,6 +199,10 @@
- #define VBE_VESA_MODE_1280X1024X1555 0x119
- #define VBE_VESA_MODE_1280X1024X565 0x11A
- #define VBE_VESA_MODE_1280X1024X888 0x11B
-+#define VBE_VESA_MODE_1600X1200X8 0x11C
-+#define VBE_VESA_MODE_1600X1200X1555 0x11D
-+#define VBE_VESA_MODE_1600X1200X565 0x11E
-+#define VBE_VESA_MODE_1600X1200X888 0x11F
-
- // BOCHS/PLEX86 'own' mode numbers
- #define VBE_OWN_MODE_320X200X8888 0x140
-@@ -202,6 +212,12 @@
- #define VBE_OWN_MODE_1024X768X8888 0x144
- #define VBE_OWN_MODE_1280X1024X8888 0x145
- #define VBE_OWN_MODE_320X200X8 0x146
-+#define VBE_OWN_MODE_1600X1200X8888 0x147
-+#define VBE_OWN_MODE_1152X864X8 0x148
-+#define VBE_OWN_MODE_1152X864X1555 0x149
-+#define VBE_OWN_MODE_1152X864X565 0x14a
-+#define VBE_OWN_MODE_1152X864X888 0x14b
-+#define VBE_OWN_MODE_1152X864X8888 0x14c
-
- #define VBE_VESA_MODE_END_OF_LIST 0xFFFF
-
-@@ -259,7 +275,7 @@
- // like 0xE0000000
-
-
-- #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 4
-+ #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 8
-
- #define VBE_DISPI_BANK_ADDRESS 0xA0000
- #define VBE_DISPI_BANK_SIZE_KB 64
-Index: vgabios.c
-===================================================================
-RCS file: /sources/vgabios/vgabios/vgabios.c,v
-retrieving revision 1.64
-diff -u -w -r1.64 vgabios.c
---- vgabios.c 25 Mar 2006 10:19:16 -0000 1.64
-+++ vgabios.c 14 Jun 2006 00:51:07 -0000
-@@ -109,8 +109,8 @@
- static void biosfn_write_string();
- static void biosfn_read_state_info();
- static void biosfn_read_video_state_size();
--static void biosfn_save_video_state();
--static void biosfn_restore_video_state();
-+static Bit16u biosfn_save_video_state();
-+static Bit16u biosfn_restore_video_state();
- extern Bit8u video_save_pointer_table[];
-
- // This is for compiling with gcc2 and gcc3
-@@ -748,12 +748,7 @@
- vbe_biosfn_set_mode(&AX,BX,ES,DI);
- break;
- case 0x04:
-- //FIXME
--#ifdef DEBUG
-- unimplemented();
--#endif
-- // function failed
-- AX=0x100;
-+ vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);
- break;
- case 0x09:
- //FIXME
-@@ -3138,23 +3133,215 @@
- }
-
- // --------------------------------------------------------------------------------------------
--static void biosfn_read_video_state_size (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX;
-+// --------------------------------------------------------------------------------------------
-+static Bit16u biosfn_read_video_state_size2 (CX)
-+ Bit16u CX;
- {
--#ifdef DEBUG
-- unimplemented();
--#endif
-+ Bit16u size;
-+ size = 0;
-+ if (CX & 1) {
-+ size += 0x46;
-+ }
-+ if (CX & 2) {
-+ size += (5 + 8 + 5) * 2 + 6;
-+ }
-+ if (CX & 4) {
-+ size += 3 + 256 * 3 + 1;
- }
--static void biosfn_save_video_state (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX;
-+ return size;
-+}
-+
-+static void biosfn_read_video_state_size (CX, BX)
-+ Bit16u CX; Bit16u *BX;
- {
--#ifdef DEBUG
-- unimplemented();
--#endif
-+ Bit16u ss=get_SS();
-+ write_word(ss, BX, biosfn_read_video_state_size2(CX));
- }
--static void biosfn_restore_video_state (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX;
-+
-+static Bit16u biosfn_save_video_state (CX,ES,BX)
-+ Bit16u CX;Bit16u ES;Bit16u BX;
- {
--#ifdef DEBUG
-- unimplemented();
--#endif
-+ Bit16u i, v, crtc_addr, ar_index;
-+
-+ crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS);
-+ if (CX & 1) {
-+ write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++;
-+ write_byte(ES, BX, inb(crtc_addr)); BX++;
-+ write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++;
-+ inb(VGAREG_ACTL_RESET);
-+ ar_index = inb(VGAREG_ACTL_ADDRESS);
-+ write_byte(ES, BX, ar_index); BX++;
-+ write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++;
-+
-+ for(i=1;i<=4;i++){
-+ outb(VGAREG_SEQU_ADDRESS, i);
-+ write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++;
-+ }
-+ outb(VGAREG_SEQU_ADDRESS, 0);
-+ write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++;
-+
-+ for(i=0;i<=0x18;i++) {
-+ outb(crtc_addr,i);
-+ write_byte(ES, BX, inb(crtc_addr+1)); BX++;
-+ }
-+
-+ for(i=0;i<=0x13;i++) {
-+ inb(VGAREG_ACTL_RESET);
-+ outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20));
-+ write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++;
-+ }
-+ inb(VGAREG_ACTL_RESET);
-+
-+ for(i=0;i<=8;i++) {
-+ outb(VGAREG_GRDC_ADDRESS,i);
-+ write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++;
-+ }
-+
-+ write_word(ES, BX, crtc_addr); BX+= 2;
-+
-+ /* XXX: read plane latches */
-+ write_byte(ES, BX, 0); BX++;
-+ write_byte(ES, BX, 0); BX++;
-+ write_byte(ES, BX, 0); BX++;
-+ write_byte(ES, BX, 0); BX++;
-+ }
-+ if (CX & 2) {
-+ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++;
-+ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2;
-+ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2;
-+ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2;
-+ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++;
-+ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2;
-+ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++;
-+ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++;
-+ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++;
-+ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2;
-+ for(i=0;i<8;i++) {
-+ write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i));
-+ BX += 2;
-+ }
-+ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2;
-+ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++;
-+ /* current font */
-+ write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2;
-+ write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2;
-+ write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2;
-+ write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2;
-+ }
-+ if (CX & 4) {
-+ /* XXX: check this */
-+ write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */
-+ write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */
-+ write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++;
-+ // Set the whole dac always, from 0
-+ outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
-+ for(i=0;i<256*3;i++) {
-+ write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++;
-+ }
-+ write_byte(ES, BX, 0); BX++; /* color select register */
-+ }
-+ return BX;
-+}
-+
-+static Bit16u biosfn_restore_video_state (CX,ES,BX)
-+ Bit16u CX;Bit16u ES;Bit16u BX;
-+{
-+ Bit16u i, crtc_addr, v, addr1, ar_index;
-+
-+ if (CX & 1) {
-+ // Reset Attribute Ctl flip-flop
-+ inb(VGAREG_ACTL_RESET);
-+
-+ crtc_addr = read_word(ES, BX + 0x40);
-+ addr1 = BX;
-+ BX += 5;
-+
-+ for(i=1;i<=4;i++){
-+ outb(VGAREG_SEQU_ADDRESS, i);
-+ outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++;
-+ }
-+ outb(VGAREG_SEQU_ADDRESS, 0);
-+ outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++;
-+
-+ // Disable CRTC write protection
-+ outw(crtc_addr,0x0011);
-+ // Set CRTC regs
-+ for(i=0;i<=0x18;i++) {
-+ if (i != 0x11) {
-+ outb(crtc_addr,i);
-+ outb(crtc_addr+1, read_byte(ES, BX));
-+ }
-+ BX++;
-+ }
-+ // select crtc base address
-+ v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
-+ if (crtc_addr = 0x3d4)
-+ v |= 0x01;
-+ outb(VGAREG_WRITE_MISC_OUTPUT, v);
-+
-+ // enable write protection if needed
-+ outb(crtc_addr, 0x11);
-+ outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11));
-+
-+ // Set Attribute Ctl
-+ ar_index = read_byte(ES, addr1 + 0x03);
-+ inb(VGAREG_ACTL_RESET);
-+ for(i=0;i<=0x13;i++) {
-+ outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20));
-+ outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++;
-+ }
-+ outb(VGAREG_ACTL_ADDRESS, ar_index);
-+ inb(VGAREG_ACTL_RESET);
-+
-+ for(i=0;i<=8;i++) {
-+ outb(VGAREG_GRDC_ADDRESS,i);
-+ outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++;
-+ }
-+ BX += 2; /* crtc_addr */
-+ BX += 4; /* plane latches */
-+
-+ outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++;
-+ outb(crtc_addr, read_byte(ES, addr1)); addr1++;
-+ outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++;
-+ addr1++;
-+ outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++;
-+ }
-+ if (CX & 2) {
-+ write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++;
-+ write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2;
-+ write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2;
-+ write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2;
-+ write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++;
-+ write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2;
-+ write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++;
-+ write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++;
-+ write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++;
-+ write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2;
-+ for(i=0;i<8;i++) {
-+ write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX));
-+ BX += 2;
-+ }
-+ write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2;
-+ write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++;
-+ /* current font */
-+ write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2;
-+ write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2;
-+ write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2;
-+ write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2;
-+ }
-+ if (CX & 4) {
-+ BX++;
-+ v = read_byte(ES, BX); BX++;
-+ outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++;
-+ // Set the whole dac always, from 0
-+ outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
-+ for(i=0;i<256*3;i++) {
-+ outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++;
-+ }
-+ BX++;
-+ outb(VGAREG_DAC_WRITE_ADDRESS, v);
-+ }
-+ return BX;
- }
-
- // ============================================================================================
-diff -u -w vbetables-gen.c
---- vbetables-gen.c 1970-01-01 01:00:00.000000000 +0100
-+++ vbetables-gen.c 2006-06-14 00:52:18.000000000 +0200
-@@ -0,0 +1,217 @@
-+/* Generate the VGABIOS VBE Tables */
-+#include <stdlib.h>
-+#include <stdio.h>
-+
-+typedef struct {
-+ int width;
-+ int height;
-+ int depth;
-+ int mode;
-+} ModeInfo;
-+
-+ModeInfo modes[] = {
-+ /* standard VESA modes */
-+{ 640, 400, 8 , 0x100},
-+{ 640, 480, 8 , 0x101},
-+{ 800, 600, 4 , 0x102},
-+{ 800, 600, 8 , 0x103},
-+ //{ 1024, 768, 4 , 0x104},
-+{ 1024, 768, 8 , 0x105},
-+ //{ 1280, 1024, 4 , 0x106},
-+{ 1280, 1024, 8 , 0x107},
-+{ 320, 200, 15 , 0x10D},
-+{ 320, 200, 16 , 0x10E},
-+{ 320, 200, 24 , 0x10F},
-+{ 640, 480, 15 , 0x110},
-+{ 640, 480, 16 , 0x111},
-+{ 640, 480, 24 , 0x112},
-+{ 800, 600, 15 , 0x113},
-+{ 800, 600, 16 , 0x114},
-+{ 800, 600, 24 , 0x115},
-+{ 1024, 768, 15 , 0x116},
-+{ 1024, 768, 16 , 0x117},
-+{ 1024, 768, 24 , 0x118},
-+{ 1280, 1024, 15 , 0x119},
-+{ 1280, 1024, 16 , 0x11A},
-+{ 1280, 1024, 24 , 0x11B},
-+{ 1600, 1200, 8 , 0x11C},
-+{ 1600, 1200, 15 , 0x11D},
-+{ 1600, 1200, 16 , 0x11E},
-+{ 1600, 1200, 24 , 0x11F},
-+
-+ /* BOCHS/PLE, 86 'own' mode numbers */
-+{ 320, 200, 32 , 0x140},
-+{ 640, 400, 32 , 0x141},
-+{ 640, 480, 32 , 0x142},
-+{ 800, 600, 32 , 0x143},
-+{ 1024, 768, 32 , 0x144},
-+{ 1280, 1024, 32 , 0x145},
-+{ 320, 200, 8 , 0x146},
-+{ 1600, 1200, 32 , 0x147},
-+{ 1152, 864, 8 , 0x148},
-+{ 1152, 864, 15 , 0x149},
-+{ 1152, 864, 16 , 0x14a},
-+{ 1152, 864, 24 , 0x14b},
-+{ 1152, 864, 32 , 0x14c},
-+{ 0, },
-+};
-+
-+int main(int argc, char **argv)
-+{
-+ const ModeInfo *pm;
-+ int pitch, r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos;
-+ const char *str;
-+
-+ printf("/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT */\n");
-+ printf("static ModeInfoListItem mode_info_list[]=\n");
-+ printf("{\n");
-+ for(pm = modes; pm->mode != 0; pm++) {
-+ printf("{ 0x%04x, /* %dx%dx%d */\n",
-+ pm->mode, pm->width, pm->height, pm->depth);
-+ printf("{ /*Bit16u ModeAttributes*/ %s,\n",
-+ "VBE_MODE_ATTRIBUTE_SUPPORTED | "
-+ "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | "
-+ "VBE_MODE_ATTRIBUTE_COLOR_MODE | "
-+ "VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE | "
-+ "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE");
-+
-+ printf("/*Bit8u WinAAttributes*/ %s,\n",
-+ "VBE_WINDOW_ATTRIBUTE_RELOCATABLE | "
-+ "VBE_WINDOW_ATTRIBUTE_READABLE | "
-+ "VBE_WINDOW_ATTRIBUTE_WRITEABLE");
-+
-+ printf("/*Bit8u WinBAttributes*/ %d,\n", 0);
-+
-+ printf("/*Bit16u WinGranularity*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB");
-+
-+ printf("/*Bit16u WinSize*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB");
-+
-+ printf("/*Bit16u WinASegment*/ %s,\n", "VGAMEM_GRAPH");
-+
-+ printf("/*Bit16u WinBSegment*/ 0x%04x,\n", 0);
-+
-+ printf("/*Bit32u WinFuncPtr*/ %d,\n", 0);
-+
-+ if (pm->depth == 4)
-+ pitch = (pm->width + 7) / 8;
-+ else
-+ pitch = pm->width * ((pm->depth + 7) / 8);
-+ printf("/*Bit16u BytesPerScanLine*/ %d,\n", pitch);
-+
-+ // Mandatory information for VBE 1.2 and above
-+ printf("/*Bit16u XResolution*/ %d,\n", pm->width);
-+ printf("/*Bit16u YResolution*/ %d,\n", pm->height);
-+ printf("/*Bit8u XCharSize*/ %d,\n", 8);
-+ printf("/*Bit8u YCharSize*/ %d,\n", 16);
-+ if (pm->depth == 4) {
-+ printf("/*Bit8u NumberOfPlanes*/ %d,\n", 4);
-+ printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth);
-+ } else {
-+ printf("/*Bit8u NumberOfPlanes*/ %d,\n", 1);
-+ printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth);
-+ }
-+ printf("/*Bit8u NumberOfBanks*/ %d,\n",
-+ (pm->height * pitch + 65535) / 65536);
-+
-+ if (pm->depth == 4)
-+ str = "VBE_MEMORYMODEL_PLANAR";
-+ else if (pm->depth == 8)
-+ str = "VBE_MEMORYMODEL_PACKED_PIXEL";
-+ else
-+ str = "VBE_MEMORYMODEL_DIRECT_COLOR";
-+ printf("/*Bit8u MemoryModel*/ %s,\n", str);
-+ printf("/*Bit8u BankSize*/ %d,\n", 0);
-+ /* XXX: check */
-+ printf("/*Bit8u NumberOfImagePages*/ %d,\n", 0);
-+ printf("/*Bit8u Reserved_page*/ %d,\n", 0);
-+
-+ // Direct Color fields (required for direct/6 and YUV/7 memory models)
-+ switch(pm->depth) {
-+ case 15:
-+ r_size = 5;
-+ r_pos = 10;
-+ g_size = 5;
-+ g_pos = 5;
-+ b_size = 5;
-+ b_pos = 0;
-+ a_size = 1;
-+ a_pos = 15;
-+ break;
-+ case 16:
-+ r_size = 5;
-+ r_pos = 11;
-+ g_size = 6;
-+ g_pos = 5;
-+ b_size = 5;
-+ b_pos = 0;
-+ a_size = 0;
-+ a_pos = 0;
-+ break;
-+ case 24:
-+ r_size = 8;
-+ r_pos = 16;
-+ g_size = 8;
-+ g_pos = 8;
-+ b_size = 8;
-+ b_pos = 0;
-+ a_size = 0;
-+ a_pos = 0;
-+ break;
-+ case 32:
-+ r_size = 8;
-+ r_pos = 16;
-+ g_size = 8;
-+ g_pos = 8;
-+ b_size = 8;
-+ b_pos = 0;
-+ a_size = 8;
-+ a_pos = 24;
-+ break;
-+ default:
-+ r_size = 0;
-+ r_pos = 0;
-+ g_size = 0;
-+ g_pos = 0;
-+ b_size = 0;
-+ b_pos = 0;
-+ a_size = 0;
-+ a_pos = 0;
-+ break;
-+ }
-+
-+ printf("/*Bit8u RedMaskSize*/ %d,\n", r_size);
-+ printf("/*Bit8u RedFieldPosition*/ %d,\n", r_pos);
-+ printf("/*Bit8u GreenMaskSize*/ %d,\n", g_size);
-+ printf("/*Bit8u GreenFieldPosition*/ %d,\n", g_pos);
-+ printf("/*Bit8u BlueMaskSize*/ %d,\n", b_size);
-+ printf("/*Bit8u BlueFieldPosition*/ %d,\n", b_pos);
-+ printf("/*Bit8u RsvdMaskSize*/ %d,\n", a_size);
-+ printf("/*Bit8u RsvdFieldPosition*/ %d,\n", a_pos);
-+ printf("/*Bit8u DirectColorModeInfo*/ %d,\n", 0);
-+
-+// Mandatory information for VBE 2.0 and above
-+ printf("/*Bit32u PhysBasePtr*/ %s,\n",
-+ "VBE_DISPI_LFB_PHYSICAL_ADDRESS");
-+ printf("/*Bit32u OffScreenMemOffset*/ %d,\n", 0);
-+ printf("/*Bit16u OffScreenMemSize*/ %d,\n", 0);
-+ // Mandatory information for VBE 3.0 and above
-+ printf("/*Bit16u LinBytesPerScanLine*/ %d,\n", pitch);
-+ printf("/*Bit8u BnkNumberOfPages*/ %d,\n", 0);
-+ printf("/*Bit8u LinNumberOfPages*/ %d,\n", 0);
-+ printf("/*Bit8u LinRedMaskSize*/ %d,\n", r_size);
-+ printf("/*Bit8u LinRedFieldPosition*/ %d,\n", r_pos);
-+ printf("/*Bit8u LinGreenMaskSize*/ %d,\n", g_size);
-+ printf("/*Bit8u LinGreenFieldPosition*/ %d,\n", g_pos);
-+ printf("/*Bit8u LinBlueMaskSize*/ %d,\n", b_size);
-+ printf("/*Bit8u LinBlueFieldPosition*/ %d,\n", b_pos);
-+ printf("/*Bit8u LinRsvdMaskSize*/ %d,\n", a_size);
-+ printf("/*Bit8u LinRsvdFieldPosition*/ %d,\n", a_pos);
-+ printf("/*Bit32u MaxPixelClock*/ %d,\n", 0);
-+ printf("} },\n");
-+ }
-+ printf("{ VBE_VESA_MODE_END_OF_LIST,\n");
-+ printf("{ 0,\n");
-+ printf("} },\n");
-+ printf("};\n");
-+ return 0;
-+}
diff --git a/tools/ioemu/pc-bios/video.x b/tools/ioemu/pc-bios/video.x
deleted file mode 100644
index 761aa0c9d4..0000000000
--- a/tools/ioemu/pc-bios/video.x
+++ /dev/null
Binary files differ
diff --git a/tools/ioemu/qemu-binfmt-conf.sh b/tools/ioemu/qemu-binfmt-conf.sh
deleted file mode 100644
index bd278d908e..0000000000
--- a/tools/ioemu/qemu-binfmt-conf.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# enable automatic i386/ARM/SPARC/PPC program execution by the kernel
-
-# load the binfmt_misc module
-/sbin/modprobe binfmt_misc
-
-# probe cpu type
-cpu=`uname -m`
-case "$cpu" in
- i386|i486|i586|i686|i86pc|BePC)
- cpu="i386"
- ;;
- "Power Macintosh"|ppc|ppc64)
- cpu="ppc"
- ;;
- armv4l)
- cpu="arm"
- ;;
-esac
-
-# register the interpreter for each cpu except for the native one
-if [ $cpu != "i386" ] ; then
- echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
- echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "arm" ] ; then
- echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
- echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "sparc" ] ; then
- echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "ppc" ] ; then
- echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "mips" ] ; then
- echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
- echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
-fi
diff --git a/tools/ioemu/qemu-doc.texi b/tools/ioemu/qemu-doc.texi
deleted file mode 100644
index 834c778552..0000000000
--- a/tools/ioemu/qemu-doc.texi
+++ /dev/null
@@ -1,2057 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-@c %**start of header
-@setfilename qemu-doc.info
-@settitle QEMU Emulator User Documentation
-@exampleindent 0
-@paragraphindent 0
-@c %**end of header
-
-@iftex
-@titlepage
-@sp 7
-@center @titlefont{QEMU Emulator}
-@sp 1
-@center @titlefont{User Documentation}
-@sp 3
-@end titlepage
-@end iftex
-
-@ifnottex
-@node Top
-@top
-
-@menu
-* Introduction::
-* Installation::
-* QEMU PC System emulator::
-* QEMU System emulator for non PC targets::
-* QEMU User space emulator::
-* compilation:: Compilation from the sources
-* Index::
-@end menu
-@end ifnottex
-
-@contents
-
-@node Introduction
-@chapter Introduction
-
-@menu
-* intro_features:: Features
-@end menu
-
-@node intro_features
-@section Features
-
-QEMU is a FAST! processor emulator using dynamic translation to
-achieve good emulation speed.
-
-QEMU has two operating modes:
-
-@itemize @minus
-
-@item
-Full system emulation. In this mode, QEMU emulates a full system (for
-example a PC), including one or several processors and various
-peripherals. It can be used to launch different Operating Systems
-without rebooting the PC or to debug system code.
-
-@item
-User mode emulation. In this mode, QEMU can launch
-processes compiled for one CPU on another CPU. It can be used to
-launch the Wine Windows API emulator (@url{http://www.winehq.org}) or
-to ease cross-compilation and cross-debugging.
-
-@end itemize
-
-QEMU can run without an host kernel driver and yet gives acceptable
-performance.
-
-For system emulation, the following hardware targets are supported:
-@itemize
-@item PC (x86 or x86_64 processor)
-@item ISA PC (old style PC without PCI bus)
-@item PREP (PowerPC processor)
-@item G3 BW PowerMac (PowerPC processor)
-@item Mac99 PowerMac (PowerPC processor, in progress)
-@item Sun4m (32-bit Sparc processor)
-@item Sun4u (64-bit Sparc processor, in progress)
-@item Malta board (32-bit MIPS processor)
-@item ARM Integrator/CP (ARM926E or 1026E processor)
-@item ARM Versatile baseboard (ARM926E)
-@end itemize
-
-For user emulation, x86, PowerPC, ARM, MIPS, Sparc32/64 and ColdFire(m68k) CPUs are supported.
-
-@node Installation
-@chapter Installation
-
-If you want to compile QEMU yourself, see @ref{compilation}.
-
-@menu
-* install_linux:: Linux
-* install_windows:: Windows
-* install_mac:: Macintosh
-@end menu
-
-@node install_linux
-@section Linux
-
-If a precompiled package is available for your distribution - you just
-have to install it. Otherwise, see @ref{compilation}.
-
-@node install_windows
-@section Windows
-
-Download the experimental binary installer at
-@url{http://www.free.oszoo.org/@/download.html}.
-
-@node install_mac
-@section Mac OS X
-
-Download the experimental binary installer at
-@url{http://www.free.oszoo.org/@/download.html}.
-
-@node QEMU PC System emulator
-@chapter QEMU PC System emulator
-
-@menu
-* pcsys_introduction:: Introduction
-* pcsys_quickstart:: Quick Start
-* sec_invocation:: Invocation
-* pcsys_keys:: Keys
-* pcsys_monitor:: QEMU Monitor
-* disk_images:: Disk Images
-* pcsys_network:: Network emulation
-* direct_linux_boot:: Direct Linux Boot
-* pcsys_usb:: USB emulation
-* gdb_usage:: GDB usage
-* pcsys_os_specific:: Target OS specific information
-@end menu
-
-@node pcsys_introduction
-@section Introduction
-
-@c man begin DESCRIPTION
-
-The QEMU PC System emulator simulates the
-following peripherals:
-
-@itemize @minus
-@item
-i440FX host PCI bridge and PIIX3 PCI to ISA bridge
-@item
-Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA
-extensions (hardware level, including all non standard modes).
-@item
-PS/2 mouse and keyboard
-@item
-2 PCI IDE interfaces with hard disk and CD-ROM support
-@item
-Floppy disk
-@item
-NE2000 PCI network adapters
-@item
-Serial ports
-@item
-Creative SoundBlaster 16 sound card
-@item
-ENSONIQ AudioPCI ES1370 sound card
-@item
-Adlib(OPL2) - Yamaha YM3812 compatible chip
-@item
-PCI UHCI USB controller and a virtual USB hub.
-@end itemize
-
-SMP is supported with up to 255 CPUs.
-
-Note that adlib is only available when QEMU was configured with
--enable-adlib
-
-QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
-VGA BIOS.
-
-QEMU uses YM3812 emulation by Tatsuyuki Satoh.
-
-@c man end
-
-@node pcsys_quickstart
-@section Quick Start
-
-Download and uncompress the linux image (@file{linux.img}) and type:
-
-@example
-qemu linux.img
-@end example
-
-Linux should boot and give you a prompt.
-
-@node sec_invocation
-@section Invocation
-
-@example
-@c man begin SYNOPSIS
-usage: qemu [options] [disk_image]
-@c man end
-@end example
-
-@c man begin OPTIONS
-@var{disk_image} is a raw hard disk image for IDE hard disk 0.
-
-General options:
-@table @option
-@item -M machine
-Select the emulated machine (@code{-M ?} for list)
-
-@item -fda file
-@item -fdb file
-Use @var{file} as floppy disk 0/1 image (@pxref{disk_images}). You can
-use the host floppy by using @file{/dev/fd0} as filename (@pxref{host_drives}).
-
-@item -hda file
-@item -hdb file
-@item -hdc file
-@item -hdd file
-Use @var{file} as hard disk 0, 1, 2 or 3 image (@pxref{disk_images}).
-
-@item -cdrom file
-Use @var{file} as CD-ROM image (you cannot use @option{-hdc} and and
-@option{-cdrom} at the same time). You can use the host CD-ROM by
-using @file{/dev/cdrom} as filename (@pxref{host_drives}).
-
-@item -boot [a|c|d|n]
-Boot on floppy (a), hard disk (c), CD-ROM (d), or Etherboot (n). Hard disk boot
-is the default.
-
-@item -snapshot
-Write to temporary files instead of disk image files. In this case,
-the raw disk image you use is not written back. You can however force
-the write back by pressing @key{C-a s} (@pxref{disk_images}).
-
-@item -no-fd-bootchk
-Disable boot signature checking for floppy disks in Bochs BIOS. It may
-be needed to boot from old floppy disks.
-
-@item -m megs
-Set virtual RAM size to @var{megs} megabytes. Default is 128 MB.
-
-@item -smp n
-Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255
-CPUs are supported.
-
-@item -nographic
-
-Normally, QEMU uses SDL to display the VGA output. With this option,
-you can totally disable graphical output so that QEMU is a simple
-command line application. The emulated serial port is redirected on
-the console. Therefore, you can still use QEMU to debug a Linux kernel
-with a serial console.
-
-@item -vnc display
-
-Normally, QEMU uses SDL to display the VGA output. With this option,
-you can have QEMU listen on VNC display @var{display} and redirect the VGA
-display over the VNC session. It is very useful to enable the usb
-tablet device when using this option (option @option{-usbdevice
-tablet}). When using the VNC display, you must use the @option{-k}
-option to set the keyboard layout if you are not using en-us.
-
-@var{display} may be in the form @var{interface:d}, in which case connections
-will only be allowed from @var{interface} on display @var{d}. Optionally,
-@var{interface} can be omitted. @var{display} can also be in the form
-@var{unix:path} where @var{path} is the location of a unix socket to listen for
-connections on.
-
-
-@item -k language
-
-Use keyboard layout @var{language} (for example @code{fr} for
-French). This option is only needed where it is not easy to get raw PC
-keycodes (e.g. on Macs, with some X11 servers or with a VNC
-display). You don't normally need to use it on PC/Linux or PC/Windows
-hosts.
-
-The available layouts are:
-@example
-ar de-ch es fo fr-ca hu ja mk no pt-br sv
-da en-gb et fr fr-ch is lt nl pl ru th
-de en-us fi fr-be hr it lv nl-be pt sl tr
-@end example
-
-The default is @code{en-us}.
-
-@item -audio-help
-
-Will show the audio subsystem help: list of drivers, tunable
-parameters.
-
-@item -soundhw card1,card2,... or -soundhw all
-
-Enable audio and selected sound hardware. Use ? to print all
-available sound hardware.
-
-@example
-qemu -soundhw sb16,adlib hda
-qemu -soundhw es1370 hda
-qemu -soundhw all hda
-qemu -soundhw ?
-@end example
-
-@item -localtime
-Set the real time clock to local time (the default is to UTC
-time). This option is needed to have correct date in MS-DOS or
-Windows.
-
-@item -full-screen
-Start in full screen.
-
-@item -pidfile file
-Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
-from a script.
-
-@item -daemonize
-Daemonize the QEMU process after initialization. QEMU will not detach from
-standard IO until it is ready to receive connections on any of its devices.
-This option is a useful way for external programs to launch QEMU without having
-to cope with initialization race conditions.
-
-@item -win2k-hack
-Use it when installing Windows 2000 to avoid a disk full bug. After
-Windows 2000 is installed, you no longer need this option (this option
-slows down the IDE transfers).
-
-@item -option-rom file
-Load the contents of file as an option ROM. This option is useful to load
-things like EtherBoot.
-
-@end table
-
-USB options:
-@table @option
-
-@item -usb
-Enable the USB driver (will be the default soon)
-
-@item -usbdevice devname
-Add the USB device @var{devname}. @xref{usb_devices}.
-@end table
-
-Network options:
-
-@table @option
-
-@item -net nic[,vlan=n][,macaddr=addr][,model=type]
-Create a new Network Interface Card and connect it to VLAN @var{n} (@var{n}
-= 0 is the default). The NIC is currently an NE2000 on the PC
-target. Optionally, the MAC address can be changed. If no
-@option{-net} option is specified, a single NIC is created.
-Qemu can emulate several different models of network card. Valid values for
-@var{type} are @code{ne2k_pci}, @code{ne2k_isa}, @code{rtl8139},
-@code{smc91c111} and @code{lance}. Not all devices are supported on all
-targets.
-
-@item -net user[,vlan=n][,hostname=name]
-Use the user mode network stack which requires no administrator
-priviledge to run. @option{hostname=name} can be used to specify the client
-hostname reported by the builtin DHCP server.
-
-@item -net tap[,vlan=n][,fd=h][,ifname=name][,script=file]
-Connect the host TAP network interface @var{name} to VLAN @var{n} and
-use the network script @var{file} to configure it. The default
-network script is @file{/etc/qemu-ifup}. Use @option{script=no} to
-disable script execution. If @var{name} is not
-provided, the OS automatically provides one. @option{fd=h} can be
-used to specify the handle of an already opened host TAP interface. Example:
-
-@example
-qemu linux.img -net nic -net tap
-@end example
-
-More complicated example (two NICs, each one connected to a TAP device)
-@example
-qemu linux.img -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
- -net nic,vlan=1 -net tap,vlan=1,ifname=tap1
-@end example
-
-
-@item -net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]
-
-Connect the VLAN @var{n} to a remote VLAN in another QEMU virtual
-machine using a TCP socket connection. If @option{listen} is
-specified, QEMU waits for incoming connections on @var{port}
-(@var{host} is optional). @option{connect} is used to connect to
-another QEMU instance using the @option{listen} option. @option{fd=h}
-specifies an already opened TCP socket.
-
-Example:
-@example
-# launch a first QEMU instance
-qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \
- -net socket,listen=:1234
-# connect the VLAN 0 of this instance to the VLAN 0
-# of the first instance
-qemu linux.img -net nic,macaddr=52:54:00:12:34:57 \
- -net socket,connect=127.0.0.1:1234
-@end example
-
-@item -net socket[,vlan=n][,fd=h][,mcast=maddr:port]
-
-Create a VLAN @var{n} shared with another QEMU virtual
-machines using a UDP multicast socket, effectively making a bus for
-every QEMU with same multicast address @var{maddr} and @var{port}.
-NOTES:
-@enumerate
-@item
-Several QEMU can be running on different hosts and share same bus (assuming
-correct multicast setup for these hosts).
-@item
-mcast support is compatible with User Mode Linux (argument @option{eth@var{N}=mcast}), see
-@url{http://user-mode-linux.sf.net}.
-@item Use @option{fd=h} to specify an already opened UDP multicast socket.
-@end enumerate
-
-Example:
-@example
-# launch one QEMU instance
-qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \
- -net socket,mcast=230.0.0.1:1234
-# launch another QEMU instance on same "bus"
-qemu linux.img -net nic,macaddr=52:54:00:12:34:57 \
- -net socket,mcast=230.0.0.1:1234
-# launch yet another QEMU instance on same "bus"
-qemu linux.img -net nic,macaddr=52:54:00:12:34:58 \
- -net socket,mcast=230.0.0.1:1234
-@end example
-
-Example (User Mode Linux compat.):
-@example
-# launch QEMU instance (note mcast address selected
-# is UML's default)
-qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \
- -net socket,mcast=239.192.168.1:1102
-# launch UML
-/path/to/linux ubd0=/path/to/root_fs eth0=mcast
-@end example
-
-@item -net none
-Indicate that no network devices should be configured. It is used to
-override the default configuration (@option{-net nic -net user}) which
-is activated if no @option{-net} options are provided.
-
-@item -tftp prefix
-When using the user mode network stack, activate a built-in TFTP
-server. All filenames beginning with @var{prefix} can be downloaded
-from the host to the guest using a TFTP client. The TFTP client on the
-guest must be configured in binary mode (use the command @code{bin} of
-the Unix TFTP client). The host IP address on the guest is as usual
-10.0.2.2.
-
-@item -smb dir
-When using the user mode network stack, activate a built-in SMB
-server so that Windows OSes can access to the host files in @file{dir}
-transparently.
-
-In the guest Windows OS, the line:
-@example
-10.0.2.4 smbserver
-@end example
-must be added in the file @file{C:\WINDOWS\LMHOSTS} (for windows 9x/Me)
-or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000).
-
-Then @file{dir} can be accessed in @file{\\smbserver\qemu}.
-
-Note that a SAMBA server must be installed on the host OS in
-@file{/usr/sbin/smbd}. QEMU was tested successfully with smbd version
-2.2.7a from the Red Hat 9 and version 3.0.10-1.fc3 from Fedora Core 3.
-
-@item -redir [tcp|udp]:host-port:[guest-host]:guest-port
-
-When using the user mode network stack, redirect incoming TCP or UDP
-connections to the host port @var{host-port} to the guest
-@var{guest-host} on guest port @var{guest-port}. If @var{guest-host}
-is not specified, its value is 10.0.2.15 (default address given by the
-built-in DHCP server).
-
-For example, to redirect host X11 connection from screen 1 to guest
-screen 0, use the following:
-
-@example
-# on the host
-qemu -redir tcp:6001::6000 [...]
-# this host xterm should open in the guest X11 server
-xterm -display :1
-@end example
-
-To redirect telnet connections from host port 5555 to telnet port on
-the guest, use the following:
-
-@example
-# on the host
-qemu -redir tcp:5555::23 [...]
-telnet localhost 5555
-@end example
-
-Then when you use on the host @code{telnet localhost 5555}, you
-connect to the guest telnet server.
-
-@end table
-
-Linux boot specific: When using these options, you can use a given
-Linux kernel without installing it in the disk image. It can be useful
-for easier testing of various kernels.
-
-@table @option
-
-@item -kernel bzImage
-Use @var{bzImage} as kernel image.
-
-@item -append cmdline
-Use @var{cmdline} as kernel command line
-
-@item -initrd file
-Use @var{file} as initial ram disk.
-
-@end table
-
-Debug/Expert options:
-@table @option
-
-@item -serial dev
-Redirect the virtual serial port to host character device
-@var{dev}. The default device is @code{vc} in graphical mode and
-@code{stdio} in non graphical mode.
-
-This option can be used several times to simulate up to 4 serials
-ports.
-
-Use @code{-serial none} to disable all serial ports.
-
-Available character devices are:
-@table @code
-@item vc
-Virtual console
-@item pty
-[Linux only] Pseudo TTY (a new PTY is automatically allocated)
-@item none
-No device is allocated.
-@item null
-void device
-@item /dev/XXX
-[Linux only] Use host tty, e.g. @file{/dev/ttyS0}. The host serial port
-parameters are set according to the emulated ones.
-@item /dev/parportN
-[Linux only, parallel port only] Use host parallel port
-@var{N}. Currently only SPP parallel port features can be used.
-@item file:filename
-Write output to filename. No character can be read.
-@item stdio
-[Unix only] standard input/output
-@item pipe:filename
-name pipe @var{filename}
-@item COMn
-[Windows only] Use host serial port @var{n}
-@item udp:[remote_host]:remote_port[@@[src_ip]:src_port]
-This implements UDP Net Console. When @var{remote_host} or @var{src_ip} are not specified they default to @code{0.0.0.0}. When not using a specifed @var{src_port} a random port is automatically chosen.
-
-If you just want a simple readonly console you can use @code{netcat} or
-@code{nc}, by starting qemu with: @code{-serial udp::4555} and nc as:
-@code{nc -u -l -p 4555}. Any time qemu writes something to that port it
-will appear in the netconsole session.
-
-If you plan to send characters back via netconsole or you want to stop
-and start qemu a lot of times, you should have qemu use the same
-source port each time by using something like @code{-serial
-udp::4555@@:4556} to qemu. Another approach is to use a patched
-version of netcat which can listen to a TCP port and send and receive
-characters via udp. If you have a patched version of netcat which
-activates telnet remote echo and single char transfer, then you can
-use the following options to step up a netcat redirector to allow
-telnet on port 5555 to access the qemu port.
-@table @code
-@item Qemu Options:
--serial udp::4555@@:4556
-@item netcat options:
--u -P 4555 -L 0.0.0.0:4556 -t -p 5555 -I -T
-@item telnet options:
-localhost 5555
-@end table
-
-
-@item tcp:[host]:port[,server][,nowait][,nodelay]
-The TCP Net Console has two modes of operation. It can send the serial
-I/O to a location or wait for a connection from a location. By default
-the TCP Net Console is sent to @var{host} at the @var{port}. If you use
-the @var{server} option QEMU will wait for a client socket application
-to connect to the port before continuing, unless the @code{nowait}
-option was specified. The @code{nodelay} option disables the Nagle buffering
-algoritm. If @var{host} is omitted, 0.0.0.0 is assumed. Only
-one TCP connection at a time is accepted. You can use @code{telnet} to
-connect to the corresponding character device.
-@table @code
-@item Example to send tcp console to 192.168.0.2 port 4444
--serial tcp:192.168.0.2:4444
-@item Example to listen and wait on port 4444 for connection
--serial tcp::4444,server
-@item Example to not wait and listen on ip 192.168.0.100 port 4444
--serial tcp:192.168.0.100:4444,server,nowait
-@end table
-
-@item telnet:host:port[,server][,nowait][,nodelay]
-The telnet protocol is used instead of raw tcp sockets. The options
-work the same as if you had specified @code{-serial tcp}. The
-difference is that the port acts like a telnet server or client using
-telnet option negotiation. This will also allow you to send the
-MAGIC_SYSRQ sequence if you use a telnet that supports sending the break
-sequence. Typically in unix telnet you do it with Control-] and then
-type "send break" followed by pressing the enter key.
-
-@item unix:path[,server][,nowait]
-A unix domain socket is used instead of a tcp socket. The option works the
-same as if you had specified @code{-serial tcp} except the unix domain socket
-@var{path} is used for connections.
-
-@end table
-
-@item -parallel dev
-Redirect the virtual parallel port to host device @var{dev} (same
-devices as the serial port). On Linux hosts, @file{/dev/parportN} can
-be used to use hardware devices connected on the corresponding host
-parallel port.
-
-This option can be used several times to simulate up to 3 parallel
-ports.
-
-Use @code{-parallel none} to disable all parallel ports.
-
-@item -monitor dev
-Redirect the monitor to host device @var{dev} (same devices as the
-serial port).
-The default device is @code{vc} in graphical mode and @code{stdio} in
-non graphical mode.
-
-@item -s
-Wait gdb connection to port 1234 (@pxref{gdb_usage}).
-@item -p port
-Change gdb connection port. @var{port} can be either a decimal number
-to specify a TCP port, or a host device (same devices as the serial port).
-@item -S
-Do not start CPU at startup (you must type 'c' in the monitor).
-@item -d
-Output log in /tmp/qemu.log
-@item -hdachs c,h,s,[,t]
-Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
-@var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS
-translation mode (@var{t}=none, lba or auto). Usually QEMU can guess
-all thoses parameters. This option is useful for old MS-DOS disk
-images.
-
-@item -L path
-Set the directory for the BIOS, VGA BIOS and keymaps.
-
-@item -std-vga
-Simulate a standard VGA card with Bochs VBE extensions (default is
-Cirrus Logic GD5446 PCI VGA). If your guest OS supports the VESA 2.0
-VBE extensions (e.g. Windows XP) and if you want to use high
-resolution modes (>= 1280x1024x16) then you should use this option.
-
-@item -no-acpi
-Disable ACPI (Advanced Configuration and Power Interface) support. Use
-it if your guest OS complains about ACPI problems (PC target machine
-only).
-
-@item -no-reboot
-Exit instead of rebooting.
-
-@item -loadvm file
-Start right away with a saved state (@code{loadvm} in monitor)
-
-@item -semihosting
-Enable "Angel" semihosting interface (ARM target machines only).
-Note that this allows guest direct access to the host filesystem,
-so should only be used with trusted guest OS.
-@end table
-
-@c man end
-
-@node pcsys_keys
-@section Keys
-
-@c man begin OPTIONS
-
-During the graphical emulation, you can use the following keys:
-@table @key
-@item Ctrl-Alt-f
-Toggle full screen
-
-@item Ctrl-Alt-n
-Switch to virtual console 'n'. Standard console mappings are:
-@table @emph
-@item 1
-Target system display
-@item 2
-Monitor
-@item 3
-Serial port
-@end table
-
-@item Ctrl-Alt
-Toggle mouse and keyboard grab.
-@end table
-
-In the virtual consoles, you can use @key{Ctrl-Up}, @key{Ctrl-Down},
-@key{Ctrl-PageUp} and @key{Ctrl-PageDown} to move in the back log.
-
-During emulation, if you are using the @option{-nographic} option, use
-@key{Ctrl-a h} to get terminal commands:
-
-@table @key
-@item Ctrl-a h
-Print this help
-@item Ctrl-a x
-Exit emulator
-@item Ctrl-a s
-Save disk data back to file (if -snapshot)
-@item Ctrl-a b
-Send break (magic sysrq in Linux)
-@item Ctrl-a c
-Switch between console and monitor
-@item Ctrl-a Ctrl-a
-Send Ctrl-a
-@end table
-@c man end
-
-@ignore
-
-@c man begin SEEALSO
-The HTML documentation of QEMU for more precise information and Linux
-user mode emulator invocation.
-@c man end
-
-@c man begin AUTHOR
-Fabrice Bellard
-@c man end
-
-@end ignore
-
-@node pcsys_monitor
-@section QEMU Monitor
-
-The QEMU monitor is used to give complex commands to the QEMU
-emulator. You can use it to:
-
-@itemize @minus
-
-@item
-Remove or insert removable medias images
-(such as CD-ROM or floppies)
-
-@item
-Freeze/unfreeze the Virtual Machine (VM) and save or restore its state
-from a disk file.
-
-@item Inspect the VM state without an external debugger.
-
-@end itemize
-
-@subsection Commands
-
-The following commands are available:
-
-@table @option
-
-@item help or ? [cmd]
-Show the help for all commands or just for command @var{cmd}.
-
-@item commit
-Commit changes to the disk images (if -snapshot is used)
-
-@item info subcommand
-show various information about the system state
-
-@table @option
-@item info network
-show the various VLANs and the associated devices
-@item info block
-show the block devices
-@item info registers
-show the cpu registers
-@item info history
-show the command line history
-@item info pci
-show emulated PCI device
-@item info usb
-show USB devices plugged on the virtual USB hub
-@item info usbhost
-show all USB host devices
-@item info capture
-show information about active capturing
-@item info snapshots
-show list of VM snapshots
-@item info mice
-show which guest mouse is receiving events
-@end table
-
-@item q or quit
-Quit the emulator.
-
-@item eject [-f] device
-Eject a removable media (use -f to force it).
-
-@item change device filename
-Change a removable media.
-
-@item screendump filename
-Save screen into PPM image @var{filename}.
-
-@item mouse_move dx dy [dz]
-Move the active mouse to the specified coordinates @var{dx} @var{dy}
-with optional scroll axis @var{dz}.
-
-@item mouse_button val
-Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
-
-@item mouse_set index
-Set which mouse device receives events at given @var{index}, index
-can be obtained with
-@example
-info mice
-@end example
-
-@item wavcapture filename [frequency [bits [channels]]]
-Capture audio into @var{filename}. Using sample rate @var{frequency}
-bits per sample @var{bits} and number of channels @var{channels}.
-
-Defaults:
-@itemize @minus
-@item Sample rate = 44100 Hz - CD quality
-@item Bits = 16
-@item Number of channels = 2 - Stereo
-@end itemize
-
-@item stopcapture index
-Stop capture with a given @var{index}, index can be obtained with
-@example
-info capture
-@end example
-
-@item log item1[,...]
-Activate logging of the specified items to @file{/tmp/qemu.log}.
-
-@item savevm [tag|id]
-Create a snapshot of the whole virtual machine. If @var{tag} is
-provided, it is used as human readable identifier. If there is already
-a snapshot with the same tag or ID, it is replaced. More info at
-@ref{vm_snapshots}.
-
-@item loadvm tag|id
-Set the whole virtual machine to the snapshot identified by the tag
-@var{tag} or the unique snapshot ID @var{id}.
-
-@item delvm tag|id
-Delete the snapshot identified by @var{tag} or @var{id}.
-
-@item stop
-Stop emulation.
-
-@item c or cont
-Resume emulation.
-
-@item gdbserver [port]
-Start gdbserver session (default port=1234)
-
-@item x/fmt addr
-Virtual memory dump starting at @var{addr}.
-
-@item xp /fmt addr
-Physical memory dump starting at @var{addr}.
-
-@var{fmt} is a format which tells the command how to format the
-data. Its syntax is: @option{/@{count@}@{format@}@{size@}}
-
-@table @var
-@item count
-is the number of items to be dumped.
-
-@item format
-can be x (hexa), d (signed decimal), u (unsigned decimal), o (octal),
-c (char) or i (asm instruction).
-
-@item size
-can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
-@code{h} or @code{w} can be specified with the @code{i} format to
-respectively select 16 or 32 bit code instruction size.
-
-@end table
-
-Examples:
-@itemize
-@item
-Dump 10 instructions at the current instruction pointer:
-@example
-(qemu) x/10i $eip
-0x90107063: ret
-0x90107064: sti
-0x90107065: lea 0x0(%esi,1),%esi
-0x90107069: lea 0x0(%edi,1),%edi
-0x90107070: ret
-0x90107071: jmp 0x90107080
-0x90107073: nop
-0x90107074: nop
-0x90107075: nop
-0x90107076: nop
-@end example
-
-@item
-Dump 80 16 bit values at the start of the video memory.
-@smallexample
-(qemu) xp/80hx 0xb8000
-0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
-0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
-0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
-0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
-0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
-0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
-0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-@end smallexample
-@end itemize
-
-@item p or print/fmt expr
-
-Print expression value. Only the @var{format} part of @var{fmt} is
-used.
-
-@item sendkey keys
-
-Send @var{keys} to the emulator. Use @code{-} to press several keys
-simultaneously. Example:
-@example
-sendkey ctrl-alt-f1
-@end example
-
-This command is useful to send keys that your graphical user interface
-intercepts at low level, such as @code{ctrl-alt-f1} in X Window.
-
-@item system_reset
-
-Reset the system.
-
-@item usb_add devname
-
-Add the USB device @var{devname}. For details of available devices see
-@ref{usb_devices}
-
-@item usb_del devname
-
-Remove the USB device @var{devname} from the QEMU virtual USB
-hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
-command @code{info usb} to see the devices you can remove.
-
-@end table
-
-@subsection Integer expressions
-
-The monitor understands integers expressions for every integer
-argument. You can use register names to get the value of specifics
-CPU registers by prefixing them with @emph{$}.
-
-@node disk_images
-@section Disk Images
-
-Since version 0.6.1, QEMU supports many disk image formats, including
-growable disk images (their size increase as non empty sectors are
-written), compressed and encrypted disk images. Version 0.8.3 added
-the new qcow2 disk image format which is essential to support VM
-snapshots.
-
-@menu
-* disk_images_quickstart:: Quick start for disk image creation
-* disk_images_snapshot_mode:: Snapshot mode
-* vm_snapshots:: VM snapshots
-* qemu_img_invocation:: qemu-img Invocation
-* host_drives:: Using host drives
-* disk_images_fat_images:: Virtual FAT disk images
-@end menu
-
-@node disk_images_quickstart
-@subsection Quick start for disk image creation
-
-You can create a disk image with the command:
-@example
-qemu-img create myimage.img mysize
-@end example
-where @var{myimage.img} is the disk image filename and @var{mysize} is its
-size in kilobytes. You can add an @code{M} suffix to give the size in
-megabytes and a @code{G} suffix for gigabytes.
-
-See @ref{qemu_img_invocation} for more information.
-
-@node disk_images_snapshot_mode
-@subsection Snapshot mode
-
-If you use the option @option{-snapshot}, all disk images are
-considered as read only. When sectors in written, they are written in
-a temporary file created in @file{/tmp}. You can however force the
-write back to the raw disk images by using the @code{commit} monitor
-command (or @key{C-a s} in the serial console).
-
-@node vm_snapshots
-@subsection VM snapshots
-
-VM snapshots are snapshots of the complete virtual machine including
-CPU state, RAM, device state and the content of all the writable
-disks. In order to use VM snapshots, you must have at least one non
-removable and writable block device using the @code{qcow2} disk image
-format. Normally this device is the first virtual hard drive.
-
-Use the monitor command @code{savevm} to create a new VM snapshot or
-replace an existing one. A human readable name can be assigned to each
-snapshot in addition to its numerical ID.
-
-Use @code{loadvm} to restore a VM snapshot and @code{delvm} to remove
-a VM snapshot. @code{info snapshots} lists the available snapshots
-with their associated information:
-
-@example
-(qemu) info snapshots
-Snapshot devices: hda
-Snapshot list (from hda):
-ID TAG VM SIZE DATE VM CLOCK
-1 start 41M 2006-08-06 12:38:02 00:00:14.954
-2 40M 2006-08-06 12:43:29 00:00:18.633
-3 msys 40M 2006-08-06 12:44:04 00:00:23.514
-@end example
-
-A VM snapshot is made of a VM state info (its size is shown in
-@code{info snapshots}) and a snapshot of every writable disk image.
-The VM state info is stored in the first @code{qcow2} non removable
-and writable block device. The disk image snapshots are stored in
-every disk image. The size of a snapshot in a disk image is difficult
-to evaluate and is not shown by @code{info snapshots} because the
-associated disk sectors are shared among all the snapshots to save
-disk space (otherwise each snapshot would need a full copy of all the
-disk images).
-
-When using the (unrelated) @code{-snapshot} option
-(@ref{disk_images_snapshot_mode}), you can always make VM snapshots,
-but they are deleted as soon as you exit QEMU.
-
-VM snapshots currently have the following known limitations:
-@itemize
-@item
-They cannot cope with removable devices if they are removed or
-inserted after a snapshot is done.
-@item
-A few device drivers still have incomplete snapshot support so their
-state is not saved or restored properly (in particular USB).
-@end itemize
-
-@node qemu_img_invocation
-@subsection @code{qemu-img} Invocation
-
-@include qemu-img.texi
-
-@node host_drives
-@subsection Using host drives
-
-In addition to disk image files, QEMU can directly access host
-devices. We describe here the usage for QEMU version >= 0.8.3.
-
-@subsubsection Linux
-
-On Linux, you can directly use the host device filename instead of a
-disk image filename provided you have enough proviledge to access
-it. For example, use @file{/dev/cdrom} to access to the CDROM or
-@file{/dev/fd0} for the floppy.
-
-@table @code
-@item CD
-You can specify a CDROM device even if no CDROM is loaded. QEMU has
-specific code to detect CDROM insertion or removal. CDROM ejection by
-the guest OS is supported. Currently only data CDs are supported.
-@item Floppy
-You can specify a floppy device even if no floppy is loaded. Floppy
-removal is currently not detected accurately (if you change floppy
-without doing floppy access while the floppy is not loaded, the guest
-OS will think that the same floppy is loaded).
-@item Hard disks
-Hard disks can be used. Normally you must specify the whole disk
-(@file{/dev/hdb} instead of @file{/dev/hdb1}) so that the guest OS can
-see it as a partitioned disk. WARNING: unless you know what you do, it
-is better to only make READ-ONLY accesses to the hard disk otherwise
-you may corrupt your host data (use the @option{-snapshot} command
-line option or modify the device permissions accordingly).
-@end table
-
-@subsubsection Windows
-
-@table @code
-@item CD
-The prefered syntax is the drive letter (e.g. @file{d:}). The
-alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
-supported as an alias to the first CDROM drive.
-
-Currently there is no specific code to handle removable medias, so it
-is better to use the @code{change} or @code{eject} monitor commands to
-change or eject media.
-@item Hard disks
-Hard disks can be used with the syntax: @file{\\.\PhysicalDriveN}
-where @var{N} is the drive number (0 is the first hard disk).
-
-WARNING: unless you know what you do, it is better to only make
-READ-ONLY accesses to the hard disk otherwise you may corrupt your
-host data (use the @option{-snapshot} command line so that the
-modifications are written in a temporary file).
-@end table
-
-
-@subsubsection Mac OS X
-
-@file{/dev/cdrom} is an alias to the first CDROM.
-
-Currently there is no specific code to handle removable medias, so it
-is better to use the @code{change} or @code{eject} monitor commands to
-change or eject media.
-
-@node disk_images_fat_images
-@subsection Virtual FAT disk images
-
-QEMU can automatically create a virtual FAT disk image from a
-directory tree. In order to use it, just type:
-
-@example
-qemu linux.img -hdb fat:/my_directory
-@end example
-
-Then you access access to all the files in the @file{/my_directory}
-directory without having to copy them in a disk image or to export
-them via SAMBA or NFS. The default access is @emph{read-only}.
-
-Floppies can be emulated with the @code{:floppy:} option:
-
-@example
-qemu linux.img -fda fat:floppy:/my_directory
-@end example
-
-A read/write support is available for testing (beta stage) with the
-@code{:rw:} option:
-
-@example
-qemu linux.img -fda fat:floppy:rw:/my_directory
-@end example
-
-What you should @emph{never} do:
-@itemize
-@item use non-ASCII filenames ;
-@item use "-snapshot" together with ":rw:" ;
-@item expect it to work when loadvm'ing ;
-@item write to the FAT directory on the host system while accessing it with the guest system.
-@end itemize
-
-@node pcsys_network
-@section Network emulation
-
-QEMU can simulate several networks cards (NE2000 boards on the PC
-target) and can connect them to an arbitrary number of Virtual Local
-Area Networks (VLANs). Host TAP devices can be connected to any QEMU
-VLAN. VLAN can be connected between separate instances of QEMU to
-simulate large networks. For simpler usage, a non priviledged user mode
-network stack can replace the TAP device to have a basic network
-connection.
-
-@subsection VLANs
-
-QEMU simulates several VLANs. A VLAN can be symbolised as a virtual
-connection between several network devices. These devices can be for
-example QEMU virtual Ethernet cards or virtual Host ethernet devices
-(TAP devices).
-
-@subsection Using TAP network interfaces
-
-This is the standard way to connect QEMU to a real network. QEMU adds
-a virtual network device on your host (called @code{tapN}), and you
-can then configure it as if it was a real ethernet card.
-
-@subsubsection Linux host
-
-As an example, you can download the @file{linux-test-xxx.tar.gz}
-archive and copy the script @file{qemu-ifup} in @file{/etc} and
-configure properly @code{sudo} so that the command @code{ifconfig}
-contained in @file{qemu-ifup} can be executed as root. You must verify
-that your host kernel supports the TAP network interfaces: the
-device @file{/dev/net/tun} must be present.
-
-See @ref{sec_invocation} to have examples of command lines using the
-TAP network interfaces.
-
-@subsubsection Windows host
-
-There is a virtual ethernet driver for Windows 2000/XP systems, called
-TAP-Win32. But it is not included in standard QEMU for Windows,
-so you will need to get it separately. It is part of OpenVPN package,
-so download OpenVPN from : @url{http://openvpn.net/}.
-
-@subsection Using the user mode network stack
-
-By using the option @option{-net user} (default configuration if no
-@option{-net} option is specified), QEMU uses a completely user mode
-network stack (you don't need root priviledge to use the virtual
-network). The virtual network configuration is the following:
-
-@example
-
- QEMU VLAN <------> Firewall/DHCP server <-----> Internet
- | (10.0.2.2)
- |
- ----> DNS server (10.0.2.3)
- |
- ----> SMB server (10.0.2.4)
-@end example
-
-The QEMU VM behaves as if it was behind a firewall which blocks all
-incoming connections. You can use a DHCP client to automatically
-configure the network in the QEMU VM. The DHCP server assign addresses
-to the hosts starting from 10.0.2.15.
-
-In order to check that the user mode network is working, you can ping
-the address 10.0.2.2 and verify that you got an address in the range
-10.0.2.x from the QEMU virtual DHCP server.
-
-Note that @code{ping} is not supported reliably to the internet as it
-would require root priviledges. It means you can only ping the local
-router (10.0.2.2).
-
-When using the built-in TFTP server, the router is also the TFTP
-server.
-
-When using the @option{-redir} option, TCP or UDP connections can be
-redirected from the host to the guest. It allows for example to
-redirect X11, telnet or SSH connections.
-
-@subsection Connecting VLANs between QEMU instances
-
-Using the @option{-net socket} option, it is possible to make VLANs
-that span several QEMU instances. See @ref{sec_invocation} to have a
-basic example.
-
-@node direct_linux_boot
-@section Direct Linux Boot
-
-This section explains how to launch a Linux kernel inside QEMU without
-having to make a full bootable image. It is very useful for fast Linux
-kernel testing.
-
-The syntax is:
-@example
-qemu -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda"
-@end example
-
-Use @option{-kernel} to provide the Linux kernel image and
-@option{-append} to give the kernel command line arguments. The
-@option{-initrd} option can be used to provide an INITRD image.
-
-When using the direct Linux boot, a disk image for the first hard disk
-@file{hda} is required because its boot sector is used to launch the
-Linux kernel.
-
-If you do not need graphical output, you can disable it and redirect
-the virtual serial port and the QEMU monitor to the console with the
-@option{-nographic} option. The typical command line is:
-@example
-qemu -kernel arch/i386/boot/bzImage -hda root-2.4.20.img \
- -append "root=/dev/hda console=ttyS0" -nographic
-@end example
-
-Use @key{Ctrl-a c} to switch between the serial console and the
-monitor (@pxref{pcsys_keys}).
-
-@node pcsys_usb
-@section USB emulation
-
-QEMU emulates a PCI UHCI USB controller. You can virtually plug
-virtual USB devices or real host USB devices (experimental, works only
-on Linux hosts). Qemu will automatically create and connect virtual USB hubs
-as necessary to connect multiple USB devices.
-
-@menu
-* usb_devices::
-* host_usb_devices::
-@end menu
-@node usb_devices
-@subsection Connecting USB devices
-
-USB devices can be connected with the @option{-usbdevice} commandline option
-or the @code{usb_add} monitor command. Available devices are:
-
-@table @var
-@item @code{mouse}
-Virtual Mouse. This will override the PS/2 mouse emulation when activated.
-@item @code{tablet}
-Pointer device that uses absolute coordinates (like a touchscreen).
-This means qemu is able to report the mouse position without having
-to grab the mouse. Also overrides the PS/2 mouse emulation when activated.
-@item @code{disk:file}
-Mass storage device based on @var{file} (@pxref{disk_images})
-@item @code{host:bus.addr}
-Pass through the host device identified by @var{bus.addr}
-(Linux only)
-@item @code{host:vendor_id:product_id}
-Pass through the host device identified by @var{vendor_id:product_id}
-(Linux only)
-@end table
-
-@node host_usb_devices
-@subsection Using host USB devices on a Linux host
-
-WARNING: this is an experimental feature. QEMU will slow down when
-using it. USB devices requiring real time streaming (i.e. USB Video
-Cameras) are not supported yet.
-
-@enumerate
-@item If you use an early Linux 2.4 kernel, verify that no Linux driver
-is actually using the USB device. A simple way to do that is simply to
-disable the corresponding kernel module by renaming it from @file{mydriver.o}
-to @file{mydriver.o.disabled}.
-
-@item Verify that @file{/proc/bus/usb} is working (most Linux distributions should enable it by default). You should see something like that:
-@example
-ls /proc/bus/usb
-001 devices drivers
-@end example
-
-@item Since only root can access to the USB devices directly, you can either launch QEMU as root or change the permissions of the USB devices you want to use. For testing, the following suffices:
-@example
-chown -R myuid /proc/bus/usb
-@end example
-
-@item Launch QEMU and do in the monitor:
-@example
-info usbhost
- Device 1.2, speed 480 Mb/s
- Class 00: USB device 1234:5678, USB DISK
-@end example
-You should see the list of the devices you can use (Never try to use
-hubs, it won't work).
-
-@item Add the device in QEMU by using:
-@example
-usb_add host:1234:5678
-@end example
-
-Normally the guest OS should report that a new USB device is
-plugged. You can use the option @option{-usbdevice} to do the same.
-
-@item Now you can try to use the host USB device in QEMU.
-
-@end enumerate
-
-When relaunching QEMU, you may have to unplug and plug again the USB
-device to make it work again (this is a bug).
-
-@node gdb_usage
-@section GDB usage
-
-QEMU has a primitive support to work with gdb, so that you can do
-'Ctrl-C' while the virtual machine is running and inspect its state.
-
-In order to use gdb, launch qemu with the '-s' option. It will wait for a
-gdb connection:
-@example
-> qemu -s -kernel arch/i386/boot/bzImage -hda root-2.4.20.img \
- -append "root=/dev/hda"
-Connected to host network interface: tun0
-Waiting gdb connection on port 1234
-@end example
-
-Then launch gdb on the 'vmlinux' executable:
-@example
-> gdb vmlinux
-@end example
-
-In gdb, connect to QEMU:
-@example
-(gdb) target remote localhost:1234
-@end example
-
-Then you can use gdb normally. For example, type 'c' to launch the kernel:
-@example
-(gdb) c
-@end example
-
-Here are some useful tips in order to use gdb on system code:
-
-@enumerate
-@item
-Use @code{info reg} to display all the CPU registers.
-@item
-Use @code{x/10i $eip} to display the code at the PC position.
-@item
-Use @code{set architecture i8086} to dump 16 bit code. Then use
-@code{x/10i $cs*16+$eip} to dump the code at the PC position.
-@end enumerate
-
-@node pcsys_os_specific
-@section Target OS specific information
-
-@subsection Linux
-
-To have access to SVGA graphic modes under X11, use the @code{vesa} or
-the @code{cirrus} X11 driver. For optimal performances, use 16 bit
-color depth in the guest and the host OS.
-
-When using a 2.6 guest Linux kernel, you should add the option
-@code{clock=pit} on the kernel command line because the 2.6 Linux
-kernels make very strict real time clock checks by default that QEMU
-cannot simulate exactly.
-
-When using a 2.6 guest Linux kernel, verify that the 4G/4G patch is
-not activated because QEMU is slower with this patch. The QEMU
-Accelerator Module is also much slower in this case. Earlier Fedora
-Core 3 Linux kernel (< 2.6.9-1.724_FC3) were known to incorporte this
-patch by default. Newer kernels don't have it.
-
-@subsection Windows
-
-If you have a slow host, using Windows 95 is better as it gives the
-best speed. Windows 2000 is also a good choice.
-
-@subsubsection SVGA graphic modes support
-
-QEMU emulates a Cirrus Logic GD5446 Video
-card. All Windows versions starting from Windows 95 should recognize
-and use this graphic card. For optimal performances, use 16 bit color
-depth in the guest and the host OS.
-
-If you are using Windows XP as guest OS and if you want to use high
-resolution modes which the Cirrus Logic BIOS does not support (i.e. >=
-1280x1024x16), then you should use the VESA VBE virtual graphic card
-(option @option{-std-vga}).
-
-@subsubsection CPU usage reduction
-
-Windows 9x does not correctly use the CPU HLT
-instruction. The result is that it takes host CPU cycles even when
-idle. You can install the utility from
-@url{http://www.user.cityline.ru/~maxamn/amnhltm.zip} to solve this
-problem. Note that no such tool is needed for NT, 2000 or XP.
-
-@subsubsection Windows 2000 disk full problem
-
-Windows 2000 has a bug which gives a disk full problem during its
-installation. When installing it, use the @option{-win2k-hack} QEMU
-option to enable a specific workaround. After Windows 2000 is
-installed, you no longer need this option (this option slows down the
-IDE transfers).
-
-@subsubsection Windows 2000 shutdown
-
-Windows 2000 cannot automatically shutdown in QEMU although Windows 98
-can. It comes from the fact that Windows 2000 does not automatically
-use the APM driver provided by the BIOS.
-
-In order to correct that, do the following (thanks to Struan
-Bartlett): go to the Control Panel => Add/Remove Hardware & Next =>
-Add/Troubleshoot a device => Add a new device & Next => No, select the
-hardware from a list & Next => NT Apm/Legacy Support & Next => Next
-(again) a few times. Now the driver is installed and Windows 2000 now
-correctly instructs QEMU to shutdown at the appropriate moment.
-
-@subsubsection Share a directory between Unix and Windows
-
-See @ref{sec_invocation} about the help of the option @option{-smb}.
-
-@subsubsection Windows XP security problem
-
-Some releases of Windows XP install correctly but give a security
-error when booting:
-@example
-A problem is preventing Windows from accurately checking the
-license for this computer. Error code: 0x800703e6.
-@end example
-
-The workaround is to install a service pack for XP after a boot in safe
-mode. Then reboot, and the problem should go away. Since there is no
-network while in safe mode, its recommended to download the full
-installation of SP1 or SP2 and transfer that via an ISO or using the
-vvfat block device ("-hdb fat:directory_which_holds_the_SP").
-
-@subsection MS-DOS and FreeDOS
-
-@subsubsection CPU usage reduction
-
-DOS does not correctly use the CPU HLT instruction. The result is that
-it takes host CPU cycles even when idle. You can install the utility
-from @url{http://www.vmware.com/software/dosidle210.zip} to solve this
-problem.
-
-@node QEMU System emulator for non PC targets
-@chapter QEMU System emulator for non PC targets
-
-QEMU is a generic emulator and it emulates many non PC
-machines. Most of the options are similar to the PC emulator. The
-differences are mentionned in the following sections.
-
-@menu
-* QEMU PowerPC System emulator::
-* Sparc32 System emulator invocation::
-* Sparc64 System emulator invocation::
-* MIPS System emulator invocation::
-* ARM System emulator invocation::
-@end menu
-
-@node QEMU PowerPC System emulator
-@section QEMU PowerPC System emulator
-
-Use the executable @file{qemu-system-ppc} to simulate a complete PREP
-or PowerMac PowerPC system.
-
-QEMU emulates the following PowerMac peripherals:
-
-@itemize @minus
-@item
-UniNorth PCI Bridge
-@item
-PCI VGA compatible card with VESA Bochs Extensions
-@item
-2 PMAC IDE interfaces with hard disk and CD-ROM support
-@item
-NE2000 PCI adapters
-@item
-Non Volatile RAM
-@item
-VIA-CUDA with ADB keyboard and mouse.
-@end itemize
-
-QEMU emulates the following PREP peripherals:
-
-@itemize @minus
-@item
-PCI Bridge
-@item
-PCI VGA compatible card with VESA Bochs Extensions
-@item
-2 IDE interfaces with hard disk and CD-ROM support
-@item
-Floppy disk
-@item
-NE2000 network adapters
-@item
-Serial port
-@item
-PREP Non Volatile RAM
-@item
-PC compatible keyboard and mouse.
-@end itemize
-
-QEMU uses the Open Hack'Ware Open Firmware Compatible BIOS available at
-@url{http://perso.magic.fr/l_indien/OpenHackWare/index.htm}.
-
-@c man begin OPTIONS
-
-The following options are specific to the PowerPC emulation:
-
-@table @option
-
-@item -g WxH[xDEPTH]
-
-Set the initial VGA graphic mode. The default is 800x600x15.
-
-@end table
-
-@c man end
-
-
-More information is available at
-@url{http://perso.magic.fr/l_indien/qemu-ppc/}.
-
-@node Sparc32 System emulator invocation
-@section Sparc32 System emulator invocation
-
-Use the executable @file{qemu-system-sparc} to simulate a SparcStation 5
-(sun4m architecture). The emulation is somewhat complete.
-
-QEMU emulates the following sun4m peripherals:
-
-@itemize @minus
-@item
-IOMMU
-@item
-TCX Frame buffer
-@item
-Lance (Am7990) Ethernet
-@item
-Non Volatile RAM M48T08
-@item
-Slave I/O: timers, interrupt controllers, Zilog serial ports, keyboard
-and power/reset logic
-@item
-ESP SCSI controller with hard disk and CD-ROM support
-@item
-Floppy drive
-@end itemize
-
-The number of peripherals is fixed in the architecture.
-
-Since version 0.8.2, QEMU uses OpenBIOS
-@url{http://www.openbios.org/}. OpenBIOS is a free (GPL v2) portable
-firmware implementation. The goal is to implement a 100% IEEE
-1275-1994 (referred to as Open Firmware) compliant firmware.
-
-A sample Linux 2.6 series kernel and ram disk image are available on
-the QEMU web site. Please note that currently NetBSD, OpenBSD or
-Solaris kernels don't work.
-
-@c man begin OPTIONS
-
-The following options are specific to the Sparc emulation:
-
-@table @option
-
-@item -g WxH
-
-Set the initial TCX graphic mode. The default is 1024x768.
-
-@end table
-
-@c man end
-
-@node Sparc64 System emulator invocation
-@section Sparc64 System emulator invocation
-
-Use the executable @file{qemu-system-sparc64} to simulate a Sun4u machine.
-The emulator is not usable for anything yet.
-
-QEMU emulates the following sun4u peripherals:
-
-@itemize @minus
-@item
-UltraSparc IIi APB PCI Bridge
-@item
-PCI VGA compatible card with VESA Bochs Extensions
-@item
-Non Volatile RAM M48T59
-@item
-PC-compatible serial ports
-@end itemize
-
-@node MIPS System emulator invocation
-@section MIPS System emulator invocation
-
-Use the executable @file{qemu-system-mips} to simulate a MIPS machine.
-The emulator is able to boot a Linux kernel and to run a Linux Debian
-installation from NFS. The following devices are emulated:
-
-@itemize @minus
-@item
-MIPS R4K CPU
-@item
-PC style serial port
-@item
-NE2000 network card
-@end itemize
-
-More information is available in the QEMU mailing-list archive.
-
-@node ARM System emulator invocation
-@section ARM System emulator invocation
-
-Use the executable @file{qemu-system-arm} to simulate a ARM
-machine. The ARM Integrator/CP board is emulated with the following
-devices:
-
-@itemize @minus
-@item
-ARM926E or ARM1026E CPU
-@item
-Two PL011 UARTs
-@item
-SMC 91c111 Ethernet adapter
-@item
-PL110 LCD controller
-@item
-PL050 KMI with PS/2 keyboard and mouse.
-@end itemize
-
-The ARM Versatile baseboard is emulated with the following devices:
-
-@itemize @minus
-@item
-ARM926E CPU
-@item
-PL190 Vectored Interrupt Controller
-@item
-Four PL011 UARTs
-@item
-SMC 91c111 Ethernet adapter
-@item
-PL110 LCD controller
-@item
-PL050 KMI with PS/2 keyboard and mouse.
-@item
-PCI host bridge. Note the emulated PCI bridge only provides access to
-PCI memory space. It does not provide access to PCI IO space.
-This means some devices (eg. ne2k_pci NIC) are not useable, and others
-(eg. rtl8139 NIC) are only useable when the guest drivers use the memory
-mapped control registers.
-@item
-PCI OHCI USB controller.
-@item
-LSI53C895A PCI SCSI Host Bus Adapter with hard disk and CD-ROM devices.
-@end itemize
-
-A Linux 2.6 test image is available on the QEMU web site. More
-information is available in the QEMU mailing-list archive.
-
-@node QEMU User space emulator
-@chapter QEMU User space emulator
-
-@menu
-* Supported Operating Systems ::
-* Linux User space emulator::
-* Mac OS X/Darwin User space emulator ::
-@end menu
-
-@node Supported Operating Systems
-@section Supported Operating Systems
-
-The following OS are supported in user space emulation:
-
-@itemize @minus
-@item
-Linux (refered as qemu-linux-user)
-@item
-Mac OS X/Darwin (refered as qemu-darwin-user)
-@end itemize
-
-@node Linux User space emulator
-@section Linux User space emulator
-
-@menu
-* Quick Start::
-* Wine launch::
-* Command line options::
-* Other binaries::
-@end menu
-
-@node Quick Start
-@subsection Quick Start
-
-In order to launch a Linux process, QEMU needs the process executable
-itself and all the target (x86) dynamic libraries used by it.
-
-@itemize
-
-@item On x86, you can just try to launch any process by using the native
-libraries:
-
-@example
-qemu-i386 -L / /bin/ls
-@end example
-
-@code{-L /} tells that the x86 dynamic linker must be searched with a
-@file{/} prefix.
-
-@item Since QEMU is also a linux process, you can launch qemu with qemu (NOTE: you can only do that if you compiled QEMU from the sources):
-
-@example
-qemu-i386 -L / qemu-i386 -L / /bin/ls
-@end example
-
-@item On non x86 CPUs, you need first to download at least an x86 glibc
-(@file{qemu-runtime-i386-XXX-.tar.gz} on the QEMU web page). Ensure that
-@code{LD_LIBRARY_PATH} is not set:
-
-@example
-unset LD_LIBRARY_PATH
-@end example
-
-Then you can launch the precompiled @file{ls} x86 executable:
-
-@example
-qemu-i386 tests/i386/ls
-@end example
-You can look at @file{qemu-binfmt-conf.sh} so that
-QEMU is automatically launched by the Linux kernel when you try to
-launch x86 executables. It requires the @code{binfmt_misc} module in the
-Linux kernel.
-
-@item The x86 version of QEMU is also included. You can try weird things such as:
-@example
-qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 \
- /usr/local/qemu-i386/bin/ls-i386
-@end example
-
-@end itemize
-
-@node Wine launch
-@subsection Wine launch
-
-@itemize
-
-@item Ensure that you have a working QEMU with the x86 glibc
-distribution (see previous section). In order to verify it, you must be
-able to do:
-
-@example
-qemu-i386 /usr/local/qemu-i386/bin/ls-i386
-@end example
-
-@item Download the binary x86 Wine install
-(@file{qemu-XXX-i386-wine.tar.gz} on the QEMU web page).
-
-@item Configure Wine on your account. Look at the provided script
-@file{/usr/local/qemu-i386/@/bin/wine-conf.sh}. Your previous
-@code{$@{HOME@}/.wine} directory is saved to @code{$@{HOME@}/.wine.org}.
-
-@item Then you can try the example @file{putty.exe}:
-
-@example
-qemu-i386 /usr/local/qemu-i386/wine/bin/wine \
- /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe
-@end example
-
-@end itemize
-
-@node Command line options
-@subsection Command line options
-
-@example
-usage: qemu-i386 [-h] [-d] [-L path] [-s size] program [arguments...]
-@end example
-
-@table @option
-@item -h
-Print the help
-@item -L path
-Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
-@item -s size
-Set the x86 stack size in bytes (default=524288)
-@end table
-
-Debug options:
-
-@table @option
-@item -d
-Activate log (logfile=/tmp/qemu.log)
-@item -p pagesize
-Act as if the host page size was 'pagesize' bytes
-@end table
-
-@node Other binaries
-@subsection Other binaries
-
-@command{qemu-arm} is also capable of running ARM "Angel" semihosted ELF
-binaries (as implemented by the arm-elf and arm-eabi Newlib/GDB
-configurations), and arm-uclinux bFLT format binaries.
-
-@command{qemu-m68k} is capable of running semihosted binaries using the BDM
-(m5xxx-ram-hosted.ld) or m68k-sim (sim.ld) syscall interfaces, and
-coldfire uClinux bFLT format binaries.
-
-The binary format is detected automatically.
-
-@node Mac OS X/Darwin User space emulator
-@section Mac OS X/Darwin User space emulator
-
-@menu
-* Mac OS X/Darwin Status::
-* Mac OS X/Darwin Quick Start::
-* Mac OS X/Darwin Command line options::
-@end menu
-
-@node Mac OS X/Darwin Status
-@subsection Mac OS X/Darwin Status
-
-@itemize @minus
-@item
-target x86 on x86: Most apps (Cocoa and Carbon too) works. [1]
-@item
-target PowerPC on x86: Not working as the ppc commpage can't be mapped (yet!)
-@item
-target x86 on x86: Most apps (Cocoa and Carbon too) works. [1]
-@item
-target x86 on PowerPC: most utilities work. Cocoa and Carbon apps are not yet supported.
-@end itemize
-
-[1] If you're host commpage can be executed by qemu.
-
-@node Mac OS X/Darwin Quick Start
-@subsection Quick Start
-
-In order to launch a Mac OS X/Darwin process, QEMU needs the process executable
-itself and all the target dynamic libraries used by it. If you don't have the FAT
-libraries (you're running Mac OS X/ppc) you'll need to obtain it from a Mac OS X
-CD or compile them by hand.
-
-@itemize
-
-@item On x86, you can just try to launch any process by using the native
-libraries:
-
-@example
-qemu-darwin-i386 /bin/ls
-@end example
-
-or to run the ppc version of the executable:
-
-@example
-qemu-darwin-ppc /bin/ls
-@end example
-
-@item On ppc, you'll have to tell qemu where your x86 libraries (and dynamic linker)
-are installed:
-
-@example
-qemu-darwin-i386 -L /opt/x86_root/ /bin/ls
-@end example
-
-@code{-L /opt/x86_root/} tells that the dynamic linker (dyld) path is in
-@file{/opt/x86_root/usr/bin/dyld}.
-
-@end itemize
-
-@node Mac OS X/Darwin Command line options
-@subsection Command line options
-
-@example
-usage: qemu-darwin-i386 [-h] [-d] [-L path] [-s size] program [arguments...]
-@end example
-
-@table @option
-@item -h
-Print the help
-@item -L path
-Set the library root path (default=/)
-@item -s size
-Set the stack size in bytes (default=524288)
-@end table
-
-Debug options:
-
-@table @option
-@item -d
-Activate log (logfile=/tmp/qemu.log)
-@item -p pagesize
-Act as if the host page size was 'pagesize' bytes
-@end table
-
-@node compilation
-@chapter Compilation from the sources
-
-@menu
-* Linux/Unix::
-* Windows::
-* Cross compilation for Windows with Linux::
-* Mac OS X::
-@end menu
-
-@node Linux/Unix
-@section Linux/Unix
-
-@subsection Compilation
-
-First you must decompress the sources:
-@example
-cd /tmp
-tar zxvf qemu-x.y.z.tar.gz
-cd qemu-x.y.z
-@end example
-
-Then you configure QEMU and build it (usually no options are needed):
-@example
-./configure
-make
-@end example
-
-Then type as root user:
-@example
-make install
-@end example
-to install QEMU in @file{/usr/local}.
-
-@subsection GCC version
-
-In order to compile QEMU successfully, it is very important that you
-have the right tools. The most important one is gcc. On most hosts and
-in particular on x86 ones, @emph{gcc 4.x is not supported}. If your
-Linux distribution includes a gcc 4.x compiler, you can usually
-install an older version (it is invoked by @code{gcc32} or
-@code{gcc34}). The QEMU configure script automatically probes for
-these older versions so that usally you don't have to do anything.
-
-@node Windows
-@section Windows
-
-@itemize
-@item Install the current versions of MSYS and MinGW from
-@url{http://www.mingw.org/}. You can find detailed installation
-instructions in the download section and the FAQ.
-
-@item Download
-the MinGW development library of SDL 1.2.x
-(@file{SDL-devel-1.2.x-@/mingw32.tar.gz}) from
-@url{http://www.libsdl.org}. Unpack it in a temporary place, and
-unpack the archive @file{i386-mingw32msvc.tar.gz} in the MinGW tool
-directory. Edit the @file{sdl-config} script so that it gives the
-correct SDL directory when invoked.
-
-@item Extract the current version of QEMU.
-
-@item Start the MSYS shell (file @file{msys.bat}).
-
-@item Change to the QEMU directory. Launch @file{./configure} and
-@file{make}. If you have problems using SDL, verify that
-@file{sdl-config} can be launched from the MSYS command line.
-
-@item You can install QEMU in @file{Program Files/Qemu} by typing
-@file{make install}. Don't forget to copy @file{SDL.dll} in
-@file{Program Files/Qemu}.
-
-@end itemize
-
-@node Cross compilation for Windows with Linux
-@section Cross compilation for Windows with Linux
-
-@itemize
-@item
-Install the MinGW cross compilation tools available at
-@url{http://www.mingw.org/}.
-
-@item
-Install the Win32 version of SDL (@url{http://www.libsdl.org}) by
-unpacking @file{i386-mingw32msvc.tar.gz}. Set up the PATH environment
-variable so that @file{i386-mingw32msvc-sdl-config} can be launched by
-the QEMU configuration script.
-
-@item
-Configure QEMU for Windows cross compilation:
-@example
-./configure --enable-mingw32
-@end example
-If necessary, you can change the cross-prefix according to the prefix
-choosen for the MinGW tools with --cross-prefix. You can also use
---prefix to set the Win32 install path.
-
-@item You can install QEMU in the installation directory by typing
-@file{make install}. Don't forget to copy @file{SDL.dll} in the
-installation directory.
-
-@end itemize
-
-Note: Currently, Wine does not seem able to launch
-QEMU for Win32.
-
-@node Mac OS X
-@section Mac OS X
-
-The Mac OS X patches are not fully merged in QEMU, so you should look
-at the QEMU mailing list archive to have all the necessary
-information.
-
-@node Index
-@chapter Index
-@printindex cp
-
-@bye
diff --git a/tools/ioemu/qemu-img.c b/tools/ioemu/qemu-img.c
deleted file mode 100644
index 0fdd58a136..0000000000
--- a/tools/ioemu/qemu-img.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * QEMU disk image utility
- *
- * Copyright (c) 2003-2007 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-void *get_mmap_addr(unsigned long size)
-{
- return NULL;
-}
-
-void qemu_free(void *ptr)
-{
- free(ptr);
-}
-
-void *qemu_malloc(size_t size)
-{
- return malloc(size);
-}
-
-void *qemu_mallocz(size_t size)
-{
- void *ptr;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- memset(ptr, 0, size);
- return ptr;
-}
-
-char *qemu_strdup(const char *str)
-{
- char *ptr;
- ptr = qemu_malloc(strlen(str) + 1);
- if (!ptr)
- return NULL;
- strcpy(ptr, str);
- return ptr;
-}
-
-void term_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-}
-
-void term_print_filename(const char *filename)
-{
- term_printf(filename);
-}
-
-void __attribute__((noreturn)) error(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "qemu-img: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- exit(1);
- va_end(ap);
-}
-
-static void format_print(void *opaque, const char *name)
-{
- printf(" %s", name);
-}
-
-void help(void)
-{
- printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2007 Fabrice Bellard\n"
- "usage: qemu-img command [command options]\n"
- "QEMU disk image utility\n"
- "\n"
- "Command syntax:\n"
- " create [-e] [-b base_image] [-f fmt] filename [size]\n"
- " commit [-f fmt] filename\n"
- " convert [-c] [-e] [-f fmt] filename [-O output_fmt] output_filename\n"
- " info [-f fmt] filename\n"
- "\n"
- "Command parameters:\n"
- " 'filename' is a disk image filename\n"
- " 'base_image' is the read-only disk image which is used as base for a copy on\n"
- " write image; the copy on write image only stores the modified data\n"
- " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
- " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
- " and 'G' (gigabyte) are supported\n"
- " 'output_filename' is the destination disk image filename\n"
- " 'output_fmt' is the destination format\n"
- " '-c' indicates that target image must be compressed (qcow format only)\n"
- " '-e' indicates that the target image must be encrypted (qcow format only)\n"
- );
- printf("\nSupported format:");
- bdrv_iterate_format(format_print, NULL);
- printf("\n");
- exit(1);
-}
-
-#if defined(WIN32)
-/* XXX: put correct support for win32 */
-static int read_password(char *buf, int buf_size)
-{
- int c, i;
- printf("Password: ");
- fflush(stdout);
- i = 0;
- for(;;) {
- c = getchar();
- if (c == '\n')
- break;
- if (i < (buf_size - 1))
- buf[i++] = c;
- }
- buf[i] = '\0';
- return 0;
-}
-
-#else
-
-#include <termios.h>
-
-static struct termios oldtty;
-
-static void term_exit(void)
-{
- tcsetattr (0, TCSANOW, &oldtty);
-}
-
-static void term_init(void)
-{
- struct termios tty;
-
- tcgetattr (0, &tty);
- oldtty = tty;
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
- tty.c_cflag &= ~(CSIZE|PARENB);
- tty.c_cflag |= CS8;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VTIME] = 0;
-
- tcsetattr (0, TCSANOW, &tty);
-
- atexit(term_exit);
-}
-
-int read_password(char *buf, int buf_size)
-{
- uint8_t ch;
- int i, ret;
-
- printf("password: ");
- fflush(stdout);
- term_init();
- i = 0;
- for(;;) {
- ret = read(0, &ch, 1);
- if (ret == -1) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- ret = -1;
- break;
- }
- } else if (ret == 0) {
- ret = -1;
- break;
- } else {
- if (ch == '\r') {
- ret = 0;
- break;
- }
- if (i < (buf_size - 1))
- buf[i++] = ch;
- }
- }
- term_exit();
- buf[i] = '\0';
- printf("\n");
- return ret;
-}
-#endif
-
-static BlockDriverState *bdrv_new_open(const char *filename,
- const char *fmt)
-{
- BlockDriverState *bs;
- BlockDriver *drv;
- char password[256];
-
- bs = bdrv_new("");
- if (!bs)
- error("Not enough memory");
- if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- } else {
- drv = NULL;
- }
- if (bdrv_open2(bs, filename, 0, drv) < 0) {
- error("Could not open '%s'", filename);
- }
- if (bdrv_is_encrypted(bs)) {
- printf("Disk image '%s' is encrypted.\n", filename);
- if (read_password(password, sizeof(password)) < 0)
- error("No password given");
- if (bdrv_set_key(bs, password) < 0)
- error("invalid password");
- }
- return bs;
-}
-
-static int img_create(int argc, char **argv)
-{
- int c, ret, encrypted;
- const char *fmt = "raw";
- const char *filename;
- const char *base_filename = NULL;
- int64_t size;
- const char *p;
- BlockDriver *drv;
-
- encrypted = 0;
- for(;;) {
- c = getopt(argc, argv, "b:f:he");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'b':
- base_filename = optarg;
- break;
- case 'f':
- fmt = optarg;
- break;
- case 'e':
- encrypted = 1;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
- size = 0;
- if (base_filename) {
- BlockDriverState *bs;
- bs = bdrv_new_open(base_filename, NULL);
- bdrv_get_geometry(bs, &size);
- size *= 512;
- bdrv_delete(bs);
- } else {
- if (optind >= argc)
- help();
- p = argv[optind];
- size = strtoul(p, (char **)&p, 0);
- if (*p == 'M') {
- size *= 1024 * 1024;
- } else if (*p == 'G') {
- size *= 1024 * 1024 * 1024;
- } else if (*p == 'k' || *p == 'K' || *p == '\0') {
- size *= 1024;
- } else {
- help();
- }
- }
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- printf("Formating '%s', fmt=%s",
- filename, fmt);
- if (encrypted)
- printf(", encrypted");
- if (base_filename) {
- printf(", backing_file=%s",
- base_filename);
- }
- printf(", size=%" PRId64 " kB\n", (int64_t) (size / 1024));
- ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);
- if (ret < 0) {
- if (ret == -ENOTSUP) {
- error("Formatting or formatting option not supported for file format '%s'", fmt);
- } else {
- error("Error while formatting");
- }
- }
- return 0;
-}
-
-static int img_commit(int argc, char **argv)
-{
- int c, ret;
- const char *filename, *fmt;
- BlockDriver *drv;
- BlockDriverState *bs;
-
- fmt = NULL;
- for(;;) {
- c = getopt(argc, argv, "f:h");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'f':
- fmt = optarg;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
-
- bs = bdrv_new("");
- if (!bs)
- error("Not enough memory");
- if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- } else {
- drv = NULL;
- }
- if (bdrv_open2(bs, filename, 0, drv) < 0) {
- error("Could not open '%s'", filename);
- }
- ret = bdrv_commit(bs);
- switch(ret) {
- case 0:
- printf("Image committed.\n");
- break;
- case -ENOENT:
- error("No disk inserted");
- break;
- case -EACCES:
- error("Image is read-only");
- break;
- case -ENOTSUP:
- error("Image is already committed");
- break;
- default:
- error("Error while committing image");
- break;
- }
-
- bdrv_delete(bs);
- return 0;
-}
-
-static int is_not_zero(const uint8_t *sector, int len)
-{
- int i;
- len >>= 2;
- for(i = 0;i < len; i++) {
- if (((uint32_t *)sector)[i] != 0)
- return 1;
- }
- return 0;
-}
-
-static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
-{
- int v, i;
-
- if (n <= 0) {
- *pnum = 0;
- return 0;
- }
- v = is_not_zero(buf, 512);
- for(i = 1; i < n; i++) {
- buf += 512;
- if (v != is_not_zero(buf, 512))
- break;
- }
- *pnum = i;
- return v;
-}
-
-#define IO_BUF_SIZE 65536
-
-static int img_convert(int argc, char **argv)
-{
- int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt;
- const char *filename, *fmt, *out_fmt, *out_filename;
- BlockDriver *drv;
- BlockDriverState *bs, *out_bs;
- int64_t total_sectors, nb_sectors, sector_num;
- uint8_t buf[IO_BUF_SIZE];
- const uint8_t *buf1;
- BlockDriverInfo bdi;
-
- fmt = NULL;
- out_fmt = "raw";
- compress = 0;
- encrypt = 0;
- for(;;) {
- c = getopt(argc, argv, "f:O:hce");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'f':
- fmt = optarg;
- break;
- case 'O':
- out_fmt = optarg;
- break;
- case 'c':
- compress = 1;
- break;
- case 'e':
- encrypt = 1;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
- if (optind >= argc)
- help();
- out_filename = argv[optind++];
-
- bs = bdrv_new_open(filename, fmt);
-
- drv = bdrv_find_format(out_fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- if (compress && drv != &bdrv_qcow && drv != &bdrv_qcow2)
- error("Compression not supported for this file format");
- if (encrypt && drv != &bdrv_qcow && drv != &bdrv_qcow2)
- error("Encryption not supported for this file format");
- if (compress && encrypt)
- error("Compression and encryption not supported at the same time");
- bdrv_get_geometry(bs, &total_sectors);
- ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);
- if (ret < 0) {
- if (ret == -ENOTSUP) {
- error("Formatting not supported for file format '%s'", fmt);
- } else {
- error("Error while formatting '%s'", out_filename);
- }
- }
-
- out_bs = bdrv_new_open(out_filename, out_fmt);
-
- if (compress) {
- if (bdrv_get_info(out_bs, &bdi) < 0)
- error("could not get block driver info");
- cluster_size = bdi.cluster_size;
- if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
- error("invalid cluster size");
- cluster_sectors = cluster_size >> 9;
- sector_num = 0;
- for(;;) {
- nb_sectors = total_sectors - sector_num;
- if (nb_sectors <= 0)
- break;
- if (nb_sectors >= cluster_sectors)
- n = cluster_sectors;
- else
- n = nb_sectors;
- if (bdrv_read(bs, sector_num, buf, n) < 0)
- error("error while reading");
- if (n < cluster_sectors)
- memset(buf + n * 512, 0, cluster_size - n * 512);
- if (is_not_zero(buf, cluster_size)) {
- if (bdrv_write_compressed(out_bs, sector_num, buf,
- cluster_sectors) != 0)
- error("error while compressing sector %" PRId64,
- sector_num);
- }
- sector_num += n;
- }
- /* signal EOF to align */
- bdrv_write_compressed(out_bs, 0, NULL, 0);
- } else {
- sector_num = 0;
- for(;;) {
- nb_sectors = total_sectors - sector_num;
- if (nb_sectors <= 0)
- break;
- if (nb_sectors >= (IO_BUF_SIZE / 512))
- n = (IO_BUF_SIZE / 512);
- else
- n = nb_sectors;
- if (bdrv_read(bs, sector_num, buf, n) < 0)
- error("error while reading");
- /* NOTE: at the same time we convert, we do not write zero
- sectors to have a chance to compress the image. Ideally, we
- should add a specific call to have the info to go faster */
- buf1 = buf;
- while (n > 0) {
- if (is_allocated_sectors(buf1, n, &n1)) {
- if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
- error("error while writing");
- }
- sector_num += n1;
- n -= n1;
- buf1 += n1 * 512;
- }
- }
- }
- bdrv_delete(out_bs);
- bdrv_delete(bs);
- return 0;
-}
-
-#ifdef _WIN32
-static int64_t get_allocated_file_size(const char *filename)
-{
- typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
- get_compressed_t get_compressed;
- struct _stati64 st;
-
- /* WinNT support GetCompressedFileSize to determine allocate size */
- get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
- if (get_compressed) {
- DWORD high, low;
- low = get_compressed(filename, &high);
- if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
- return (((int64_t) high) << 32) + low;
- }
-
- if (_stati64(filename, &st) < 0)
- return -1;
- return st.st_size;
-}
-#else
-static int64_t get_allocated_file_size(const char *filename)
-{
- struct stat st;
- if (stat(filename, &st) < 0)
- return -1;
- return (int64_t)st.st_blocks * 512;
-}
-#endif
-
-static void dump_snapshots(BlockDriverState *bs)
-{
- QEMUSnapshotInfo *sn_tab, *sn;
- int nb_sns, i;
- char buf[256];
-
- nb_sns = bdrv_snapshot_list(bs, &sn_tab);
- if (nb_sns <= 0)
- return;
- printf("Snapshot list:\n");
- printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
- for(i = 0; i < nb_sns; i++) {
- sn = &sn_tab[i];
- printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
- }
- qemu_free(sn_tab);
-}
-
-static int img_info(int argc, char **argv)
-{
- int c;
- const char *filename, *fmt;
- BlockDriver *drv;
- BlockDriverState *bs;
- char fmt_name[128], size_buf[128], dsize_buf[128];
- int64_t total_sectors, allocated_size;
- char backing_filename[PATH_MAX];
- char backing_filename2[PATH_MAX];
- BlockDriverInfo bdi;
-
- fmt = NULL;
- for(;;) {
- c = getopt(argc, argv, "f:h");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'f':
- fmt = optarg;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
-
- bs = bdrv_new("");
- if (!bs)
- error("Not enough memory");
- if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- } else {
- drv = NULL;
- }
- if (bdrv_open2(bs, filename, 0, drv) < 0) {
- error("Could not open '%s'", filename);
- }
- bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
- bdrv_get_geometry(bs, &total_sectors);
- get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
- allocated_size = get_allocated_file_size(filename);
- if (allocated_size < 0)
- sprintf(dsize_buf, "unavailable");
- else
- get_human_readable_size(dsize_buf, sizeof(dsize_buf),
- allocated_size);
- printf("image: %s\n"
- "file format: %s\n"
- "virtual size: %s (%" PRId64 " bytes)\n"
- "disk size: %s\n",
- filename, fmt_name, size_buf,
- (total_sectors * 512),
- dsize_buf);
- if (bdrv_is_encrypted(bs))
- printf("encrypted: yes\n");
- if (bdrv_get_info(bs, &bdi) >= 0) {
- if (bdi.cluster_size != 0)
- printf("cluster_size: %d\n", bdi.cluster_size);
- }
- bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
- if (backing_filename[0] != '\0') {
- path_combine(backing_filename2, sizeof(backing_filename2),
- filename, backing_filename);
- printf("backing file: %s (actual path: %s)\n",
- backing_filename,
- backing_filename2);
- }
- dump_snapshots(bs);
- bdrv_delete(bs);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- const char *cmd;
-
- bdrv_init();
- if (argc < 2)
- help();
- cmd = argv[1];
- optind++;
- if (!strcmp(cmd, "create")) {
- img_create(argc, argv);
- } else if (!strcmp(cmd, "commit")) {
- img_commit(argc, argv);
- } else if (!strcmp(cmd, "convert")) {
- img_convert(argc, argv);
- } else if (!strcmp(cmd, "info")) {
- img_info(argc, argv);
- } else {
- help();
- }
- return 0;
-}
diff --git a/tools/ioemu/qemu-img.texi b/tools/ioemu/qemu-img.texi
deleted file mode 100644
index 1f01dce162..0000000000
--- a/tools/ioemu/qemu-img.texi
+++ /dev/null
@@ -1,130 +0,0 @@
-@example
-@c man begin SYNOPSIS
-usage: qemu-img command [command options]
-@c man end
-@end example
-
-@c man begin OPTIONS
-
-The following commands are supported:
-@table @option
-@item create [-e] [-b @var{base_image}] [-f @var{fmt}] @var{filename} [@var{size}]
-@item commit [-f @var{fmt}] @var{filename}
-@item convert [-c] [-e] [-f @var{fmt}] @var{filename} [-O @var{output_fmt}] @var{output_filename}
-@item info [-f @var{fmt}] @var{filename}
-@end table
-
-Command parameters:
-@table @var
-@item filename
- is a disk image filename
-@item base_image
-is the read-only disk image which is used as base for a copy on
- write image; the copy on write image only stores the modified data
-
-@item fmt
-is the disk image format. It is guessed automatically in most cases. The following formats are supported:
-
-@table @code
-@item raw
-
-Raw disk image format (default). This format has the advantage of
-being simple and easily exportable to all other emulators. If your
-file system supports @emph{holes} (for example in ext2 or ext3 on
-Linux or NTFS on Windows), then only the written sectors will reserve
-space. Use @code{qemu-img info} to know the real size used by the
-image or @code{ls -ls} on Unix/Linux.
-
-@item qcow2
-QEMU image format, the most versatile format. Use it to have smaller
-images (useful if your filesystem does not supports holes, for example
-on Windows), optional AES encryption, zlib based compression and
-support of multiple VM snapshots.
-@item qcow
-Old QEMU image format. Left for compatibility.
-@item cow
-User Mode Linux Copy On Write image format. Used to be the only growable
-image format in QEMU. It is supported only for compatibility with
-previous versions. It does not work on win32.
-@item vmdk
-VMware 3 and 4 compatible image format.
-@item cloop
-Linux Compressed Loop image, useful only to reuse directly compressed
-CD-ROM images present for example in the Knoppix CD-ROMs.
-@end table
-
-@item size
-is the disk image size in kilobytes. Optional suffixes @code{M}
-(megabyte) and @code{G} (gigabyte) are supported
-
-@item output_filename
-is the destination disk image filename
-
-@item output_fmt
- is the destination format
-
-@item -c
-indicates that target image must be compressed (qcow format only)
-@item -e
-indicates that the target image must be encrypted (qcow format only)
-@end table
-
-Command description:
-
-@table @option
-@item create [-e] [-b @var{base_image}] [-f @var{fmt}] @var{filename} [@var{size}]
-
-Create the new disk image @var{filename} of size @var{size} and format
-@var{fmt}.
-
-If @var{base_image} is specified, then the image will record only the
-differences from @var{base_image}. No size needs to be specified in
-this case. @var{base_image} will never be modified unless you use the
-@code{commit} monitor command.
-
-@item commit [-f @var{fmt}] @var{filename}
-
-Commit the changes recorded in @var{filename} in its base image.
-
-@item convert [-c] [-e] [-f @var{fmt}] @var{filename} [-O @var{output_fmt}] @var{output_filename}
-
-Convert the disk image @var{filename} to disk image @var{output_filename}
-using format @var{output_fmt}. It can be optionnaly encrypted
-(@code{-e} option) or compressed (@code{-c} option).
-
-Only the format @code{qcow} supports encryption or compression. The
-compression is read-only. It means that if a compressed sector is
-rewritten, then it is rewritten as uncompressed data.
-
-Encryption uses the AES format which is very secure (128 bit keys). Use
-a long password (16 characters) to get maximum protection.
-
-Image conversion is also useful to get smaller image when using a
-growable format such as @code{qcow} or @code{cow}: the empty sectors
-are detected and suppressed from the destination image.
-
-@item info [-f @var{fmt}] @var{filename}
-
-Give information about the disk image @var{filename}. Use it in
-particular to know the size reserved on disk which can be different
-from the displayed size. If VM snapshots are stored in the disk image,
-they are displayed too.
-@end table
-
-@c man end
-
-@ignore
-
-@setfilename qemu-img
-@settitle QEMU disk image utility
-
-@c man begin SEEALSO
-The HTML documentation of QEMU for more precise information and Linux
-user mode emulator invocation.
-@c man end
-
-@c man begin AUTHOR
-Fabrice Bellard
-@c man end
-
-@end ignore
diff --git a/tools/ioemu/qemu-tech.texi b/tools/ioemu/qemu-tech.texi
deleted file mode 100644
index 77bda8637e..0000000000
--- a/tools/ioemu/qemu-tech.texi
+++ /dev/null
@@ -1,595 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-@c %**start of header
-@setfilename qemu-tech.info
-@settitle QEMU Internals
-@exampleindent 0
-@paragraphindent 0
-@c %**end of header
-
-@iftex
-@titlepage
-@sp 7
-@center @titlefont{QEMU Internals}
-@sp 3
-@end titlepage
-@end iftex
-
-@ifnottex
-@node Top
-@top
-
-@menu
-* Introduction::
-* QEMU Internals::
-* Regression Tests::
-* Index::
-@end menu
-@end ifnottex
-
-@contents
-
-@node Introduction
-@chapter Introduction
-
-@menu
-* intro_features:: Features
-* intro_x86_emulation:: x86 emulation
-* intro_arm_emulation:: ARM emulation
-* intro_ppc_emulation:: PowerPC emulation
-* intro_sparc_emulation:: SPARC emulation
-@end menu
-
-@node intro_features
-@section Features
-
-QEMU is a FAST! processor emulator using a portable dynamic
-translator.
-
-QEMU has two operating modes:
-
-@itemize @minus
-
-@item
-Full system emulation. In this mode, QEMU emulates a full system
-(usually a PC), including a processor and various peripherals. It can
-be used to launch an different Operating System without rebooting the
-PC or to debug system code.
-
-@item
-User mode emulation (Linux host only). In this mode, QEMU can launch
-Linux processes compiled for one CPU on another CPU. It can be used to
-launch the Wine Windows API emulator (@url{http://www.winehq.org}) or
-to ease cross-compilation and cross-debugging.
-
-@end itemize
-
-As QEMU requires no host kernel driver to run, it is very safe and
-easy to use.
-
-QEMU generic features:
-
-@itemize
-
-@item User space only or full system emulation.
-
-@item Using dynamic translation to native code for reasonable speed.
-
-@item Working on x86 and PowerPC hosts. Being tested on ARM, Sparc32, Alpha and S390.
-
-@item Self-modifying code support.
-
-@item Precise exceptions support.
-
-@item The virtual CPU is a library (@code{libqemu}) which can be used
-in other projects (look at @file{qemu/tests/qruncom.c} to have an
-example of user mode @code{libqemu} usage).
-
-@end itemize
-
-QEMU user mode emulation features:
-@itemize
-@item Generic Linux system call converter, including most ioctls.
-
-@item clone() emulation using native CPU clone() to use Linux scheduler for threads.
-
-@item Accurate signal handling by remapping host signals to target signals.
-@end itemize
-
-QEMU full system emulation features:
-@itemize
-@item QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU.
-@end itemize
-
-@node intro_x86_emulation
-@section x86 emulation
-
-QEMU x86 target features:
-
-@itemize
-
-@item The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation.
-LDT/GDT and IDT are emulated. VM86 mode is also supported to run DOSEMU.
-
-@item Support of host page sizes bigger than 4KB in user mode emulation.
-
-@item QEMU can emulate itself on x86.
-
-@item An extensive Linux x86 CPU test program is included @file{tests/test-i386}.
-It can be used to test other x86 virtual CPUs.
-
-@end itemize
-
-Current QEMU limitations:
-
-@itemize
-
-@item No SSE/MMX support (yet).
-
-@item No x86-64 support.
-
-@item IPC syscalls are missing.
-
-@item The x86 segment limits and access rights are not tested at every
-memory access (yet). Hopefully, very few OSes seem to rely on that for
-normal use.
-
-@item On non x86 host CPUs, @code{double}s are used instead of the non standard
-10 byte @code{long double}s of x86 for floating point emulation to get
-maximum performances.
-
-@end itemize
-
-@node intro_arm_emulation
-@section ARM emulation
-
-@itemize
-
-@item Full ARM 7 user emulation.
-
-@item NWFPE FPU support included in user Linux emulation.
-
-@item Can run most ARM Linux binaries.
-
-@end itemize
-
-@node intro_ppc_emulation
-@section PowerPC emulation
-
-@itemize
-
-@item Full PowerPC 32 bit emulation, including privileged instructions,
-FPU and MMU.
-
-@item Can run most PowerPC Linux binaries.
-
-@end itemize
-
-@node intro_sparc_emulation
-@section SPARC emulation
-
-@itemize
-
-@item Somewhat complete SPARC V8 emulation, including privileged
-instructions, FPU and MMU. SPARC V9 emulation includes most privileged
-instructions, FPU and I/D MMU, but misses VIS instructions.
-
-@item Can run some 32-bit SPARC Linux binaries.
-
-@end itemize
-
-Current QEMU limitations:
-
-@itemize
-
-@item Tagged add/subtract instructions are not supported, but they are
-probably not used.
-
-@item IPC syscalls are missing.
-
-@item 128-bit floating point operations are not supported, though none of the
-real CPUs implement them either. FCMPE[SD] are not correctly
-implemented. Floating point exception support is untested.
-
-@item Alignment is not enforced at all.
-
-@item Atomic instructions are not correctly implemented.
-
-@item Sparc64 emulators are not usable for anything yet.
-
-@end itemize
-
-@node QEMU Internals
-@chapter QEMU Internals
-
-@menu
-* QEMU compared to other emulators::
-* Portable dynamic translation::
-* Register allocation::
-* Condition code optimisations::
-* CPU state optimisations::
-* Translation cache::
-* Direct block chaining::
-* Self-modifying code and translated code invalidation::
-* Exception support::
-* MMU emulation::
-* Hardware interrupts::
-* User emulation specific details::
-* Bibliography::
-@end menu
-
-@node QEMU compared to other emulators
-@section QEMU compared to other emulators
-
-Like bochs [3], QEMU emulates an x86 CPU. But QEMU is much faster than
-bochs as it uses dynamic compilation. Bochs is closely tied to x86 PC
-emulation while QEMU can emulate several processors.
-
-Like Valgrind [2], QEMU does user space emulation and dynamic
-translation. Valgrind is mainly a memory debugger while QEMU has no
-support for it (QEMU could be used to detect out of bound memory
-accesses as Valgrind, but it has no support to track uninitialised data
-as Valgrind does). The Valgrind dynamic translator generates better code
-than QEMU (in particular it does register allocation) but it is closely
-tied to an x86 host and target and has no support for precise exceptions
-and system emulation.
-
-EM86 [4] is the closest project to user space QEMU (and QEMU still uses
-some of its code, in particular the ELF file loader). EM86 was limited
-to an alpha host and used a proprietary and slow interpreter (the
-interpreter part of the FX!32 Digital Win32 code translator [5]).
-
-TWIN [6] is a Windows API emulator like Wine. It is less accurate than
-Wine but includes a protected mode x86 interpreter to launch x86 Windows
-executables. Such an approach has greater potential because most of the
-Windows API is executed natively but it is far more difficult to develop
-because all the data structures and function parameters exchanged
-between the API and the x86 code must be converted.
-
-User mode Linux [7] was the only solution before QEMU to launch a
-Linux kernel as a process while not needing any host kernel
-patches. However, user mode Linux requires heavy kernel patches while
-QEMU accepts unpatched Linux kernels. The price to pay is that QEMU is
-slower.
-
-The new Plex86 [8] PC virtualizer is done in the same spirit as the
-qemu-fast system emulator. It requires a patched Linux kernel to work
-(you cannot launch the same kernel on your PC), but the patches are
-really small. As it is a PC virtualizer (no emulation is done except
-for some priveledged instructions), it has the potential of being
-faster than QEMU. The downside is that a complicated (and potentially
-unsafe) host kernel patch is needed.
-
-The commercial PC Virtualizers (VMWare [9], VirtualPC [10], TwoOStwo
-[11]) are faster than QEMU, but they all need specific, proprietary
-and potentially unsafe host drivers. Moreover, they are unable to
-provide cycle exact simulation as an emulator can.
-
-@node Portable dynamic translation
-@section Portable dynamic translation
-
-QEMU is a dynamic translator. When it first encounters a piece of code,
-it converts it to the host instruction set. Usually dynamic translators
-are very complicated and highly CPU dependent. QEMU uses some tricks
-which make it relatively easily portable and simple while achieving good
-performances.
-
-The basic idea is to split every x86 instruction into fewer simpler
-instructions. Each simple instruction is implemented by a piece of C
-code (see @file{target-i386/op.c}). Then a compile time tool
-(@file{dyngen}) takes the corresponding object file (@file{op.o})
-to generate a dynamic code generator which concatenates the simple
-instructions to build a function (see @file{op.h:dyngen_code()}).
-
-In essence, the process is similar to [1], but more work is done at
-compile time.
-
-A key idea to get optimal performances is that constant parameters can
-be passed to the simple operations. For that purpose, dummy ELF
-relocations are generated with gcc for each constant parameter. Then,
-the tool (@file{dyngen}) can locate the relocations and generate the
-appriopriate C code to resolve them when building the dynamic code.
-
-That way, QEMU is no more difficult to port than a dynamic linker.
-
-To go even faster, GCC static register variables are used to keep the
-state of the virtual CPU.
-
-@node Register allocation
-@section Register allocation
-
-Since QEMU uses fixed simple instructions, no efficient register
-allocation can be done. However, because RISC CPUs have a lot of
-register, most of the virtual CPU state can be put in registers without
-doing complicated register allocation.
-
-@node Condition code optimisations
-@section Condition code optimisations
-
-Good CPU condition codes emulation (@code{EFLAGS} register on x86) is a
-critical point to get good performances. QEMU uses lazy condition code
-evaluation: instead of computing the condition codes after each x86
-instruction, it just stores one operand (called @code{CC_SRC}), the
-result (called @code{CC_DST}) and the type of operation (called
-@code{CC_OP}).
-
-@code{CC_OP} is almost never explicitely set in the generated code
-because it is known at translation time.
-
-In order to increase performances, a backward pass is performed on the
-generated simple instructions (see
-@code{target-i386/translate.c:optimize_flags()}). When it can be proved that
-the condition codes are not needed by the next instructions, no
-condition codes are computed at all.
-
-@node CPU state optimisations
-@section CPU state optimisations
-
-The x86 CPU has many internal states which change the way it evaluates
-instructions. In order to achieve a good speed, the translation phase
-considers that some state information of the virtual x86 CPU cannot
-change in it. For example, if the SS, DS and ES segments have a zero
-base, then the translator does not even generate an addition for the
-segment base.
-
-[The FPU stack pointer register is not handled that way yet].
-
-@node Translation cache
-@section Translation cache
-
-A 16 MByte cache holds the most recently used translations. For
-simplicity, it is completely flushed when it is full. A translation unit
-contains just a single basic block (a block of x86 instructions
-terminated by a jump or by a virtual CPU state change which the
-translator cannot deduce statically).
-
-@node Direct block chaining
-@section Direct block chaining
-
-After each translated basic block is executed, QEMU uses the simulated
-Program Counter (PC) and other cpu state informations (such as the CS
-segment base value) to find the next basic block.
-
-In order to accelerate the most common cases where the new simulated PC
-is known, QEMU can patch a basic block so that it jumps directly to the
-next one.
-
-The most portable code uses an indirect jump. An indirect jump makes
-it easier to make the jump target modification atomic. On some host
-architectures (such as x86 or PowerPC), the @code{JUMP} opcode is
-directly patched so that the block chaining has no overhead.
-
-@node Self-modifying code and translated code invalidation
-@section Self-modifying code and translated code invalidation
-
-Self-modifying code is a special challenge in x86 emulation because no
-instruction cache invalidation is signaled by the application when code
-is modified.
-
-When translated code is generated for a basic block, the corresponding
-host page is write protected if it is not already read-only (with the
-system call @code{mprotect()}). Then, if a write access is done to the
-page, Linux raises a SEGV signal. QEMU then invalidates all the
-translated code in the page and enables write accesses to the page.
-
-Correct translated code invalidation is done efficiently by maintaining
-a linked list of every translated block contained in a given page. Other
-linked lists are also maintained to undo direct block chaining.
-
-Although the overhead of doing @code{mprotect()} calls is important,
-most MSDOS programs can be emulated at reasonnable speed with QEMU and
-DOSEMU.
-
-Note that QEMU also invalidates pages of translated code when it detects
-that memory mappings are modified with @code{mmap()} or @code{munmap()}.
-
-When using a software MMU, the code invalidation is more efficient: if
-a given code page is invalidated too often because of write accesses,
-then a bitmap representing all the code inside the page is
-built. Every store into that page checks the bitmap to see if the code
-really needs to be invalidated. It avoids invalidating the code when
-only data is modified in the page.
-
-@node Exception support
-@section Exception support
-
-longjmp() is used when an exception such as division by zero is
-encountered.
-
-The host SIGSEGV and SIGBUS signal handlers are used to get invalid
-memory accesses. The exact CPU state can be retrieved because all the
-x86 registers are stored in fixed host registers. The simulated program
-counter is found by retranslating the corresponding basic block and by
-looking where the host program counter was at the exception point.
-
-The virtual CPU cannot retrieve the exact @code{EFLAGS} register because
-in some cases it is not computed because of condition code
-optimisations. It is not a big concern because the emulated code can
-still be restarted in any cases.
-
-@node MMU emulation
-@section MMU emulation
-
-For system emulation, QEMU uses the mmap() system call to emulate the
-target CPU MMU. It works as long the emulated OS does not use an area
-reserved by the host OS (such as the area above 0xc0000000 on x86
-Linux).
-
-In order to be able to launch any OS, QEMU also supports a soft
-MMU. In that mode, the MMU virtual to physical address translation is
-done at every memory access. QEMU uses an address translation cache to
-speed up the translation.
-
-In order to avoid flushing the translated code each time the MMU
-mappings change, QEMU uses a physically indexed translation cache. It
-means that each basic block is indexed with its physical address.
-
-When MMU mappings change, only the chaining of the basic blocks is
-reset (i.e. a basic block can no longer jump directly to another one).
-
-@node Hardware interrupts
-@section Hardware interrupts
-
-In order to be faster, QEMU does not check at every basic block if an
-hardware interrupt is pending. Instead, the user must asynchrously
-call a specific function to tell that an interrupt is pending. This
-function resets the chaining of the currently executing basic
-block. It ensures that the execution will return soon in the main loop
-of the CPU emulator. Then the main loop can test if the interrupt is
-pending and handle it.
-
-@node User emulation specific details
-@section User emulation specific details
-
-@subsection Linux system call translation
-
-QEMU includes a generic system call translator for Linux. It means that
-the parameters of the system calls can be converted to fix the
-endianness and 32/64 bit issues. The IOCTLs are converted with a generic
-type description system (see @file{ioctls.h} and @file{thunk.c}).
-
-QEMU supports host CPUs which have pages bigger than 4KB. It records all
-the mappings the process does and try to emulated the @code{mmap()}
-system calls in cases where the host @code{mmap()} call would fail
-because of bad page alignment.
-
-@subsection Linux signals
-
-Normal and real-time signals are queued along with their information
-(@code{siginfo_t}) as it is done in the Linux kernel. Then an interrupt
-request is done to the virtual CPU. When it is interrupted, one queued
-signal is handled by generating a stack frame in the virtual CPU as the
-Linux kernel does. The @code{sigreturn()} system call is emulated to return
-from the virtual signal handler.
-
-Some signals (such as SIGALRM) directly come from the host. Other
-signals are synthetized from the virtual CPU exceptions such as SIGFPE
-when a division by zero is done (see @code{main.c:cpu_loop()}).
-
-The blocked signal mask is still handled by the host Linux kernel so
-that most signal system calls can be redirected directly to the host
-Linux kernel. Only the @code{sigaction()} and @code{sigreturn()} system
-calls need to be fully emulated (see @file{signal.c}).
-
-@subsection clone() system call and threads
-
-The Linux clone() system call is usually used to create a thread. QEMU
-uses the host clone() system call so that real host threads are created
-for each emulated thread. One virtual CPU instance is created for each
-thread.
-
-The virtual x86 CPU atomic operations are emulated with a global lock so
-that their semantic is preserved.
-
-Note that currently there are still some locking issues in QEMU. In
-particular, the translated cache flush is not protected yet against
-reentrancy.
-
-@subsection Self-virtualization
-
-QEMU was conceived so that ultimately it can emulate itself. Although
-it is not very useful, it is an important test to show the power of the
-emulator.
-
-Achieving self-virtualization is not easy because there may be address
-space conflicts. QEMU solves this problem by being an executable ELF
-shared object as the ld-linux.so ELF interpreter. That way, it can be
-relocated at load time.
-
-@node Bibliography
-@section Bibliography
-
-@table @asis
-
-@item [1]
-@url{http://citeseer.nj.nec.com/piumarta98optimizing.html}, Optimizing
-direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio
-Riccardi.
-
-@item [2]
-@url{http://developer.kde.org/~sewardj/}, Valgrind, an open-source
-memory debugger for x86-GNU/Linux, by Julian Seward.
-
-@item [3]
-@url{http://bochs.sourceforge.net/}, the Bochs IA-32 Emulator Project,
-by Kevin Lawton et al.
-
-@item [4]
-@url{http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html}, the EM86
-x86 emulator on Alpha-Linux.
-
-@item [5]
-@url{http://www.usenix.org/publications/library/proceedings/usenix-nt97/@/full_papers/chernoff/chernoff.pdf},
-DIGITAL FX!32: Running 32-Bit x86 Applications on Alpha NT, by Anton
-Chernoff and Ray Hookway.
-
-@item [6]
-@url{http://www.willows.com/}, Windows API library emulation from
-Willows Software.
-
-@item [7]
-@url{http://user-mode-linux.sourceforge.net/},
-The User-mode Linux Kernel.
-
-@item [8]
-@url{http://www.plex86.org/},
-The new Plex86 project.
-
-@item [9]
-@url{http://www.vmware.com/},
-The VMWare PC virtualizer.
-
-@item [10]
-@url{http://www.microsoft.com/windowsxp/virtualpc/},
-The VirtualPC PC virtualizer.
-
-@item [11]
-@url{http://www.twoostwo.org/},
-The TwoOStwo PC virtualizer.
-
-@end table
-
-@node Regression Tests
-@chapter Regression Tests
-
-In the directory @file{tests/}, various interesting testing programs
-are available. There are used for regression testing.
-
-@menu
-* test-i386::
-* linux-test::
-* qruncom.c::
-@end menu
-
-@node test-i386
-@section @file{test-i386}
-
-This program executes most of the 16 bit and 32 bit x86 instructions and
-generates a text output. It can be compared with the output obtained with
-a real CPU or another emulator. The target @code{make test} runs this
-program and a @code{diff} on the generated output.
-
-The Linux system call @code{modify_ldt()} is used to create x86 selectors
-to test some 16 bit addressing and 32 bit with segmentation cases.
-
-The Linux system call @code{vm86()} is used to test vm86 emulation.
-
-Various exceptions are raised to test most of the x86 user space
-exception reporting.
-
-@node linux-test
-@section @file{linux-test}
-
-This program tests various Linux system calls. It is used to verify
-that the system call parameters are correctly converted between target
-and host CPUs.
-
-@node qruncom.c
-@section @file{qruncom.c}
-
-Example of usage of @code{libqemu} to emulate a user mode i386 CPU.
-
-@node Index
-@chapter Index
-@printindex cp
-
-@bye
diff --git a/tools/ioemu/qemu_socket.h b/tools/ioemu/qemu_socket.h
deleted file mode 100644
index d462d08d60..0000000000
--- a/tools/ioemu/qemu_socket.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* headers to use the BSD sockets */
-#ifndef QEMU_SOCKET_H
-#define QEMU_SOCKET_H
-
-#ifdef _WIN32
-
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#define socket_error() WSAGetLastError()
-#undef EINTR
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define EINTR WSAEINTR
-#define EINPROGRESS WSAEINPROGRESS
-
-#ifndef NO_UNIX_SOCKETS
-#define NO_UNIX_SOCKETS 1
-#endif
-
-#else
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#ifndef NO_UNIX_SOCKETS
-#include <sys/un.h>
-#endif
-
-#define socket_error() errno
-#define closesocket(s) close(s)
-
-#endif /* !_WIN32 */
-
-void socket_set_nonblock(int fd);
-
-#endif /* QEMU_SOCKET_H */
diff --git a/tools/ioemu/readline.c b/tools/ioemu/readline.c
deleted file mode 100644
index cbe33dbdd8..0000000000
--- a/tools/ioemu/readline.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * QEMU readline utility
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define TERM_CMD_BUF_SIZE 4095
-#define TERM_MAX_CMDS 64
-#define NB_COMPLETIONS_MAX 256
-
-#define IS_NORM 0
-#define IS_ESC 1
-#define IS_CSI 2
-
-#define printf do_not_use_printf
-
-static char term_cmd_buf[TERM_CMD_BUF_SIZE + 1];
-static int term_cmd_buf_index;
-static int term_cmd_buf_size;
-
-static char term_last_cmd_buf[TERM_CMD_BUF_SIZE + 1];
-static int term_last_cmd_buf_index;
-static int term_last_cmd_buf_size;
-
-static int term_esc_state;
-static int term_esc_param;
-
-static char *term_history[TERM_MAX_CMDS];
-static int term_hist_entry = -1;
-
-static int nb_completions;
-int completion_index;
-static char *completions[NB_COMPLETIONS_MAX];
-
-static ReadLineFunc *term_readline_func;
-static int term_is_password;
-static char term_prompt[256];
-static void *term_readline_opaque;
-
-static void term_show_prompt2(void)
-{
- term_printf("%s", term_prompt);
- term_flush();
- term_last_cmd_buf_index = 0;
- term_last_cmd_buf_size = 0;
- term_esc_state = IS_NORM;
-}
-
-static void term_show_prompt(void)
-{
- term_show_prompt2();
- term_cmd_buf_index = 0;
- term_cmd_buf_size = 0;
-}
-
-/* update the displayed command line */
-static void term_update(void)
-{
- int i, delta, len;
-
- if (term_cmd_buf_size != term_last_cmd_buf_size ||
- memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) {
- for(i = 0; i < term_last_cmd_buf_index; i++) {
- term_printf("\033[D");
- }
- term_cmd_buf[term_cmd_buf_size] = '\0';
- if (term_is_password) {
- len = strlen(term_cmd_buf);
- for(i = 0; i < len; i++)
- term_printf("*");
- } else {
- term_printf("%s", term_cmd_buf);
- }
- term_printf("\033[K");
- memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size);
- term_last_cmd_buf_size = term_cmd_buf_size;
- term_last_cmd_buf_index = term_cmd_buf_size;
- }
- if (term_cmd_buf_index != term_last_cmd_buf_index) {
- delta = term_cmd_buf_index - term_last_cmd_buf_index;
- if (delta > 0) {
- for(i = 0;i < delta; i++) {
- term_printf("\033[C");
- }
- } else {
- delta = -delta;
- for(i = 0;i < delta; i++) {
- term_printf("\033[D");
- }
- }
- term_last_cmd_buf_index = term_cmd_buf_index;
- }
- term_flush();
-}
-
-static void term_insert_char(int ch)
-{
- if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) {
- memmove(term_cmd_buf + term_cmd_buf_index + 1,
- term_cmd_buf + term_cmd_buf_index,
- term_cmd_buf_size - term_cmd_buf_index);
- term_cmd_buf[term_cmd_buf_index] = ch;
- term_cmd_buf_size++;
- term_cmd_buf_index++;
- }
-}
-
-static void term_backward_char(void)
-{
- if (term_cmd_buf_index > 0) {
- term_cmd_buf_index--;
- }
-}
-
-static void term_forward_char(void)
-{
- if (term_cmd_buf_index < term_cmd_buf_size) {
- term_cmd_buf_index++;
- }
-}
-
-static void term_delete_char(void)
-{
- if (term_cmd_buf_index < term_cmd_buf_size) {
- memmove(term_cmd_buf + term_cmd_buf_index,
- term_cmd_buf + term_cmd_buf_index + 1,
- term_cmd_buf_size - term_cmd_buf_index - 1);
- term_cmd_buf_size--;
- }
-}
-
-static void term_backspace(void)
-{
- if (term_cmd_buf_index > 0) {
- term_backward_char();
- term_delete_char();
- }
-}
-
-static void term_bol(void)
-{
- term_cmd_buf_index = 0;
-}
-
-static void term_eol(void)
-{
- term_cmd_buf_index = term_cmd_buf_size;
-}
-
-static void term_up_char(void)
-{
- int idx;
-
- if (term_hist_entry == 0)
- return;
- if (term_hist_entry == -1) {
- /* Find latest entry */
- for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
- if (term_history[idx] == NULL)
- break;
- }
- term_hist_entry = idx;
- }
- term_hist_entry--;
- if (term_hist_entry >= 0) {
- pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
- term_history[term_hist_entry]);
- term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
- }
-}
-
-static void term_down_char(void)
-{
- if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1)
- return;
- if (term_history[++term_hist_entry] != NULL) {
- pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
- term_history[term_hist_entry]);
- } else {
- term_hist_entry = -1;
- }
- term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
-}
-
-static void term_hist_add(const char *cmdline)
-{
- char *hist_entry, *new_entry;
- int idx;
-
- if (cmdline[0] == '\0')
- return;
- new_entry = NULL;
- if (term_hist_entry != -1) {
- /* We were editing an existing history entry: replace it */
- hist_entry = term_history[term_hist_entry];
- idx = term_hist_entry;
- if (strcmp(hist_entry, cmdline) == 0) {
- goto same_entry;
- }
- }
- /* Search cmdline in history buffers */
- for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
- hist_entry = term_history[idx];
- if (hist_entry == NULL)
- break;
- if (strcmp(hist_entry, cmdline) == 0) {
- same_entry:
- new_entry = hist_entry;
- /* Put this entry at the end of history */
- memmove(&term_history[idx], &term_history[idx + 1],
- &term_history[TERM_MAX_CMDS] - &term_history[idx + 1]);
- term_history[TERM_MAX_CMDS - 1] = NULL;
- for (; idx < TERM_MAX_CMDS; idx++) {
- if (term_history[idx] == NULL)
- break;
- }
- break;
- }
- }
- if (idx == TERM_MAX_CMDS) {
- /* Need to get one free slot */
- free(term_history[0]);
- memcpy(term_history, &term_history[1],
- &term_history[TERM_MAX_CMDS] - &term_history[1]);
- term_history[TERM_MAX_CMDS - 1] = NULL;
- idx = TERM_MAX_CMDS - 1;
- }
- if (new_entry == NULL)
- new_entry = strdup(cmdline);
- term_history[idx] = new_entry;
- term_hist_entry = -1;
-}
-
-/* completion support */
-
-void add_completion(const char *str)
-{
- if (nb_completions < NB_COMPLETIONS_MAX) {
- completions[nb_completions++] = qemu_strdup(str);
- }
-}
-
-static void term_completion(void)
-{
- int len, i, j, max_width, nb_cols;
- char *cmdline;
-
- nb_completions = 0;
-
- cmdline = qemu_malloc(term_cmd_buf_index + 1);
- if (!cmdline)
- return;
- memcpy(cmdline, term_cmd_buf, term_cmd_buf_index);
- cmdline[term_cmd_buf_index] = '\0';
- readline_find_completion(cmdline);
- qemu_free(cmdline);
-
- /* no completion found */
- if (nb_completions <= 0)
- return;
- if (nb_completions == 1) {
- len = strlen(completions[0]);
- for(i = completion_index; i < len; i++) {
- term_insert_char(completions[0][i]);
- }
- /* extra space for next argument. XXX: make it more generic */
- if (len > 0 && completions[0][len - 1] != '/')
- term_insert_char(' ');
- } else {
- term_printf("\n");
- max_width = 0;
- for(i = 0; i < nb_completions; i++) {
- len = strlen(completions[i]);
- if (len > max_width)
- max_width = len;
- }
- max_width += 2;
- if (max_width < 10)
- max_width = 10;
- else if (max_width > 80)
- max_width = 80;
- nb_cols = 80 / max_width;
- j = 0;
- for(i = 0; i < nb_completions; i++) {
- term_printf("%-*s", max_width, completions[i]);
- if (++j == nb_cols || i == (nb_completions - 1)) {
- term_printf("\n");
- j = 0;
- }
- }
- term_show_prompt2();
- }
-}
-
-/* return true if command handled */
-void readline_handle_byte(int ch)
-{
- switch(term_esc_state) {
- case IS_NORM:
- switch(ch) {
- case 1:
- term_bol();
- break;
- case 4:
- term_delete_char();
- break;
- case 5:
- term_eol();
- break;
- case 9:
- term_completion();
- break;
- case 10:
- case 13:
- term_cmd_buf[term_cmd_buf_size] = '\0';
- if (!term_is_password)
- term_hist_add(term_cmd_buf);
- term_printf("\n");
- /* NOTE: readline_start can be called here */
- term_readline_func(term_readline_opaque, term_cmd_buf);
- break;
- case 27:
- term_esc_state = IS_ESC;
- break;
- case 127:
- case 8:
- term_backspace();
- break;
- case 155:
- term_esc_state = IS_CSI;
- break;
- default:
- if (ch >= 32) {
- term_insert_char(ch);
- }
- break;
- }
- break;
- case IS_ESC:
- if (ch == '[') {
- term_esc_state = IS_CSI;
- term_esc_param = 0;
- } else {
- term_esc_state = IS_NORM;
- }
- break;
- case IS_CSI:
- switch(ch) {
- case 'A':
- case 'F':
- term_up_char();
- break;
- case 'B':
- case 'E':
- term_down_char();
- break;
- case 'D':
- term_backward_char();
- break;
- case 'C':
- term_forward_char();
- break;
- case '0' ... '9':
- term_esc_param = term_esc_param * 10 + (ch - '0');
- goto the_end;
- case '~':
- switch(term_esc_param) {
- case 1:
- term_bol();
- break;
- case 3:
- term_delete_char();
- break;
- case 4:
- term_eol();
- break;
- }
- break;
- default:
- break;
- }
- term_esc_state = IS_NORM;
- the_end:
- break;
- }
- term_update();
-}
-
-void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque)
-{
- pstrcpy(term_prompt, sizeof(term_prompt), prompt);
- term_readline_func = readline_func;
- term_readline_opaque = opaque;
- term_is_password = is_password;
- term_show_prompt();
-}
-
-const char *readline_get_history(unsigned int index)
-{
- if (index >= TERM_MAX_CMDS)
- return NULL;
- return term_history[index];
-}
-
-
diff --git a/tools/ioemu/sdl.c b/tools/ioemu/sdl.c
deleted file mode 100644
index a16b504c4d..0000000000
--- a/tools/ioemu/sdl.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#include <SDL.h>
-
-#ifndef _WIN32
-#include <signal.h>
-#endif
-
-#ifdef CONFIG_OPENGL
-#include <SDL_opengl.h>
-#endif
-
-static SDL_Surface *screen;
-static SDL_Surface *shared = NULL;
-static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
-static int last_vm_running;
-static int gui_saved_grab;
-static int gui_fullscreen;
-static int gui_key_modifier_pressed;
-static int gui_keysym;
-static int gui_fullscreen_initial_grab;
-static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
-static uint8_t modifiers_state[256];
-static int width, height;
-static SDL_Cursor *sdl_cursor_normal;
-static SDL_Cursor *sdl_cursor_hidden;
-static int absolute_enabled = 0;
-static int opengl_enabled;
-
-static void sdl_colourdepth(DisplayState *ds, int depth);
-
-#ifdef CONFIG_OPENGL
-static GLint tex_format;
-static GLint tex_type;
-static GLuint texture_ref = 0;
-static GLint gl_format;
-
-static void opengl_setdata(DisplayState *ds, void *pixels)
-{
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glClearColor(0, 0, 0, 0);
- glDisable(GL_BLEND);
- glDisable(GL_LIGHTING);
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDisable(GL_CULL_FACE);
- glViewport( 0, 0, screen->w, screen->h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, screen->w, screen->h, 0, -1,1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glClear(GL_COLOR_BUFFER_BIT);
- ds->data = pixels;
-
- if (texture_ref) {
- glDeleteTextures(1, &texture_ref);
- texture_ref = 0;
- }
-
- glGenTextures(1, &texture_ref);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref);
- glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
- switch (ds->depth) {
- case 8:
- if (ds->palette == NULL) {
- tex_format = GL_RGB;
- tex_type = GL_UNSIGNED_BYTE_3_3_2;
- } else {
- int i;
- GLushort paletter[256], paletteg[256], paletteb[256];
- for (i = 0; i < 256; i++) {
- uint8_t rgb = ds->palette[i] >> 16;
- paletter[i] = ((rgb & 0xe0) >> 5) * 65535 / 7;
- paletteg[i] = ((rgb & 0x1c) >> 2) * 65535 / 7;
- paletteb[i] = (rgb & 0x3) * 65535 / 3;
- }
- glPixelMapusv(GL_PIXEL_MAP_I_TO_R, 256, paletter);
- glPixelMapusv(GL_PIXEL_MAP_I_TO_G, 256, paletteg);
- glPixelMapusv(GL_PIXEL_MAP_I_TO_B, 256, paletteb);
-
- tex_format = GL_COLOR_INDEX;
- tex_type = GL_UNSIGNED_BYTE;
- }
- break;
- case 16:
- tex_format = GL_RGB;
- tex_type = GL_UNSIGNED_SHORT_5_6_5;
- break;
- case 24:
- tex_format = GL_BGR;
- tex_type = GL_UNSIGNED_BYTE;
- break;
- case 32:
- if (!ds->bgr) {
- tex_format = GL_BGRA;
- tex_type = GL_UNSIGNED_BYTE;
- } else {
- tex_format = GL_RGBA;
- tex_type = GL_UNSIGNED_BYTE;
- }
- break;
- }
- glPixelStorei(GL_UNPACK_ROW_LENGTH, (ds->linesize * 8) / ds->depth);
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_format, ds->width, ds->height, 0, tex_format, tex_type, pixels);
- glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_PRIORITY, 1.0);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
-}
-
-static void opengl_update(DisplayState *ds, int x, int y, int w, int h)
-{
- int bpp = ds->depth / 8;
- GLvoid *pixels = ds->data + y * ds->linesize + x * bpp;
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, ds->linesize / bpp);
- glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, w, h, tex_format, tex_type, pixels);
- glBegin(GL_QUADS);
- glTexCoord2d(0, 0);
- glVertex2d(0, 0);
- glTexCoord2d(ds->width, 0);
- glVertex2d(screen->w, 0);
- glTexCoord2d(ds->width, ds->height);
- glVertex2d(screen->w, screen->h);
- glTexCoord2d(0, ds->height);
- glVertex2d(0, screen->h);
- glEnd();
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- SDL_GL_SwapBuffers();
-}
-#endif
-
-static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
-{
- // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
- if (shared) {
- SDL_Rect rec;
- rec.x = x;
- rec.y = y;
- rec.w = w;
- rec.h = h;
- SDL_BlitSurface(shared, &rec, screen, &rec);
- }
- SDL_Flip(screen);
-}
-
-static void sdl_setdata(DisplayState *ds, void *pixels)
-{
- uint32_t rmask, gmask, bmask, amask = 0;
- switch (ds->depth) {
- case 8:
- rmask = 0x000000E0;
- gmask = 0x0000001C;
- bmask = 0x00000003;
- break;
- case 16:
- rmask = 0x0000F800;
- gmask = 0x000007E0;
- bmask = 0x0000001F;
- break;
- case 24:
- rmask = 0x00FF0000;
- gmask = 0x0000FF00;
- bmask = 0x000000FF;
- break;
- case 32:
- rmask = 0x00FF0000;
- gmask = 0x0000FF00;
- bmask = 0x000000FF;
- break;
- default:
- return;
- }
- shared = SDL_CreateRGBSurfaceFrom(pixels, width, height, ds->depth, ds->linesize, rmask , gmask, bmask, amask);
- if (ds->depth == 8 && ds->palette != NULL) {
- SDL_Color palette[256];
- int i;
- for (i = 0; i < 256; i++) {
- uint8_t rgb = ds->palette[i] >> 16;
- palette[i].r = ((rgb & 0xe0) >> 5) * 255 / 7;
- palette[i].g = ((rgb & 0x1c) >> 2) * 255 / 7;
- palette[i].b = (rgb & 0x3) * 255 / 3;
- }
- SDL_SetColors(shared, palette, 0, 256);
- }
- ds->data = pixels;
-}
-
-static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
-{
- int flags;
-
- // printf("resizing to %d %d\n", w, h);
-
- sdl_colourdepth(ds, depth);
-
-#ifdef CONFIG_OPENGL
- if (ds->shared_buf && opengl_enabled)
- flags = SDL_OPENGL|SDL_RESIZABLE;
- else
-#endif
- flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_DOUBLEBUF|SDL_HWPALETTE;
-
- if (gui_fullscreen) {
- flags |= SDL_FULLSCREEN;
- flags &= ~SDL_RESIZABLE;
- }
-
- width = w;
- height = h;
-
- again:
- screen = SDL_SetVideoMode(w, h, 0, flags);
-
- /* Process any WM-generated resize event */
- SDL_PumpEvents();
-
- if (!screen) {
- fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError());
- if (opengl_enabled) {
- /* Fallback to SDL */
- opengl_enabled = 0;
- ds->dpy_update = sdl_update;
- ds->dpy_setdata = sdl_setdata;
- ds->dpy_resize_shared = sdl_resize_shared;
- sdl_resize_shared(ds, w, h, depth, linesize, pixels);
- return;
- }
- exit(1);
- }
-
- if (!opengl_enabled) {
- if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) {
- flags &= ~SDL_HWSURFACE;
- goto again;
- }
-
- if (!screen->pixels) {
- fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError());
- exit(1);
- }
- }
-
- ds->width = w;
- ds->height = h;
- if (!ds->shared_buf) {
- ds->depth = screen->format->BitsPerPixel;
- if (ds->depth == 32 && screen->format->Rshift == 0) {
- ds->bgr = 1;
- } else {
- ds->bgr = 0;
- }
- shared = NULL;
- ds->data = screen->pixels;
- ds->linesize = screen->pitch;
- } else {
- ds->linesize = linesize;
-#ifdef CONFIG_OPENGL
- switch(screen->format->BitsPerPixel) {
- case 8:
- gl_format = GL_RGB;
- break;
- case 16:
- gl_format = GL_RGB;
- break;
- case 24:
- gl_format = GL_RGB;
- break;
- case 32:
- if (!screen->format->Rshift)
- gl_format = GL_BGRA;
- else
- gl_format = GL_RGBA;
- break;
- };
-#endif
- }
- if (ds->shared_buf) ds->dpy_setdata(ds, pixels);
-}
-
-static void sdl_resize(DisplayState *ds, int w, int h)
-{
- sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
-}
-
-static void sdl_colourdepth(DisplayState *ds, int depth)
-{
- if (!depth || !ds->depth) {
- ds->shared_buf = 0;
- ds->dpy_update = sdl_update;
- return;
- }
- ds->shared_buf = 1;
- ds->depth = depth;
-#ifdef CONFIG_OPENGL
- if (opengl_enabled) {
- ds->dpy_update = opengl_update;
- }
-#endif
-}
-
-/* generic keyboard conversion */
-
-#include "sdl_keysym.h"
-#include "keymaps.c"
-
-static kbd_layout_t *kbd_layout = NULL;
-
-static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
-{
- int keysym;
- /* workaround for X11+SDL bug with AltGR */
- keysym = ev->keysym.sym;
- if (keysym == 0 && ev->keysym.scancode == 113)
- keysym = SDLK_MODE;
- /* For Japanese key '\' and '|' */
- if (keysym == 92 && ev->keysym.scancode == 133) {
- keysym = 0xa5;
- }
- return keysym2scancode(kbd_layout, keysym);
-}
-
-/* specific keyboard conversions from scan codes */
-
-#if defined(_WIN32)
-
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
-{
- return ev->keysym.scancode;
-}
-
-#else
-
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
-{
- int keycode;
-
- keycode = ev->keysym.scancode;
-
- if (keycode < 9) {
- keycode = 0;
- } else if (keycode < 97) {
- keycode -= 8; /* just an offset */
- } else if (keycode < 212) {
- /* use conversion table */
- keycode = _translate_keycode(keycode - 97);
- } else {
- keycode = 0;
- }
- return keycode;
-}
-
-#endif
-
-static void reset_keys(void)
-{
- int i;
- for(i = 0; i < 256; i++) {
- if (modifiers_state[i]) {
- if (i & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(i | 0x80);
- modifiers_state[i] = 0;
- }
- }
-}
-
-static void sdl_process_key(SDL_KeyboardEvent *ev)
-{
- int keycode, v;
-
- if (ev->keysym.sym == SDLK_PAUSE) {
- /* specific case */
- v = 0;
- if (ev->type == SDL_KEYUP)
- v |= 0x80;
- kbd_put_keycode(0xe1);
- kbd_put_keycode(0x1d | v);
- kbd_put_keycode(0x45 | v);
- return;
- }
-
- if (kbd_layout) {
- keycode = sdl_keyevent_to_keycode_generic(ev);
- } else {
- keycode = sdl_keyevent_to_keycode(ev);
- }
-
- switch(keycode) {
- case 0x00:
- /* sent when leaving window: reset the modifiers state */
- reset_keys();
- return;
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- if (ev->type == SDL_KEYUP)
- modifiers_state[keycode] = 0;
- else
- modifiers_state[keycode] = 1;
- break;
- case 0x45: /* num lock */
- case 0x3a: /* caps lock */
- /* SDL does not send the key up event, so we generate it */
- kbd_put_keycode(keycode);
- kbd_put_keycode(keycode | 0x80);
- return;
- }
-
- /* now send the key code */
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (ev->type == SDL_KEYUP)
- kbd_put_keycode(keycode | 0x80);
- else
- kbd_put_keycode(keycode & 0x7f);
-}
-
-static void sdl_update_caption(void)
-{
- char buf[1024];
- strcpy(buf, domain_name);
- if (!vm_running) {
- strcat(buf, " [Stopped]");
- }
- if (gui_grab) {
- strcat(buf, " - Press Ctrl-Alt to exit grab");
- }
- SDL_WM_SetCaption(buf, domain_name);
-}
-
-static void sdl_hide_cursor(void)
-{
- if (kbd_mouse_is_absolute()) {
- SDL_ShowCursor(1);
- SDL_SetCursor(sdl_cursor_hidden);
- } else {
- SDL_ShowCursor(0);
- }
-}
-
-static void sdl_show_cursor(void)
-{
- if (!kbd_mouse_is_absolute()) {
- SDL_ShowCursor(1);
- SDL_SetCursor(sdl_cursor_normal);
- }
-}
-
-static void sdl_grab_start(void)
-{
- sdl_hide_cursor();
- SDL_WM_GrabInput(SDL_GRAB_ON);
- /* dummy read to avoid moving the mouse */
- SDL_GetRelativeMouseState(NULL, NULL);
- gui_grab = 1;
- sdl_update_caption();
-}
-
-static void sdl_grab_end(void)
-{
- SDL_WM_GrabInput(SDL_GRAB_OFF);
- sdl_show_cursor();
- gui_grab = 0;
- sdl_update_caption();
-}
-
-static void sdl_send_mouse_event(int dx, int dy, int dz, int state)
-{
- int buttons = 0;
- if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
- buttons |= MOUSE_EVENT_LBUTTON;
- if (state & SDL_BUTTON(SDL_BUTTON_RIGHT))
- buttons |= MOUSE_EVENT_RBUTTON;
- if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
- buttons |= MOUSE_EVENT_MBUTTON;
-
- if (kbd_mouse_is_absolute()) {
- if (!absolute_enabled) {
- sdl_hide_cursor();
- if (gui_grab) {
- sdl_grab_end();
- }
- absolute_enabled = 1;
- }
-
- SDL_GetMouseState(&dx, &dy);
- dx = dx * 0x7FFF / (screen->w - 1);
- dy = dy * 0x7FFF / (screen->h - 1);
- } else if (absolute_enabled) {
- sdl_show_cursor();
- absolute_enabled = 0;
- }
-
- kbd_mouse_event(dx, dy, dz, buttons);
-}
-
-static void toggle_full_screen(DisplayState *ds)
-{
- gui_fullscreen = !gui_fullscreen;
- sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, ds->data);
- if (gui_fullscreen) {
- gui_saved_grab = gui_grab;
- sdl_grab_start();
- } else {
- if (!gui_saved_grab)
- sdl_grab_end();
- }
- vga_hw_invalidate();
- vga_hw_update();
-}
-
-static void sdl_refresh(DisplayState *ds)
-{
- SDL_Event ev1, *ev = &ev1;
- int mod_state;
-
- if (last_vm_running != vm_running) {
- last_vm_running = vm_running;
- sdl_update_caption();
- }
-
- vga_hw_update();
-
- while (SDL_PollEvent(ev)) {
- switch (ev->type) {
- case SDL_VIDEOEXPOSE:
- ds->dpy_update(ds, 0, 0, ds->width, ds->height);
- break;
- case SDL_KEYDOWN:
- case SDL_KEYUP:
- if (ev->type == SDL_KEYDOWN) {
- mod_state = (SDL_GetModState() & gui_grab_code) ==
- gui_grab_code;
- gui_key_modifier_pressed = mod_state;
- if (gui_key_modifier_pressed) {
- int keycode;
- keycode = sdl_keyevent_to_keycode(&ev->key);
- switch(keycode) {
- case 0x21: /* 'f' key on US keyboard */
- toggle_full_screen(ds);
- gui_keysym = 1;
- break;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
- /* Reset the modifiers sent to the current console */
- reset_keys();
- console_select(keycode - 0x02);
- if (!is_graphic_console()) {
- /* display grab if going to a text console */
- if (gui_grab)
- sdl_grab_end();
- }
- gui_keysym = 1;
- break;
- default:
- break;
- }
- } else if (!is_graphic_console()) {
- int keysym;
- keysym = 0;
- if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
- switch(ev->key.keysym.sym) {
- case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break;
- case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break;
- case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break;
- case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break;
- case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
- case SDLK_END: keysym = QEMU_KEY_CTRL_END; break;
- case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
- case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
- default: break;
- }
- } else {
- switch(ev->key.keysym.sym) {
- case SDLK_UP: keysym = QEMU_KEY_UP; break;
- case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break;
- case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break;
- case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break;
- case SDLK_HOME: keysym = QEMU_KEY_HOME; break;
- case SDLK_END: keysym = QEMU_KEY_END; break;
- case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
- case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
- case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break; case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
- default: break;
- }
- }
- if (keysym) {
- kbd_put_keysym(keysym);
- } else if (ev->key.keysym.unicode != 0) {
- kbd_put_keysym(ev->key.keysym.unicode);
- }
- }
- } else if (ev->type == SDL_KEYUP) {
- mod_state = (ev->key.keysym.mod & gui_grab_code);
- if (!mod_state) {
- if (gui_key_modifier_pressed) {
- gui_key_modifier_pressed = 0;
- if (gui_keysym == 0) {
- /* exit/enter grab if pressing Ctrl-Alt */
- if (!gui_grab) {
- /* if the application is not active,
- do not try to enter grab state. It
- prevents
- 'SDL_WM_GrabInput(SDL_GRAB_ON)'
- from blocking all the application
- (SDL bug). */
- if (SDL_GetAppState() & SDL_APPACTIVE)
- sdl_grab_start();
- } else {
- sdl_grab_end();
- }
- /* SDL does not send back all the
- modifiers key, so we must correct it */
- reset_keys();
- break;
- }
- gui_keysym = 0;
- }
- }
- }
- if (is_graphic_console() && !gui_keysym)
- sdl_process_key(&ev->key);
- break;
- case SDL_QUIT:
- if (!no_quit) {
- qemu_system_shutdown_request();
- }
- break;
- case SDL_MOUSEMOTION:
- if (gui_grab || kbd_mouse_is_absolute() ||
- absolute_enabled) {
- int dx, dy, state;
- state = SDL_GetRelativeMouseState(&dx, &dy);
- sdl_send_mouse_event(dx, dy, 0, state);
- }
- break;
- case SDL_MOUSEBUTTONUP:
- if (gui_grab || kbd_mouse_is_absolute()) {
- int dx, dy, state;
- state = SDL_GetRelativeMouseState(&dx, &dy);
- sdl_send_mouse_event(dx, dy, 0, state);
- }
- break;
- case SDL_MOUSEBUTTONDOWN:
- {
- SDL_MouseButtonEvent *bev = &ev->button;
- if (!gui_grab && !kbd_mouse_is_absolute()) {
- if (ev->type == SDL_MOUSEBUTTONDOWN &&
- (bev->state & SDL_BUTTON_LMASK)) {
- /* start grabbing all events */
- sdl_grab_start();
- }
- } else {
- int dx, dy, dz, state;
- dz = 0;
- state = SDL_GetRelativeMouseState(&dx, &dy);
-#ifdef SDL_BUTTON_WHEELUP
- if (bev->button == SDL_BUTTON_WHEELUP) {
- dz = -1;
- } else if (bev->button == SDL_BUTTON_WHEELDOWN) {
- dz = 1;
- } else {
- state = bev->button | state;
- }
-#endif
- sdl_send_mouse_event(dx, dy, dz, state);
- }
- }
- break;
- case SDL_ACTIVEEVENT:
- if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS &&
- !ev->active.gain && !gui_fullscreen_initial_grab) {
- sdl_grab_end();
- }
- if (ev->active.state & SDL_APPACTIVE) {
- if (ev->active.gain) {
- /* Back to default interval */
- ds->gui_timer_interval = 0;
- ds->idle = 0;
- } else {
- /* Sleeping interval */
- ds->gui_timer_interval = 500;
- ds->idle = 1;
- }
- }
- break;
-#ifdef CONFIG_OPENGL
- case SDL_VIDEORESIZE:
- {
- if (ds->shared_buf && opengl_enabled) {
- SDL_ResizeEvent *rev = &ev->resize;
- screen = SDL_SetVideoMode(rev->w, rev->h, 0, SDL_OPENGL|SDL_RESIZABLE);
- opengl_setdata(ds, ds->data);
- opengl_update(ds, 0, 0, ds->width, ds->height);
- }
- break;
- }
-#endif
- default:
- break;
- }
- }
-}
-
-static void sdl_cleanup(void)
-{
-#ifdef CONFIG_OPENGL
- if (texture_ref) glDeleteTextures(1, &texture_ref);
-#endif
- SDL_Quit();
-}
-
-void sdl_display_init(DisplayState *ds, int full_screen, int opengl)
-{
- int flags;
- uint8_t data = 0;
- opengl_enabled = opengl;
-
-#if defined(__APPLE__)
- /* always use generic keymaps */
- if (!keyboard_layout)
- keyboard_layout = "en-us";
-#endif
- if(keyboard_layout) {
- kbd_layout = init_keyboard_layout(keyboard_layout);
- if (!kbd_layout)
- exit(1);
- }
-
- flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
- if (SDL_Init (flags)) {
- fprintf(stderr, "Could not initialize SDL - exiting\n");
- exit(1);
- }
-#ifndef _WIN32
- /* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
-#endif
-
- ds->dpy_update = sdl_update;
- ds->dpy_resize = sdl_resize;
- ds->dpy_resize_shared = sdl_resize_shared;
- ds->dpy_refresh = sdl_refresh;
- ds->dpy_setdata = sdl_setdata;
-#ifdef CONFIG_OPENGL
- if (opengl_enabled)
- ds->dpy_setdata = opengl_setdata;
-#endif
-
- sdl_resize(ds, 640, 400);
- sdl_update_caption();
- SDL_EnableKeyRepeat(250, 50);
- SDL_EnableUNICODE(1);
- gui_grab = 0;
-
- sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
- sdl_cursor_normal = SDL_GetCursor();
-
- atexit(sdl_cleanup);
- if (full_screen) {
- gui_fullscreen = 1;
- gui_fullscreen_initial_grab = 1;
- sdl_grab_start();
- }
-}
diff --git a/tools/ioemu/sdl_keysym.h b/tools/ioemu/sdl_keysym.h
deleted file mode 100644
index 9a7414209f..0000000000
--- a/tools/ioemu/sdl_keysym.h
+++ /dev/null
@@ -1,278 +0,0 @@
-typedef struct {
- const char* name;
- int keysym;
-} name2keysym_t;
-static name2keysym_t name2keysym[]={
-/* ascii */
- { "space", 0x020},
- { "exclam", 0x021},
- { "quotedbl", 0x022},
- { "numbersign", 0x023},
- { "dollar", 0x024},
- { "percent", 0x025},
- { "ampersand", 0x026},
- { "apostrophe", 0x027},
- { "parenleft", 0x028},
- { "parenright", 0x029},
- { "asterisk", 0x02a},
- { "plus", 0x02b},
- { "comma", 0x02c},
- { "minus", 0x02d},
- { "period", 0x02e},
- { "slash", 0x02f},
- { "0", 0x030},
- { "1", 0x031},
- { "2", 0x032},
- { "3", 0x033},
- { "4", 0x034},
- { "5", 0x035},
- { "6", 0x036},
- { "7", 0x037},
- { "8", 0x038},
- { "9", 0x039},
- { "colon", 0x03a},
- { "semicolon", 0x03b},
- { "less", 0x03c},
- { "equal", 0x03d},
- { "greater", 0x03e},
- { "question", 0x03f},
- { "at", 0x040},
- { "A", 0x041},
- { "B", 0x042},
- { "C", 0x043},
- { "D", 0x044},
- { "E", 0x045},
- { "F", 0x046},
- { "G", 0x047},
- { "H", 0x048},
- { "I", 0x049},
- { "J", 0x04a},
- { "K", 0x04b},
- { "L", 0x04c},
- { "M", 0x04d},
- { "N", 0x04e},
- { "O", 0x04f},
- { "P", 0x050},
- { "Q", 0x051},
- { "R", 0x052},
- { "S", 0x053},
- { "T", 0x054},
- { "U", 0x055},
- { "V", 0x056},
- { "W", 0x057},
- { "X", 0x058},
- { "Y", 0x059},
- { "Z", 0x05a},
- { "bracketleft", 0x05b},
- { "backslash", 0x05c},
- { "bracketright", 0x05d},
- { "asciicircum", 0x05e},
- { "underscore", 0x05f},
- { "grave", 0x060},
- { "a", 0x061},
- { "b", 0x062},
- { "c", 0x063},
- { "d", 0x064},
- { "e", 0x065},
- { "f", 0x066},
- { "g", 0x067},
- { "h", 0x068},
- { "i", 0x069},
- { "j", 0x06a},
- { "k", 0x06b},
- { "l", 0x06c},
- { "m", 0x06d},
- { "n", 0x06e},
- { "o", 0x06f},
- { "p", 0x070},
- { "q", 0x071},
- { "r", 0x072},
- { "s", 0x073},
- { "t", 0x074},
- { "u", 0x075},
- { "v", 0x076},
- { "w", 0x077},
- { "x", 0x078},
- { "y", 0x079},
- { "z", 0x07a},
- { "braceleft", 0x07b},
- { "bar", 0x07c},
- { "braceright", 0x07d},
- { "asciitilde", 0x07e},
-
-/* latin 1 extensions */
-{ "nobreakspace", 0x0a0},
-{ "exclamdown", 0x0a1},
-{ "cent", 0x0a2},
-{ "sterling", 0x0a3},
-{ "currency", 0x0a4},
-{ "yen", 0x0a5},
-{ "brokenbar", 0x0a6},
-{ "section", 0x0a7},
-{ "diaeresis", 0x0a8},
-{ "copyright", 0x0a9},
-{ "ordfeminine", 0x0aa},
-{ "guillemotleft", 0x0ab},
-{ "notsign", 0x0ac},
-{ "hyphen", 0x0ad},
-{ "registered", 0x0ae},
-{ "macron", 0x0af},
-{ "degree", 0x0b0},
-{ "plusminus", 0x0b1},
-{ "twosuperior", 0x0b2},
-{ "threesuperior", 0x0b3},
-{ "acute", 0x0b4},
-{ "mu", 0x0b5},
-{ "paragraph", 0x0b6},
-{ "periodcentered", 0x0b7},
-{ "cedilla", 0x0b8},
-{ "onesuperior", 0x0b9},
-{ "masculine", 0x0ba},
-{ "guillemotright", 0x0bb},
-{ "onequarter", 0x0bc},
-{ "onehalf", 0x0bd},
-{ "threequarters", 0x0be},
-{ "questiondown", 0x0bf},
-{ "Agrave", 0x0c0},
-{ "Aacute", 0x0c1},
-{ "Acircumflex", 0x0c2},
-{ "Atilde", 0x0c3},
-{ "Adiaeresis", 0x0c4},
-{ "Aring", 0x0c5},
-{ "AE", 0x0c6},
-{ "Ccedilla", 0x0c7},
-{ "Egrave", 0x0c8},
-{ "Eacute", 0x0c9},
-{ "Ecircumflex", 0x0ca},
-{ "Ediaeresis", 0x0cb},
-{ "Igrave", 0x0cc},
-{ "Iacute", 0x0cd},
-{ "Icircumflex", 0x0ce},
-{ "Idiaeresis", 0x0cf},
-{ "ETH", 0x0d0},
-{ "Eth", 0x0d0},
-{ "Ntilde", 0x0d1},
-{ "Ograve", 0x0d2},
-{ "Oacute", 0x0d3},
-{ "Ocircumflex", 0x0d4},
-{ "Otilde", 0x0d5},
-{ "Odiaeresis", 0x0d6},
-{ "multiply", 0x0d7},
-{ "Ooblique", 0x0d8},
-{ "Oslash", 0x0d8},
-{ "Ugrave", 0x0d9},
-{ "Uacute", 0x0da},
-{ "Ucircumflex", 0x0db},
-{ "Udiaeresis", 0x0dc},
-{ "Yacute", 0x0dd},
-{ "THORN", 0x0de},
-{ "Thorn", 0x0de},
-{ "ssharp", 0x0df},
-{ "agrave", 0x0e0},
-{ "aacute", 0x0e1},
-{ "acircumflex", 0x0e2},
-{ "atilde", 0x0e3},
-{ "adiaeresis", 0x0e4},
-{ "aring", 0x0e5},
-{ "ae", 0x0e6},
-{ "ccedilla", 0x0e7},
-{ "egrave", 0x0e8},
-{ "eacute", 0x0e9},
-{ "ecircumflex", 0x0ea},
-{ "ediaeresis", 0x0eb},
-{ "igrave", 0x0ec},
-{ "iacute", 0x0ed},
-{ "icircumflex", 0x0ee},
-{ "idiaeresis", 0x0ef},
-{ "eth", 0x0f0},
-{ "ntilde", 0x0f1},
-{ "ograve", 0x0f2},
-{ "oacute", 0x0f3},
-{ "ocircumflex", 0x0f4},
-{ "otilde", 0x0f5},
-{ "odiaeresis", 0x0f6},
-{ "division", 0x0f7},
-{ "oslash", 0x0f8},
-{ "ooblique", 0x0f8},
-{ "ugrave", 0x0f9},
-{ "uacute", 0x0fa},
-{ "ucircumflex", 0x0fb},
-{ "udiaeresis", 0x0fc},
-{ "yacute", 0x0fd},
-{ "thorn", 0x0fe},
-{ "ydiaeresis", 0x0ff},
-{"EuroSign", SDLK_EURO},
-
- /* modifiers */
-{"Control_L", SDLK_LCTRL},
-{"Control_R", SDLK_RCTRL},
-{"Alt_L", SDLK_LALT},
-{"Alt_R", SDLK_RALT},
-{"Caps_Lock", SDLK_CAPSLOCK},
-{"Meta_L", SDLK_LMETA},
-{"Meta_R", SDLK_RMETA},
-{"Shift_L", SDLK_LSHIFT},
-{"Shift_R", SDLK_RSHIFT},
-{"Super_L", SDLK_LSUPER},
-{"Super_R", SDLK_RSUPER},
-
- /* special keys */
-{"BackSpace", SDLK_BACKSPACE},
-{"Tab", SDLK_TAB},
-{"Return", SDLK_RETURN},
-{"Right", SDLK_RIGHT},
-{"Left", SDLK_LEFT},
-{"Up", SDLK_UP},
-{"Down", SDLK_DOWN},
-{"Page_Down", SDLK_PAGEDOWN},
-{"Page_Up", SDLK_PAGEUP},
-{"Insert", SDLK_INSERT},
-{"Delete", SDLK_DELETE},
-{"Home", SDLK_HOME},
-{"End", SDLK_END},
-{"Scroll_Lock", SDLK_SCROLLOCK},
-{"F1", SDLK_F1},
-{"F2", SDLK_F2},
-{"F3", SDLK_F3},
-{"F4", SDLK_F4},
-{"F5", SDLK_F5},
-{"F6", SDLK_F6},
-{"F7", SDLK_F7},
-{"F8", SDLK_F8},
-{"F9", SDLK_F9},
-{"F10", SDLK_F10},
-{"F11", SDLK_F11},
-{"F12", SDLK_F12},
-{"F13", SDLK_F13},
-{"F14", SDLK_F14},
-{"F15", SDLK_F15},
-{"Sys_Req", SDLK_SYSREQ},
-{"KP_0", SDLK_KP0},
-{"KP_1", SDLK_KP1},
-{"KP_2", SDLK_KP2},
-{"KP_3", SDLK_KP3},
-{"KP_4", SDLK_KP4},
-{"KP_5", SDLK_KP5},
-{"KP_6", SDLK_KP6},
-{"KP_7", SDLK_KP7},
-{"KP_8", SDLK_KP8},
-{"KP_9", SDLK_KP9},
-{"KP_Add", SDLK_KP_PLUS},
-{"KP_Decimal", SDLK_KP_PERIOD},
-{"KP_Divide", SDLK_KP_DIVIDE},
-{"KP_Enter", SDLK_KP_ENTER},
-{"KP_Equal", SDLK_KP_EQUALS},
-{"KP_Multiply", SDLK_KP_MULTIPLY},
-{"KP_Subtract", SDLK_KP_MINUS},
-{"help", SDLK_HELP},
-{"Menu", SDLK_MENU},
-{"Power", SDLK_POWER},
-{"Print", SDLK_PRINT},
-{"Mode_switch", SDLK_MODE},
-{"Multi_Key", SDLK_COMPOSE},
-{"Num_Lock", SDLK_NUMLOCK},
-{"Pause", SDLK_PAUSE},
-{"Escape", SDLK_ESCAPE},
-
-{0,0},
-};
diff --git a/tools/ioemu/softmmu_exec.h b/tools/ioemu/softmmu_exec.h
deleted file mode 100644
index 3b789eeb75..0000000000
--- a/tools/ioemu/softmmu_exec.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Common softmmu definitions and inline routines. */
-
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
-
-#define ACCESS_TYPE 0
-#define MEMSUFFIX _kernel
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-#define ACCESS_TYPE 1
-#define MEMSUFFIX _user
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-/* these access are slower, they must be as rare as possible */
-#define ACCESS_TYPE 2
-#define MEMSUFFIX _data
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-#define ldub(p) ldub_data(p)
-#define ldsb(p) ldsb_data(p)
-#define lduw(p) lduw_data(p)
-#define ldsw(p) ldsw_data(p)
-#define ldl(p) ldl_data(p)
-#define ldq(p) ldq_data(p)
-
-#define stb(p, v) stb_data(p, v)
-#define stw(p, v) stw_data(p, v)
-#define stl(p, v) stl_data(p, v)
-#define stq(p, v) stq_data(p, v)
diff --git a/tools/ioemu/softmmu_header.h b/tools/ioemu/softmmu_header.h
deleted file mode 100644
index d5b3debc74..0000000000
--- a/tools/ioemu/softmmu_header.h
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Software MMU support
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#if DATA_SIZE == 8
-#define SUFFIX q
-#define USUFFIX q
-#define DATA_TYPE uint64_t
-#elif DATA_SIZE == 4
-#define SUFFIX l
-#define USUFFIX l
-#define DATA_TYPE uint32_t
-#elif DATA_SIZE == 2
-#define SUFFIX w
-#define USUFFIX uw
-#define DATA_TYPE uint16_t
-#define DATA_STYPE int16_t
-#elif DATA_SIZE == 1
-#define SUFFIX b
-#define USUFFIX ub
-#define DATA_TYPE uint8_t
-#define DATA_STYPE int8_t
-#else
-#error unsupported data size
-#endif
-
-#if ACCESS_TYPE == 0
-
-#define CPU_MEM_INDEX 0
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == 1
-
-#define CPU_MEM_INDEX 1
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == 2
-
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#else
-#error unsupported CPU
-#endif
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == 3
-
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#else
-#error unsupported CPU
-#endif
-#define MMUSUFFIX _cmmu
-
-#else
-#error invalid ACCESS_TYPE
-#endif
-
-#if DATA_SIZE == 8
-#define RES_TYPE uint64_t
-#else
-#define RES_TYPE int
-#endif
-
-#if ACCESS_TYPE == 3
-#define ADDR_READ addr_code
-#else
-#define ADDR_READ addr_read
-#endif
-
-DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
- int is_user);
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
-
-#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
- (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
-
-#define CPU_TLB_ENTRY_BITS 4
-
-static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "pushl %6\n"
- "call %7\n"
- "popl %%edx\n"
- "movl %%eax, %0\n"
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movzbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movzwl (%%eax), %0\n"
-#elif DATA_SIZE == 4
- "movl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
- "i" (CPU_MEM_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-
-#if DATA_SIZE <= 2
-static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "pushl %6\n"
- "call %7\n"
- "popl %%edx\n"
-#if DATA_SIZE == 1
- "movsbl %%al, %0\n"
-#elif DATA_SIZE == 2
- "movswl %%ax, %0\n"
-#else
-#error unsupported size
-#endif
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movsbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movswl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
- "i" (CPU_MEM_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-#endif
-
-static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-{
- asm volatile ("movl %0, %%edx\n"
- "movl %0, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %0, %%eax\n"
- "je 1f\n"
-#if DATA_SIZE == 1
- "movzbl %b1, %%edx\n"
-#elif DATA_SIZE == 2
- "movzwl %w1, %%edx\n"
-#elif DATA_SIZE == 4
- "movl %1, %%edx\n"
-#else
-#error unsupported size
-#endif
- "pushl %6\n"
- "call %7\n"
- "popl %%eax\n"
- "jmp 2f\n"
- "1:\n"
- "addl 8(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movb %b1, (%%eax)\n"
-#elif DATA_SIZE == 2
- "movw %w1, (%%eax)\n"
-#elif DATA_SIZE == 4
- "movl %1, (%%eax)\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- :
- : "r" (ptr),
-/* NOTE: 'q' would be needed as constraint, but we could not use it
- with T1 ! */
- "r" (v),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
- "i" (CPU_MEM_INDEX),
- "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
-}
-
-#else
-
-/* generic load/store macros */
-
-static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int index;
- RES_TYPE res;
- target_ulong addr;
- unsigned long physaddr;
- int is_user;
-
- addr = ptr;
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- is_user = CPU_MEM_INDEX;
- if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
- (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
- res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
- } else {
- physaddr = addr + env->tlb_table[is_user][index].addend;
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
- }
- return res;
-}
-
-#if DATA_SIZE <= 2
-static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res, index;
- target_ulong addr;
- unsigned long physaddr;
- int is_user;
-
- addr = ptr;
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- is_user = CPU_MEM_INDEX;
- if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
- (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
- res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
- } else {
- physaddr = addr + env->tlb_table[is_user][index].addend;
- res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
- }
- return res;
-}
-#endif
-
-#if ACCESS_TYPE != 3
-
-/* generic store macro */
-
-static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-{
- int index;
- target_ulong addr;
- unsigned long physaddr;
- int is_user;
-
- addr = ptr;
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- is_user = CPU_MEM_INDEX;
- if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
- (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
- glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
- } else {
- physaddr = addr + env->tlb_table[is_user][index].addend;
- glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
- }
-}
-
-#endif /* ACCESS_TYPE != 3 */
-
-#endif /* !asm */
-
-#if ACCESS_TYPE != 3
-
-#if DATA_SIZE == 8
-static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
-{
- union {
- float64 d;
- uint64_t i;
- } u;
- u.i = glue(ldq, MEMSUFFIX)(ptr);
- return u.d;
-}
-
-static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
-{
- union {
- float64 d;
- uint64_t i;
- } u;
- u.d = v;
- glue(stq, MEMSUFFIX)(ptr, u.i);
-}
-#endif /* DATA_SIZE == 8 */
-
-#if DATA_SIZE == 4
-static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = glue(ldl, MEMSUFFIX)(ptr);
- return u.f;
-}
-
-static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = v;
- glue(stl, MEMSUFFIX)(ptr, u.i);
-}
-#endif /* DATA_SIZE == 4 */
-
-#endif /* ACCESS_TYPE != 3 */
-
-#undef RES_TYPE
-#undef DATA_TYPE
-#undef DATA_STYPE
-#undef SUFFIX
-#undef USUFFIX
-#undef DATA_SIZE
-#undef CPU_MEM_INDEX
-#undef MMUSUFFIX
-#undef ADDR_READ
diff --git a/tools/ioemu/softmmu_template.h b/tools/ioemu/softmmu_template.h
deleted file mode 100644
index 1c12c42411..0000000000
--- a/tools/ioemu/softmmu_template.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Software MMU support
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#define DATA_SIZE (1 << SHIFT)
-
-#if DATA_SIZE == 8
-#define SUFFIX q
-#define USUFFIX q
-#define DATA_TYPE uint64_t
-#elif DATA_SIZE == 4
-#define SUFFIX l
-#define USUFFIX l
-#define DATA_TYPE uint32_t
-#elif DATA_SIZE == 2
-#define SUFFIX w
-#define USUFFIX uw
-#define DATA_TYPE uint16_t
-#elif DATA_SIZE == 1
-#define SUFFIX b
-#define USUFFIX ub
-#define DATA_TYPE uint8_t
-#else
-#error unsupported data size
-#endif
-
-#ifdef SOFTMMU_CODE_ACCESS
-#define READ_ACCESS_TYPE 2
-#define ADDR_READ addr_code
-#else
-#define READ_ACCESS_TYPE 0
-#define ADDR_READ addr_read
-#endif
-
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
- int is_user,
- void *retaddr);
-static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
- target_ulong tlb_addr)
-{
- DATA_TYPE res;
- int index;
-
- index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-#if SHIFT <= 2
- res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
-#else
-#ifdef TARGET_WORDS_BIGENDIAN
- res = (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr) << 32;
- res |= io_mem_read[index][2](io_mem_opaque[index], physaddr + 4);
-#else
- res = io_mem_read[index][2](io_mem_opaque[index], physaddr);
- res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
-#endif
-#endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
- env->last_io_time = cpu_get_time_fast();
-#endif
- return res;
-}
-
-/* handle all cases except unaligned access which span two pages */
-DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
- int is_user)
-{
- DATA_TYPE res;
- int index;
- target_ulong tlb_addr;
- target_phys_addr_t physaddr;
- void *retaddr;
-
- /* test if there is match for unaligned or IO access */
- /* XXX: could done more in memory macro in a non portable way */
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- physaddr = addr + env->tlb_table[is_user][index].addend;
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- /* slow unaligned access (it spans two pages or IO) */
- do_unaligned_access:
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
-#endif
- res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
- is_user, retaddr);
- } else {
- /* unaligned/aligned access in the same page */
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0) {
- retaddr = GETPC();
- do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
- }
-#endif
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
- }
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0)
- do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
-#endif
- tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
- goto redo;
- }
- return res;
-}
-
-/* handle all unaligned cases */
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
- int is_user,
- void *retaddr)
-{
- DATA_TYPE res, res1, res2;
- int index, shift;
- target_phys_addr_t physaddr;
- target_ulong tlb_addr, addr1, addr2;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- physaddr = addr + env->tlb_table[is_user][index].addend;
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- /* slow unaligned access (it spans two pages) */
- addr1 = addr & ~(DATA_SIZE - 1);
- addr2 = addr1 + DATA_SIZE;
- res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
- is_user, retaddr);
- res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
- is_user, retaddr);
- shift = (addr & (DATA_SIZE - 1)) * 8;
-#ifdef TARGET_WORDS_BIGENDIAN
- res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
-#else
- res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
-#endif
- res = (DATA_TYPE)res;
- } else {
- /* unaligned/aligned access in the same page */
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
- }
- } else {
- /* the page is not in the TLB : fill it */
- tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
- goto redo;
- }
- return res;
-}
-
-#ifndef SOFTMMU_CODE_ACCESS
-
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
- DATA_TYPE val,
- int is_user,
- void *retaddr);
-
-static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
- DATA_TYPE val,
- target_ulong tlb_addr,
- void *retaddr)
-{
- int index;
-
- index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- env->mem_write_vaddr = tlb_addr;
- env->mem_write_pc = (unsigned long)retaddr;
-#if SHIFT <= 2
- io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
-#else
-#ifdef TARGET_WORDS_BIGENDIAN
- io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32);
- io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val);
-#else
- io_mem_write[index][2](io_mem_opaque[index], physaddr, val);
- io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
-#endif
-#endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
- DATA_TYPE val,
- int is_user)
-{
- target_phys_addr_t physaddr;
- target_ulong tlb_addr;
- void *retaddr;
- int index;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[is_user][index].addr_write;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- physaddr = addr + env->tlb_table[is_user][index].addend;
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- retaddr = GETPC();
- glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- do_unaligned_access(addr, 1, is_user, retaddr);
-#endif
- glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
- is_user, retaddr);
- } else {
- /* aligned/unaligned access in the same page */
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0) {
- retaddr = GETPC();
- do_unaligned_access(addr, 1, is_user, retaddr);
- }
-#endif
- glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
- }
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0)
- do_unaligned_access(addr, 1, is_user, retaddr);
-#endif
- tlb_fill(addr, 1, is_user, retaddr);
- goto redo;
- }
-}
-
-/* handles all unaligned cases */
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
- DATA_TYPE val,
- int is_user,
- void *retaddr)
-{
- target_phys_addr_t physaddr;
- target_ulong tlb_addr;
- int index, i;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[is_user][index].addr_write;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- physaddr = addr + env->tlb_table[is_user][index].addend;
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- /* XXX: not efficient, but simple */
- for(i = 0;i < DATA_SIZE; i++) {
-#ifdef TARGET_WORDS_BIGENDIAN
- glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
- is_user, retaddr);
-#else
- glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
- is_user, retaddr);
-#endif
- }
- } else {
- /* aligned/unaligned access in the same page */
- glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
- }
- } else {
- /* the page is not in the TLB : fill it */
- tlb_fill(addr, 1, is_user, retaddr);
- goto redo;
- }
-}
-
-#endif /* !defined(SOFTMMU_CODE_ACCESS) */
-
-#undef READ_ACCESS_TYPE
-#undef SHIFT
-#undef DATA_TYPE
-#undef SUFFIX
-#undef USUFFIX
-#undef DATA_SIZE
-#undef ADDR_READ
diff --git a/tools/ioemu/tap-win32.c b/tools/ioemu/tap-win32.c
deleted file mode 100644
index d84a622d35..0000000000
--- a/tools/ioemu/tap-win32.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * TAP-Win32 -- A kernel driver to provide virtual tap device functionality
- * on Windows. Originally derived from the CIPE-Win32
- * project by Damion K. Wilson, with extensive modifications by
- * James Yonan.
- *
- * All source code which derives from the CIPE-Win32 project is
- * Copyright (C) Damion K. Wilson, 2003, and is released under the
- * GPL version 2 (see below).
- *
- * All other source code is Copyright (C) James Yonan, 2003-2004,
- * and is released under the GPL version 2 (see below).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "vl.h"
-#include <stdio.h>
-#include <windows.h>
-
-/* NOTE: PCIBus is redefined in winddk.h */
-#define PCIBus _PCIBus
-#include <ddk/ntapi.h>
-#include <ddk/winddk.h>
-#include <ddk/ntddk.h>
-#undef PCIBus
-
-//=============
-// TAP IOCTLs
-//=============
-
-#define TAP_CONTROL_CODE(request,method) \
- CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
-
-#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED)
-#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED)
-
-//=================
-// Registry keys
-//=================
-
-#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-
-#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-
-//======================
-// Filesystem prefixes
-//======================
-
-#define USERMODEDEVICEDIR "\\\\.\\Global\\"
-#define TAPSUFFIX ".tap"
-
-
-//======================
-// Compile time configuration
-//======================
-
-//#define DEBUG_TAP_WIN32 1
-
-#define TUN_ASYNCHRONOUS_WRITES 1
-
-#define TUN_BUFFER_SIZE 1560
-#define TUN_MAX_BUFFER_COUNT 32
-
-/*
- * The data member "buffer" must be the first element in the tun_buffer
- * structure. See the function, tap_win32_free_buffer.
- */
-typedef struct tun_buffer_s {
- unsigned char buffer [TUN_BUFFER_SIZE];
- unsigned long read_size;
- struct tun_buffer_s* next;
-} tun_buffer_t;
-
-typedef struct tap_win32_overlapped {
- HANDLE handle;
- HANDLE read_event;
- HANDLE write_event;
- HANDLE output_queue_semaphore;
- HANDLE free_list_semaphore;
- HANDLE tap_semaphore;
- CRITICAL_SECTION output_queue_cs;
- CRITICAL_SECTION free_list_cs;
- OVERLAPPED read_overlapped;
- OVERLAPPED write_overlapped;
- tun_buffer_t buffers[TUN_MAX_BUFFER_COUNT];
- tun_buffer_t* free_list;
- tun_buffer_t* output_queue_front;
- tun_buffer_t* output_queue_back;
-} tap_win32_overlapped_t;
-
-static tap_win32_overlapped_t tap_overlapped;
-
-static tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped)
-{
- tun_buffer_t* buffer = NULL;
- WaitForSingleObject(overlapped->free_list_semaphore, INFINITE);
- EnterCriticalSection(&overlapped->free_list_cs);
- buffer = overlapped->free_list;
-// assert(buffer != NULL);
- overlapped->free_list = buffer->next;
- LeaveCriticalSection(&overlapped->free_list_cs);
- buffer->next = NULL;
- return buffer;
-}
-
-static void put_buffer_on_free_list(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer)
-{
- EnterCriticalSection(&overlapped->free_list_cs);
- buffer->next = overlapped->free_list;
- overlapped->free_list = buffer;
- LeaveCriticalSection(&overlapped->free_list_cs);
- ReleaseSemaphore(overlapped->free_list_semaphore, 1, NULL);
-}
-
-static tun_buffer_t* get_buffer_from_output_queue(tap_win32_overlapped_t* const overlapped, const int block)
-{
- tun_buffer_t* buffer = NULL;
- DWORD result, timeout = block ? INFINITE : 0L;
-
- // Non-blocking call
- result = WaitForSingleObject(overlapped->output_queue_semaphore, timeout);
-
- switch (result)
- {
- // The semaphore object was signaled.
- case WAIT_OBJECT_0:
- EnterCriticalSection(&overlapped->output_queue_cs);
-
- buffer = overlapped->output_queue_front;
- overlapped->output_queue_front = buffer->next;
-
- if(overlapped->output_queue_front == NULL) {
- overlapped->output_queue_back = NULL;
- }
-
- LeaveCriticalSection(&overlapped->output_queue_cs);
- break;
-
- // Semaphore was nonsignaled, so a time-out occurred.
- case WAIT_TIMEOUT:
- // Cannot open another window.
- break;
- }
-
- return buffer;
-}
-
-static tun_buffer_t* get_buffer_from_output_queue_immediate (tap_win32_overlapped_t* const overlapped)
-{
- return get_buffer_from_output_queue(overlapped, 0);
-}
-
-static void put_buffer_on_output_queue(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer)
-{
- EnterCriticalSection(&overlapped->output_queue_cs);
-
- if(overlapped->output_queue_front == NULL && overlapped->output_queue_back == NULL) {
- overlapped->output_queue_front = overlapped->output_queue_back = buffer;
- } else {
- buffer->next = NULL;
- overlapped->output_queue_back->next = buffer;
- overlapped->output_queue_back = buffer;
- }
-
- LeaveCriticalSection(&overlapped->output_queue_cs);
-
- ReleaseSemaphore(overlapped->output_queue_semaphore, 1, NULL);
-}
-
-
-static int is_tap_win32_dev(const char *guid)
-{
- HKEY netcard_key;
- LONG status;
- DWORD len;
- int i = 0;
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- ADAPTER_KEY,
- 0,
- KEY_READ,
- &netcard_key);
-
- if (status != ERROR_SUCCESS) {
- return FALSE;
- }
-
- for (;;) {
- char enum_name[256];
- char unit_string[256];
- HKEY unit_key;
- char component_id_string[] = "ComponentId";
- char component_id[256];
- char net_cfg_instance_id_string[] = "NetCfgInstanceId";
- char net_cfg_instance_id[256];
- DWORD data_type;
-
- len = sizeof (enum_name);
- status = RegEnumKeyEx(
- netcard_key,
- i,
- enum_name,
- &len,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (status == ERROR_NO_MORE_ITEMS)
- break;
- else if (status != ERROR_SUCCESS) {
- return FALSE;
- }
-
- snprintf (unit_string, sizeof(unit_string), "%s\\%s",
- ADAPTER_KEY, enum_name);
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- unit_string,
- 0,
- KEY_READ,
- &unit_key);
-
- if (status != ERROR_SUCCESS) {
- return FALSE;
- } else {
- len = sizeof (component_id);
- status = RegQueryValueEx(
- unit_key,
- component_id_string,
- NULL,
- &data_type,
- component_id,
- &len);
-
- if (!(status != ERROR_SUCCESS || data_type != REG_SZ)) {
- len = sizeof (net_cfg_instance_id);
- status = RegQueryValueEx(
- unit_key,
- net_cfg_instance_id_string,
- NULL,
- &data_type,
- net_cfg_instance_id,
- &len);
-
- if (status == ERROR_SUCCESS && data_type == REG_SZ) {
- if (/* !strcmp (component_id, TAP_COMPONENT_ID) &&*/
- !strcmp (net_cfg_instance_id, guid)) {
- RegCloseKey (unit_key);
- RegCloseKey (netcard_key);
- return TRUE;
- }
- }
- }
- RegCloseKey (unit_key);
- }
- ++i;
- }
-
- RegCloseKey (netcard_key);
- return FALSE;
-}
-
-static int get_device_guid(
- char *name,
- int name_size,
- char *actual_name,
- int actual_name_size)
-{
- LONG status;
- HKEY control_net_key;
- DWORD len;
- int i = 0;
- int stop = 0;
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- NETWORK_CONNECTIONS_KEY,
- 0,
- KEY_READ,
- &control_net_key);
-
- if (status != ERROR_SUCCESS) {
- return -1;
- }
-
- while (!stop)
- {
- char enum_name[256];
- char connection_string[256];
- HKEY connection_key;
- char name_data[256];
- DWORD name_type;
- const char name_string[] = "Name";
-
- len = sizeof (enum_name);
- status = RegEnumKeyEx(
- control_net_key,
- i,
- enum_name,
- &len,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (status == ERROR_NO_MORE_ITEMS)
- break;
- else if (status != ERROR_SUCCESS) {
- return -1;
- }
-
- snprintf(connection_string,
- sizeof(connection_string),
- "%s\\%s\\Connection",
- NETWORK_CONNECTIONS_KEY, enum_name);
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- connection_string,
- 0,
- KEY_READ,
- &connection_key);
-
- if (status == ERROR_SUCCESS) {
- len = sizeof (name_data);
- status = RegQueryValueEx(
- connection_key,
- name_string,
- NULL,
- &name_type,
- name_data,
- &len);
-
- if (status != ERROR_SUCCESS || name_type != REG_SZ) {
- return -1;
- }
- else {
- if (is_tap_win32_dev(enum_name)) {
- snprintf(name, name_size, "%s", enum_name);
- if (actual_name) {
- if (strcmp(actual_name, "") != 0) {
- if (strcmp(name_data, actual_name) != 0) {
- RegCloseKey (connection_key);
- ++i;
- continue;
- }
- }
- else {
- snprintf(actual_name, actual_name_size, "%s", name_data);
- }
- }
- stop = 1;
- }
- }
-
- RegCloseKey (connection_key);
- }
- ++i;
- }
-
- RegCloseKey (control_net_key);
-
- if (stop == 0)
- return -1;
-
- return 0;
-}
-
-static int tap_win32_set_status(HANDLE handle, int status)
-{
- unsigned long len = 0;
-
- return DeviceIoControl(handle, TAP_IOCTL_SET_MEDIA_STATUS,
- &status, sizeof (status),
- &status, sizeof (status), &len, NULL);
-}
-
-static void tap_win32_overlapped_init(tap_win32_overlapped_t* const overlapped, const HANDLE handle)
-{
- overlapped->handle = handle;
-
- overlapped->read_event = CreateEvent(NULL, FALSE, FALSE, NULL);
- overlapped->write_event = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- overlapped->read_overlapped.Offset = 0;
- overlapped->read_overlapped.OffsetHigh = 0;
- overlapped->read_overlapped.hEvent = overlapped->read_event;
-
- overlapped->write_overlapped.Offset = 0;
- overlapped->write_overlapped.OffsetHigh = 0;
- overlapped->write_overlapped.hEvent = overlapped->write_event;
-
- InitializeCriticalSection(&overlapped->output_queue_cs);
- InitializeCriticalSection(&overlapped->free_list_cs);
-
- overlapped->output_queue_semaphore = CreateSemaphore(
- NULL, // default security attributes
- 0, // initial count
- TUN_MAX_BUFFER_COUNT, // maximum count
- NULL); // unnamed semaphore
-
- if(!overlapped->output_queue_semaphore) {
- fprintf(stderr, "error creating output queue semaphore!\n");
- }
-
- overlapped->free_list_semaphore = CreateSemaphore(
- NULL, // default security attributes
- TUN_MAX_BUFFER_COUNT, // initial count
- TUN_MAX_BUFFER_COUNT, // maximum count
- NULL); // unnamed semaphore
-
- if(!overlapped->free_list_semaphore) {
- fprintf(stderr, "error creating free list semaphore!\n");
- }
-
- overlapped->free_list = overlapped->output_queue_front = overlapped->output_queue_back = NULL;
-
- {
- unsigned index;
- for(index = 0; index < TUN_MAX_BUFFER_COUNT; index++) {
- tun_buffer_t* element = &overlapped->buffers[index];
- element->next = overlapped->free_list;
- overlapped->free_list = element;
- }
- }
- /* To count buffers, initially no-signal. */
- overlapped->tap_semaphore = CreateSemaphore(NULL, 0, TUN_MAX_BUFFER_COUNT, NULL);
- if(!overlapped->tap_semaphore)
- fprintf(stderr, "error creating tap_semaphore.\n");
-}
-
-static int tap_win32_write(tap_win32_overlapped_t *overlapped,
- const void *buffer, unsigned long size)
-{
- unsigned long write_size;
- BOOL result;
- DWORD error;
-
- result = GetOverlappedResult( overlapped->handle, &overlapped->write_overlapped,
- &write_size, FALSE);
-
- if (!result && GetLastError() == ERROR_IO_INCOMPLETE)
- WaitForSingleObject(overlapped->write_event, INFINITE);
-
- result = WriteFile(overlapped->handle, buffer, size,
- &write_size, &overlapped->write_overlapped);
-
- if (!result) {
- switch (error = GetLastError())
- {
- case ERROR_IO_PENDING:
-#ifndef TUN_ASYNCHRONOUS_WRITES
- WaitForSingleObject(overlapped->write_event, INFINITE);
-#endif
- break;
- default:
- return -1;
- }
- }
-
- return 0;
-}
-
-static DWORD WINAPI tap_win32_thread_entry(LPVOID param)
-{
- tap_win32_overlapped_t *overlapped = (tap_win32_overlapped_t*)param;
- unsigned long read_size;
- BOOL result;
- DWORD dwError;
- tun_buffer_t* buffer = get_buffer_from_free_list(overlapped);
-
-
- for (;;) {
- result = ReadFile(overlapped->handle,
- buffer->buffer,
- sizeof(buffer->buffer),
- &read_size,
- &overlapped->read_overlapped);
- if (!result) {
- dwError = GetLastError();
- if (dwError == ERROR_IO_PENDING) {
- WaitForSingleObject(overlapped->read_event, INFINITE);
- result = GetOverlappedResult( overlapped->handle, &overlapped->read_overlapped,
- &read_size, FALSE);
- if (!result) {
-#if DEBUG_TAP_WIN32
- LPVOID lpBuffer;
- dwError = GetLastError();
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) & lpBuffer, 0, NULL );
- fprintf(stderr, "Tap-Win32: Error GetOverlappedResult %d - %s\n", dwError, lpBuffer);
- LocalFree( lpBuffer );
-#endif
- }
- } else {
-#if DEBUG_TAP_WIN32
- LPVOID lpBuffer;
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) & lpBuffer, 0, NULL );
- fprintf(stderr, "Tap-Win32: Error ReadFile %d - %s\n", dwError, lpBuffer);
- LocalFree( lpBuffer );
-#endif
- }
- }
-
- if(read_size > 0) {
- buffer->read_size = read_size;
- put_buffer_on_output_queue(overlapped, buffer);
- ReleaseSemaphore(overlapped->tap_semaphore, 1, NULL);
- buffer = get_buffer_from_free_list(overlapped);
- }
- }
-
- return 0;
-}
-
-static int tap_win32_read(tap_win32_overlapped_t *overlapped,
- uint8_t **pbuf, int max_size)
-{
- int size = 0;
-
- tun_buffer_t* buffer = get_buffer_from_output_queue_immediate(overlapped);
-
- if(buffer != NULL) {
- *pbuf = buffer->buffer;
- size = (int)buffer->read_size;
- if(size > max_size) {
- size = max_size;
- }
- }
-
- return size;
-}
-
-static void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped,
- char* pbuf)
-{
- tun_buffer_t* buffer = (tun_buffer_t*)pbuf;
- put_buffer_on_free_list(overlapped, buffer);
-}
-
-static int tap_win32_open(tap_win32_overlapped_t **phandle,
- const char *prefered_name)
-{
- char device_path[256];
- char device_guid[0x100];
- int rc;
- HANDLE handle;
- BOOL bret;
- char name_buffer[0x100] = {0, };
- struct {
- unsigned long major;
- unsigned long minor;
- unsigned long debug;
- } version;
- LONG version_len;
- DWORD idThread;
- HANDLE hThread;
-
- if (prefered_name != NULL)
- snprintf(name_buffer, sizeof(name_buffer), "%s", prefered_name);
-
- rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
- if (rc)
- return -1;
-
- snprintf (device_path, sizeof(device_path), "%s%s%s",
- USERMODEDEVICEDIR,
- device_guid,
- TAPSUFFIX);
-
- handle = CreateFile (
- device_path,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- 0,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
- 0 );
-
- if (handle == INVALID_HANDLE_VALUE) {
- return -1;
- }
-
- bret = DeviceIoControl(handle, TAP_IOCTL_GET_VERSION,
- &version, sizeof (version),
- &version, sizeof (version), &version_len, NULL);
-
- if (bret == FALSE) {
- CloseHandle(handle);
- return -1;
- }
-
- if (!tap_win32_set_status(handle, TRUE)) {
- return -1;
- }
-
- tap_win32_overlapped_init(&tap_overlapped, handle);
-
- *phandle = &tap_overlapped;
-
- hThread = CreateThread(NULL, 0, tap_win32_thread_entry,
- (LPVOID)&tap_overlapped, 0, &idThread);
- return 0;
-}
-
-/********************************************/
-
- typedef struct TAPState {
- VLANClientState *vc;
- tap_win32_overlapped_t *handle;
- } TAPState;
-
-static void tap_receive(void *opaque, const uint8_t *buf, int size)
-{
- TAPState *s = opaque;
-
- tap_win32_write(s->handle, buf, size);
-}
-
-static void tap_win32_send(void *opaque)
-{
- TAPState *s = opaque;
- uint8_t *buf;
- int max_size = 4096;
- int size;
-
- size = tap_win32_read(s->handle, &buf, max_size);
- if (size > 0) {
- qemu_send_packet(s->vc, buf, size);
- tap_win32_free_buffer(s->handle, buf);
- }
-}
-
-int tap_win32_init(VLANState *vlan, const char *ifname)
-{
- TAPState *s;
-
- s = qemu_mallocz(sizeof(TAPState));
- if (!s)
- return -1;
- if (tap_win32_open(&s->handle, ifname) < 0) {
- printf("tap: Could not open '%s'\n", ifname);
- return -1;
- }
-
- s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "tap: ifname=%s", ifname);
-
- qemu_add_wait_object(s->handle->tap_semaphore, tap_win32_send, s);
- return 0;
-}
diff --git a/tools/ioemu/tapdisk-ioemu.c b/tools/ioemu/tapdisk-ioemu.c
deleted file mode 100644
index 52c5ac67ed..0000000000
--- a/tools/ioemu/tapdisk-ioemu.c
+++ /dev/null
@@ -1,156 +0,0 @@
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include <assert.h>
-
-extern int init_blktap(void);
-extern void qemu_aio_init(void);
-extern void qemu_aio_poll(void);
-extern void bdrv_init(void);
-
-extern void *qemu_mallocz(size_t size);
-extern void qemu_free(void *ptr);
-
-extern void *fd_start;
-
-int domid = 0;
-FILE* logfile;
-
-void term_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-}
-
-void term_print_filename(const char *filename)
-{
- term_printf(filename);
-}
-
-
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanRWHandler(void *opaque);
-typedef void IOHandler(void *opaque);
-
-typedef struct IOHandlerRecord {
- int fd;
- IOCanRWHandler *fd_read_poll;
- IOHandler *fd_read;
- IOHandler *fd_write;
- int deleted;
- void *opaque;
- /* temporary data */
- struct pollfd *ufd;
- struct IOHandlerRecord *next;
-} IOHandlerRecord;
-
-static IOHandlerRecord *first_io_handler;
-
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
-{
- IOHandlerRecord *ioh;
-
- /* This is a stripped down version of fd handling */
- assert(fd_read_poll == NULL);
- assert(fd_write == NULL);
-
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next)
- if (ioh->fd == fd)
- goto found;
-
- if (!fd_read && !fd_write)
- return 0;
-
- ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- if (!ioh)
- return -1;
- ioh->next = first_io_handler;
- first_io_handler = ioh;
-
-found:
- if (!fd_read && !fd_write) {
- ioh->deleted = 1;
- } else {
- ioh->fd = fd;
- ioh->fd_read = fd_read;
- ioh->opaque = opaque;
- ioh->deleted = 0;
- }
-
- return 0;
-}
-
-int main(void)
-{
- IOHandlerRecord *ioh, **pioh;
- int max_fd;
- fd_set rfds;
- struct timeval tv;
- void *old_fd_start = NULL;
-
- logfile = stderr;
-
- bdrv_init();
- qemu_aio_init();
- init_blktap();
-
- /* Daemonize */
- if (fork() != 0)
- exit(0);
-
- /*
- * Main loop: Pass events to the corrsponding handlers and check for
- * completed aio operations.
- */
- while (1) {
- qemu_aio_poll();
-
- max_fd = -1;
- FD_ZERO(&rfds);
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next)
- if (!ioh->deleted) {
- FD_SET(ioh->fd, &rfds);
- max_fd = max_fd > ioh->fd ? max_fd : ioh->fd;
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 10000;
- if (select(max_fd + 1, &rfds, NULL, NULL, &tv) <= 0)
- continue;
-
- /* Call handlers */
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next)
- if (FD_ISSET(ioh->fd, &rfds))
- ioh->fd_read(ioh->opaque);
-
- /* Remove deleted IO handlers */
- pioh = &first_io_handler;
- while (*pioh) {
- ioh = *pioh;
- if (ioh->deleted) {
- *pioh = ioh->next;
- qemu_free(ioh);
- } else
- pioh = &ioh->next;
- }
-
- /* Exit when the last image has been closed */
- if (old_fd_start != NULL && fd_start == NULL)
- exit(0);
-
- old_fd_start = fd_start;
- }
- return 0;
-}
diff --git a/tools/ioemu/target-i386-dm/cpu.h b/tools/ioemu/target-i386-dm/cpu.h
deleted file mode 100644
index 6071a8529e..0000000000
--- a/tools/ioemu/target-i386-dm/cpu.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * i386 virtual CPU header
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_I386_H
-#define CPU_I386_H
-
-#include "config.h"
-
-#ifdef TARGET_X86_64
-#define TARGET_LONG_BITS 64
-#else
-/* #define TARGET_LONG_BITS 32 */
-#define TARGET_LONG_BITS 64 /* for Qemu map cache */
-#endif
-
-/* target supports implicit self modifying code */
-#define TARGET_HAS_SMC
-/* support for self modifying code even if the modified instruction is
- close to the modifying instruction */
-#define TARGET_HAS_PRECISE_SMC
-
-#include "cpu-defs.h"
-
-#ifdef CONFIG_SOFTFLOAT
-#include "softfloat.h"
-#endif
-
-#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
-#define USE_CODE_COPY
-#endif
-
-#ifdef CONFIG_SOFTFLOAT
-#ifdef USE_X86LDOUBLE
-typedef floatx80 CPU86_LDouble;
-#else
-typedef float64 CPU86_LDouble;
-#endif
-#endif
-
-/* Empty for now */
-typedef struct CPUX86State {
- uint32_t a20_mask;
-
- int interrupt_request;
-
- CPU_COMMON
-} CPUX86State;
-
-CPUX86State *cpu_x86_init(void);
-int cpu_x86_exec(CPUX86State *s);
-void cpu_x86_close(CPUX86State *s);
-int cpu_get_pic_interrupt(CPUX86State *s);
-/* MSDOS compatibility mode FPU exception support */
-void cpu_set_ferr(CPUX86State *s);
-
-void cpu_x86_set_a20(CPUX86State *env, int a20_state);
-
-#ifndef IN_OP_I386
-void cpu_x86_outb(CPUX86State *env, int addr, int val);
-void cpu_x86_outw(CPUX86State *env, int addr, int val);
-void cpu_x86_outl(CPUX86State *env, int addr, int val);
-int cpu_x86_inb(CPUX86State *env, int addr);
-int cpu_x86_inw(CPUX86State *env, int addr);
-int cpu_x86_inl(CPUX86State *env, int addr);
-#endif
-
-/* helper2.c */
-int main_loop(void);
-
-#if defined(__i386__) || defined(__x86_64__)
-#define TARGET_PAGE_BITS 12
-#elif defined(__ia64__)
-#define TARGET_PAGE_BITS 14
-#endif
-#include "cpu-all.h"
-
-#endif /* CPU_I386_H */
diff --git a/tools/ioemu/target-i386-dm/exec-dm.c b/tools/ioemu/target-i386-dm/exec-dm.c
deleted file mode 100644
index 74235675f9..0000000000
--- a/tools/ioemu/target-i386-dm/exec-dm.c
+++ /dev/null
@@ -1,629 +0,0 @@
-/*
- * virtual page mapping and translated block handling
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <sys/types.h>
-#include <sys/mman.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "vl.h"
-
-//#define DEBUG_TB_INVALIDATE
-//#define DEBUG_FLUSH
-//#define DEBUG_TLB
-
-/* make various TB consistency checks */
-//#define DEBUG_TB_CHECK
-//#define DEBUG_TLB_CHECK
-
-#ifndef CONFIG_DM
-/* threshold to flush the translated code buffer */
-#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
-
-#define SMC_BITMAP_USE_THRESHOLD 10
-
-#define MMAP_AREA_START 0x00000000
-#define MMAP_AREA_END 0xa8000000
-
-TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
-TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
-TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-int nb_tbs;
-/* any access to the tbs or the page table must use this lock */
-spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
-
-uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
-uint8_t *code_gen_ptr;
-#endif /* !CONFIG_DM */
-
-uint64_t phys_ram_size;
-extern uint64_t ram_size;
-int phys_ram_fd;
-uint8_t *phys_ram_base;
-uint8_t *phys_ram_dirty;
-
-CPUState *first_cpu;
-/* current CPU in the current thread. It is only valid inside
- cpu_exec() */
-CPUState *cpu_single_env;
-
-typedef struct PageDesc {
- /* list of TBs intersecting this ram page */
- TranslationBlock *first_tb;
- /* in order to optimize self modifying code, we count the number
- of lookups we do to a given page to use a bitmap */
- unsigned int code_write_count;
- uint8_t *code_bitmap;
-#if defined(CONFIG_USER_ONLY)
- unsigned long flags;
-#endif
-} PageDesc;
-
-typedef struct PhysPageDesc {
- /* offset in host memory of the page + io_index in the low 12 bits */
- unsigned long phys_offset;
-} PhysPageDesc;
-
-typedef struct VirtPageDesc {
- /* physical address of code page. It is valid only if 'valid_tag'
- matches 'virt_valid_tag' */
- target_ulong phys_addr;
- unsigned int valid_tag;
-#if !defined(CONFIG_SOFTMMU)
- /* original page access rights. It is valid only if 'valid_tag'
- matches 'virt_valid_tag' */
- unsigned int prot;
-#endif
-} VirtPageDesc;
-
-#define L2_BITS 10
-#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
-
-#define L1_SIZE (1 << L1_BITS)
-#define L2_SIZE (1 << L2_BITS)
-
-unsigned long qemu_real_host_page_size;
-unsigned long qemu_host_page_bits;
-unsigned long qemu_host_page_size;
-unsigned long qemu_host_page_mask;
-
-/* io memory support */
-CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb = 1;
-
-/* log support */
-FILE *logfile;
-int loglevel;
-
-void cpu_exec_init(CPUState *env)
-{
- CPUState **penv;
- int cpu_index;
-
- env->next_cpu = NULL;
- penv = &first_cpu;
- cpu_index = 0;
- while (*penv != NULL) {
- penv = (CPUState **)&(*penv)->next_cpu;
- cpu_index++;
- }
- env->cpu_index = cpu_index;
- *penv = env;
-
- /* alloc dirty bits array */
- phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
-}
-
-/* enable or disable low levels log */
-void cpu_set_log(int log_flags)
-{
- loglevel = log_flags;
- if (!logfile)
- logfile = stderr;
-}
-
-void cpu_set_log_filename(const char *filename)
-{
- logfile = fopen(filename, "w");
- if (!logfile) {
- perror(filename);
- _exit(1);
- }
-#if !defined(CONFIG_SOFTMMU)
- /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
- {
- static uint8_t logfile_buf[4096];
- setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
- }
-#else
- setvbuf(logfile, NULL, _IOLBF, 0);
-#endif
- dup2(fileno(logfile), 1);
- dup2(fileno(logfile), 2);
-}
-
-/* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
-{
- env->interrupt_request |= mask;
-}
-
-void cpu_reset_interrupt(CPUState *env, int mask)
-{
- env->interrupt_request &= ~mask;
-}
-
-CPULogItem cpu_log_items[] = {
- { CPU_LOG_TB_OUT_ASM, "out_asm",
- "show generated host assembly code for each compiled TB" },
- { CPU_LOG_TB_IN_ASM, "in_asm",
- "show target assembly code for each compiled TB" },
- { CPU_LOG_TB_OP, "op",
- "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
-#ifdef TARGET_I386
- { CPU_LOG_TB_OP_OPT, "op_opt",
- "show micro ops after optimization for each compiled TB" },
-#endif
- { CPU_LOG_INT, "int",
- "show interrupts/exceptions in short format" },
- { CPU_LOG_EXEC, "exec",
- "show trace before each executed TB (lots of logs)" },
- { CPU_LOG_TB_CPU, "cpu",
- "show CPU state before bloc translation" },
-#ifdef TARGET_I386
- { CPU_LOG_PCALL, "pcall",
- "show protected mode far calls/returns/exceptions" },
-#endif
-#ifdef DEBUG_IOPORT
- { CPU_LOG_IOPORT, "ioport",
- "show all i/o ports accesses" },
-#endif
- { 0, NULL, NULL },
-};
-
-static int cmp1(const char *s1, int n, const char *s2)
-{
- if (strlen(s2) != n)
- return 0;
- return memcmp(s1, s2, n) == 0;
-}
-
-/* takes a comma separated list of log masks. Return 0 if error. */
-int cpu_str_to_log_mask(const char *str)
-{
- CPULogItem *item;
- int mask;
- const char *p, *p1;
-
- p = str;
- mask = 0;
- for(;;) {
- p1 = strchr(p, ',');
- if (!p1)
- p1 = p + strlen(p);
- if(cmp1(p,p1-p,"all")) {
- for(item = cpu_log_items; item->mask != 0; item++) {
- mask |= item->mask;
- }
- } else {
- for(item = cpu_log_items; item->mask != 0; item++) {
- if (cmp1(p, p1 - p, item->name))
- goto found;
- }
- return 0;
- }
- found:
- mask |= item->mask;
- if (*p1 != ',')
- break;
- p = p1 + 1;
- }
- return mask;
-}
-
-void cpu_abort(CPUState *env, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "qemu: fatal: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- abort();
-}
-
-
-/* XXX: Simple implementation. Fix later */
-#define MAX_MMIO 32
-struct mmio_space {
- target_phys_addr_t start;
- unsigned long size;
- unsigned long io_index;
-} mmio[MAX_MMIO];
-unsigned long mmio_cnt;
-
-/* register physical memory. 'size' must be a multiple of the target
- page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
- io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- unsigned long size,
- unsigned long phys_offset)
-{
- int i;
-
- for (i = 0; i < mmio_cnt; i++) {
- if(mmio[i].start == start_addr) {
- mmio[i].io_index = phys_offset;
- mmio[i].size = size;
- return;
- }
- }
-
- if (mmio_cnt == MAX_MMIO) {
- fprintf(logfile, "too many mmio regions\n");
- exit(-1);
- }
-
- mmio[mmio_cnt].io_index = phys_offset;
- mmio[mmio_cnt].start = start_addr;
- mmio[mmio_cnt++].size = size;
-}
-
-/* mem_read and mem_write are arrays of functions containing the
- function to access byte (index 0), word (index 1) and dword (index
- 2). All functions must be supplied. If io_index is non zero, the
- corresponding io zone is modified. If it is zero, a new io zone is
- allocated. The return value can be used with
- cpu_register_physical_memory(). (-1) is returned if error. */
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque)
-{
- int i;
-
- if (io_index <= 0) {
- if (io_index >= IO_MEM_NB_ENTRIES)
- return -1;
- io_index = io_mem_nb++;
- } else {
- if (io_index >= IO_MEM_NB_ENTRIES)
- return -1;
- }
-
- for(i = 0;i < 3; i++) {
- io_mem_read[io_index][i] = mem_read[i];
- io_mem_write[io_index][i] = mem_write[i];
- }
- io_mem_opaque[io_index] = opaque;
- return io_index << IO_MEM_SHIFT;
-}
-
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
-{
- return io_mem_write[io_index >> IO_MEM_SHIFT];
-}
-
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
-{
- return io_mem_read[io_index >> IO_MEM_SHIFT];
-}
-
-#ifdef __ia64__
-
-#define __ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
-#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
-#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
-
-/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
- * So to emulate right behavior that guest OS is assumed, we need to flush
- * I/D cache here.
- */
-static void sync_icache(uint8_t *address, int len)
-{
- unsigned long addr = (unsigned long)address;
- unsigned long end = addr + len;
-
- for (addr &= ~(32UL-1); addr < end; addr += 32UL)
- __ia64_fc(addr);
-
- ia64_sync_i();
- ia64_srlz_i();
-}
-#endif
-
-/* physical memory access (slow version, mainly for debug) */
-#if defined(CONFIG_USER_ONLY)
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-{
- int l, flags;
- target_ulong page;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- flags = page_get_flags(page);
- if (!(flags & PAGE_VALID))
- return;
- if (is_write) {
- if (!(flags & PAGE_WRITE))
- return;
- memcpy((uint8_t *)addr, buf, len);
- } else {
- if (!(flags & PAGE_READ))
- return;
- memcpy(buf, (uint8_t *)addr, len);
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-#else
-
-int iomem_index(target_phys_addr_t addr)
-{
- int i;
-
- for (i = 0; i < mmio_cnt; i++) {
- unsigned long start, end;
-
- start = mmio[i].start;
- end = mmio[i].start + mmio[i].size;
-
- if ((addr >= start) && (addr < end)){
- return (mmio[i].io_index >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- }
- }
- return 0;
-}
-
-#if defined(__i386__) || defined(__x86_64__)
-#define phys_ram_addr(x) (qemu_map_cache(x))
-#elif defined(__ia64__)
-#define phys_ram_addr(x) (((x) < ram_size) ? (phys_ram_base + (x)) : NULL)
-#endif
-
-extern unsigned long *logdirty_bitmap;
-extern unsigned long logdirty_bitmap_size;
-
-/*
- * Replace the standard byte memcpy with a word memcpy for appropriately sized
- * memory copy operations. Some users (USB-UHCI) can not tolerate the possible
- * word tearing that can result from a guest concurrently writing a memory
- * structure while the qemu device model is modifying the same location.
- * Forcing a word-sized read/write prevents the guest from seeing a partially
- * written word-sized atom.
- */
-#if defined(__x86_64__) || defined(__i386__)
-static void memcpy_words(void *dst, void *src, size_t n)
-{
- asm volatile (
- " movl %%edx,%%ecx \n"
-#ifdef __x86_64__
- " shrl $3,%%ecx \n"
- " rep movsq \n"
- " test $4,%%edx \n"
- " jz 1f \n"
- " movsl \n"
-#else /* __i386__ */
- " shrl $2,%%ecx \n"
- " rep movsl \n"
-#endif
- "1: test $2,%%edx \n"
- " jz 1f \n"
- " movsw \n"
- "1: test $1,%%edx \n"
- " jz 1f \n"
- " movsb \n"
- "1: \n"
- : "+S" (src), "+D" (dst) : "d" (n) : "ecx", "memory" );
-}
-#else
-static void memcpy_words(void *dst, void *src, size_t n)
-{
- /* Some architectures do not like unaligned accesses. */
- if (((unsigned long)dst | (unsigned long)src) & 3) {
- memcpy(dst, src, n);
- return;
- }
-
- while (n >= sizeof(uint32_t)) {
- *((uint32_t *)dst) = *((uint32_t *)src);
- dst = ((uint32_t *)dst) + 1;
- src = ((uint32_t *)src) + 1;
- n -= sizeof(uint32_t);
- }
-
- if (n & 2) {
- *((uint16_t *)dst) = *((uint16_t *)src);
- dst = ((uint16_t *)dst) + 1;
- src = ((uint16_t *)src) + 1;
- }
-
- if (n & 1) {
- *((uint8_t *)dst) = *((uint8_t *)src);
- dst = ((uint8_t *)dst) + 1;
- src = ((uint8_t *)src) + 1;
- }
-}
-#endif
-
-void cpu_physical_memory_rw(target_phys_addr_t _addr, uint8_t *buf,
- int _len, int is_write)
-{
- target_phys_addr_t addr = _addr;
- int len = _len;
- int l, io_index;
- uint8_t *ptr;
- uint32_t val;
-
- mapcache_lock();
-
- while (len > 0) {
- /* How much can we copy before the next page boundary? */
- l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
- if (l > len)
- l = len;
-
- io_index = iomem_index(addr);
- if (is_write) {
- if (io_index) {
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit read access */
- val = ldl_raw(buf);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit read access */
- val = lduw_raw(buf);
- io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
- l = 2;
- } else {
- /* 8 bit access */
- val = ldub_raw(buf);
- io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
- l = 1;
- }
- } else if ((ptr = phys_ram_addr(addr)) != NULL) {
- /* Writing to RAM */
- memcpy_words(ptr, buf, l);
-#ifndef CONFIG_STUBDOM
- if (logdirty_bitmap != NULL) {
- /* Record that we have dirtied this frame */
- unsigned long pfn = addr >> TARGET_PAGE_BITS;
- if (pfn / 8 >= logdirty_bitmap_size) {
- fprintf(logfile, "dirtying pfn %lx >= bitmap "
- "size %lx\n", pfn, logdirty_bitmap_size * 8);
- } else {
- logdirty_bitmap[pfn / HOST_LONG_BITS]
- |= 1UL << pfn % HOST_LONG_BITS;
- }
- }
-#endif
-#ifdef __ia64__
- sync_icache(ptr, l);
-#endif
- }
- } else {
- if (io_index) {
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit read access */
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- stl_raw(buf, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit read access */
- val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
- stw_raw(buf, val);
- l = 2;
- } else {
- /* 8 bit access */
- val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
- stb_raw(buf, val);
- l = 1;
- }
- } else if ((ptr = phys_ram_addr(addr)) != NULL) {
- /* Reading from RAM */
- memcpy_words(buf, ptr, l);
- } else {
- /* Neither RAM nor known MMIO space */
- memset(buf, 0xff, len);
- }
- }
- len -= l;
- buf += l;
- addr += l;
- }
-
-#ifdef CONFIG_STUBDOM
- if (logdirty_bitmap != NULL)
- xc_hvm_modified_memory(xc_handle, domid, _addr >> TARGET_PAGE_BITS,
- ((_addr + _len + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
- - (_addr >> TARGET_PAGE_BITS));
-#endif
-
- mapcache_unlock();
-}
-#endif
-
-/* virtual memory access for debug */
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write)
-{
- int l;
- target_ulong page, phys_addr;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- phys_addr = cpu_get_phys_page_debug(env, page);
- /* if no physical page mapped, return an error */
- if (phys_addr == -1)
- return -1;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
- buf, l, is_write);
- len -= l;
- buf += l;
- addr += l;
- }
- return 0;
-}
-
-void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
- int dirty_flags)
-{
- unsigned long length;
- int i, mask, len;
- uint8_t *p;
-
- start &= TARGET_PAGE_MASK;
- end = TARGET_PAGE_ALIGN(end);
-
- length = end - start;
- if (length == 0)
- return;
- mask = ~dirty_flags;
- p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
- len = length >> TARGET_PAGE_BITS;
- for(i = 0; i < len; i++)
- p[i] &= mask;
-
- return;
-}
diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c
deleted file mode 100644
index c7b0820ed8..0000000000
--- a/tools/ioemu/target-i386-dm/helper2.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * i386 helpers (without register variable usage)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Main cpu loop for handling I/O requests coming from a virtual machine
- * Copyright © 2004, Intel Corporation.
- * Copyright © 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <signal.h>
-#include <assert.h>
-
-#include <limits.h>
-#include <fcntl.h>
-
-#include <xenctrl.h>
-#include <xen/hvm/ioreq.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-
-//#define DEBUG_MMU
-
-#ifdef USE_CODE_COPY
-#include <asm/ldt.h>
-#include <linux/unistd.h>
-#include <linux/version.h>
-
-_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
-#define modify_ldt_ldt_s user_desc
-#endif
-#endif /* USE_CODE_COPY */
-
-#include "vl.h"
-
-int domid = -1;
-int vcpus = 1;
-
-extern int xc_handle;
-
-long time_offset = 0;
-
-shared_iopage_t *shared_page = NULL;
-
-#define BUFFER_IO_MAX_DELAY 100
-buffered_iopage_t *buffered_io_page = NULL;
-QEMUTimer *buffered_io_timer;
-
-/* the evtchn fd for polling */
-int xce_handle = -1;
-
-/* which vcpu we are serving */
-int send_vcpu = 0;
-
-//the evtchn port for polling the notification,
-#define NR_CPUS 32
-evtchn_port_t ioreq_local_port[NR_CPUS];
-
-CPUX86State *cpu_x86_init(void)
-{
- CPUX86State *env;
- static int inited;
- int i, rc;
-
- env = qemu_mallocz(sizeof(CPUX86State));
- if (!env)
- return NULL;
- cpu_exec_init(env);
-
- /* init various static tables */
- if (!inited) {
- inited = 1;
-
- cpu_single_env = env;
-
- xce_handle = xc_evtchn_open();
- if (xce_handle == -1) {
- perror("open");
- return NULL;
- }
-
- /* FIXME: how about if we overflow the page here? */
- for (i = 0; i < vcpus; i++) {
- rc = xc_evtchn_bind_interdomain(
- xce_handle, domid, shared_page->vcpu_iodata[i].vp_eport);
- if (rc == -1) {
- fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
- return NULL;
- }
- ioreq_local_port[i] = rc;
- }
- }
-
- return env;
-}
-
-/* called from main_cpu_reset */
-void cpu_reset(CPUX86State *env)
-{
- extern int s3_shutdown_flag;
- int xcHandle;
- int sts;
-
- if (s3_shutdown_flag)
- return;
-
- xcHandle = xc_interface_open();
- if (xcHandle < 0)
- fprintf(logfile, "Cannot acquire xenctrl handle\n");
- else {
- xc_domain_shutdown_hook(xcHandle, domid);
- sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_reboot);
- if (sts != 0)
- fprintf(logfile,
- "? xc_domain_shutdown failed to issue reboot, sts %d\n",
- sts);
- else
- fprintf(logfile, "Issued domain %d reboot\n", domid);
- xc_interface_close(xcHandle);
- }
-}
-
-void cpu_x86_close(CPUX86State *env)
-{
- free(env);
-}
-
-
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags)
-{
-}
-
-/***********************************************************/
-/* x86 mmu */
-/* XXX: add PGE support */
-
-void cpu_x86_set_a20(CPUX86State *env, int a20_state)
-{
- a20_state = (a20_state != 0);
- if (a20_state != ((env->a20_mask >> 20) & 1)) {
-#if defined(DEBUG_MMU)
- printf("A20 update: a20=%d\n", a20_state);
-#endif
- env->a20_mask = 0xffefffff | (a20_state << 20);
- }
-}
-
-target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-
-//some functions to handle the io req packet
-void sp_info()
-{
- ioreq_t *req;
- int i;
-
- for (i = 0; i < vcpus; i++) {
- req = &(shared_page->vcpu_iodata[i].vp_ioreq);
- term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
- term_printf(" req state: %x, ptr: %x, addr: %"PRIx64", "
- "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
- req->state, req->data_is_ptr, req->addr,
- req->data, req->count, req->size);
- term_printf(" IO totally occurred on this vcpu: %"PRIx64"\n",
- req->io_count);
- }
-}
-
-//get the ioreq packets from share mem
-static ioreq_t *__cpu_get_ioreq(int vcpu)
-{
- ioreq_t *req;
-
- req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
-
- if (req->state != STATE_IOREQ_READY) {
- fprintf(logfile, "I/O request not ready: "
- "%x, ptr: %x, port: %"PRIx64", "
- "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
- req->state, req->data_is_ptr, req->addr,
- req->data, req->count, req->size);
- return NULL;
- }
-
- xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
-
- req->state = STATE_IOREQ_INPROCESS;
- return req;
-}
-
-//use poll to get the port notification
-//ioreq_vec--out,the
-//retval--the number of ioreq packet
-static ioreq_t *cpu_get_ioreq(void)
-{
- int i;
- evtchn_port_t port;
-
- port = xc_evtchn_pending(xce_handle);
- if (port != -1) {
- for ( i = 0; i < vcpus; i++ )
- if ( ioreq_local_port[i] == port )
- break;
-
- if ( i == vcpus ) {
- fprintf(logfile, "Fatal error while trying to get io event!\n");
- exit(1);
- }
-
- // unmask the wanted port again
- xc_evtchn_unmask(xce_handle, port);
-
- //get the io packet from shared memory
- send_vcpu = i;
- return __cpu_get_ioreq(i);
- }
-
- //read error or read nothing
- return NULL;
-}
-
-unsigned long do_inp(CPUState *env, unsigned long addr, unsigned long size)
-{
- switch(size) {
- case 1:
- return cpu_inb(env, addr);
- case 2:
- return cpu_inw(env, addr);
- case 4:
- return cpu_inl(env, addr);
- default:
- fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
- exit(-1);
- }
-}
-
-void do_outp(CPUState *env, unsigned long addr,
- unsigned long size, unsigned long val)
-{
- switch(size) {
- case 1:
- return cpu_outb(env, addr, val);
- case 2:
- return cpu_outw(env, addr, val);
- case 4:
- return cpu_outl(env, addr, val);
- default:
- fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
- exit(-1);
- }
-}
-
-extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write);
-
-static inline void read_physical(uint64_t addr, unsigned long size, void *val)
-{
- return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0);
-}
-
-static inline void write_physical(uint64_t addr, unsigned long size, void *val)
-{
- return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1);
-}
-
-void cpu_ioreq_pio(CPUState *env, ioreq_t *req)
-{
- int i, sign;
-
- sign = req->df ? -1 : 1;
-
- if (req->dir == IOREQ_READ) {
- if (!req->data_is_ptr) {
- req->data = do_inp(env, req->addr, req->size);
- } else {
- unsigned long tmp;
-
- for (i = 0; i < req->count; i++) {
- tmp = do_inp(env, req->addr, req->size);
- write_physical((target_phys_addr_t) req->data
- + (sign * i * req->size),
- req->size, &tmp);
- }
- }
- } else if (req->dir == IOREQ_WRITE) {
- if (!req->data_is_ptr) {
- do_outp(env, req->addr, req->size, req->data);
- } else {
- for (i = 0; i < req->count; i++) {
- unsigned long tmp = 0;
-
- read_physical((target_phys_addr_t) req->data
- + (sign * i * req->size),
- req->size, &tmp);
- do_outp(env, req->addr, req->size, tmp);
- }
- }
- }
-}
-
-void cpu_ioreq_move(CPUState *env, ioreq_t *req)
-{
- int i, sign;
-
- sign = req->df ? -1 : 1;
-
- if (!req->data_is_ptr) {
- if (req->dir == IOREQ_READ) {
- for (i = 0; i < req->count; i++) {
- read_physical(req->addr
- + (sign * i * req->size),
- req->size, &req->data);
- }
- } else if (req->dir == IOREQ_WRITE) {
- for (i = 0; i < req->count; i++) {
- write_physical(req->addr
- + (sign * i * req->size),
- req->size, &req->data);
- }
- }
- } else {
- target_ulong tmp;
-
- if (req->dir == IOREQ_READ) {
- for (i = 0; i < req->count; i++) {
- read_physical(req->addr
- + (sign * i * req->size),
- req->size, &tmp);
- write_physical((target_phys_addr_t )req->data
- + (sign * i * req->size),
- req->size, &tmp);
- }
- } else if (req->dir == IOREQ_WRITE) {
- for (i = 0; i < req->count; i++) {
- read_physical((target_phys_addr_t) req->data
- + (sign * i * req->size),
- req->size, &tmp);
- write_physical(req->addr
- + (sign * i * req->size),
- req->size, &tmp);
- }
- }
- }
-}
-
-void timeoffset_get(void)
-{
- char *p;
-
- p = xenstore_vm_read(domid, "rtc/timeoffset", NULL);
- if (!p)
- return;
-
- if (sscanf(p, "%ld", &time_offset) == 1)
- fprintf(logfile, "Time offset set %ld\n", time_offset);
- else
- time_offset = 0;
-
- free(p);
-}
-
-void cpu_ioreq_timeoffset(CPUState *env, ioreq_t *req)
-{
- char b[64];
-
- time_offset += (unsigned long)req->data;
-
- fprintf(logfile, "Time offset set %ld, added offset %ld\n", time_offset, req->data);
- sprintf(b, "%ld", time_offset);
- xenstore_vm_write(domid, "rtc/timeoffset", b);
-}
-
-void __handle_ioreq(CPUState *env, ioreq_t *req)
-{
- if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
- (req->size < sizeof(target_ulong)))
- req->data &= ((target_ulong)1 << (8 * req->size)) - 1;
-
- switch (req->type) {
- case IOREQ_TYPE_PIO:
- cpu_ioreq_pio(env, req);
- break;
- case IOREQ_TYPE_COPY:
- cpu_ioreq_move(env, req);
- break;
- case IOREQ_TYPE_TIMEOFFSET:
- cpu_ioreq_timeoffset(env, req);
- break;
- case IOREQ_TYPE_INVALIDATE:
- qemu_invalidate_map_cache();
- break;
- default:
- hw_error("Invalid ioreq type 0x%x\n", req->type);
- }
-}
-
-void __handle_buffered_iopage(CPUState *env)
-{
- buf_ioreq_t *buf_req = NULL;
- ioreq_t req;
- int qw;
-
- if (!buffered_io_page)
- return;
-
- while (buffered_io_page->read_pointer !=
- buffered_io_page->write_pointer) {
- buf_req = &buffered_io_page->buf_ioreq[
- buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
- req.size = 1UL << buf_req->size;
- req.count = 1;
- req.addr = buf_req->addr;
- req.data = buf_req->data;
- req.state = STATE_IOREQ_READY;
- req.dir = buf_req->dir;
- req.df = 1;
- req.type = buf_req->type;
- req.data_is_ptr = 0;
- qw = (req.size == 8);
- if (qw) {
- buf_req = &buffered_io_page->buf_ioreq[
- (buffered_io_page->read_pointer+1) % IOREQ_BUFFER_SLOT_NUM];
- req.data |= ((uint64_t)buf_req->data) << 32;
- }
-
- __handle_ioreq(env, &req);
-
- xen_mb();
- buffered_io_page->read_pointer += qw ? 2 : 1;
- }
-}
-
-void handle_buffered_io(void *opaque)
-{
- CPUState *env = opaque;
-
- __handle_buffered_iopage(env);
- qemu_mod_timer(buffered_io_timer, BUFFER_IO_MAX_DELAY +
- qemu_get_clock(rt_clock));
-}
-
-void cpu_handle_ioreq(void *opaque)
-{
- extern int vm_running;
- extern int shutdown_requested;
- CPUState *env = opaque;
- ioreq_t *req = cpu_get_ioreq();
-
- __handle_buffered_iopage(env);
- if (req) {
- __handle_ioreq(env, req);
-
- if (req->state != STATE_IOREQ_INPROCESS) {
- fprintf(logfile, "Badness in I/O request ... not in service?!: "
- "%x, ptr: %x, port: %"PRIx64", "
- "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
- req->state, req->data_is_ptr, req->addr,
- req->data, req->count, req->size);
- destroy_hvm_domain();
- return;
- }
-
- xen_wmb(); /* Update ioreq contents /then/ update state. */
-
- /*
- * We do this before we send the response so that the tools
- * have the opportunity to pick up on the reset before the
- * guest resumes and does a hlt with interrupts disabled which
- * causes Xen to powerdown the domain.
- */
- if (vm_running) {
- if (shutdown_requested) {
- fprintf(logfile, "shutdown requested in cpu_handle_ioreq\n");
- destroy_hvm_domain();
- }
- if (reset_requested) {
- fprintf(logfile, "reset requested in cpu_handle_ioreq.\n");
- qemu_system_reset();
- reset_requested = 0;
- }
- }
-
- req->state = STATE_IORESP_READY;
- xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
- }
-}
-
-int main_loop(void)
-{
- extern int vm_running;
- extern int shutdown_requested;
- extern int suspend_requested;
- CPUState *env = cpu_single_env;
- int evtchn_fd = xce_handle == -1 ? -1 : xc_evtchn_fd(xce_handle);
- char *qemu_file;
- fd_set fds;
-
- buffered_io_timer = qemu_new_timer(rt_clock, handle_buffered_io,
- cpu_single_env);
- qemu_mod_timer(buffered_io_timer, qemu_get_clock(rt_clock));
-
- if (evtchn_fd != -1)
- qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
-
- xenstore_record_dm_state("running");
- while (1) {
- while (!(vm_running && suspend_requested))
- /* Wait up to 10 msec. */
- main_loop_wait(10);
-
- fprintf(logfile, "device model saving state\n");
-
- /* Pull all outstanding ioreqs through the system */
- handle_buffered_pio();
- handle_buffered_io(env);
- main_loop_wait(1); /* For the select() on events */
-
- /* Save the device state */
- asprintf(&qemu_file, "/var/lib/xen/qemu-save.%d", domid);
- do_savevm(qemu_file);
- free(qemu_file);
-
- xenstore_record_dm_state("paused");
-
- /* Wait to be allowed to continue */
- while (suspend_requested) {
- FD_ZERO(&fds);
- FD_SET(xenstore_fd(), &fds);
- if (select(xenstore_fd() + 1, &fds, NULL, NULL, NULL) > 0)
- xenstore_process_event(NULL);
- }
-
- xenstore_record_dm_state("running");
- }
-
- return 0;
-}
-
-void destroy_hvm_domain(void)
-{
- int xcHandle;
- int sts;
-
- xcHandle = xc_interface_open();
- if (xcHandle < 0)
- fprintf(logfile, "Cannot acquire xenctrl handle\n");
- else {
- sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_poweroff);
- if (sts != 0)
- fprintf(logfile, "? xc_domain_shutdown failed to issue poweroff, "
- "sts %d, errno %d\n", sts, errno);
- else
- fprintf(logfile, "Issued domain %d poweroff\n", domid);
- xc_interface_close(xcHandle);
- }
-}
diff --git a/tools/ioemu/target-i386-dm/i8259-dm.c b/tools/ioemu/target-i386-dm/i8259-dm.c
deleted file mode 100644
index 333db17537..0000000000
--- a/tools/ioemu/target-i386-dm/i8259-dm.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Xen 8259 stub for interrupt controller emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- * Copyright (c) 2005 Intel corperation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "xenctrl.h"
-#include <xen/hvm/ioreq.h>
-#include <stdio.h>
-#include "cpu.h"
-#include "cpu-all.h"
-
-struct PicState2 {
-};
-
-void pic_set_irq_new(void *opaque, int irq, int level)
-{
- xc_hvm_set_isa_irq_level(xc_handle, domid, irq, level);
-}
-
-/* obsolete function */
-void pic_set_irq(int irq, int level)
-{
- pic_set_irq_new(isa_pic, irq, level);
-}
-
-void irq_info(void)
-{
- term_printf("irq statistic code not compiled.\n");
-}
-
-void pic_info(void)
-{
- term_printf("pic_info code not compiled.\n");
-}
-
-PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque)
-{
- PicState2 *s;
- s = qemu_mallocz(sizeof(PicState2));
- if (!s)
- return NULL;
- return s;
-}
-
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
- void *alt_irq_opaque)
-{
-}
diff --git a/tools/ioemu/target-i386-dm/piix_pci-dm.c b/tools/ioemu/target-i386-dm/piix_pci-dm.c
deleted file mode 100644
index 82ee0551cc..0000000000
--- a/tools/ioemu/target-i386-dm/piix_pci-dm.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * QEMU i440FX/PIIX3 PCI Bridge Emulation
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-typedef uint32_t pci_addr_t;
-#include "hw/pci_host.h"
-
-typedef PCIHostState I440FXState;
-
-static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
-{
- I440FXState *s = opaque;
- s->config_reg = val;
-}
-
-static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
-{
- I440FXState *s = opaque;
- return s->config_reg;
-}
-
-/* return the global irq number corresponding to a given device irq
- pin. We could also use the bus number to have a more precise
- mapping. */
-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
-{
-#ifndef CONFIG_DM
- int slot_addend;
- slot_addend = (pci_dev->devfn >> 3) - 1;
- return (irq_num + slot_addend) & 3;
-#else /* !CONFIG_DM */
- return irq_num + ((pci_dev->devfn >> 3) << 2);
-#endif /* !CONFIG_DM */
-}
-
-static void i440fx_set_irq(void *pic, int irq_num, int level)
-{
- xc_hvm_set_pci_intx_level(xc_handle, domid, 0, 0, irq_num >> 2,
- irq_num & 3, level);
-}
-
-static void i440fx_save(QEMUFile* f, void *opaque)
-{
- PCIDevice *d = opaque;
- pci_device_save(d, f);
-#ifndef CONFIG_DM
- qemu_put_8s(f, &smm_enabled);
-#endif /* !CONFIG_DM */
-}
-
-static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
-{
- PCIDevice *d = opaque;
- int ret;
-
- if (version_id != 1)
- return -EINVAL;
- ret = pci_device_load(d, f);
- if (ret < 0)
- return ret;
-#ifndef CONFIG_DM
- i440fx_update_memory_mappings(d);
- qemu_get_8s(f, &smm_enabled);
-#endif /* !CONFIG_DM */
- return 0;
-}
-
-PCIBus *i440fx_init(PCIDevice **pi440fx_state)
-{
- PCIBus *b;
- PCIDevice *d;
- I440FXState *s;
-
- s = qemu_mallocz(sizeof(I440FXState));
- b = pci_register_bus(i440fx_set_irq, pci_slot_get_pirq, NULL, 0, 128);
- s->bus = b;
-
- register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
- register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
-
- register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
- register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
- register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
- register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
- register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
- register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
-
- d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
- NULL, NULL);
-
- d->config[0x00] = 0x86; // vendor_id
- d->config[0x01] = 0x80;
- d->config[0x02] = 0x37; // device_id
- d->config[0x03] = 0x12;
- d->config[0x08] = 0x02; // revision
- d->config[0x0a] = 0x00; // class_sub = host2pci
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x00; // header_type
-
- register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d);
- *pi440fx_state = d;
- return b;
-}
-
-/* PIIX3 PCI to ISA bridge */
-
-static PCIDevice *piix3_dev;
-
-static void piix3_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- int i;
-
- /* Scan for updates to PCI link routes (0x60-0x63). */
- for (i = 0; i < len; i++) {
- uint8_t v = (val >> (8*i)) & 0xff;
- if (v & 0x80)
- v = 0;
- v &= 0xf;
- if (((address+i) >= 0x60) && ((address+i) <= 0x63))
- xc_hvm_set_pci_link_route(xc_handle, domid, address + i - 0x60, v);
- }
-
- /* Hand off to default logic. */
- pci_default_write_config(d, address, val, len);
-}
-
-static void piix3_reset(PCIDevice *d)
-{
- uint8_t *pci_conf = d->config;
-
- pci_conf[0x04] = 0x07; // master, memory and I/O
- pci_conf[0x05] = 0x00;
- pci_conf[0x06] = 0x00;
- pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
- pci_conf[0x4c] = 0x4d;
- pci_conf[0x4e] = 0x03;
- pci_conf[0x4f] = 0x00;
- pci_conf[0x60] = 0x80;
- pci_conf[0x61] = 0x80;
- pci_conf[0x62] = 0x80;
- pci_conf[0x63] = 0x80;
- pci_conf[0x69] = 0x02;
- pci_conf[0x70] = 0x80;
- pci_conf[0x76] = 0x0c;
- pci_conf[0x77] = 0x0c;
- pci_conf[0x78] = 0x02;
- pci_conf[0x79] = 0x00;
- pci_conf[0x80] = 0x00;
- pci_conf[0x82] = 0x00;
- pci_conf[0xa0] = 0x08;
- pci_conf[0xa2] = 0x00;
- pci_conf[0xa3] = 0x00;
- pci_conf[0xa4] = 0x00;
- pci_conf[0xa5] = 0x00;
- pci_conf[0xa6] = 0x00;
- pci_conf[0xa7] = 0x00;
- pci_conf[0xa8] = 0x0f;
- pci_conf[0xaa] = 0x00;
- pci_conf[0xab] = 0x00;
- pci_conf[0xac] = 0x00;
- pci_conf[0xae] = 0x00;
-}
-
-static void piix_save(QEMUFile* f, void *opaque)
-{
- PCIDevice *d = opaque;
- pci_device_save(d, f);
-}
-
-static int piix_load(QEMUFile* f, void *opaque, int version_id)
-{
- PCIDevice *d = opaque;
- if (version_id != 2)
- return -EINVAL;
- return pci_device_load(d, f);
-}
-
-int piix3_init(PCIBus *bus, int devfn)
-{
- PCIDevice *d;
- uint8_t *pci_conf;
-
- d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),
- devfn, NULL, piix3_write_config);
- register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);
-
- piix3_dev = d;
- pci_conf = d->config;
-
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
- pci_conf[0x03] = 0x70;
- pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
- pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
- pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
-
- piix3_reset(d);
- return d->devfn;
-}
diff --git a/tools/ioemu/target-i386-dm/qemu-dm.debug b/tools/ioemu/target-i386-dm/qemu-dm.debug
deleted file mode 100644
index cea6b57c77..0000000000
--- a/tools/ioemu/target-i386-dm/qemu-dm.debug
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-if [ "`arch`" = "x86_64" ]; then
- LIBDIR="lib64"
-else
- LIBDIR="lib"
-fi
-echo $* > /tmp/args
-echo $DISPLAY >> /tmp/args
-exec /usr/$LIBDIR/xen/bin/qemu-dm $*
diff --git a/tools/ioemu/target-i386-dm/qemu-ifup b/tools/ioemu/target-i386-dm/qemu-ifup
deleted file mode 100644
index bcbee92d65..0000000000
--- a/tools/ioemu/target-i386-dm/qemu-ifup
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-
-#. /etc/rc.d/init.d/functions
-#ulimit -c unlimited
-
-echo 'config qemu network with xen bridge for ' $*
-
-bridge=$2
-
-#
-# Old style bridge setup with netloop, used to have a bridge name
-# of xenbrX, enslaving pethX and vif0.X, and then configuring
-# eth0.
-#
-# New style bridge setup does not use netloop, so the bridge name
-# is ethX and the physical device is enslaved pethX
-#
-# So if...
-#
-# - User asks for xenbrX
-# - AND xenbrX doesn't exist
-# - AND there is a ethX device which is a bridge
-#
-# ..then we translate xenbrX to ethX
-#
-# This lets old config files work without modification
-#
-if [ ! -e "/sys/class/net/$bridge" ] && [ -z "${bridge##xenbr*}" ]
-then
- if [ -e "/sys/class/net/eth${bridge#xenbr}/bridge" ]
- then
- bridge="eth${bridge#xenbr}"
- fi
-fi
-
-ifconfig $1 0.0.0.0 up
-brctl addif $bridge $1 || true
diff --git a/tools/ioemu/target-i386-dm/rtc-dm.c b/tools/ioemu/target-i386-dm/rtc-dm.c
deleted file mode 100644
index ee3a3c4251..0000000000
--- a/tools/ioemu/target-i386-dm/rtc-dm.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * QEMU MC146818 RTC emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-
-// #define DEBUG_CMOS
-
-struct RTCState {
- uint8_t cmos_data[128];
- uint8_t cmos_index;
-};
-
-static inline int to_bcd(RTCState *s, int a)
-{
- return ((a / 10) << 4) | (a % 10);
-}
-
-void rtc_set_memory(RTCState *s, int addr, int val)
-{
- if (addr >= 0 && addr <= 127)
- s->cmos_data[addr] = val;
-}
-
-static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
-{
- RTCState *s = opaque;
-
- if ((addr & 1) == 0) {
- s->cmos_index = data & 0x7f;
- } else {
-#ifdef DEBUG_CMOS
- printf("cmos: write index=0x%02x val=0x%02x\n",
- s->cmos_index, data);
-#endif
- s->cmos_data[s->cmos_index] = data;
- }
-}
-
-static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
-{
- RTCState *s = opaque;
- int ret;
- if ((addr & 1) == 0) {
- return 0xff;
- } else {
- ret = s->cmos_data[s->cmos_index];
-#ifdef DEBUG_CMOS
- printf("cmos: read index=0x%02x val=0x%02x\n",
- s->cmos_index, ret);
-#endif
- return ret;
- }
-}
-
-static void rtc_save(QEMUFile *f, void *opaque)
-{
- RTCState *s = opaque;
-
- qemu_put_buffer(f, s->cmos_data, 128);
- qemu_put_8s(f, &s->cmos_index);
-}
-
-static int rtc_load(QEMUFile *f, void *opaque, int version_id)
-{
- RTCState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_buffer(f, s->cmos_data, 128);
- qemu_get_8s(f, &s->cmos_index);
-
- return 0;
-}
-
-RTCState *rtc_init(int base, int irq)
-{
- RTCState *s;
- time_t ti;
- struct tm *tm;
- int val;
-
- s = qemu_mallocz(sizeof(RTCState));
- if (!s)
- return NULL;
-
-/* PC cmos mappings */
-#define REG_IBM_CENTURY_BYTE 0x32
-#define REG_IBM_PS2_CENTURY_BYTE 0x37
- time(&ti);
- tm = gmtime(&ti); /* XXX localtime and update from guest? */
- val = to_bcd(s, (tm->tm_year / 100) + 19);
- rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
- rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
-
- register_ioport_write(base, 2, 1, cmos_ioport_write, s);
- register_ioport_read(base, 2, 1, cmos_ioport_read, s);
-
- register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
- return s;
-}
-
-void rtc_set_date(RTCState *s, const struct tm *tm) {}
diff --git a/tools/ioemu/target-i386/.CVS/Entries b/tools/ioemu/target-i386/.CVS/Entries
deleted file mode 100644
index c1573dee55..0000000000
--- a/tools/ioemu/target-i386/.CVS/Entries
+++ /dev/null
@@ -1,13 +0,0 @@
-/cpu.h/1.41/Thu May 3 17:18:12 2007//Trelease_0_9_0
-/exec.h/1.31/Thu May 3 17:18:12 2007//Trelease_0_9_0
-/helper.c/1.74/Thu May 3 17:18:12 2007//Trelease_0_9_0
-/helper2.c/1.45/Thu May 3 17:18:12 2007//Trelease_0_9_0
-/op.c/1.47/Thu May 3 17:18:12 2007//Trelease_0_9_0
-/opreg_template.h/1.3/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/ops_mem.h/1.7/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/ops_sse.h/1.7/Thu May 3 17:18:12 2007//Trelease_0_9_0
-/ops_template.h/1.10/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/ops_template_mem.h/1.6/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/translate-copy.c/1.7/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/translate.c/1.62/Thu May 3 17:18:12 2007//Trelease_0_9_0
-D
diff --git a/tools/ioemu/target-i386/.CVS/Repository b/tools/ioemu/target-i386/.CVS/Repository
deleted file mode 100644
index 8e42d3620f..0000000000
--- a/tools/ioemu/target-i386/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu/target-i386
diff --git a/tools/ioemu/target-i386/.CVS/Root b/tools/ioemu/target-i386/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/target-i386/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/target-i386/.CVS/Tag b/tools/ioemu/target-i386/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/target-i386/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/target-i386/cpu.h b/tools/ioemu/target-i386/cpu.h
deleted file mode 100644
index 1eb546e566..0000000000
--- a/tools/ioemu/target-i386/cpu.h
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * i386 virtual CPU header
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_I386_H
-#define CPU_I386_H
-
-#include "config.h"
-
-#ifdef TARGET_X86_64
-#define TARGET_LONG_BITS 64
-#else
-#define TARGET_LONG_BITS 32
-#endif
-
-/* target supports implicit self modifying code */
-#define TARGET_HAS_SMC
-/* support for self modifying code even if the modified instruction is
- close to the modifying instruction */
-#define TARGET_HAS_PRECISE_SMC
-
-#define TARGET_HAS_ICE 1
-
-#ifdef TARGET_X86_64
-#define ELF_MACHINE EM_X86_64
-#else
-#define ELF_MACHINE EM_386
-#endif
-
-#include "cpu-defs.h"
-
-#include "softfloat.h"
-
-#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(__APPLE__)
-#define USE_CODE_COPY
-#endif
-
-#define R_EAX 0
-#define R_ECX 1
-#define R_EDX 2
-#define R_EBX 3
-#define R_ESP 4
-#define R_EBP 5
-#define R_ESI 6
-#define R_EDI 7
-
-#define R_AL 0
-#define R_CL 1
-#define R_DL 2
-#define R_BL 3
-#define R_AH 4
-#define R_CH 5
-#define R_DH 6
-#define R_BH 7
-
-#define R_ES 0
-#define R_CS 1
-#define R_SS 2
-#define R_DS 3
-#define R_FS 4
-#define R_GS 5
-
-/* segment descriptor fields */
-#define DESC_G_MASK (1 << 23)
-#define DESC_B_SHIFT 22
-#define DESC_B_MASK (1 << DESC_B_SHIFT)
-#define DESC_L_SHIFT 21 /* x86_64 only : 64 bit code segment */
-#define DESC_L_MASK (1 << DESC_L_SHIFT)
-#define DESC_AVL_MASK (1 << 20)
-#define DESC_P_MASK (1 << 15)
-#define DESC_DPL_SHIFT 13
-#define DESC_S_MASK (1 << 12)
-#define DESC_TYPE_SHIFT 8
-#define DESC_A_MASK (1 << 8)
-
-#define DESC_CS_MASK (1 << 11) /* 1=code segment 0=data segment */
-#define DESC_C_MASK (1 << 10) /* code: conforming */
-#define DESC_R_MASK (1 << 9) /* code: readable */
-
-#define DESC_E_MASK (1 << 10) /* data: expansion direction */
-#define DESC_W_MASK (1 << 9) /* data: writable */
-
-#define DESC_TSS_BUSY_MASK (1 << 9)
-
-/* eflags masks */
-#define CC_C 0x0001
-#define CC_P 0x0004
-#define CC_A 0x0010
-#define CC_Z 0x0040
-#define CC_S 0x0080
-#define CC_O 0x0800
-
-#define TF_SHIFT 8
-#define IOPL_SHIFT 12
-#define VM_SHIFT 17
-
-#define TF_MASK 0x00000100
-#define IF_MASK 0x00000200
-#define DF_MASK 0x00000400
-#define IOPL_MASK 0x00003000
-#define NT_MASK 0x00004000
-#define RF_MASK 0x00010000
-#define VM_MASK 0x00020000
-#define AC_MASK 0x00040000
-#define VIF_MASK 0x00080000
-#define VIP_MASK 0x00100000
-#define ID_MASK 0x00200000
-
-/* hidden flags - used internally by qemu to represent additionnal cpu
- states. Only the CPL, INHIBIT_IRQ and HALTED are not redundant. We avoid
- using the IOPL_MASK, TF_MASK and VM_MASK bit position to ease oring
- with eflags. */
-/* current cpl */
-#define HF_CPL_SHIFT 0
-/* true if soft mmu is being used */
-#define HF_SOFTMMU_SHIFT 2
-/* true if hardware interrupts must be disabled for next instruction */
-#define HF_INHIBIT_IRQ_SHIFT 3
-/* 16 or 32 segments */
-#define HF_CS32_SHIFT 4
-#define HF_SS32_SHIFT 5
-/* zero base for DS, ES and SS : can be '0' only in 32 bit CS segment */
-#define HF_ADDSEG_SHIFT 6
-/* copy of CR0.PE (protected mode) */
-#define HF_PE_SHIFT 7
-#define HF_TF_SHIFT 8 /* must be same as eflags */
-#define HF_MP_SHIFT 9 /* the order must be MP, EM, TS */
-#define HF_EM_SHIFT 10
-#define HF_TS_SHIFT 11
-#define HF_IOPL_SHIFT 12 /* must be same as eflags */
-#define HF_LMA_SHIFT 14 /* only used on x86_64: long mode active */
-#define HF_CS64_SHIFT 15 /* only used on x86_64: 64 bit code segment */
-#define HF_OSFXSR_SHIFT 16 /* CR4.OSFXSR */
-#define HF_VM_SHIFT 17 /* must be same as eflags */
-#define HF_HALTED_SHIFT 18 /* CPU halted */
-#define HF_SMM_SHIFT 19 /* CPU in SMM mode */
-
-#define HF_CPL_MASK (3 << HF_CPL_SHIFT)
-#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT)
-#define HF_INHIBIT_IRQ_MASK (1 << HF_INHIBIT_IRQ_SHIFT)
-#define HF_CS32_MASK (1 << HF_CS32_SHIFT)
-#define HF_SS32_MASK (1 << HF_SS32_SHIFT)
-#define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT)
-#define HF_PE_MASK (1 << HF_PE_SHIFT)
-#define HF_TF_MASK (1 << HF_TF_SHIFT)
-#define HF_MP_MASK (1 << HF_MP_SHIFT)
-#define HF_EM_MASK (1 << HF_EM_SHIFT)
-#define HF_TS_MASK (1 << HF_TS_SHIFT)
-#define HF_LMA_MASK (1 << HF_LMA_SHIFT)
-#define HF_CS64_MASK (1 << HF_CS64_SHIFT)
-#define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT)
-#define HF_HALTED_MASK (1 << HF_HALTED_SHIFT)
-#define HF_SMM_MASK (1 << HF_SMM_SHIFT)
-
-#define CR0_PE_MASK (1 << 0)
-#define CR0_MP_MASK (1 << 1)
-#define CR0_EM_MASK (1 << 2)
-#define CR0_TS_MASK (1 << 3)
-#define CR0_ET_MASK (1 << 4)
-#define CR0_NE_MASK (1 << 5)
-#define CR0_WP_MASK (1 << 16)
-#define CR0_AM_MASK (1 << 18)
-#define CR0_PG_MASK (1 << 31)
-
-#define CR4_VME_MASK (1 << 0)
-#define CR4_PVI_MASK (1 << 1)
-#define CR4_TSD_MASK (1 << 2)
-#define CR4_DE_MASK (1 << 3)
-#define CR4_PSE_MASK (1 << 4)
-#define CR4_PAE_MASK (1 << 5)
-#define CR4_PGE_MASK (1 << 7)
-#define CR4_PCE_MASK (1 << 8)
-#define CR4_OSFXSR_MASK (1 << 9)
-#define CR4_OSXMMEXCPT_MASK (1 << 10)
-
-#define PG_PRESENT_BIT 0
-#define PG_RW_BIT 1
-#define PG_USER_BIT 2
-#define PG_PWT_BIT 3
-#define PG_PCD_BIT 4
-#define PG_ACCESSED_BIT 5
-#define PG_DIRTY_BIT 6
-#define PG_PSE_BIT 7
-#define PG_GLOBAL_BIT 8
-#define PG_NX_BIT 63
-
-#define PG_PRESENT_MASK (1 << PG_PRESENT_BIT)
-#define PG_RW_MASK (1 << PG_RW_BIT)
-#define PG_USER_MASK (1 << PG_USER_BIT)
-#define PG_PWT_MASK (1 << PG_PWT_BIT)
-#define PG_PCD_MASK (1 << PG_PCD_BIT)
-#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
-#define PG_DIRTY_MASK (1 << PG_DIRTY_BIT)
-#define PG_PSE_MASK (1 << PG_PSE_BIT)
-#define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT)
-#define PG_NX_MASK (1LL << PG_NX_BIT)
-
-#define PG_ERROR_W_BIT 1
-
-#define PG_ERROR_P_MASK 0x01
-#define PG_ERROR_W_MASK (1 << PG_ERROR_W_BIT)
-#define PG_ERROR_U_MASK 0x04
-#define PG_ERROR_RSVD_MASK 0x08
-#define PG_ERROR_I_D_MASK 0x10
-
-#define MSR_IA32_APICBASE 0x1b
-#define MSR_IA32_APICBASE_BSP (1<<8)
-#define MSR_IA32_APICBASE_ENABLE (1<<11)
-#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
-
-#define MSR_IA32_SYSENTER_CS 0x174
-#define MSR_IA32_SYSENTER_ESP 0x175
-#define MSR_IA32_SYSENTER_EIP 0x176
-
-#define MSR_MCG_CAP 0x179
-#define MSR_MCG_STATUS 0x17a
-#define MSR_MCG_CTL 0x17b
-
-#define MSR_PAT 0x277
-
-#define MSR_EFER 0xc0000080
-
-#define MSR_EFER_SCE (1 << 0)
-#define MSR_EFER_LME (1 << 8)
-#define MSR_EFER_LMA (1 << 10)
-#define MSR_EFER_NXE (1 << 11)
-#define MSR_EFER_FFXSR (1 << 14)
-
-#define MSR_STAR 0xc0000081
-#define MSR_LSTAR 0xc0000082
-#define MSR_CSTAR 0xc0000083
-#define MSR_FMASK 0xc0000084
-#define MSR_FSBASE 0xc0000100
-#define MSR_GSBASE 0xc0000101
-#define MSR_KERNELGSBASE 0xc0000102
-
-/* cpuid_features bits */
-#define CPUID_FP87 (1 << 0)
-#define CPUID_VME (1 << 1)
-#define CPUID_DE (1 << 2)
-#define CPUID_PSE (1 << 3)
-#define CPUID_TSC (1 << 4)
-#define CPUID_MSR (1 << 5)
-#define CPUID_PAE (1 << 6)
-#define CPUID_MCE (1 << 7)
-#define CPUID_CX8 (1 << 8)
-#define CPUID_APIC (1 << 9)
-#define CPUID_SEP (1 << 11) /* sysenter/sysexit */
-#define CPUID_MTRR (1 << 12)
-#define CPUID_PGE (1 << 13)
-#define CPUID_MCA (1 << 14)
-#define CPUID_CMOV (1 << 15)
-#define CPUID_PAT (1 << 16)
-#define CPUID_PSE36 (1 << 17)
-#define CPUID_CLFLUSH (1 << 19)
-/* ... */
-#define CPUID_MMX (1 << 23)
-#define CPUID_FXSR (1 << 24)
-#define CPUID_SSE (1 << 25)
-#define CPUID_SSE2 (1 << 26)
-
-#define CPUID_EXT_SSE3 (1 << 0)
-#define CPUID_EXT_MONITOR (1 << 3)
-#define CPUID_EXT_CX16 (1 << 13)
-
-#define CPUID_EXT2_SYSCALL (1 << 11)
-#define CPUID_EXT2_NX (1 << 20)
-#define CPUID_EXT2_FFXSR (1 << 25)
-#define CPUID_EXT2_LM (1 << 29)
-
-#define EXCP00_DIVZ 0
-#define EXCP01_SSTP 1
-#define EXCP02_NMI 2
-#define EXCP03_INT3 3
-#define EXCP04_INTO 4
-#define EXCP05_BOUND 5
-#define EXCP06_ILLOP 6
-#define EXCP07_PREX 7
-#define EXCP08_DBLE 8
-#define EXCP09_XERR 9
-#define EXCP0A_TSS 10
-#define EXCP0B_NOSEG 11
-#define EXCP0C_STACK 12
-#define EXCP0D_GPF 13
-#define EXCP0E_PAGE 14
-#define EXCP10_COPR 16
-#define EXCP11_ALGN 17
-#define EXCP12_MCHK 18
-
-enum {
- CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
- CC_OP_EFLAGS, /* all cc are explicitely computed, CC_SRC = flags */
-
- CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */
- CC_OP_MULW,
- CC_OP_MULL,
- CC_OP_MULQ,
-
- CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
- CC_OP_ADDW,
- CC_OP_ADDL,
- CC_OP_ADDQ,
-
- CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
- CC_OP_ADCW,
- CC_OP_ADCL,
- CC_OP_ADCQ,
-
- CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
- CC_OP_SUBW,
- CC_OP_SUBL,
- CC_OP_SUBQ,
-
- CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
- CC_OP_SBBW,
- CC_OP_SBBL,
- CC_OP_SBBQ,
-
- CC_OP_LOGICB, /* modify all flags, CC_DST = res */
- CC_OP_LOGICW,
- CC_OP_LOGICL,
- CC_OP_LOGICQ,
-
- CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */
- CC_OP_INCW,
- CC_OP_INCL,
- CC_OP_INCQ,
-
- CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C */
- CC_OP_DECW,
- CC_OP_DECL,
- CC_OP_DECQ,
-
- CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.msb = C */
- CC_OP_SHLW,
- CC_OP_SHLL,
- CC_OP_SHLQ,
-
- CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
- CC_OP_SARW,
- CC_OP_SARL,
- CC_OP_SARQ,
-
- CC_OP_NB,
-};
-
-#ifdef FLOATX80
-#define USE_X86LDOUBLE
-#endif
-
-#ifdef USE_X86LDOUBLE
-typedef floatx80 CPU86_LDouble;
-#else
-typedef float64 CPU86_LDouble;
-#endif
-
-typedef struct SegmentCache {
- uint32_t selector;
- target_ulong base;
- uint32_t limit;
- uint32_t flags;
-} SegmentCache;
-
-typedef union {
- uint8_t _b[16];
- uint16_t _w[8];
- uint32_t _l[4];
- uint64_t _q[2];
- float32 _s[4];
- float64 _d[2];
-} XMMReg;
-
-typedef union {
- uint8_t _b[8];
- uint16_t _w[2];
- uint32_t _l[1];
- uint64_t q;
-} MMXReg;
-
-#ifdef WORDS_BIGENDIAN
-#define XMM_B(n) _b[15 - (n)]
-#define XMM_W(n) _w[7 - (n)]
-#define XMM_L(n) _l[3 - (n)]
-#define XMM_S(n) _s[3 - (n)]
-#define XMM_Q(n) _q[1 - (n)]
-#define XMM_D(n) _d[1 - (n)]
-
-#define MMX_B(n) _b[7 - (n)]
-#define MMX_W(n) _w[3 - (n)]
-#define MMX_L(n) _l[1 - (n)]
-#else
-#define XMM_B(n) _b[n]
-#define XMM_W(n) _w[n]
-#define XMM_L(n) _l[n]
-#define XMM_S(n) _s[n]
-#define XMM_Q(n) _q[n]
-#define XMM_D(n) _d[n]
-
-#define MMX_B(n) _b[n]
-#define MMX_W(n) _w[n]
-#define MMX_L(n) _l[n]
-#endif
-#define MMX_Q(n) q
-
-#ifdef TARGET_X86_64
-#define CPU_NB_REGS 16
-#else
-#define CPU_NB_REGS 8
-#endif
-
-typedef struct CPUX86State {
-#if TARGET_LONG_BITS > HOST_LONG_BITS
- /* temporaries if we cannot store them in host registers */
- target_ulong t0, t1, t2;
-#endif
-
- /* standard registers */
- target_ulong regs[CPU_NB_REGS];
- target_ulong eip;
- target_ulong eflags; /* eflags register. During CPU emulation, CC
- flags and DF are set to zero because they are
- stored elsewhere */
-
- /* emulator internal eflags handling */
- target_ulong cc_src;
- target_ulong cc_dst;
- uint32_t cc_op;
- int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
- uint32_t hflags; /* hidden flags, see HF_xxx constants */
-
- /* segments */
- SegmentCache segs[6]; /* selector values */
- SegmentCache ldt;
- SegmentCache tr;
- SegmentCache gdt; /* only base and limit are used */
- SegmentCache idt; /* only base and limit are used */
-
- target_ulong cr[5]; /* NOTE: cr1 is unused */
- uint32_t a20_mask;
-
- /* FPU state */
- unsigned int fpstt; /* top of stack index */
- unsigned int fpus;
- unsigned int fpuc;
- uint8_t fptags[8]; /* 0 = valid, 1 = empty */
- union {
-#ifdef USE_X86LDOUBLE
- CPU86_LDouble d __attribute__((aligned(16)));
-#else
- CPU86_LDouble d;
-#endif
- MMXReg mmx;
- } fpregs[8];
-
- /* emulator internal variables */
- float_status fp_status;
- CPU86_LDouble ft0;
- union {
- float f;
- double d;
- int i32;
- int64_t i64;
- } fp_convert;
-
- float_status sse_status;
- uint32_t mxcsr;
- XMMReg xmm_regs[CPU_NB_REGS];
- XMMReg xmm_t0;
- MMXReg mmx_t0;
-
- /* sysenter registers */
- uint32_t sysenter_cs;
- uint32_t sysenter_esp;
- uint32_t sysenter_eip;
- uint64_t efer;
- uint64_t star;
-#ifdef TARGET_X86_64
- target_ulong lstar;
- target_ulong cstar;
- target_ulong fmask;
- target_ulong kernelgsbase;
-#endif
-
- uint64_t pat;
-
- /* temporary data for USE_CODE_COPY mode */
-#ifdef USE_CODE_COPY
- uint32_t tmp0;
- uint32_t saved_esp;
- int native_fp_regs; /* if true, the FPU state is in the native CPU regs */
-#endif
-
- /* exception/interrupt handling */
- jmp_buf jmp_env;
- int exception_index;
- int error_code;
- int exception_is_int;
- target_ulong exception_next_eip;
- target_ulong dr[8]; /* debug registers */
- uint32_t smbase;
- int interrupt_request;
- int user_mode_only; /* user mode only simulation */
-
- CPU_COMMON
-
- /* processor features (e.g. for CPUID insn) */
- uint32_t cpuid_level;
- uint32_t cpuid_vendor1;
- uint32_t cpuid_vendor2;
- uint32_t cpuid_vendor3;
- uint32_t cpuid_version;
- uint32_t cpuid_features;
- uint32_t cpuid_ext_features;
- uint32_t cpuid_xlevel;
- uint32_t cpuid_model[12];
- uint32_t cpuid_ext2_features;
-
-#ifdef USE_KQEMU
- int kqemu_enabled;
- int last_io_time;
-#endif
- /* in order to simplify APIC support, we leave this pointer to the
- user */
- struct APICState *apic_state;
-} CPUX86State;
-
-CPUX86State *cpu_x86_init(void);
-int cpu_x86_exec(CPUX86State *s);
-void cpu_x86_close(CPUX86State *s);
-int cpu_get_pic_interrupt(CPUX86State *s);
-/* MSDOS compatibility mode FPU exception support */
-void cpu_set_ferr(CPUX86State *s);
-
-/* this function must always be used to load data in the segment
- cache: it synchronizes the hflags with the segment cache values */
-static inline void cpu_x86_load_seg_cache(CPUX86State *env,
- int seg_reg, unsigned int selector,
- target_ulong base,
- unsigned int limit,
- unsigned int flags)
-{
- SegmentCache *sc;
- unsigned int new_hflags;
-
- sc = &env->segs[seg_reg];
- sc->selector = selector;
- sc->base = base;
- sc->limit = limit;
- sc->flags = flags;
-
- /* update the hidden flags */
- {
- if (seg_reg == R_CS) {
-#ifdef TARGET_X86_64
- if ((env->hflags & HF_LMA_MASK) && (flags & DESC_L_MASK)) {
- /* long mode */
- env->hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
- env->hflags &= ~(HF_ADDSEG_MASK);
- } else
-#endif
- {
- /* legacy / compatibility case */
- new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
- >> (DESC_B_SHIFT - HF_CS32_SHIFT);
- env->hflags = (env->hflags & ~(HF_CS32_MASK | HF_CS64_MASK)) |
- new_hflags;
- }
- }
- new_hflags = (env->segs[R_SS].flags & DESC_B_MASK)
- >> (DESC_B_SHIFT - HF_SS32_SHIFT);
- if (env->hflags & HF_CS64_MASK) {
- /* zero base assumed for DS, ES and SS in long mode */
- } else if (!(env->cr[0] & CR0_PE_MASK) ||
- (env->eflags & VM_MASK) ||
- !(env->hflags & HF_CS32_MASK)) {
- /* XXX: try to avoid this test. The problem comes from the
- fact that is real mode or vm86 mode we only modify the
- 'base' and 'selector' fields of the segment cache to go
- faster. A solution may be to force addseg to one in
- translate-i386.c. */
- new_hflags |= HF_ADDSEG_MASK;
- } else {
- new_hflags |= ((env->segs[R_DS].base |
- env->segs[R_ES].base |
- env->segs[R_SS].base) != 0) <<
- HF_ADDSEG_SHIFT;
- }
- env->hflags = (env->hflags &
- ~(HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags;
- }
-}
-
-/* wrapper, just in case memory mappings must be changed */
-static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
-{
-#if HF_CPL_MASK == 3
- s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;
-#else
-#error HF_CPL_MASK is hardcoded
-#endif
-}
-
-/* used for debug or cpu save/restore */
-void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f);
-CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper);
-
-/* the following helpers are only usable in user mode simulation as
- they can trigger unexpected exceptions */
-void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
-void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32);
-void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32);
-
-/* you can call this signal handler from your SIGBUS and SIGSEGV
- signal handlers to inform the virtual CPU of exceptions. non zero
- is returned if the signal was handled by the virtual CPU. */
-int cpu_x86_signal_handler(int host_signum, void *pinfo,
- void *puc);
-void cpu_x86_set_a20(CPUX86State *env, int a20_state);
-
-uint64_t cpu_get_tsc(CPUX86State *env);
-
-void cpu_set_apic_base(CPUX86State *env, uint64_t val);
-uint64_t cpu_get_apic_base(CPUX86State *env);
-void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
-#ifndef NO_CPU_IO_DEFS
-uint8_t cpu_get_apic_tpr(CPUX86State *env);
-#endif
-void cpu_smm_update(CPUX86State *env);
-
-/* will be suppressed */
-void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
-
-/* used to debug */
-#define X86_DUMP_FPU 0x0001 /* dump FPU state too */
-#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
-
-#ifdef USE_KQEMU
-static inline int cpu_get_time_fast(void)
-{
- int low, high;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- return low;
-}
-#endif
-
-#define TARGET_PAGE_BITS 12
-#include "cpu-all.h"
-
-#endif /* CPU_I386_H */
diff --git a/tools/ioemu/target-i386/exec.h b/tools/ioemu/target-i386/exec.h
deleted file mode 100644
index 377f7bd28b..0000000000
--- a/tools/ioemu/target-i386/exec.h
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * i386 execution defines
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#include "dyngen-exec.h"
-
-/* XXX: factorize this mess */
-#ifdef TARGET_X86_64
-#define TARGET_LONG_BITS 64
-#else
-#define TARGET_LONG_BITS 32
-#endif
-
-#include "cpu-defs.h"
-
-/* at least 4 register variables are defined */
-register struct CPUX86State *env asm(AREG0);
-
-#if TARGET_LONG_BITS > HOST_LONG_BITS
-
-/* no registers can be used */
-#define T0 (env->t0)
-#define T1 (env->t1)
-#define T2 (env->t2)
-
-#else
-
-/* XXX: use unsigned long instead of target_ulong - better code will
- be generated for 64 bit CPUs */
-register target_ulong T0 asm(AREG1);
-register target_ulong T1 asm(AREG2);
-register target_ulong T2 asm(AREG3);
-
-/* if more registers are available, we define some registers too */
-#ifdef AREG4
-register target_ulong EAX asm(AREG4);
-#define reg_EAX
-#endif
-
-#ifdef AREG5
-register target_ulong ESP asm(AREG5);
-#define reg_ESP
-#endif
-
-#ifdef AREG6
-register target_ulong EBP asm(AREG6);
-#define reg_EBP
-#endif
-
-#ifdef AREG7
-register target_ulong ECX asm(AREG7);
-#define reg_ECX
-#endif
-
-#ifdef AREG8
-register target_ulong EDX asm(AREG8);
-#define reg_EDX
-#endif
-
-#ifdef AREG9
-register target_ulong EBX asm(AREG9);
-#define reg_EBX
-#endif
-
-#ifdef AREG10
-register target_ulong ESI asm(AREG10);
-#define reg_ESI
-#endif
-
-#ifdef AREG11
-register target_ulong EDI asm(AREG11);
-#define reg_EDI
-#endif
-
-#endif /* ! (TARGET_LONG_BITS > HOST_LONG_BITS) */
-
-#define A0 T2
-
-extern FILE *logfile;
-extern int loglevel;
-
-#ifndef reg_EAX
-#define EAX (env->regs[R_EAX])
-#endif
-#ifndef reg_ECX
-#define ECX (env->regs[R_ECX])
-#endif
-#ifndef reg_EDX
-#define EDX (env->regs[R_EDX])
-#endif
-#ifndef reg_EBX
-#define EBX (env->regs[R_EBX])
-#endif
-#ifndef reg_ESP
-#define ESP (env->regs[R_ESP])
-#endif
-#ifndef reg_EBP
-#define EBP (env->regs[R_EBP])
-#endif
-#ifndef reg_ESI
-#define ESI (env->regs[R_ESI])
-#endif
-#ifndef reg_EDI
-#define EDI (env->regs[R_EDI])
-#endif
-#define EIP (env->eip)
-#define DF (env->df)
-
-#define CC_SRC (env->cc_src)
-#define CC_DST (env->cc_dst)
-#define CC_OP (env->cc_op)
-
-/* float macros */
-#define FT0 (env->ft0)
-#define ST0 (env->fpregs[env->fpstt].d)
-#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
-#define ST1 ST(1)
-
-#ifdef USE_FP_CONVERT
-#define FP_CONVERT (env->fp_convert)
-#endif
-
-#include "cpu.h"
-#include "exec-all.h"
-
-typedef struct CCTable {
- int (*compute_all)(void); /* return all the flags */
- int (*compute_c)(void); /* return the C flag */
-} CCTable;
-
-extern CCTable cc_table[];
-
-void load_seg(int seg_reg, int selector);
-void helper_ljmp_protected_T0_T1(int next_eip);
-void helper_lcall_real_T0_T1(int shift, int next_eip);
-void helper_lcall_protected_T0_T1(int shift, int next_eip);
-void helper_iret_real(int shift);
-void helper_iret_protected(int shift, int next_eip);
-void helper_lret_protected(int shift, int addend);
-void helper_lldt_T0(void);
-void helper_ltr_T0(void);
-void helper_movl_crN_T0(int reg);
-void helper_movl_drN_T0(int reg);
-void helper_invlpg(target_ulong addr);
-void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
-void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
-void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
-void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
- int is_write, int is_user, int is_softmmu);
-void tlb_fill(target_ulong addr, int is_write, int is_user,
- void *retaddr);
-void __hidden cpu_lock(void);
-void __hidden cpu_unlock(void);
-void do_interrupt(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw);
-void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip);
-void raise_interrupt(int intno, int is_int, int error_code,
- int next_eip_addend);
-void raise_exception_err(int exception_index, int error_code);
-void raise_exception(int exception_index);
-void do_smm_enter(void);
-void __hidden cpu_loop_exit(void);
-
-void OPPROTO op_movl_eflags_T0(void);
-void OPPROTO op_movl_T0_eflags(void);
-void helper_divl_EAX_T0(void);
-void helper_idivl_EAX_T0(void);
-void helper_mulq_EAX_T0(void);
-void helper_imulq_EAX_T0(void);
-void helper_imulq_T0_T1(void);
-void helper_divq_EAX_T0(void);
-void helper_idivq_EAX_T0(void);
-void helper_bswapq_T0(void);
-void helper_cmpxchg8b(void);
-void helper_cpuid(void);
-void helper_enter_level(int level, int data32);
-void helper_enter64_level(int level, int data64);
-void helper_sysenter(void);
-void helper_sysexit(void);
-void helper_syscall(int next_eip_addend);
-void helper_sysret(int dflag);
-void helper_rdtsc(void);
-void helper_rdmsr(void);
-void helper_wrmsr(void);
-void helper_lsl(void);
-void helper_lar(void);
-void helper_verr(void);
-void helper_verw(void);
-void helper_rsm(void);
-
-void check_iob_T0(void);
-void check_iow_T0(void);
-void check_iol_T0(void);
-void check_iob_DX(void);
-void check_iow_DX(void);
-void check_iol_DX(void);
-
-#if !defined(CONFIG_USER_ONLY)
-
-#include "softmmu_exec.h"
-
-static inline double ldfq(target_ulong ptr)
-{
- union {
- double d;
- uint64_t i;
- } u;
- u.i = ldq(ptr);
- return u.d;
-}
-
-static inline void stfq(target_ulong ptr, double v)
-{
- union {
- double d;
- uint64_t i;
- } u;
- u.d = v;
- stq(ptr, u.i);
-}
-
-static inline float ldfl(target_ulong ptr)
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.i = ldl(ptr);
- return u.f;
-}
-
-static inline void stfl(target_ulong ptr, float v)
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.f = v;
- stl(ptr, u.i);
-}
-
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-#ifdef USE_X86LDOUBLE
-/* use long double functions */
-#define floatx_to_int32 floatx80_to_int32
-#define floatx_to_int64 floatx80_to_int64
-#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero
-#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero
-#define floatx_abs floatx80_abs
-#define floatx_chs floatx80_chs
-#define floatx_round_to_int floatx80_round_to_int
-#define floatx_compare floatx80_compare
-#define floatx_compare_quiet floatx80_compare_quiet
-#define sin sinl
-#define cos cosl
-#define sqrt sqrtl
-#define pow powl
-#define log logl
-#define tan tanl
-#define atan2 atan2l
-#define floor floorl
-#define ceil ceill
-#define ldexp ldexpl
-#else
-#define floatx_to_int32 float64_to_int32
-#define floatx_to_int64 float64_to_int64
-#define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero
-#define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero
-#define floatx_abs float64_abs
-#define floatx_chs float64_chs
-#define floatx_round_to_int float64_round_to_int
-#define floatx_compare float64_compare
-#define floatx_compare_quiet float64_compare_quiet
-#endif
-
-extern CPU86_LDouble sin(CPU86_LDouble x);
-extern CPU86_LDouble cos(CPU86_LDouble x);
-extern CPU86_LDouble sqrt(CPU86_LDouble x);
-extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);
-extern CPU86_LDouble log(CPU86_LDouble x);
-extern CPU86_LDouble tan(CPU86_LDouble x);
-extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
-extern CPU86_LDouble floor(CPU86_LDouble x);
-extern CPU86_LDouble ceil(CPU86_LDouble x);
-
-#define RC_MASK 0xc00
-#define RC_NEAR 0x000
-#define RC_DOWN 0x400
-#define RC_UP 0x800
-#define RC_CHOP 0xc00
-
-#define MAXTAN 9223372036854775808.0
-
-#ifdef USE_X86LDOUBLE
-
-/* only for x86 */
-typedef union {
- long double d;
- struct {
- unsigned long long lower;
- unsigned short upper;
- } l;
-} CPU86_LDoubleU;
-
-/* the following deal with x86 long double-precision numbers */
-#define MAXEXPD 0x7fff
-#define EXPBIAS 16383
-#define EXPD(fp) (fp.l.upper & 0x7fff)
-#define SIGND(fp) ((fp.l.upper) & 0x8000)
-#define MANTD(fp) (fp.l.lower)
-#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
-
-#else
-
-/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
-typedef union {
- double d;
-#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
- struct {
- uint32_t lower;
- int32_t upper;
- } l;
-#else
- struct {
- int32_t upper;
- uint32_t lower;
- } l;
-#endif
-#ifndef __arm__
- int64_t ll;
-#endif
-} CPU86_LDoubleU;
-
-/* the following deal with IEEE double-precision numbers */
-#define MAXEXPD 0x7ff
-#define EXPBIAS 1023
-#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
-#define SIGND(fp) ((fp.l.upper) & 0x80000000)
-#ifdef __arm__
-#define MANTD(fp) (fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32))
-#else
-#define MANTD(fp) (fp.ll & ((1LL << 52) - 1))
-#endif
-#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
-#endif
-
-static inline void fpush(void)
-{
- env->fpstt = (env->fpstt - 1) & 7;
- env->fptags[env->fpstt] = 0; /* validate stack entry */
-}
-
-static inline void fpop(void)
-{
- env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
- env->fpstt = (env->fpstt + 1) & 7;
-}
-
-#ifndef USE_X86LDOUBLE
-static inline CPU86_LDouble helper_fldt(target_ulong ptr)
-{
- CPU86_LDoubleU temp;
- int upper, e;
- uint64_t ll;
-
- /* mantissa */
- upper = lduw(ptr + 8);
- /* XXX: handle overflow ? */
- e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
- e |= (upper >> 4) & 0x800; /* sign */
- ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1);
-#ifdef __arm__
- temp.l.upper = (e << 20) | (ll >> 32);
- temp.l.lower = ll;
-#else
- temp.ll = ll | ((uint64_t)e << 52);
-#endif
- return temp.d;
-}
-
-static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
-{
- CPU86_LDoubleU temp;
- int e;
-
- temp.d = f;
- /* mantissa */
- stq(ptr, (MANTD(temp) << 11) | (1LL << 63));
- /* exponent + sign */
- e = EXPD(temp) - EXPBIAS + 16383;
- e |= SIGND(temp) >> 16;
- stw(ptr + 8, e);
-}
-#else
-
-/* XXX: same endianness assumed */
-
-#ifdef CONFIG_USER_ONLY
-
-static inline CPU86_LDouble helper_fldt(target_ulong ptr)
-{
- return *(CPU86_LDouble *)ptr;
-}
-
-static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
-{
- *(CPU86_LDouble *)ptr = f;
-}
-
-#else
-
-/* we use memory access macros */
-
-static inline CPU86_LDouble helper_fldt(target_ulong ptr)
-{
- CPU86_LDoubleU temp;
-
- temp.l.lower = ldq(ptr);
- temp.l.upper = lduw(ptr + 8);
- return temp.d;
-}
-
-static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
-{
- CPU86_LDoubleU temp;
-
- temp.d = f;
- stq(ptr, temp.l.lower);
- stw(ptr + 8, temp.l.upper);
-}
-
-#endif /* !CONFIG_USER_ONLY */
-
-#endif /* USE_X86LDOUBLE */
-
-#define FPUS_IE (1 << 0)
-#define FPUS_DE (1 << 1)
-#define FPUS_ZE (1 << 2)
-#define FPUS_OE (1 << 3)
-#define FPUS_UE (1 << 4)
-#define FPUS_PE (1 << 5)
-#define FPUS_SF (1 << 6)
-#define FPUS_SE (1 << 7)
-#define FPUS_B (1 << 15)
-
-#define FPUC_EM 0x3f
-
-extern const CPU86_LDouble f15rk[7];
-
-void helper_fldt_ST0_A0(void);
-void helper_fstt_ST0_A0(void);
-void fpu_raise_exception(void);
-CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b);
-void helper_fbld_ST0_A0(void);
-void helper_fbst_ST0_A0(void);
-void helper_f2xm1(void);
-void helper_fyl2x(void);
-void helper_fptan(void);
-void helper_fpatan(void);
-void helper_fxtract(void);
-void helper_fprem1(void);
-void helper_fprem(void);
-void helper_fyl2xp1(void);
-void helper_fsqrt(void);
-void helper_fsincos(void);
-void helper_frndint(void);
-void helper_fscale(void);
-void helper_fsin(void);
-void helper_fcos(void);
-void helper_fxam_ST0(void);
-void helper_fstenv(target_ulong ptr, int data32);
-void helper_fldenv(target_ulong ptr, int data32);
-void helper_fsave(target_ulong ptr, int data32);
-void helper_frstor(target_ulong ptr, int data32);
-void helper_fxsave(target_ulong ptr, int data64);
-void helper_fxrstor(target_ulong ptr, int data64);
-void restore_native_fp_state(CPUState *env);
-void save_native_fp_state(CPUState *env);
-float approx_rsqrt(float a);
-float approx_rcp(float a);
-void update_fp_status(void);
-void helper_hlt(void);
-void helper_monitor(void);
-void helper_mwait(void);
-
-extern const uint8_t parity_table[256];
-extern const uint8_t rclw_table[32];
-extern const uint8_t rclb_table[32];
-
-static inline uint32_t compute_eflags(void)
-{
- return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-}
-
-/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
-static inline void load_eflags(int eflags, int update_mask)
-{
- CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((eflags >> 10) & 1));
- env->eflags = (env->eflags & ~update_mask) |
- (eflags & update_mask);
-}
-
-static inline void env_to_regs(void)
-{
-#ifdef reg_EAX
- EAX = env->regs[R_EAX];
-#endif
-#ifdef reg_ECX
- ECX = env->regs[R_ECX];
-#endif
-#ifdef reg_EDX
- EDX = env->regs[R_EDX];
-#endif
-#ifdef reg_EBX
- EBX = env->regs[R_EBX];
-#endif
-#ifdef reg_ESP
- ESP = env->regs[R_ESP];
-#endif
-#ifdef reg_EBP
- EBP = env->regs[R_EBP];
-#endif
-#ifdef reg_ESI
- ESI = env->regs[R_ESI];
-#endif
-#ifdef reg_EDI
- EDI = env->regs[R_EDI];
-#endif
-}
-
-static inline void regs_to_env(void)
-{
-#ifdef reg_EAX
- env->regs[R_EAX] = EAX;
-#endif
-#ifdef reg_ECX
- env->regs[R_ECX] = ECX;
-#endif
-#ifdef reg_EDX
- env->regs[R_EDX] = EDX;
-#endif
-#ifdef reg_EBX
- env->regs[R_EBX] = EBX;
-#endif
-#ifdef reg_ESP
- env->regs[R_ESP] = ESP;
-#endif
-#ifdef reg_EBP
- env->regs[R_EBP] = EBP;
-#endif
-#ifdef reg_ESI
- env->regs[R_ESI] = ESI;
-#endif
-#ifdef reg_EDI
- env->regs[R_EDI] = EDI;
-#endif
-}
diff --git a/tools/ioemu/target-i386/helper.c b/tools/ioemu/target-i386/helper.c
deleted file mode 100644
index 1d62f6b2e3..0000000000
--- a/tools/ioemu/target-i386/helper.c
+++ /dev/null
@@ -1,3840 +0,0 @@
-/*
- * i386 helpers
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "exec.h"
-
-//#define DEBUG_PCALL
-
-#if 0
-#define raise_exception_err(a, b)\
-do {\
- if (logfile)\
- fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
- (raise_exception_err)(a, b);\
-} while (0)
-#endif
-
-const uint8_t parity_table[256] = {
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
- 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-};
-
-/* modulo 17 table */
-const uint8_t rclw_table[32] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9,10,11,12,13,14,15,
- 16, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9,10,11,12,13,14,
-};
-
-/* modulo 9 table */
-const uint8_t rclb_table[32] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 0, 1, 2, 3, 4,
-};
-
-const CPU86_LDouble f15rk[7] =
-{
- 0.00000000000000000000L,
- 1.00000000000000000000L,
- 3.14159265358979323851L, /*pi*/
- 0.30102999566398119523L, /*lg2*/
- 0.69314718055994530943L, /*ln2*/
- 1.44269504088896340739L, /*l2e*/
- 3.32192809488736234781L, /*l2t*/
-};
-
-/* thread support */
-
-spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
-
-void cpu_lock(void)
-{
- spin_lock(&global_cpu_lock);
-}
-
-void cpu_unlock(void)
-{
- spin_unlock(&global_cpu_lock);
-}
-
-void cpu_loop_exit(void)
-{
- /* NOTE: the register at this point must be saved by hand because
- longjmp restore them */
- regs_to_env();
- longjmp(env->jmp_env, 1);
-}
-
-/* return non zero if error */
-static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
- int selector)
-{
- SegmentCache *dt;
- int index;
- target_ulong ptr;
-
- if (selector & 0x4)
- dt = &env->ldt;
- else
- dt = &env->gdt;
- index = selector & ~7;
- if ((index + 7) > dt->limit)
- return -1;
- ptr = dt->base + index;
- *e1_ptr = ldl_kernel(ptr);
- *e2_ptr = ldl_kernel(ptr + 4);
- return 0;
-}
-
-static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2)
-{
- unsigned int limit;
- limit = (e1 & 0xffff) | (e2 & 0x000f0000);
- if (e2 & DESC_G_MASK)
- limit = (limit << 12) | 0xfff;
- return limit;
-}
-
-static inline uint32_t get_seg_base(uint32_t e1, uint32_t e2)
-{
- return ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
-}
-
-static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2)
-{
- sc->base = get_seg_base(e1, e2);
- sc->limit = get_seg_limit(e1, e2);
- sc->flags = e2;
-}
-
-/* init the segment cache in vm86 mode. */
-static inline void load_seg_vm(int seg, int selector)
-{
- selector &= 0xffff;
- cpu_x86_load_seg_cache(env, seg, selector,
- (selector << 4), 0xffff, 0);
-}
-
-static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
- uint32_t *esp_ptr, int dpl)
-{
- int type, index, shift;
-
-#if 0
- {
- int i;
- printf("TR: base=%p limit=%x\n", env->tr.base, env->tr.limit);
- for(i=0;i<env->tr.limit;i++) {
- printf("%02x ", env->tr.base[i]);
- if ((i & 7) == 7) printf("\n");
- }
- printf("\n");
- }
-#endif
-
- if (!(env->tr.flags & DESC_P_MASK))
- cpu_abort(env, "invalid tss");
- type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
- if ((type & 7) != 1)
- cpu_abort(env, "invalid tss type");
- shift = type >> 3;
- index = (dpl * 4 + 2) << shift;
- if (index + (4 << shift) - 1 > env->tr.limit)
- raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
- if (shift == 0) {
- *esp_ptr = lduw_kernel(env->tr.base + index);
- *ss_ptr = lduw_kernel(env->tr.base + index + 2);
- } else {
- *esp_ptr = ldl_kernel(env->tr.base + index);
- *ss_ptr = lduw_kernel(env->tr.base + index + 4);
- }
-}
-
-/* XXX: merge with load_seg() */
-static void tss_load_seg(int seg_reg, int selector)
-{
- uint32_t e1, e2;
- int rpl, dpl, cpl;
-
- if ((selector & 0xfffc) != 0) {
- if (load_segment(&e1, &e2, selector) != 0)
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- if (!(e2 & DESC_S_MASK))
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- rpl = selector & 3;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- if (seg_reg == R_CS) {
- if (!(e2 & DESC_CS_MASK))
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- /* XXX: is it correct ? */
- if (dpl != rpl)
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- if ((e2 & DESC_C_MASK) && dpl > rpl)
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- } else if (seg_reg == R_SS) {
- /* SS must be writable data */
- if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK))
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- if (dpl != cpl || dpl != rpl)
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- } else {
- /* not readable code */
- if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK))
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- /* if data or non conforming code, checks the rights */
- if (((e2 >> DESC_TYPE_SHIFT) & 0xf) < 12) {
- if (dpl < cpl || dpl < rpl)
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- }
- }
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
- cpu_x86_load_seg_cache(env, seg_reg, selector,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2),
- e2);
- } else {
- if (seg_reg == R_SS || seg_reg == R_CS)
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
- }
-}
-
-#define SWITCH_TSS_JMP 0
-#define SWITCH_TSS_IRET 1
-#define SWITCH_TSS_CALL 2
-
-/* XXX: restore CPU state in registers (PowerPC case) */
-static void switch_tss(int tss_selector,
- uint32_t e1, uint32_t e2, int source,
- uint32_t next_eip)
-{
- int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, v1, v2, i;
- target_ulong tss_base;
- uint32_t new_regs[8], new_segs[6];
- uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap;
- uint32_t old_eflags, eflags_mask;
- SegmentCache *dt;
- int index;
- target_ulong ptr;
-
- type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL)
- fprintf(logfile, "switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, source);
-#endif
-
- /* if task gate, we read the TSS segment and we load it */
- if (type == 5) {
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc);
- tss_selector = e1 >> 16;
- if (tss_selector & 4)
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
- if (load_segment(&e1, &e2, tss_selector) != 0)
- raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
- if (e2 & DESC_S_MASK)
- raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
- type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
- if ((type & 7) != 1)
- raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
- }
-
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc);
-
- if (type & 8)
- tss_limit_max = 103;
- else
- tss_limit_max = 43;
- tss_limit = get_seg_limit(e1, e2);
- tss_base = get_seg_base(e1, e2);
- if ((tss_selector & 4) != 0 ||
- tss_limit < tss_limit_max)
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
- old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
- if (old_type & 8)
- old_tss_limit_max = 103;
- else
- old_tss_limit_max = 43;
-
- /* read all the registers from the new TSS */
- if (type & 8) {
- /* 32 bit */
- new_cr3 = ldl_kernel(tss_base + 0x1c);
- new_eip = ldl_kernel(tss_base + 0x20);
- new_eflags = ldl_kernel(tss_base + 0x24);
- for(i = 0; i < 8; i++)
- new_regs[i] = ldl_kernel(tss_base + (0x28 + i * 4));
- for(i = 0; i < 6; i++)
- new_segs[i] = lduw_kernel(tss_base + (0x48 + i * 4));
- new_ldt = lduw_kernel(tss_base + 0x60);
- new_trap = ldl_kernel(tss_base + 0x64);
- } else {
- /* 16 bit */
- new_cr3 = 0;
- new_eip = lduw_kernel(tss_base + 0x0e);
- new_eflags = lduw_kernel(tss_base + 0x10);
- for(i = 0; i < 8; i++)
- new_regs[i] = lduw_kernel(tss_base + (0x12 + i * 2)) | 0xffff0000;
- for(i = 0; i < 4; i++)
- new_segs[i] = lduw_kernel(tss_base + (0x22 + i * 4));
- new_ldt = lduw_kernel(tss_base + 0x2a);
- new_segs[R_FS] = 0;
- new_segs[R_GS] = 0;
- new_trap = 0;
- }
-
- /* NOTE: we must avoid memory exceptions during the task switch,
- so we make dummy accesses before */
- /* XXX: it can still fail in some cases, so a bigger hack is
- necessary to valid the TLB after having done the accesses */
-
- v1 = ldub_kernel(env->tr.base);
- v2 = ldub_kernel(env->tr.base + old_tss_limit_max);
- stb_kernel(env->tr.base, v1);
- stb_kernel(env->tr.base + old_tss_limit_max, v2);
-
- /* clear busy bit (it is restartable) */
- if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) {
- target_ulong ptr;
- uint32_t e2;
- ptr = env->gdt.base + (env->tr.selector & ~7);
- e2 = ldl_kernel(ptr + 4);
- e2 &= ~DESC_TSS_BUSY_MASK;
- stl_kernel(ptr + 4, e2);
- }
- old_eflags = compute_eflags();
- if (source == SWITCH_TSS_IRET)
- old_eflags &= ~NT_MASK;
-
- /* save the current state in the old TSS */
- if (type & 8) {
- /* 32 bit */
- stl_kernel(env->tr.base + 0x20, next_eip);
- stl_kernel(env->tr.base + 0x24, old_eflags);
- stl_kernel(env->tr.base + (0x28 + 0 * 4), EAX);
- stl_kernel(env->tr.base + (0x28 + 1 * 4), ECX);
- stl_kernel(env->tr.base + (0x28 + 2 * 4), EDX);
- stl_kernel(env->tr.base + (0x28 + 3 * 4), EBX);
- stl_kernel(env->tr.base + (0x28 + 4 * 4), ESP);
- stl_kernel(env->tr.base + (0x28 + 5 * 4), EBP);
- stl_kernel(env->tr.base + (0x28 + 6 * 4), ESI);
- stl_kernel(env->tr.base + (0x28 + 7 * 4), EDI);
- for(i = 0; i < 6; i++)
- stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
- } else {
- /* 16 bit */
- stw_kernel(env->tr.base + 0x0e, next_eip);
- stw_kernel(env->tr.base + 0x10, old_eflags);
- stw_kernel(env->tr.base + (0x12 + 0 * 2), EAX);
- stw_kernel(env->tr.base + (0x12 + 1 * 2), ECX);
- stw_kernel(env->tr.base + (0x12 + 2 * 2), EDX);
- stw_kernel(env->tr.base + (0x12 + 3 * 2), EBX);
- stw_kernel(env->tr.base + (0x12 + 4 * 2), ESP);
- stw_kernel(env->tr.base + (0x12 + 5 * 2), EBP);
- stw_kernel(env->tr.base + (0x12 + 6 * 2), ESI);
- stw_kernel(env->tr.base + (0x12 + 7 * 2), EDI);
- for(i = 0; i < 4; i++)
- stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector);
- }
-
- /* now if an exception occurs, it will occurs in the next task
- context */
-
- if (source == SWITCH_TSS_CALL) {
- stw_kernel(tss_base, env->tr.selector);
- new_eflags |= NT_MASK;
- }
-
- /* set busy bit */
- if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_CALL) {
- target_ulong ptr;
- uint32_t e2;
- ptr = env->gdt.base + (tss_selector & ~7);
- e2 = ldl_kernel(ptr + 4);
- e2 |= DESC_TSS_BUSY_MASK;
- stl_kernel(ptr + 4, e2);
- }
-
- /* set the new CPU state */
- /* from this point, any exception which occurs can give problems */
- env->cr[0] |= CR0_TS_MASK;
- env->hflags |= HF_TS_MASK;
- env->tr.selector = tss_selector;
- env->tr.base = tss_base;
- env->tr.limit = tss_limit;
- env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK;
-
- if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) {
- cpu_x86_update_cr3(env, new_cr3);
- }
-
- /* load all registers without an exception, then reload them with
- possible exception */
- env->eip = new_eip;
- eflags_mask = TF_MASK | AC_MASK | ID_MASK |
- IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK;
- if (!(type & 8))
- eflags_mask &= 0xffff;
- load_eflags(new_eflags, eflags_mask);
- /* XXX: what to do in 16 bit case ? */
- EAX = new_regs[0];
- ECX = new_regs[1];
- EDX = new_regs[2];
- EBX = new_regs[3];
- ESP = new_regs[4];
- EBP = new_regs[5];
- ESI = new_regs[6];
- EDI = new_regs[7];
- if (new_eflags & VM_MASK) {
- for(i = 0; i < 6; i++)
- load_seg_vm(i, new_segs[i]);
- /* in vm86, CPL is always 3 */
- cpu_x86_set_cpl(env, 3);
- } else {
- /* CPL is set the RPL of CS */
- cpu_x86_set_cpl(env, new_segs[R_CS] & 3);
- /* first just selectors as the rest may trigger exceptions */
- for(i = 0; i < 6; i++)
- cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0);
- }
-
- env->ldt.selector = new_ldt & ~4;
- env->ldt.base = 0;
- env->ldt.limit = 0;
- env->ldt.flags = 0;
-
- /* load the LDT */
- if (new_ldt & 4)
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
-
- if ((new_ldt & 0xfffc) != 0) {
- dt = &env->gdt;
- index = new_ldt & ~7;
- if ((index + 7) > dt->limit)
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
- ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
- if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
- load_seg_cache_raw_dt(&env->ldt, e1, e2);
- }
-
- /* load the segments */
- if (!(new_eflags & VM_MASK)) {
- tss_load_seg(R_CS, new_segs[R_CS]);
- tss_load_seg(R_SS, new_segs[R_SS]);
- tss_load_seg(R_ES, new_segs[R_ES]);
- tss_load_seg(R_DS, new_segs[R_DS]);
- tss_load_seg(R_FS, new_segs[R_FS]);
- tss_load_seg(R_GS, new_segs[R_GS]);
- }
-
- /* check that EIP is in the CS segment limits */
- if (new_eip > env->segs[R_CS].limit) {
- /* XXX: different exception if CALL ? */
- raise_exception_err(EXCP0D_GPF, 0);
- }
-}
-
-/* check if Port I/O is allowed in TSS */
-static inline void check_io(int addr, int size)
-{
- int io_offset, val, mask;
-
- /* TSS must be a valid 32 bit one */
- if (!(env->tr.flags & DESC_P_MASK) ||
- ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
- env->tr.limit < 103)
- goto fail;
- io_offset = lduw_kernel(env->tr.base + 0x66);
- io_offset += (addr >> 3);
- /* Note: the check needs two bytes */
- if ((io_offset + 1) > env->tr.limit)
- goto fail;
- val = lduw_kernel(env->tr.base + io_offset);
- val >>= (addr & 7);
- mask = (1 << size) - 1;
- /* all bits must be zero to allow the I/O */
- if ((val & mask) != 0) {
- fail:
- raise_exception_err(EXCP0D_GPF, 0);
- }
-}
-
-void check_iob_T0(void)
-{
- check_io(T0, 1);
-}
-
-void check_iow_T0(void)
-{
- check_io(T0, 2);
-}
-
-void check_iol_T0(void)
-{
- check_io(T0, 4);
-}
-
-void check_iob_DX(void)
-{
- check_io(EDX & 0xffff, 1);
-}
-
-void check_iow_DX(void)
-{
- check_io(EDX & 0xffff, 2);
-}
-
-void check_iol_DX(void)
-{
- check_io(EDX & 0xffff, 4);
-}
-
-static inline unsigned int get_sp_mask(unsigned int e2)
-{
- if (e2 & DESC_B_MASK)
- return 0xffffffff;
- else
- return 0xffff;
-}
-
-#ifdef TARGET_X86_64
-#define SET_ESP(val, sp_mask)\
-do {\
- if ((sp_mask) == 0xffff)\
- ESP = (ESP & ~0xffff) | ((val) & 0xffff);\
- else if ((sp_mask) == 0xffffffffLL)\
- ESP = (uint32_t)(val);\
- else\
- ESP = (val);\
-} while (0)
-#else
-#define SET_ESP(val, sp_mask) ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask))
-#endif
-
-/* XXX: add a is_user flag to have proper security support */
-#define PUSHW(ssp, sp, sp_mask, val)\
-{\
- sp -= 2;\
- stw_kernel((ssp) + (sp & (sp_mask)), (val));\
-}
-
-#define PUSHL(ssp, sp, sp_mask, val)\
-{\
- sp -= 4;\
- stl_kernel((ssp) + (sp & (sp_mask)), (val));\
-}
-
-#define POPW(ssp, sp, sp_mask, val)\
-{\
- val = lduw_kernel((ssp) + (sp & (sp_mask)));\
- sp += 2;\
-}
-
-#define POPL(ssp, sp, sp_mask, val)\
-{\
- val = (uint32_t)ldl_kernel((ssp) + (sp & (sp_mask)));\
- sp += 4;\
-}
-
-/* protected mode interrupt */
-static void do_interrupt_protected(int intno, int is_int, int error_code,
- unsigned int next_eip, int is_hw)
-{
- SegmentCache *dt;
- target_ulong ptr, ssp;
- int type, dpl, selector, ss_dpl, cpl;
- int has_error_code, new_stack, shift;
- uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2;
- uint32_t old_eip, sp_mask;
-
- has_error_code = 0;
- if (!is_int && !is_hw) {
- switch(intno) {
- case 8:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 17:
- has_error_code = 1;
- break;
- }
- }
- if (is_int)
- old_eip = next_eip;
- else
- old_eip = env->eip;
-
- dt = &env->idt;
- if (intno * 8 + 7 > dt->limit)
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
- ptr = dt->base + intno * 8;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
- /* check gate type */
- type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
- switch(type) {
- case 5: /* task gate */
- /* must do that check here to return the correct error code */
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
- switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);
- if (has_error_code) {
- int type;
- uint32_t mask;
- /* push the error code */
- type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
- shift = type >> 3;
- if (env->segs[R_SS].flags & DESC_B_MASK)
- mask = 0xffffffff;
- else
- mask = 0xffff;
- esp = (ESP - (2 << shift)) & mask;
- ssp = env->segs[R_SS].base + esp;
- if (shift)
- stl_kernel(ssp, error_code);
- else
- stw_kernel(ssp, error_code);
- SET_ESP(esp, mask);
- }
- return;
- case 6: /* 286 interrupt gate */
- case 7: /* 286 trap gate */
- case 14: /* 386 interrupt gate */
- case 15: /* 386 trap gate */
- break;
- default:
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
- break;
- }
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- /* check privledge if software int */
- if (is_int && dpl < cpl)
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
- /* check valid bit */
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
- selector = e1 >> 16;
- offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
- if ((selector & 0xfffc) == 0)
- raise_exception_err(EXCP0D_GPF, 0);
-
- if (load_segment(&e1, &e2, selector) != 0)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (dpl > cpl)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
- if (!(e2 & DESC_C_MASK) && dpl < cpl) {
- /* to inner priviledge */
- get_ss_esp_from_tss(&ss, &esp, dpl);
- if ((ss & 0xfffc) == 0)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if ((ss & 3) != dpl)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if (load_segment(&ss_e1, &ss_e2, ss) != 0)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
- if (ss_dpl != dpl)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if (!(ss_e2 & DESC_S_MASK) ||
- (ss_e2 & DESC_CS_MASK) ||
- !(ss_e2 & DESC_W_MASK))
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if (!(ss_e2 & DESC_P_MASK))
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- new_stack = 1;
- sp_mask = get_sp_mask(ss_e2);
- ssp = get_seg_base(ss_e1, ss_e2);
- } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
- /* to same priviledge */
- if (env->eflags & VM_MASK)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- new_stack = 0;
- sp_mask = get_sp_mask(env->segs[R_SS].flags);
- ssp = env->segs[R_SS].base;
- esp = ESP;
- dpl = cpl;
- } else {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- new_stack = 0; /* avoid warning */
- sp_mask = 0; /* avoid warning */
- ssp = 0; /* avoid warning */
- esp = 0; /* avoid warning */
- }
-
- shift = type >> 3;
-
-#if 0
- /* XXX: check that enough room is available */
- push_size = 6 + (new_stack << 2) + (has_error_code << 1);
- if (env->eflags & VM_MASK)
- push_size += 8;
- push_size <<= shift;
-#endif
- if (shift == 1) {
- if (new_stack) {
- if (env->eflags & VM_MASK) {
- PUSHL(ssp, esp, sp_mask, env->segs[R_GS].selector);
- PUSHL(ssp, esp, sp_mask, env->segs[R_FS].selector);
- PUSHL(ssp, esp, sp_mask, env->segs[R_DS].selector);
- PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector);
- }
- PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector);
- PUSHL(ssp, esp, sp_mask, ESP);
- }
- PUSHL(ssp, esp, sp_mask, compute_eflags());
- PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector);
- PUSHL(ssp, esp, sp_mask, old_eip);
- if (has_error_code) {
- PUSHL(ssp, esp, sp_mask, error_code);
- }
- } else {
- if (new_stack) {
- if (env->eflags & VM_MASK) {
- PUSHW(ssp, esp, sp_mask, env->segs[R_GS].selector);
- PUSHW(ssp, esp, sp_mask, env->segs[R_FS].selector);
- PUSHW(ssp, esp, sp_mask, env->segs[R_DS].selector);
- PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector);
- }
- PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector);
- PUSHW(ssp, esp, sp_mask, ESP);
- }
- PUSHW(ssp, esp, sp_mask, compute_eflags());
- PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);
- PUSHW(ssp, esp, sp_mask, old_eip);
- if (has_error_code) {
- PUSHW(ssp, esp, sp_mask, error_code);
- }
- }
-
- if (new_stack) {
- if (env->eflags & VM_MASK) {
- cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);
- cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0, 0);
- cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0, 0);
- cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0);
- }
- ss = (ss & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_SS, ss,
- ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);
- }
- SET_ESP(esp, sp_mask);
-
- selector = (selector & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_CS, selector,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2),
- e2);
- cpu_x86_set_cpl(env, dpl);
- env->eip = offset;
-
- /* interrupt gate clear IF mask */
- if ((type & 1) == 0) {
- env->eflags &= ~IF_MASK;
- }
- env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
-}
-
-#ifdef TARGET_X86_64
-
-#define PUSHQ(sp, val)\
-{\
- sp -= 8;\
- stq_kernel(sp, (val));\
-}
-
-#define POPQ(sp, val)\
-{\
- val = ldq_kernel(sp);\
- sp += 8;\
-}
-
-static inline target_ulong get_rsp_from_tss(int level)
-{
- int index;
-
-#if 0
- printf("TR: base=" TARGET_FMT_lx " limit=%x\n",
- env->tr.base, env->tr.limit);
-#endif
-
- if (!(env->tr.flags & DESC_P_MASK))
- cpu_abort(env, "invalid tss");
- index = 8 * level + 4;
- if ((index + 7) > env->tr.limit)
- raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
- return ldq_kernel(env->tr.base + index);
-}
-
-/* 64 bit interrupt */
-static void do_interrupt64(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw)
-{
- SegmentCache *dt;
- target_ulong ptr;
- int type, dpl, selector, cpl, ist;
- int has_error_code, new_stack;
- uint32_t e1, e2, e3, ss;
- target_ulong old_eip, esp, offset;
-
- has_error_code = 0;
- if (!is_int && !is_hw) {
- switch(intno) {
- case 8:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 17:
- has_error_code = 1;
- break;
- }
- }
- if (is_int)
- old_eip = next_eip;
- else
- old_eip = env->eip;
-
- dt = &env->idt;
- if (intno * 16 + 15 > dt->limit)
- raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
- ptr = dt->base + intno * 16;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
- e3 = ldl_kernel(ptr + 8);
- /* check gate type */
- type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
- switch(type) {
- case 14: /* 386 interrupt gate */
- case 15: /* 386 trap gate */
- break;
- default:
- raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
- break;
- }
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- /* check privledge if software int */
- if (is_int && dpl < cpl)
- raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
- /* check valid bit */
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, intno * 16 + 2);
- selector = e1 >> 16;
- offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);
- ist = e2 & 7;
- if ((selector & 0xfffc) == 0)
- raise_exception_err(EXCP0D_GPF, 0);
-
- if (load_segment(&e1, &e2, selector) != 0)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (dpl > cpl)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
- if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK))
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
- /* to inner priviledge */
- if (ist != 0)
- esp = get_rsp_from_tss(ist + 3);
- else
- esp = get_rsp_from_tss(dpl);
- esp &= ~0xfLL; /* align stack */
- ss = 0;
- new_stack = 1;
- } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
- /* to same priviledge */
- if (env->eflags & VM_MASK)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- new_stack = 0;
- if (ist != 0)
- esp = get_rsp_from_tss(ist + 3);
- else
- esp = ESP;
- esp &= ~0xfLL; /* align stack */
- dpl = cpl;
- } else {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- new_stack = 0; /* avoid warning */
- esp = 0; /* avoid warning */
- }
-
- PUSHQ(esp, env->segs[R_SS].selector);
- PUSHQ(esp, ESP);
- PUSHQ(esp, compute_eflags());
- PUSHQ(esp, env->segs[R_CS].selector);
- PUSHQ(esp, old_eip);
- if (has_error_code) {
- PUSHQ(esp, error_code);
- }
-
- if (new_stack) {
- ss = 0 | dpl;
- cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
- }
- ESP = esp;
-
- selector = (selector & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_CS, selector,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2),
- e2);
- cpu_x86_set_cpl(env, dpl);
- env->eip = offset;
-
- /* interrupt gate clear IF mask */
- if ((type & 1) == 0) {
- env->eflags &= ~IF_MASK;
- }
- env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
-}
-#endif
-
-void helper_syscall(int next_eip_addend)
-{
- int selector;
-
- if (!(env->efer & MSR_EFER_SCE)) {
- raise_exception_err(EXCP06_ILLOP, 0);
- }
- selector = (env->star >> 32) & 0xffff;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- int code64;
-
- ECX = env->eip + next_eip_addend;
- env->regs[11] = compute_eflags();
-
- code64 = env->hflags & HF_CS64_MASK;
-
- cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~env->fmask;
- if (code64)
- env->eip = env->lstar;
- else
- env->eip = env->cstar;
- } else
-#endif
- {
- ECX = (uint32_t)(env->eip + next_eip_addend);
-
- cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
- env->eip = (uint32_t)env->star;
- }
-}
-
-void helper_sysret(int dflag)
-{
- int cpl, selector;
-
- if (!(env->efer & MSR_EFER_SCE)) {
- raise_exception_err(EXCP06_ILLOP, 0);
- }
- cpl = env->hflags & HF_CPL_MASK;
- if (!(env->cr[0] & CR0_PE_MASK) || cpl != 0) {
- raise_exception_err(EXCP0D_GPF, 0);
- }
- selector = (env->star >> 48) & 0xffff;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- if (dflag == 2) {
- cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_P_MASK |
- DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
- DESC_L_MASK);
- env->eip = ECX;
- } else {
- cpu_x86_load_seg_cache(env, R_CS, selector | 3,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- env->eip = (uint32_t)ECX;
- }
- cpu_x86_load_seg_cache(env, R_SS, selector + 8,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_W_MASK | DESC_A_MASK);
- load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK |
- IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK);
- cpu_x86_set_cpl(env, 3);
- } else
-#endif
- {
- cpu_x86_load_seg_cache(env, R_CS, selector | 3,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- env->eip = (uint32_t)ECX;
- cpu_x86_load_seg_cache(env, R_SS, selector + 8,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_W_MASK | DESC_A_MASK);
- env->eflags |= IF_MASK;
- cpu_x86_set_cpl(env, 3);
- }
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- if (env->hflags & HF_LMA_MASK)
- CC_OP = CC_OP_EFLAGS;
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
-}
-
-/* real mode interrupt */
-static void do_interrupt_real(int intno, int is_int, int error_code,
- unsigned int next_eip)
-{
- SegmentCache *dt;
- target_ulong ptr, ssp;
- int selector;
- uint32_t offset, esp;
- uint32_t old_cs, old_eip;
-
- /* real mode (simpler !) */
- dt = &env->idt;
- if (intno * 4 + 3 > dt->limit)
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
- ptr = dt->base + intno * 4;
- offset = lduw_kernel(ptr);
- selector = lduw_kernel(ptr + 2);
- esp = ESP;
- ssp = env->segs[R_SS].base;
- if (is_int)
- old_eip = next_eip;
- else
- old_eip = env->eip;
- old_cs = env->segs[R_CS].selector;
- /* XXX: use SS segment size ? */
- PUSHW(ssp, esp, 0xffff, compute_eflags());
- PUSHW(ssp, esp, 0xffff, old_cs);
- PUSHW(ssp, esp, 0xffff, old_eip);
-
- /* update processor state */
- ESP = (ESP & ~0xffff) | (esp & 0xffff);
- env->eip = offset;
- env->segs[R_CS].selector = selector;
- env->segs[R_CS].base = (selector << 4);
- env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);
-}
-
-/* fake user mode interrupt */
-void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip)
-{
- SegmentCache *dt;
- target_ulong ptr;
- int dpl, cpl;
- uint32_t e2;
-
- dt = &env->idt;
- ptr = dt->base + (intno * 8);
- e2 = ldl_kernel(ptr + 4);
-
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- /* check privledge if software int */
- if (is_int && dpl < cpl)
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
-
- /* Since we emulate only user space, we cannot do more than
- exiting the emulation with the suitable exception and error
- code */
- if (is_int)
- EIP = next_eip;
-}
-
-/*
- * Begin execution of an interruption. is_int is TRUE if coming from
- * the int instruction. next_eip is the EIP value AFTER the interrupt
- * instruction. It is only relevant if is_int is TRUE.
- */
-void do_interrupt(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw)
-{
- if (loglevel & CPU_LOG_INT) {
- if ((env->cr[0] & CR0_PE_MASK)) {
- static int count;
- fprintf(logfile, "%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx,
- count, intno, error_code, is_int,
- env->hflags & HF_CPL_MASK,
- env->segs[R_CS].selector, EIP,
- (int)env->segs[R_CS].base + EIP,
- env->segs[R_SS].selector, ESP);
- if (intno == 0x0e) {
- fprintf(logfile, " CR2=" TARGET_FMT_lx, env->cr[2]);
- } else {
- fprintf(logfile, " EAX=" TARGET_FMT_lx, EAX);
- }
- fprintf(logfile, "\n");
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
-#if 0
- {
- int i;
- uint8_t *ptr;
- fprintf(logfile, " code=");
- ptr = env->segs[R_CS].base + env->eip;
- for(i = 0; i < 16; i++) {
- fprintf(logfile, " %02x", ldub(ptr + i));
- }
- fprintf(logfile, "\n");
- }
-#endif
- count++;
- }
- }
- if (env->cr[0] & CR0_PE_MASK) {
-#if TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- do_interrupt64(intno, is_int, error_code, next_eip, is_hw);
- } else
-#endif
- {
- do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
- }
- } else {
- do_interrupt_real(intno, is_int, error_code, next_eip);
- }
-}
-
-/*
- * Signal an interruption. It is executed in the main CPU loop.
- * is_int is TRUE if coming from the int instruction. next_eip is the
- * EIP value AFTER the interrupt instruction. It is only relevant if
- * is_int is TRUE.
- */
-void raise_interrupt(int intno, int is_int, int error_code,
- int next_eip_addend)
-{
- env->exception_index = intno;
- env->error_code = error_code;
- env->exception_is_int = is_int;
- env->exception_next_eip = env->eip + next_eip_addend;
- cpu_loop_exit();
-}
-
-/* same as raise_exception_err, but do not restore global registers */
-static void raise_exception_err_norestore(int exception_index, int error_code)
-{
- env->exception_index = exception_index;
- env->error_code = error_code;
- env->exception_is_int = 0;
- env->exception_next_eip = 0;
- longjmp(env->jmp_env, 1);
-}
-
-/* shortcuts to generate exceptions */
-
-void (raise_exception_err)(int exception_index, int error_code)
-{
- raise_interrupt(exception_index, 0, error_code, 0);
-}
-
-void raise_exception(int exception_index)
-{
- raise_interrupt(exception_index, 0, 0, 0);
-}
-
-/* SMM support */
-
-#if defined(CONFIG_USER_ONLY)
-
-void do_smm_enter(void)
-{
-}
-
-void helper_rsm(void)
-{
-}
-
-#else
-
-#ifdef TARGET_X86_64
-#define SMM_REVISION_ID 0x00020064
-#else
-#define SMM_REVISION_ID 0x00020000
-#endif
-
-void do_smm_enter(void)
-{
- target_ulong sm_state;
- SegmentCache *dt;
- int i, offset;
-
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "SMM: enter\n");
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
-
- env->hflags |= HF_SMM_MASK;
- cpu_smm_update(env);
-
- sm_state = env->smbase + 0x8000;
-
-#ifdef TARGET_X86_64
- for(i = 0; i < 6; i++) {
- dt = &env->segs[i];
- offset = 0x7e00 + i * 16;
- stw_phys(sm_state + offset, dt->selector);
- stw_phys(sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
- stl_phys(sm_state + offset + 4, dt->limit);
- stq_phys(sm_state + offset + 8, dt->base);
- }
-
- stq_phys(sm_state + 0x7e68, env->gdt.base);
- stl_phys(sm_state + 0x7e64, env->gdt.limit);
-
- stw_phys(sm_state + 0x7e70, env->ldt.selector);
- stq_phys(sm_state + 0x7e78, env->ldt.base);
- stl_phys(sm_state + 0x7e74, env->ldt.limit);
- stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
-
- stq_phys(sm_state + 0x7e88, env->idt.base);
- stl_phys(sm_state + 0x7e84, env->idt.limit);
-
- stw_phys(sm_state + 0x7e90, env->tr.selector);
- stq_phys(sm_state + 0x7e98, env->tr.base);
- stl_phys(sm_state + 0x7e94, env->tr.limit);
- stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
-
- stq_phys(sm_state + 0x7ed0, env->efer);
-
- stq_phys(sm_state + 0x7ff8, EAX);
- stq_phys(sm_state + 0x7ff0, ECX);
- stq_phys(sm_state + 0x7fe8, EDX);
- stq_phys(sm_state + 0x7fe0, EBX);
- stq_phys(sm_state + 0x7fd8, ESP);
- stq_phys(sm_state + 0x7fd0, EBP);
- stq_phys(sm_state + 0x7fc8, ESI);
- stq_phys(sm_state + 0x7fc0, EDI);
- for(i = 8; i < 16; i++)
- stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]);
- stq_phys(sm_state + 0x7f78, env->eip);
- stl_phys(sm_state + 0x7f70, compute_eflags());
- stl_phys(sm_state + 0x7f68, env->dr[6]);
- stl_phys(sm_state + 0x7f60, env->dr[7]);
-
- stl_phys(sm_state + 0x7f48, env->cr[4]);
- stl_phys(sm_state + 0x7f50, env->cr[3]);
- stl_phys(sm_state + 0x7f58, env->cr[0]);
-
- stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
- stl_phys(sm_state + 0x7f00, env->smbase);
-#else
- stl_phys(sm_state + 0x7ffc, env->cr[0]);
- stl_phys(sm_state + 0x7ff8, env->cr[3]);
- stl_phys(sm_state + 0x7ff4, compute_eflags());
- stl_phys(sm_state + 0x7ff0, env->eip);
- stl_phys(sm_state + 0x7fec, EDI);
- stl_phys(sm_state + 0x7fe8, ESI);
- stl_phys(sm_state + 0x7fe4, EBP);
- stl_phys(sm_state + 0x7fe0, ESP);
- stl_phys(sm_state + 0x7fdc, EBX);
- stl_phys(sm_state + 0x7fd8, EDX);
- stl_phys(sm_state + 0x7fd4, ECX);
- stl_phys(sm_state + 0x7fd0, EAX);
- stl_phys(sm_state + 0x7fcc, env->dr[6]);
- stl_phys(sm_state + 0x7fc8, env->dr[7]);
-
- stl_phys(sm_state + 0x7fc4, env->tr.selector);
- stl_phys(sm_state + 0x7f64, env->tr.base);
- stl_phys(sm_state + 0x7f60, env->tr.limit);
- stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
-
- stl_phys(sm_state + 0x7fc0, env->ldt.selector);
- stl_phys(sm_state + 0x7f80, env->ldt.base);
- stl_phys(sm_state + 0x7f7c, env->ldt.limit);
- stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
-
- stl_phys(sm_state + 0x7f74, env->gdt.base);
- stl_phys(sm_state + 0x7f70, env->gdt.limit);
-
- stl_phys(sm_state + 0x7f58, env->idt.base);
- stl_phys(sm_state + 0x7f54, env->idt.limit);
-
- for(i = 0; i < 6; i++) {
- dt = &env->segs[i];
- if (i < 3)
- offset = 0x7f84 + i * 12;
- else
- offset = 0x7f2c + (i - 3) * 12;
- stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector);
- stl_phys(sm_state + offset + 8, dt->base);
- stl_phys(sm_state + offset + 4, dt->limit);
- stl_phys(sm_state + offset, (dt->flags >> 8) & 0xf0ff);
- }
- stl_phys(sm_state + 0x7f14, env->cr[4]);
-
- stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
- stl_phys(sm_state + 0x7ef8, env->smbase);
-#endif
- /* init SMM cpu state */
-
-#ifdef TARGET_X86_64
- env->efer = 0;
- env->hflags &= ~HF_LMA_MASK;
-#endif
- load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
- env->eip = 0x00008000;
- cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
- 0xffffffff, 0);
- cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0);
- cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0);
- cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
- cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
- cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
-
- cpu_x86_update_cr0(env,
- env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
- cpu_x86_update_cr4(env, 0);
- env->dr[7] = 0x00000400;
- CC_OP = CC_OP_EFLAGS;
-}
-
-void helper_rsm(void)
-{
- target_ulong sm_state;
- int i, offset;
- uint32_t val;
-
- sm_state = env->smbase + 0x8000;
-#ifdef TARGET_X86_64
- env->efer = ldq_phys(sm_state + 0x7ed0);
- if (env->efer & MSR_EFER_LMA)
- env->hflags |= HF_LMA_MASK;
- else
- env->hflags &= ~HF_LMA_MASK;
-
- for(i = 0; i < 6; i++) {
- offset = 0x7e00 + i * 16;
- cpu_x86_load_seg_cache(env, i,
- lduw_phys(sm_state + offset),
- ldq_phys(sm_state + offset + 8),
- ldl_phys(sm_state + offset + 4),
- (lduw_phys(sm_state + offset + 2) & 0xf0ff) << 8);
- }
-
- env->gdt.base = ldq_phys(sm_state + 0x7e68);
- env->gdt.limit = ldl_phys(sm_state + 0x7e64);
-
- env->ldt.selector = lduw_phys(sm_state + 0x7e70);
- env->ldt.base = ldq_phys(sm_state + 0x7e78);
- env->ldt.limit = ldl_phys(sm_state + 0x7e74);
- env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8;
-
- env->idt.base = ldq_phys(sm_state + 0x7e88);
- env->idt.limit = ldl_phys(sm_state + 0x7e84);
-
- env->tr.selector = lduw_phys(sm_state + 0x7e90);
- env->tr.base = ldq_phys(sm_state + 0x7e98);
- env->tr.limit = ldl_phys(sm_state + 0x7e94);
- env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
-
- EAX = ldq_phys(sm_state + 0x7ff8);
- ECX = ldq_phys(sm_state + 0x7ff0);
- EDX = ldq_phys(sm_state + 0x7fe8);
- EBX = ldq_phys(sm_state + 0x7fe0);
- ESP = ldq_phys(sm_state + 0x7fd8);
- EBP = ldq_phys(sm_state + 0x7fd0);
- ESI = ldq_phys(sm_state + 0x7fc8);
- EDI = ldq_phys(sm_state + 0x7fc0);
- for(i = 8; i < 16; i++)
- env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8);
- env->eip = ldq_phys(sm_state + 0x7f78);
- load_eflags(ldl_phys(sm_state + 0x7f70),
- ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
- env->dr[6] = ldl_phys(sm_state + 0x7f68);
- env->dr[7] = ldl_phys(sm_state + 0x7f60);
-
- cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f48));
- cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7f50));
- cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7f58));
-
- val = ldl_phys(sm_state + 0x7efc); /* revision ID */
- if (val & 0x20000) {
- env->smbase = ldl_phys(sm_state + 0x7f00) & ~0x7fff;
- }
-#else
- cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc));
- cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8));
- load_eflags(ldl_phys(sm_state + 0x7ff4),
- ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
- env->eip = ldl_phys(sm_state + 0x7ff0);
- EDI = ldl_phys(sm_state + 0x7fec);
- ESI = ldl_phys(sm_state + 0x7fe8);
- EBP = ldl_phys(sm_state + 0x7fe4);
- ESP = ldl_phys(sm_state + 0x7fe0);
- EBX = ldl_phys(sm_state + 0x7fdc);
- EDX = ldl_phys(sm_state + 0x7fd8);
- ECX = ldl_phys(sm_state + 0x7fd4);
- EAX = ldl_phys(sm_state + 0x7fd0);
- env->dr[6] = ldl_phys(sm_state + 0x7fcc);
- env->dr[7] = ldl_phys(sm_state + 0x7fc8);
-
- env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff;
- env->tr.base = ldl_phys(sm_state + 0x7f64);
- env->tr.limit = ldl_phys(sm_state + 0x7f60);
- env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8;
-
- env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff;
- env->ldt.base = ldl_phys(sm_state + 0x7f80);
- env->ldt.limit = ldl_phys(sm_state + 0x7f7c);
- env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8;
-
- env->gdt.base = ldl_phys(sm_state + 0x7f74);
- env->gdt.limit = ldl_phys(sm_state + 0x7f70);
-
- env->idt.base = ldl_phys(sm_state + 0x7f58);
- env->idt.limit = ldl_phys(sm_state + 0x7f54);
-
- for(i = 0; i < 6; i++) {
- if (i < 3)
- offset = 0x7f84 + i * 12;
- else
- offset = 0x7f2c + (i - 3) * 12;
- cpu_x86_load_seg_cache(env, i,
- ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff,
- ldl_phys(sm_state + offset + 8),
- ldl_phys(sm_state + offset + 4),
- (ldl_phys(sm_state + offset) & 0xf0ff) << 8);
- }
- cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f14));
-
- val = ldl_phys(sm_state + 0x7efc); /* revision ID */
- if (val & 0x20000) {
- env->smbase = ldl_phys(sm_state + 0x7ef8) & ~0x7fff;
- }
-#endif
- CC_OP = CC_OP_EFLAGS;
- env->hflags &= ~HF_SMM_MASK;
- cpu_smm_update(env);
-
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "SMM: after RSM\n");
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
-}
-
-#endif /* !CONFIG_USER_ONLY */
-
-
-#ifdef BUGGY_GCC_DIV64
-/* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we
- call it from another function */
-uint32_t div32(uint64_t *q_ptr, uint64_t num, uint32_t den)
-{
- *q_ptr = num / den;
- return num % den;
-}
-
-int32_t idiv32(int64_t *q_ptr, int64_t num, int32_t den)
-{
- *q_ptr = num / den;
- return num % den;
-}
-#endif
-
-void helper_divl_EAX_T0(void)
-{
- unsigned int den, r;
- uint64_t num, q;
-
- num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
- den = T0;
- if (den == 0) {
- raise_exception(EXCP00_DIVZ);
- }
-#ifdef BUGGY_GCC_DIV64
- r = div32(&q, num, den);
-#else
- q = (num / den);
- r = (num % den);
-#endif
- if (q > 0xffffffff)
- raise_exception(EXCP00_DIVZ);
- EAX = (uint32_t)q;
- EDX = (uint32_t)r;
-}
-
-void helper_idivl_EAX_T0(void)
-{
- int den, r;
- int64_t num, q;
-
- num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
- den = T0;
- if (den == 0) {
- raise_exception(EXCP00_DIVZ);
- }
-#ifdef BUGGY_GCC_DIV64
- r = idiv32(&q, num, den);
-#else
- q = (num / den);
- r = (num % den);
-#endif
- if (q != (int32_t)q)
- raise_exception(EXCP00_DIVZ);
- EAX = (uint32_t)q;
- EDX = (uint32_t)r;
-}
-
-void helper_cmpxchg8b(void)
-{
- uint64_t d;
- int eflags;
-
- eflags = cc_table[CC_OP].compute_all();
- d = ldq(A0);
- if (d == (((uint64_t)EDX << 32) | EAX)) {
- stq(A0, ((uint64_t)ECX << 32) | EBX);
- eflags |= CC_Z;
- } else {
- EDX = d >> 32;
- EAX = d;
- eflags &= ~CC_Z;
- }
- CC_SRC = eflags;
-}
-
-void helper_cpuid(void)
-{
- uint32_t index;
- index = (uint32_t)EAX;
-
- /* test if maximum index reached */
- if (index & 0x80000000) {
- if (index > env->cpuid_xlevel)
- index = env->cpuid_level;
- } else {
- if (index > env->cpuid_level)
- index = env->cpuid_level;
- }
-
- switch(index) {
- case 0:
- EAX = env->cpuid_level;
- EBX = env->cpuid_vendor1;
- EDX = env->cpuid_vendor2;
- ECX = env->cpuid_vendor3;
- break;
- case 1:
- EAX = env->cpuid_version;
- EBX = 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
- ECX = env->cpuid_ext_features;
- EDX = env->cpuid_features;
- break;
- case 2:
- /* cache info: needed for Pentium Pro compatibility */
- EAX = 0x410601;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- case 0x80000000:
- EAX = env->cpuid_xlevel;
- EBX = env->cpuid_vendor1;
- EDX = env->cpuid_vendor2;
- ECX = env->cpuid_vendor3;
- break;
- case 0x80000001:
- EAX = env->cpuid_features;
- EBX = 0;
- ECX = 0;
- EDX = env->cpuid_ext2_features;
- break;
- case 0x80000002:
- case 0x80000003:
- case 0x80000004:
- EAX = env->cpuid_model[(index - 0x80000002) * 4 + 0];
- EBX = env->cpuid_model[(index - 0x80000002) * 4 + 1];
- ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2];
- EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3];
- break;
- case 0x80000005:
- /* cache info (L1 cache) */
- EAX = 0x01ff01ff;
- EBX = 0x01ff01ff;
- ECX = 0x40020140;
- EDX = 0x40020140;
- break;
- case 0x80000006:
- /* cache info (L2 cache) */
- EAX = 0;
- EBX = 0x42004200;
- ECX = 0x02008140;
- EDX = 0;
- break;
- case 0x80000008:
- /* virtual & phys address size in low 2 bytes. */
- EAX = 0x00003028;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- default:
- /* reserved values: zero */
- EAX = 0;
- EBX = 0;
- ECX = 0;
- EDX = 0;
- break;
- }
-}
-
-void helper_enter_level(int level, int data32)
-{
- target_ulong ssp;
- uint32_t esp_mask, esp, ebp;
-
- esp_mask = get_sp_mask(env->segs[R_SS].flags);
- ssp = env->segs[R_SS].base;
- ebp = EBP;
- esp = ESP;
- if (data32) {
- /* 32 bit */
- esp -= 4;
- while (--level) {
- esp -= 4;
- ebp -= 4;
- stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
- }
- esp -= 4;
- stl(ssp + (esp & esp_mask), T1);
- } else {
- /* 16 bit */
- esp -= 2;
- while (--level) {
- esp -= 2;
- ebp -= 2;
- stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
- }
- esp -= 2;
- stw(ssp + (esp & esp_mask), T1);
- }
-}
-
-#ifdef TARGET_X86_64
-void helper_enter64_level(int level, int data64)
-{
- target_ulong esp, ebp;
- ebp = EBP;
- esp = ESP;
-
- if (data64) {
- /* 64 bit */
- esp -= 8;
- while (--level) {
- esp -= 8;
- ebp -= 8;
- stq(esp, ldq(ebp));
- }
- esp -= 8;
- stq(esp, T1);
- } else {
- /* 16 bit */
- esp -= 2;
- while (--level) {
- esp -= 2;
- ebp -= 2;
- stw(esp, lduw(ebp));
- }
- esp -= 2;
- stw(esp, T1);
- }
-}
-#endif
-
-void helper_lldt_T0(void)
-{
- int selector;
- SegmentCache *dt;
- uint32_t e1, e2;
- int index, entry_limit;
- target_ulong ptr;
-
- selector = T0 & 0xffff;
- if ((selector & 0xfffc) == 0) {
- /* XXX: NULL selector case: invalid LDT */
- env->ldt.base = 0;
- env->ldt.limit = 0;
- } else {
- if (selector & 0x4)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- dt = &env->gdt;
- index = selector & ~7;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK)
- entry_limit = 15;
- else
-#endif
- entry_limit = 7;
- if ((index + entry_limit) > dt->limit)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
- if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- uint32_t e3;
- e3 = ldl_kernel(ptr + 8);
- load_seg_cache_raw_dt(&env->ldt, e1, e2);
- env->ldt.base |= (target_ulong)e3 << 32;
- } else
-#endif
- {
- load_seg_cache_raw_dt(&env->ldt, e1, e2);
- }
- }
- env->ldt.selector = selector;
-}
-
-void helper_ltr_T0(void)
-{
- int selector;
- SegmentCache *dt;
- uint32_t e1, e2;
- int index, type, entry_limit;
- target_ulong ptr;
-
- selector = T0 & 0xffff;
- if ((selector & 0xfffc) == 0) {
- /* NULL selector case: invalid TR */
- env->tr.base = 0;
- env->tr.limit = 0;
- env->tr.flags = 0;
- } else {
- if (selector & 0x4)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- dt = &env->gdt;
- index = selector & ~7;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK)
- entry_limit = 15;
- else
-#endif
- entry_limit = 7;
- if ((index + entry_limit) > dt->limit)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
- type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
- if ((e2 & DESC_S_MASK) ||
- (type != 1 && type != 9))
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- uint32_t e3;
- e3 = ldl_kernel(ptr + 8);
- load_seg_cache_raw_dt(&env->tr, e1, e2);
- env->tr.base |= (target_ulong)e3 << 32;
- } else
-#endif
- {
- load_seg_cache_raw_dt(&env->tr, e1, e2);
- }
- e2 |= DESC_TSS_BUSY_MASK;
- stl_kernel(ptr + 4, e2);
- }
- env->tr.selector = selector;
-}
-
-/* only works if protected mode and not VM86. seg_reg must be != R_CS */
-void load_seg(int seg_reg, int selector)
-{
- uint32_t e1, e2;
- int cpl, dpl, rpl;
- SegmentCache *dt;
- int index;
- target_ulong ptr;
-
- selector &= 0xffff;
- cpl = env->hflags & HF_CPL_MASK;
- if ((selector & 0xfffc) == 0) {
- /* null selector case */
- if (seg_reg == R_SS
-#ifdef TARGET_X86_64
- && (!(env->hflags & HF_CS64_MASK) || cpl == 3)
-#endif
- )
- raise_exception_err(EXCP0D_GPF, 0);
- cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
- } else {
-
- if (selector & 0x4)
- dt = &env->ldt;
- else
- dt = &env->gdt;
- index = selector & ~7;
- if ((index + 7) > dt->limit)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
-
- if (!(e2 & DESC_S_MASK))
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- rpl = selector & 3;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (seg_reg == R_SS) {
- /* must be writable segment */
- if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK))
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (rpl != cpl || dpl != cpl)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- } else {
- /* must be readable segment */
- if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
-
- if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
- /* if not conforming code, test rights */
- if (dpl < cpl || dpl < rpl)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- }
- }
-
- if (!(e2 & DESC_P_MASK)) {
- if (seg_reg == R_SS)
- raise_exception_err(EXCP0C_STACK, selector & 0xfffc);
- else
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
- }
-
- /* set the access bit if not already set */
- if (!(e2 & DESC_A_MASK)) {
- e2 |= DESC_A_MASK;
- stl_kernel(ptr + 4, e2);
- }
-
- cpu_x86_load_seg_cache(env, seg_reg, selector,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2),
- e2);
-#if 0
- fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n",
- selector, (unsigned long)sc->base, sc->limit, sc->flags);
-#endif
- }
-}
-
-/* protected mode jump */
-void helper_ljmp_protected_T0_T1(int next_eip_addend)
-{
- int new_cs, gate_cs, type;
- uint32_t e1, e2, cpl, dpl, rpl, limit;
- target_ulong new_eip, next_eip;
-
- new_cs = T0;
- new_eip = T1;
- if ((new_cs & 0xfffc) == 0)
- raise_exception_err(EXCP0D_GPF, 0);
- if (load_segment(&e1, &e2, new_cs) != 0)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- cpl = env->hflags & HF_CPL_MASK;
- if (e2 & DESC_S_MASK) {
- if (!(e2 & DESC_CS_MASK))
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (e2 & DESC_C_MASK) {
- /* conforming code segment */
- if (dpl > cpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- } else {
- /* non conforming code segment */
- rpl = new_cs & 3;
- if (rpl > cpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- if (dpl != cpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- }
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
- limit = get_seg_limit(e1, e2);
- if (new_eip > limit &&
- !(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK))
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
- get_seg_base(e1, e2), limit, e2);
- EIP = new_eip;
- } else {
- /* jump to call or task gate */
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- rpl = new_cs & 3;
- cpl = env->hflags & HF_CPL_MASK;
- type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
- switch(type) {
- case 1: /* 286 TSS */
- case 9: /* 386 TSS */
- case 5: /* task gate */
- if (dpl < cpl || dpl < rpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- next_eip = env->eip + next_eip_addend;
- switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
- CC_OP = CC_OP_EFLAGS;
- break;
- case 4: /* 286 call gate */
- case 12: /* 386 call gate */
- if ((dpl < cpl) || (dpl < rpl))
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
- gate_cs = e1 >> 16;
- new_eip = (e1 & 0xffff);
- if (type == 12)
- new_eip |= (e2 & 0xffff0000);
- if (load_segment(&e1, &e2, gate_cs) != 0)
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- /* must be code segment */
- if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) !=
- (DESC_S_MASK | DESC_CS_MASK)))
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
- if (((e2 & DESC_C_MASK) && (dpl > cpl)) ||
- (!(e2 & DESC_C_MASK) && (dpl != cpl)))
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
- limit = get_seg_limit(e1, e2);
- if (new_eip > limit)
- raise_exception_err(EXCP0D_GPF, 0);
- cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl,
- get_seg_base(e1, e2), limit, e2);
- EIP = new_eip;
- break;
- default:
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- break;
- }
- }
-}
-
-/* real mode call */
-void helper_lcall_real_T0_T1(int shift, int next_eip)
-{
- int new_cs, new_eip;
- uint32_t esp, esp_mask;
- target_ulong ssp;
-
- new_cs = T0;
- new_eip = T1;
- esp = ESP;
- esp_mask = get_sp_mask(env->segs[R_SS].flags);
- ssp = env->segs[R_SS].base;
- if (shift) {
- PUSHL(ssp, esp, esp_mask, env->segs[R_CS].selector);
- PUSHL(ssp, esp, esp_mask, next_eip);
- } else {
- PUSHW(ssp, esp, esp_mask, env->segs[R_CS].selector);
- PUSHW(ssp, esp, esp_mask, next_eip);
- }
-
- SET_ESP(esp, esp_mask);
- env->eip = new_eip;
- env->segs[R_CS].selector = new_cs;
- env->segs[R_CS].base = (new_cs << 4);
-}
-
-/* protected mode call */
-void helper_lcall_protected_T0_T1(int shift, int next_eip_addend)
-{
- int new_cs, new_stack, i;
- uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
- uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
- uint32_t val, limit, old_sp_mask;
- target_ulong ssp, old_ssp, next_eip, new_eip;
-
- new_cs = T0;
- new_eip = T1;
- next_eip = env->eip + next_eip_addend;
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "lcall %04x:%08x s=%d\n",
- new_cs, (uint32_t)new_eip, shift);
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
-#endif
- if ((new_cs & 0xfffc) == 0)
- raise_exception_err(EXCP0D_GPF, 0);
- if (load_segment(&e1, &e2, new_cs) != 0)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- cpl = env->hflags & HF_CPL_MASK;
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "desc=%08x:%08x\n", e1, e2);
- }
-#endif
- if (e2 & DESC_S_MASK) {
- if (!(e2 & DESC_CS_MASK))
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (e2 & DESC_C_MASK) {
- /* conforming code segment */
- if (dpl > cpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- } else {
- /* non conforming code segment */
- rpl = new_cs & 3;
- if (rpl > cpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- if (dpl != cpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- }
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
-
-#ifdef TARGET_X86_64
- /* XXX: check 16/32 bit cases in long mode */
- if (shift == 2) {
- target_ulong rsp;
- /* 64 bit case */
- rsp = ESP;
- PUSHQ(rsp, env->segs[R_CS].selector);
- PUSHQ(rsp, next_eip);
- /* from this point, not restartable */
- ESP = rsp;
- cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2), e2);
- EIP = new_eip;
- } else
-#endif
- {
- sp = ESP;
- sp_mask = get_sp_mask(env->segs[R_SS].flags);
- ssp = env->segs[R_SS].base;
- if (shift) {
- PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);
- PUSHL(ssp, sp, sp_mask, next_eip);
- } else {
- PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);
- PUSHW(ssp, sp, sp_mask, next_eip);
- }
-
- limit = get_seg_limit(e1, e2);
- if (new_eip > limit)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- /* from this point, not restartable */
- SET_ESP(sp, sp_mask);
- cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
- get_seg_base(e1, e2), limit, e2);
- EIP = new_eip;
- }
- } else {
- /* check gate type */
- type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- rpl = new_cs & 3;
- switch(type) {
- case 1: /* available 286 TSS */
- case 9: /* available 386 TSS */
- case 5: /* task gate */
- if (dpl < cpl || dpl < rpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- switch_tss(new_cs, e1, e2, SWITCH_TSS_CALL, next_eip);
- CC_OP = CC_OP_EFLAGS;
- return;
- case 4: /* 286 call gate */
- case 12: /* 386 call gate */
- break;
- default:
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- break;
- }
- shift = type >> 3;
-
- if (dpl < cpl || dpl < rpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- /* check valid bit */
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
- selector = e1 >> 16;
- offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
- param_count = e2 & 0x1f;
- if ((selector & 0xfffc) == 0)
- raise_exception_err(EXCP0D_GPF, 0);
-
- if (load_segment(&e1, &e2, selector) != 0)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (dpl > cpl)
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
-
- if (!(e2 & DESC_C_MASK) && dpl < cpl) {
- /* to inner priviledge */
- get_ss_esp_from_tss(&ss, &sp, dpl);
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL)
- fprintf(logfile, "new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n",
- ss, sp, param_count, ESP);
-#endif
- if ((ss & 0xfffc) == 0)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if ((ss & 3) != dpl)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if (load_segment(&ss_e1, &ss_e2, ss) != 0)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
- if (ss_dpl != dpl)
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if (!(ss_e2 & DESC_S_MASK) ||
- (ss_e2 & DESC_CS_MASK) ||
- !(ss_e2 & DESC_W_MASK))
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
- if (!(ss_e2 & DESC_P_MASK))
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
-
- // push_size = ((param_count * 2) + 8) << shift;
-
- old_sp_mask = get_sp_mask(env->segs[R_SS].flags);
- old_ssp = env->segs[R_SS].base;
-
- sp_mask = get_sp_mask(ss_e2);
- ssp = get_seg_base(ss_e1, ss_e2);
- if (shift) {
- PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);
- PUSHL(ssp, sp, sp_mask, ESP);
- for(i = param_count - 1; i >= 0; i--) {
- val = ldl_kernel(old_ssp + ((ESP + i * 4) & old_sp_mask));
- PUSHL(ssp, sp, sp_mask, val);
- }
- } else {
- PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);
- PUSHW(ssp, sp, sp_mask, ESP);
- for(i = param_count - 1; i >= 0; i--) {
- val = lduw_kernel(old_ssp + ((ESP + i * 2) & old_sp_mask));
- PUSHW(ssp, sp, sp_mask, val);
- }
- }
- new_stack = 1;
- } else {
- /* to same priviledge */
- sp = ESP;
- sp_mask = get_sp_mask(env->segs[R_SS].flags);
- ssp = env->segs[R_SS].base;
- // push_size = (4 << shift);
- new_stack = 0;
- }
-
- if (shift) {
- PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);
- PUSHL(ssp, sp, sp_mask, next_eip);
- } else {
- PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);
- PUSHW(ssp, sp, sp_mask, next_eip);
- }
-
- /* from this point, not restartable */
-
- if (new_stack) {
- ss = (ss & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_SS, ss,
- ssp,
- get_seg_limit(ss_e1, ss_e2),
- ss_e2);
- }
-
- selector = (selector & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_CS, selector,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2),
- e2);
- cpu_x86_set_cpl(env, dpl);
- SET_ESP(sp, sp_mask);
- EIP = offset;
- }
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
-}
-
-/* real and vm86 mode iret */
-void helper_iret_real(int shift)
-{
- uint32_t sp, new_cs, new_eip, new_eflags, sp_mask;
- target_ulong ssp;
- int eflags_mask;
-
- sp_mask = 0xffff; /* XXXX: use SS segment size ? */
- sp = ESP;
- ssp = env->segs[R_SS].base;
- if (shift == 1) {
- /* 32 bits */
- POPL(ssp, sp, sp_mask, new_eip);
- POPL(ssp, sp, sp_mask, new_cs);
- new_cs &= 0xffff;
- POPL(ssp, sp, sp_mask, new_eflags);
- } else {
- /* 16 bits */
- POPW(ssp, sp, sp_mask, new_eip);
- POPW(ssp, sp, sp_mask, new_cs);
- POPW(ssp, sp, sp_mask, new_eflags);
- }
- ESP = (ESP & ~sp_mask) | (sp & sp_mask);
- load_seg_vm(R_CS, new_cs);
- env->eip = new_eip;
- if (env->eflags & VM_MASK)
- eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | NT_MASK;
- else
- eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | RF_MASK | NT_MASK;
- if (shift == 0)
- eflags_mask &= 0xffff;
- load_eflags(new_eflags, eflags_mask);
-}
-
-static inline void validate_seg(int seg_reg, int cpl)
-{
- int dpl;
- uint32_t e2;
-
- /* XXX: on x86_64, we do not want to nullify FS and GS because
- they may still contain a valid base. I would be interested to
- know how a real x86_64 CPU behaves */
- if ((seg_reg == R_FS || seg_reg == R_GS) &&
- (env->segs[seg_reg].selector & 0xfffc) == 0)
- return;
-
- e2 = env->segs[seg_reg].flags;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
- /* data or non conforming code segment */
- if (dpl < cpl) {
- cpu_x86_load_seg_cache(env, seg_reg, 0, 0, 0, 0);
- }
- }
-}
-
-/* protected mode iret */
-static inline void helper_ret_protected(int shift, int is_iret, int addend)
-{
- uint32_t new_cs, new_eflags, new_ss;
- uint32_t new_es, new_ds, new_fs, new_gs;
- uint32_t e1, e2, ss_e1, ss_e2;
- int cpl, dpl, rpl, eflags_mask, iopl;
- target_ulong ssp, sp, new_eip, new_esp, sp_mask;
-
-#ifdef TARGET_X86_64
- if (shift == 2)
- sp_mask = -1;
- else
-#endif
- sp_mask = get_sp_mask(env->segs[R_SS].flags);
- sp = ESP;
- ssp = env->segs[R_SS].base;
- new_eflags = 0; /* avoid warning */
-#ifdef TARGET_X86_64
- if (shift == 2) {
- POPQ(sp, new_eip);
- POPQ(sp, new_cs);
- new_cs &= 0xffff;
- if (is_iret) {
- POPQ(sp, new_eflags);
- }
- } else
-#endif
- if (shift == 1) {
- /* 32 bits */
- POPL(ssp, sp, sp_mask, new_eip);
- POPL(ssp, sp, sp_mask, new_cs);
- new_cs &= 0xffff;
- if (is_iret) {
- POPL(ssp, sp, sp_mask, new_eflags);
- if (new_eflags & VM_MASK)
- goto return_to_vm86;
- }
- } else {
- /* 16 bits */
- POPW(ssp, sp, sp_mask, new_eip);
- POPW(ssp, sp, sp_mask, new_cs);
- if (is_iret)
- POPW(ssp, sp, sp_mask, new_eflags);
- }
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n",
- new_cs, new_eip, shift, addend);
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
-#endif
- if ((new_cs & 0xfffc) == 0)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- if (load_segment(&e1, &e2, new_cs) != 0)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- if (!(e2 & DESC_S_MASK) ||
- !(e2 & DESC_CS_MASK))
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- cpl = env->hflags & HF_CPL_MASK;
- rpl = new_cs & 3;
- if (rpl < cpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- if (e2 & DESC_C_MASK) {
- if (dpl > rpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- } else {
- if (dpl != rpl)
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
- }
- if (!(e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
-
- sp += addend;
- if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) ||
- ((env->hflags & HF_CS64_MASK) && !is_iret))) {
- /* return to same priledge level */
- cpu_x86_load_seg_cache(env, R_CS, new_cs,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2),
- e2);
- } else {
- /* return to different priviledge level */
-#ifdef TARGET_X86_64
- if (shift == 2) {
- POPQ(sp, new_esp);
- POPQ(sp, new_ss);
- new_ss &= 0xffff;
- } else
-#endif
- if (shift == 1) {
- /* 32 bits */
- POPL(ssp, sp, sp_mask, new_esp);
- POPL(ssp, sp, sp_mask, new_ss);
- new_ss &= 0xffff;
- } else {
- /* 16 bits */
- POPW(ssp, sp, sp_mask, new_esp);
- POPW(ssp, sp, sp_mask, new_ss);
- }
-#ifdef DEBUG_PCALL
- if (loglevel & CPU_LOG_PCALL) {
- fprintf(logfile, "new ss:esp=%04x:" TARGET_FMT_lx "\n",
- new_ss, new_esp);
- }
-#endif
- if ((new_ss & 0xfffc) == 0) {
-#ifdef TARGET_X86_64
- /* NULL ss is allowed in long mode if cpl != 3*/
- /* XXX: test CS64 ? */
- if ((env->hflags & HF_LMA_MASK) && rpl != 3) {
- cpu_x86_load_seg_cache(env, R_SS, new_ss,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
- DESC_W_MASK | DESC_A_MASK);
- ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */
- } else
-#endif
- {
- raise_exception_err(EXCP0D_GPF, 0);
- }
- } else {
- if ((new_ss & 3) != rpl)
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
- if (load_segment(&ss_e1, &ss_e2, new_ss) != 0)
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
- if (!(ss_e2 & DESC_S_MASK) ||
- (ss_e2 & DESC_CS_MASK) ||
- !(ss_e2 & DESC_W_MASK))
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
- dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
- if (dpl != rpl)
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
- if (!(ss_e2 & DESC_P_MASK))
- raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
- cpu_x86_load_seg_cache(env, R_SS, new_ss,
- get_seg_base(ss_e1, ss_e2),
- get_seg_limit(ss_e1, ss_e2),
- ss_e2);
- }
-
- cpu_x86_load_seg_cache(env, R_CS, new_cs,
- get_seg_base(e1, e2),
- get_seg_limit(e1, e2),
- e2);
- cpu_x86_set_cpl(env, rpl);
- sp = new_esp;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK)
- sp_mask = -1;
- else
-#endif
- sp_mask = get_sp_mask(ss_e2);
-
- /* validate data segments */
- validate_seg(R_ES, rpl);
- validate_seg(R_DS, rpl);
- validate_seg(R_FS, rpl);
- validate_seg(R_GS, rpl);
-
- sp += addend;
- }
- SET_ESP(sp, sp_mask);
- env->eip = new_eip;
- if (is_iret) {
- /* NOTE: 'cpl' is the _old_ CPL */
- eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK;
- if (cpl == 0)
- eflags_mask |= IOPL_MASK;
- iopl = (env->eflags >> IOPL_SHIFT) & 3;
- if (cpl <= iopl)
- eflags_mask |= IF_MASK;
- if (shift == 0)
- eflags_mask &= 0xffff;
- load_eflags(new_eflags, eflags_mask);
- }
- return;
-
- return_to_vm86:
- POPL(ssp, sp, sp_mask, new_esp);
- POPL(ssp, sp, sp_mask, new_ss);
- POPL(ssp, sp, sp_mask, new_es);
- POPL(ssp, sp, sp_mask, new_ds);
- POPL(ssp, sp, sp_mask, new_fs);
- POPL(ssp, sp, sp_mask, new_gs);
-
- /* modify processor state */
- load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK |
- IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK);
- load_seg_vm(R_CS, new_cs & 0xffff);
- cpu_x86_set_cpl(env, 3);
- load_seg_vm(R_SS, new_ss & 0xffff);
- load_seg_vm(R_ES, new_es & 0xffff);
- load_seg_vm(R_DS, new_ds & 0xffff);
- load_seg_vm(R_FS, new_fs & 0xffff);
- load_seg_vm(R_GS, new_gs & 0xffff);
-
- env->eip = new_eip & 0xffff;
- ESP = new_esp;
-}
-
-void helper_iret_protected(int shift, int next_eip)
-{
- int tss_selector, type;
- uint32_t e1, e2;
-
- /* specific case for TSS */
- if (env->eflags & NT_MASK) {
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK)
- raise_exception_err(EXCP0D_GPF, 0);
-#endif
- tss_selector = lduw_kernel(env->tr.base + 0);
- if (tss_selector & 4)
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
- if (load_segment(&e1, &e2, tss_selector) != 0)
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
- type = (e2 >> DESC_TYPE_SHIFT) & 0x17;
- /* NOTE: we check both segment and busy TSS */
- if (type != 3)
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
- switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
- } else {
- helper_ret_protected(shift, 1, 0);
- }
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- CC_OP = CC_OP_EFLAGS;
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
-}
-
-void helper_lret_protected(int shift, int addend)
-{
- helper_ret_protected(shift, 0, addend);
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
-}
-
-void helper_sysenter(void)
-{
- if (env->sysenter_cs == 0) {
- raise_exception_err(EXCP0D_GPF, 0);
- }
- env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK);
- cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- ESP = env->sysenter_esp;
- EIP = env->sysenter_eip;
-}
-
-void helper_sysexit(void)
-{
- int cpl;
-
- cpl = env->hflags & HF_CPL_MASK;
- if (env->sysenter_cs == 0 || cpl != 0) {
- raise_exception_err(EXCP0D_GPF, 0);
- }
- cpu_x86_set_cpl(env, 3);
- cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_W_MASK | DESC_A_MASK);
- ESP = ECX;
- EIP = EDX;
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env)) {
- env->exception_index = -1;
- cpu_loop_exit();
- }
-#endif
-}
-
-void helper_movl_crN_T0(int reg)
-{
-#if !defined(CONFIG_USER_ONLY)
- switch(reg) {
- case 0:
- cpu_x86_update_cr0(env, T0);
- break;
- case 3:
- cpu_x86_update_cr3(env, T0);
- break;
- case 4:
- cpu_x86_update_cr4(env, T0);
- break;
- case 8:
- cpu_set_apic_tpr(env, T0);
- break;
- default:
- env->cr[reg] = T0;
- break;
- }
-#endif
-}
-
-/* XXX: do more */
-void helper_movl_drN_T0(int reg)
-{
- env->dr[reg] = T0;
-}
-
-void helper_invlpg(target_ulong addr)
-{
- cpu_x86_flush_tlb(env, addr);
-}
-
-void helper_rdtsc(void)
-{
- uint64_t val;
-
- if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
- raise_exception(EXCP0D_GPF);
- }
- val = cpu_get_tsc(env);
- EAX = (uint32_t)(val);
- EDX = (uint32_t)(val >> 32);
-}
-
-#if defined(CONFIG_USER_ONLY)
-void helper_wrmsr(void)
-{
-}
-
-void helper_rdmsr(void)
-{
-}
-#else
-void helper_wrmsr(void)
-{
- uint64_t val;
-
- val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
-
- switch((uint32_t)ECX) {
- case MSR_IA32_SYSENTER_CS:
- env->sysenter_cs = val & 0xffff;
- break;
- case MSR_IA32_SYSENTER_ESP:
- env->sysenter_esp = val;
- break;
- case MSR_IA32_SYSENTER_EIP:
- env->sysenter_eip = val;
- break;
- case MSR_IA32_APICBASE:
- cpu_set_apic_base(env, val);
- break;
- case MSR_EFER:
- {
- uint64_t update_mask;
- update_mask = 0;
- if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL)
- update_mask |= MSR_EFER_SCE;
- if (env->cpuid_ext2_features & CPUID_EXT2_LM)
- update_mask |= MSR_EFER_LME;
- if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR)
- update_mask |= MSR_EFER_FFXSR;
- if (env->cpuid_ext2_features & CPUID_EXT2_NX)
- update_mask |= MSR_EFER_NXE;
- env->efer = (env->efer & ~update_mask) |
- (val & update_mask);
- }
- break;
- case MSR_STAR:
- env->star = val;
- break;
- case MSR_PAT:
- env->pat = val;
- break;
-#ifdef TARGET_X86_64
- case MSR_LSTAR:
- env->lstar = val;
- break;
- case MSR_CSTAR:
- env->cstar = val;
- break;
- case MSR_FMASK:
- env->fmask = val;
- break;
- case MSR_FSBASE:
- env->segs[R_FS].base = val;
- break;
- case MSR_GSBASE:
- env->segs[R_GS].base = val;
- break;
- case MSR_KERNELGSBASE:
- env->kernelgsbase = val;
- break;
-#endif
- default:
- /* XXX: exception ? */
- break;
- }
-}
-
-void helper_rdmsr(void)
-{
- uint64_t val;
- switch((uint32_t)ECX) {
- case MSR_IA32_SYSENTER_CS:
- val = env->sysenter_cs;
- break;
- case MSR_IA32_SYSENTER_ESP:
- val = env->sysenter_esp;
- break;
- case MSR_IA32_SYSENTER_EIP:
- val = env->sysenter_eip;
- break;
- case MSR_IA32_APICBASE:
- val = cpu_get_apic_base(env);
- break;
- case MSR_EFER:
- val = env->efer;
- break;
- case MSR_STAR:
- val = env->star;
- break;
- case MSR_PAT:
- val = env->pat;
- break;
-#ifdef TARGET_X86_64
- case MSR_LSTAR:
- val = env->lstar;
- break;
- case MSR_CSTAR:
- val = env->cstar;
- break;
- case MSR_FMASK:
- val = env->fmask;
- break;
- case MSR_FSBASE:
- val = env->segs[R_FS].base;
- break;
- case MSR_GSBASE:
- val = env->segs[R_GS].base;
- break;
- case MSR_KERNELGSBASE:
- val = env->kernelgsbase;
- break;
-#endif
- default:
- /* XXX: exception ? */
- val = 0;
- break;
- }
- EAX = (uint32_t)(val);
- EDX = (uint32_t)(val >> 32);
-}
-#endif
-
-void helper_lsl(void)
-{
- unsigned int selector, limit;
- uint32_t e1, e2, eflags;
- int rpl, dpl, cpl, type;
-
- eflags = cc_table[CC_OP].compute_all();
- selector = T0 & 0xffff;
- if (load_segment(&e1, &e2, selector) != 0)
- goto fail;
- rpl = selector & 3;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- if (e2 & DESC_S_MASK) {
- if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
- /* conforming */
- } else {
- if (dpl < cpl || dpl < rpl)
- goto fail;
- }
- } else {
- type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
- switch(type) {
- case 1:
- case 2:
- case 3:
- case 9:
- case 11:
- break;
- default:
- goto fail;
- }
- if (dpl < cpl || dpl < rpl) {
- fail:
- CC_SRC = eflags & ~CC_Z;
- return;
- }
- }
- limit = get_seg_limit(e1, e2);
- T1 = limit;
- CC_SRC = eflags | CC_Z;
-}
-
-void helper_lar(void)
-{
- unsigned int selector;
- uint32_t e1, e2, eflags;
- int rpl, dpl, cpl, type;
-
- eflags = cc_table[CC_OP].compute_all();
- selector = T0 & 0xffff;
- if ((selector & 0xfffc) == 0)
- goto fail;
- if (load_segment(&e1, &e2, selector) != 0)
- goto fail;
- rpl = selector & 3;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- if (e2 & DESC_S_MASK) {
- if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
- /* conforming */
- } else {
- if (dpl < cpl || dpl < rpl)
- goto fail;
- }
- } else {
- type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
- switch(type) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 9:
- case 11:
- case 12:
- break;
- default:
- goto fail;
- }
- if (dpl < cpl || dpl < rpl) {
- fail:
- CC_SRC = eflags & ~CC_Z;
- return;
- }
- }
- T1 = e2 & 0x00f0ff00;
- CC_SRC = eflags | CC_Z;
-}
-
-void helper_verr(void)
-{
- unsigned int selector;
- uint32_t e1, e2, eflags;
- int rpl, dpl, cpl;
-
- eflags = cc_table[CC_OP].compute_all();
- selector = T0 & 0xffff;
- if ((selector & 0xfffc) == 0)
- goto fail;
- if (load_segment(&e1, &e2, selector) != 0)
- goto fail;
- if (!(e2 & DESC_S_MASK))
- goto fail;
- rpl = selector & 3;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- if (e2 & DESC_CS_MASK) {
- if (!(e2 & DESC_R_MASK))
- goto fail;
- if (!(e2 & DESC_C_MASK)) {
- if (dpl < cpl || dpl < rpl)
- goto fail;
- }
- } else {
- if (dpl < cpl || dpl < rpl) {
- fail:
- CC_SRC = eflags & ~CC_Z;
- return;
- }
- }
- CC_SRC = eflags | CC_Z;
-}
-
-void helper_verw(void)
-{
- unsigned int selector;
- uint32_t e1, e2, eflags;
- int rpl, dpl, cpl;
-
- eflags = cc_table[CC_OP].compute_all();
- selector = T0 & 0xffff;
- if ((selector & 0xfffc) == 0)
- goto fail;
- if (load_segment(&e1, &e2, selector) != 0)
- goto fail;
- if (!(e2 & DESC_S_MASK))
- goto fail;
- rpl = selector & 3;
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- if (e2 & DESC_CS_MASK) {
- goto fail;
- } else {
- if (dpl < cpl || dpl < rpl)
- goto fail;
- if (!(e2 & DESC_W_MASK)) {
- fail:
- CC_SRC = eflags & ~CC_Z;
- return;
- }
- }
- CC_SRC = eflags | CC_Z;
-}
-
-/* FPU helpers */
-
-void helper_fldt_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
- env->fpregs[new_fpstt].d = helper_fldt(A0);
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void helper_fstt_ST0_A0(void)
-{
- helper_fstt(ST0, A0);
-}
-
-void fpu_set_exception(int mask)
-{
- env->fpus |= mask;
- if (env->fpus & (~env->fpuc & FPUC_EM))
- env->fpus |= FPUS_SE | FPUS_B;
-}
-
-CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
-{
- if (b == 0.0)
- fpu_set_exception(FPUS_ZE);
- return a / b;
-}
-
-void fpu_raise_exception(void)
-{
- if (env->cr[0] & CR0_NE_MASK) {
- raise_exception(EXCP10_COPR);
- }
-#if !defined(CONFIG_USER_ONLY)
- else {
- cpu_set_ferr(env);
- }
-#endif
-}
-
-/* BCD ops */
-
-void helper_fbld_ST0_A0(void)
-{
- CPU86_LDouble tmp;
- uint64_t val;
- unsigned int v;
- int i;
-
- val = 0;
- for(i = 8; i >= 0; i--) {
- v = ldub(A0 + i);
- val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
- }
- tmp = val;
- if (ldub(A0 + 9) & 0x80)
- tmp = -tmp;
- fpush();
- ST0 = tmp;
-}
-
-void helper_fbst_ST0_A0(void)
-{
- int v;
- target_ulong mem_ref, mem_end;
- int64_t val;
-
- val = floatx_to_int64(ST0, &env->fp_status);
- mem_ref = A0;
- mem_end = mem_ref + 9;
- if (val < 0) {
- stb(mem_end, 0x80);
- val = -val;
- } else {
- stb(mem_end, 0x00);
- }
- while (mem_ref < mem_end) {
- if (val == 0)
- break;
- v = val % 100;
- val = val / 100;
- v = ((v / 10) << 4) | (v % 10);
- stb(mem_ref++, v);
- }
- while (mem_ref < mem_end) {
- stb(mem_ref++, 0);
- }
-}
-
-void helper_f2xm1(void)
-{
- ST0 = pow(2.0,ST0) - 1.0;
-}
-
-void helper_fyl2x(void)
-{
- CPU86_LDouble fptemp;
-
- fptemp = ST0;
- if (fptemp>0.0){
- fptemp = log(fptemp)/log(2.0); /* log2(ST) */
- ST1 *= fptemp;
- fpop();
- } else {
- env->fpus &= (~0x4700);
- env->fpus |= 0x400;
- }
-}
-
-void helper_fptan(void)
-{
- CPU86_LDouble fptemp;
-
- fptemp = ST0;
- if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
- env->fpus |= 0x400;
- } else {
- ST0 = tan(fptemp);
- fpush();
- ST0 = 1.0;
- env->fpus &= (~0x400); /* C2 <-- 0 */
- /* the above code is for |arg| < 2**52 only */
- }
-}
-
-void helper_fpatan(void)
-{
- CPU86_LDouble fptemp, fpsrcop;
-
- fpsrcop = ST1;
- fptemp = ST0;
- ST1 = atan2(fpsrcop,fptemp);
- fpop();
-}
-
-void helper_fxtract(void)
-{
- CPU86_LDoubleU temp;
- unsigned int expdif;
-
- temp.d = ST0;
- expdif = EXPD(temp) - EXPBIAS;
- /*DP exponent bias*/
- ST0 = expdif;
- fpush();
- BIASEXPONENT(temp);
- ST0 = temp.d;
-}
-
-void helper_fprem1(void)
-{
- CPU86_LDouble dblq, fpsrcop, fptemp;
- CPU86_LDoubleU fpsrcop1, fptemp1;
- int expdif;
- int q;
-
- fpsrcop = ST0;
- fptemp = ST1;
- fpsrcop1.d = fpsrcop;
- fptemp1.d = fptemp;
- expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
- if (expdif < 53) {
- dblq = fpsrcop / fptemp;
- dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
- ST0 = fpsrcop - fptemp*dblq;
- q = (int)dblq; /* cutting off top bits is assumed here */
- env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
- /* (C0,C1,C3) <-- (q2,q1,q0) */
- env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
- env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
- env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
- } else {
- env->fpus |= 0x400; /* C2 <-- 1 */
- fptemp = pow(2.0, expdif-50);
- fpsrcop = (ST0 / ST1) / fptemp;
- /* fpsrcop = integer obtained by rounding to the nearest */
- fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?
- floor(fpsrcop): ceil(fpsrcop);
- ST0 -= (ST1 * fpsrcop * fptemp);
- }
-}
-
-void helper_fprem(void)
-{
- CPU86_LDouble dblq, fpsrcop, fptemp;
- CPU86_LDoubleU fpsrcop1, fptemp1;
- int expdif;
- int q;
-
- fpsrcop = ST0;
- fptemp = ST1;
- fpsrcop1.d = fpsrcop;
- fptemp1.d = fptemp;
- expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
- if ( expdif < 53 ) {
- dblq = fpsrcop / fptemp;
- dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
- ST0 = fpsrcop - fptemp*dblq;
- q = (int)dblq; /* cutting off top bits is assumed here */
- env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
- /* (C0,C1,C3) <-- (q2,q1,q0) */
- env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
- env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
- env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
- } else {
- env->fpus |= 0x400; /* C2 <-- 1 */
- fptemp = pow(2.0, expdif-50);
- fpsrcop = (ST0 / ST1) / fptemp;
- /* fpsrcop = integer obtained by chopping */
- fpsrcop = (fpsrcop < 0.0)?
- -(floor(fabs(fpsrcop))): floor(fpsrcop);
- ST0 -= (ST1 * fpsrcop * fptemp);
- }
-}
-
-void helper_fyl2xp1(void)
-{
- CPU86_LDouble fptemp;
-
- fptemp = ST0;
- if ((fptemp+1.0)>0.0) {
- fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
- ST1 *= fptemp;
- fpop();
- } else {
- env->fpus &= (~0x4700);
- env->fpus |= 0x400;
- }
-}
-
-void helper_fsqrt(void)
-{
- CPU86_LDouble fptemp;
-
- fptemp = ST0;
- if (fptemp<0.0) {
- env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
- env->fpus |= 0x400;
- }
- ST0 = sqrt(fptemp);
-}
-
-void helper_fsincos(void)
-{
- CPU86_LDouble fptemp;
-
- fptemp = ST0;
- if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
- env->fpus |= 0x400;
- } else {
- ST0 = sin(fptemp);
- fpush();
- ST0 = cos(fptemp);
- env->fpus &= (~0x400); /* C2 <-- 0 */
- /* the above code is for |arg| < 2**63 only */
- }
-}
-
-void helper_frndint(void)
-{
- ST0 = floatx_round_to_int(ST0, &env->fp_status);
-}
-
-void helper_fscale(void)
-{
- ST0 = ldexp (ST0, (int)(ST1));
-}
-
-void helper_fsin(void)
-{
- CPU86_LDouble fptemp;
-
- fptemp = ST0;
- if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
- env->fpus |= 0x400;
- } else {
- ST0 = sin(fptemp);
- env->fpus &= (~0x400); /* C2 <-- 0 */
- /* the above code is for |arg| < 2**53 only */
- }
-}
-
-void helper_fcos(void)
-{
- CPU86_LDouble fptemp;
-
- fptemp = ST0;
- if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
- env->fpus |= 0x400;
- } else {
- ST0 = cos(fptemp);
- env->fpus &= (~0x400); /* C2 <-- 0 */
- /* the above code is for |arg5 < 2**63 only */
- }
-}
-
-void helper_fxam_ST0(void)
-{
- CPU86_LDoubleU temp;
- int expdif;
-
- temp.d = ST0;
-
- env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
- if (SIGND(temp))
- env->fpus |= 0x200; /* C1 <-- 1 */
-
- /* XXX: test fptags too */
- expdif = EXPD(temp);
- if (expdif == MAXEXPD) {
-#ifdef USE_X86LDOUBLE
- if (MANTD(temp) == 0x8000000000000000ULL)
-#else
- if (MANTD(temp) == 0)
-#endif
- env->fpus |= 0x500 /*Infinity*/;
- else
- env->fpus |= 0x100 /*NaN*/;
- } else if (expdif == 0) {
- if (MANTD(temp) == 0)
- env->fpus |= 0x4000 /*Zero*/;
- else
- env->fpus |= 0x4400 /*Denormal*/;
- } else {
- env->fpus |= 0x400;
- }
-}
-
-void helper_fstenv(target_ulong ptr, int data32)
-{
- int fpus, fptag, exp, i;
- uint64_t mant;
- CPU86_LDoubleU tmp;
-
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for (i=7; i>=0; i--) {
- fptag <<= 2;
- if (env->fptags[i]) {
- fptag |= 3;
- } else {
- tmp.d = env->fpregs[i].d;
- exp = EXPD(tmp);
- mant = MANTD(tmp);
- if (exp == 0 && mant == 0) {
- /* zero */
- fptag |= 1;
- } else if (exp == 0 || exp == MAXEXPD
-#ifdef USE_X86LDOUBLE
- || (mant & (1LL << 63)) == 0
-#endif
- ) {
- /* NaNs, infinity, denormal */
- fptag |= 2;
- }
- }
- }
- if (data32) {
- /* 32 bit */
- stl(ptr, env->fpuc);
- stl(ptr + 4, fpus);
- stl(ptr + 8, fptag);
- stl(ptr + 12, 0); /* fpip */
- stl(ptr + 16, 0); /* fpcs */
- stl(ptr + 20, 0); /* fpoo */
- stl(ptr + 24, 0); /* fpos */
- } else {
- /* 16 bit */
- stw(ptr, env->fpuc);
- stw(ptr + 2, fpus);
- stw(ptr + 4, fptag);
- stw(ptr + 6, 0);
- stw(ptr + 8, 0);
- stw(ptr + 10, 0);
- stw(ptr + 12, 0);
- }
-}
-
-void helper_fldenv(target_ulong ptr, int data32)
-{
- int i, fpus, fptag;
-
- if (data32) {
- env->fpuc = lduw(ptr);
- fpus = lduw(ptr + 4);
- fptag = lduw(ptr + 8);
- }
- else {
- env->fpuc = lduw(ptr);
- fpus = lduw(ptr + 2);
- fptag = lduw(ptr + 4);
- }
- env->fpstt = (fpus >> 11) & 7;
- env->fpus = fpus & ~0x3800;
- for(i = 0;i < 8; i++) {
- env->fptags[i] = ((fptag & 3) == 3);
- fptag >>= 2;
- }
-}
-
-void helper_fsave(target_ulong ptr, int data32)
-{
- CPU86_LDouble tmp;
- int i;
-
- helper_fstenv(ptr, data32);
-
- ptr += (14 << data32);
- for(i = 0;i < 8; i++) {
- tmp = ST(i);
- helper_fstt(tmp, ptr);
- ptr += 10;
- }
-
- /* fninit */
- env->fpus = 0;
- env->fpstt = 0;
- env->fpuc = 0x37f;
- env->fptags[0] = 1;
- env->fptags[1] = 1;
- env->fptags[2] = 1;
- env->fptags[3] = 1;
- env->fptags[4] = 1;
- env->fptags[5] = 1;
- env->fptags[6] = 1;
- env->fptags[7] = 1;
-}
-
-void helper_frstor(target_ulong ptr, int data32)
-{
- CPU86_LDouble tmp;
- int i;
-
- helper_fldenv(ptr, data32);
- ptr += (14 << data32);
-
- for(i = 0;i < 8; i++) {
- tmp = helper_fldt(ptr);
- ST(i) = tmp;
- ptr += 10;
- }
-}
-
-void helper_fxsave(target_ulong ptr, int data64)
-{
- int fpus, fptag, i, nb_xmm_regs;
- CPU86_LDouble tmp;
- target_ulong addr;
-
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for(i = 0; i < 8; i++) {
- fptag |= (env->fptags[i] << i);
- }
- stw(ptr, env->fpuc);
- stw(ptr + 2, fpus);
- stw(ptr + 4, fptag ^ 0xff);
-
- addr = ptr + 0x20;
- for(i = 0;i < 8; i++) {
- tmp = ST(i);
- helper_fstt(tmp, addr);
- addr += 16;
- }
-
- if (env->cr[4] & CR4_OSFXSR_MASK) {
- /* XXX: finish it */
- stl(ptr + 0x18, env->mxcsr); /* mxcsr */
- stl(ptr + 0x1c, 0x0000ffff); /* mxcsr_mask */
- nb_xmm_regs = 8 << data64;
- addr = ptr + 0xa0;
- for(i = 0; i < nb_xmm_regs; i++) {
- stq(addr, env->xmm_regs[i].XMM_Q(0));
- stq(addr + 8, env->xmm_regs[i].XMM_Q(1));
- addr += 16;
- }
- }
-}
-
-void helper_fxrstor(target_ulong ptr, int data64)
-{
- int i, fpus, fptag, nb_xmm_regs;
- CPU86_LDouble tmp;
- target_ulong addr;
-
- env->fpuc = lduw(ptr);
- fpus = lduw(ptr + 2);
- fptag = lduw(ptr + 4);
- env->fpstt = (fpus >> 11) & 7;
- env->fpus = fpus & ~0x3800;
- fptag ^= 0xff;
- for(i = 0;i < 8; i++) {
- env->fptags[i] = ((fptag >> i) & 1);
- }
-
- addr = ptr + 0x20;
- for(i = 0;i < 8; i++) {
- tmp = helper_fldt(addr);
- ST(i) = tmp;
- addr += 16;
- }
-
- if (env->cr[4] & CR4_OSFXSR_MASK) {
- /* XXX: finish it */
- env->mxcsr = ldl(ptr + 0x18);
- //ldl(ptr + 0x1c);
- nb_xmm_regs = 8 << data64;
- addr = ptr + 0xa0;
- for(i = 0; i < nb_xmm_regs; i++) {
- env->xmm_regs[i].XMM_Q(0) = ldq(addr);
- env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
- addr += 16;
- }
- }
-}
-
-#ifndef USE_X86LDOUBLE
-
-void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f)
-{
- CPU86_LDoubleU temp;
- int e;
-
- temp.d = f;
- /* mantissa */
- *pmant = (MANTD(temp) << 11) | (1LL << 63);
- /* exponent + sign */
- e = EXPD(temp) - EXPBIAS + 16383;
- e |= SIGND(temp) >> 16;
- *pexp = e;
-}
-
-CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper)
-{
- CPU86_LDoubleU temp;
- int e;
- uint64_t ll;
-
- /* XXX: handle overflow ? */
- e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
- e |= (upper >> 4) & 0x800; /* sign */
- ll = (mant >> 11) & ((1LL << 52) - 1);
-#ifdef __arm__
- temp.l.upper = (e << 20) | (ll >> 32);
- temp.l.lower = ll;
-#else
- temp.ll = ll | ((uint64_t)e << 52);
-#endif
- return temp.d;
-}
-
-#else
-
-void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f)
-{
- CPU86_LDoubleU temp;
-
- temp.d = f;
- *pmant = temp.l.lower;
- *pexp = temp.l.upper;
-}
-
-CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper)
-{
- CPU86_LDoubleU temp;
-
- temp.l.upper = upper;
- temp.l.lower = mant;
- return temp.d;
-}
-#endif
-
-#ifdef TARGET_X86_64
-
-//#define DEBUG_MULDIV
-
-static void add128(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
- *plow += a;
- /* carry test */
- if (*plow < a)
- (*phigh)++;
- *phigh += b;
-}
-
-static void neg128(uint64_t *plow, uint64_t *phigh)
-{
- *plow = ~ *plow;
- *phigh = ~ *phigh;
- add128(plow, phigh, 1, 0);
-}
-
-static void mul64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
- uint32_t a0, a1, b0, b1;
- uint64_t v;
-
- a0 = a;
- a1 = a >> 32;
-
- b0 = b;
- b1 = b >> 32;
-
- v = (uint64_t)a0 * (uint64_t)b0;
- *plow = v;
- *phigh = 0;
-
- v = (uint64_t)a0 * (uint64_t)b1;
- add128(plow, phigh, v << 32, v >> 32);
-
- v = (uint64_t)a1 * (uint64_t)b0;
- add128(plow, phigh, v << 32, v >> 32);
-
- v = (uint64_t)a1 * (uint64_t)b1;
- *phigh += v;
-#ifdef DEBUG_MULDIV
- printf("mul: 0x%016" PRIx64 " * 0x%016" PRIx64 " = 0x%016" PRIx64 "%016" PRIx64 "\n",
- a, b, *phigh, *plow);
-#endif
-}
-
-static void imul64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
-{
- int sa, sb;
- sa = (a < 0);
- if (sa)
- a = -a;
- sb = (b < 0);
- if (sb)
- b = -b;
- mul64(plow, phigh, a, b);
- if (sa ^ sb) {
- neg128(plow, phigh);
- }
-}
-
-/* return TRUE if overflow */
-static int div64(uint64_t *plow, uint64_t *phigh, uint64_t b)
-{
- uint64_t q, r, a1, a0;
- int i, qb, ab;
-
- a0 = *plow;
- a1 = *phigh;
- if (a1 == 0) {
- q = a0 / b;
- r = a0 % b;
- *plow = q;
- *phigh = r;
- } else {
- if (a1 >= b)
- return 1;
- /* XXX: use a better algorithm */
- for(i = 0; i < 64; i++) {
- ab = a1 >> 63;
- a1 = (a1 << 1) | (a0 >> 63);
- if (ab || a1 >= b) {
- a1 -= b;
- qb = 1;
- } else {
- qb = 0;
- }
- a0 = (a0 << 1) | qb;
- }
-#if defined(DEBUG_MULDIV)
- printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n",
- *phigh, *plow, b, a0, a1);
-#endif
- *plow = a0;
- *phigh = a1;
- }
- return 0;
-}
-
-/* return TRUE if overflow */
-static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
-{
- int sa, sb;
- sa = ((int64_t)*phigh < 0);
- if (sa)
- neg128(plow, phigh);
- sb = (b < 0);
- if (sb)
- b = -b;
- if (div64(plow, phigh, b) != 0)
- return 1;
- if (sa ^ sb) {
- if (*plow > (1ULL << 63))
- return 1;
- *plow = - *plow;
- } else {
- if (*plow >= (1ULL << 63))
- return 1;
- }
- if (sa)
- *phigh = - *phigh;
- return 0;
-}
-
-void helper_mulq_EAX_T0(void)
-{
- uint64_t r0, r1;
-
- mul64(&r0, &r1, EAX, T0);
- EAX = r0;
- EDX = r1;
- CC_DST = r0;
- CC_SRC = r1;
-}
-
-void helper_imulq_EAX_T0(void)
-{
- uint64_t r0, r1;
-
- imul64(&r0, &r1, EAX, T0);
- EAX = r0;
- EDX = r1;
- CC_DST = r0;
- CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
-}
-
-void helper_imulq_T0_T1(void)
-{
- uint64_t r0, r1;
-
- imul64(&r0, &r1, T0, T1);
- T0 = r0;
- CC_DST = r0;
- CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
-}
-
-void helper_divq_EAX_T0(void)
-{
- uint64_t r0, r1;
- if (T0 == 0) {
- raise_exception(EXCP00_DIVZ);
- }
- r0 = EAX;
- r1 = EDX;
- if (div64(&r0, &r1, T0))
- raise_exception(EXCP00_DIVZ);
- EAX = r0;
- EDX = r1;
-}
-
-void helper_idivq_EAX_T0(void)
-{
- uint64_t r0, r1;
- if (T0 == 0) {
- raise_exception(EXCP00_DIVZ);
- }
- r0 = EAX;
- r1 = EDX;
- if (idiv64(&r0, &r1, T0))
- raise_exception(EXCP00_DIVZ);
- EAX = r0;
- EDX = r1;
-}
-
-void helper_bswapq_T0(void)
-{
- T0 = bswap64(T0);
-}
-#endif
-
-void helper_hlt(void)
-{
- env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
- env->hflags |= HF_HALTED_MASK;
- env->exception_index = EXCP_HLT;
- cpu_loop_exit();
-}
-
-void helper_monitor(void)
-{
- if ((uint32_t)ECX != 0)
- raise_exception(EXCP0D_GPF);
- /* XXX: store address ? */
-}
-
-void helper_mwait(void)
-{
- if ((uint32_t)ECX != 0)
- raise_exception(EXCP0D_GPF);
- /* XXX: not complete but not completely erroneous */
- if (env->cpu_index != 0 || env->next_cpu != NULL) {
- /* more than one CPU: do not sleep because another CPU may
- wake this one */
- } else {
- helper_hlt();
- }
-}
-
-float approx_rsqrt(float a)
-{
- return 1.0 / sqrt(a);
-}
-
-float approx_rcp(float a)
-{
- return 1.0 / a;
-}
-
-void update_fp_status(void)
-{
- int rnd_type;
-
- /* set rounding mode */
- switch(env->fpuc & RC_MASK) {
- default:
- case RC_NEAR:
- rnd_type = float_round_nearest_even;
- break;
- case RC_DOWN:
- rnd_type = float_round_down;
- break;
- case RC_UP:
- rnd_type = float_round_up;
- break;
- case RC_CHOP:
- rnd_type = float_round_to_zero;
- break;
- }
- set_float_rounding_mode(rnd_type, &env->fp_status);
-#ifdef FLOATX80
- switch((env->fpuc >> 8) & 3) {
- case 0:
- rnd_type = 32;
- break;
- case 2:
- rnd_type = 64;
- break;
- case 3:
- default:
- rnd_type = 80;
- break;
- }
- set_floatx80_rounding_precision(rnd_type, &env->fp_status);
-#endif
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-#define MMUSUFFIX _mmu
-#define GETPC() (__builtin_return_address(0))
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
-#endif
-
-/* try to fill the TLB and return an exception if error. If retaddr is
- NULL, it means that the function was called in C code (i.e. not
- from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
-{
- TranslationBlock *tb;
- int ret;
- unsigned long pc;
- CPUX86State *saved_env;
-
- /* XXX: hack to restore env in all cases, even if not called from
- generated code */
- saved_env = env;
- env = cpu_single_env;
-
- ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1);
- if (ret) {
- if (retaddr) {
- /* now we have a real cpu fault */
- pc = (unsigned long)retaddr;
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, NULL);
- }
- }
- if (retaddr)
- raise_exception_err(env->exception_index, env->error_code);
- else
- raise_exception_err_norestore(env->exception_index, env->error_code);
- }
- env = saved_env;
-}
diff --git a/tools/ioemu/target-i386/helper2.c b/tools/ioemu/target-i386/helper2.c
deleted file mode 100644
index dc6a5000ec..0000000000
--- a/tools/ioemu/target-i386/helper2.c
+++ /dev/null
@@ -1,1036 +0,0 @@
-/*
- * i386 helpers (without register variable usage)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <signal.h>
-#include <assert.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-
-//#define DEBUG_MMU
-
-#ifdef USE_CODE_COPY
-#include <asm/ldt.h>
-#include <linux/unistd.h>
-#include <linux/version.h>
-
-int modify_ldt(int func, void *ptr, unsigned long bytecount)
-{
- return syscall(__NR_modify_ldt, func, ptr, bytecount);
-}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
-#define modify_ldt_ldt_s user_desc
-#endif
-#endif /* USE_CODE_COPY */
-
-CPUX86State *cpu_x86_init(void)
-{
- CPUX86State *env;
- static int inited;
-
- env = qemu_mallocz(sizeof(CPUX86State));
- if (!env)
- return NULL;
- cpu_exec_init(env);
-
- /* init various static tables */
- if (!inited) {
- inited = 1;
- optimize_flags_init();
- }
-#ifdef USE_CODE_COPY
- /* testing code for code copy case */
- {
- struct modify_ldt_ldt_s ldt;
-
- ldt.entry_number = 1;
- ldt.base_addr = (unsigned long)env;
- ldt.limit = (sizeof(CPUState) + 0xfff) >> 12;
- ldt.seg_32bit = 1;
- ldt.contents = MODIFY_LDT_CONTENTS_DATA;
- ldt.read_exec_only = 0;
- ldt.limit_in_pages = 1;
- ldt.seg_not_present = 0;
- ldt.useable = 1;
- modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
- asm volatile ("movl %0, %%fs" : : "r" ((1 << 3) | 7));
- }
-#endif
- {
- int family, model, stepping;
-#ifdef TARGET_X86_64
- env->cpuid_vendor1 = 0x68747541; /* "Auth" */
- env->cpuid_vendor2 = 0x69746e65; /* "enti" */
- env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */
- family = 6;
- model = 2;
- stepping = 3;
-#else
- env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
- env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
- env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
-#if 0
- /* pentium 75-200 */
- family = 5;
- model = 2;
- stepping = 11;
-#else
- /* pentium pro */
- family = 6;
- model = 3;
- stepping = 3;
-#endif
-#endif
- env->cpuid_level = 2;
- env->cpuid_version = (family << 8) | (model << 4) | stepping;
- env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
- CPUID_TSC | CPUID_MSR | CPUID_MCE |
- CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
- CPUID_PAT);
- env->pat = 0x0007040600070406ULL;
- env->cpuid_ext_features = CPUID_EXT_SSE3;
- env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
- env->cpuid_features |= CPUID_APIC;
- env->cpuid_xlevel = 0;
- {
- const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
- int c, len, i;
- len = strlen(model_id);
- for(i = 0; i < 48; i++) {
- if (i >= len)
- c = '\0';
- else
- c = model_id[i];
- env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
- }
- }
-#ifdef TARGET_X86_64
- /* currently not enabled for std i386 because not fully tested */
- env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
- env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
- env->cpuid_xlevel = 0x80000008;
-
- /* these features are needed for Win64 and aren't fully implemented */
- env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
- /* this feature is needed for Solaris and isn't fully implemented */
- env->cpuid_features |= CPUID_PSE36;
-#endif
- }
- cpu_reset(env);
-#ifdef USE_KQEMU
- kqemu_init(env);
-#endif
- return env;
-}
-
-/* NOTE: must be called outside the CPU execute loop */
-void cpu_reset(CPUX86State *env)
-{
- int i;
-
- memset(env, 0, offsetof(CPUX86State, breakpoints));
-
- tlb_flush(env, 1);
-
- /* init to reset state */
-
-#ifdef CONFIG_SOFTMMU
- env->hflags |= HF_SOFTMMU_MASK;
-#endif
-
- cpu_x86_update_cr0(env, 0x60000010);
- env->a20_mask = 0xffffffff;
- env->smbase = 0x30000;
-
- env->idt.limit = 0xffff;
- env->gdt.limit = 0xffff;
- env->ldt.limit = 0xffff;
- env->ldt.flags = DESC_P_MASK;
- env->tr.limit = 0xffff;
- env->tr.flags = DESC_P_MASK;
-
- cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0);
-
- env->eip = 0xfff0;
- env->regs[R_EDX] = 0x600; /* indicate P6 processor */
-
- env->eflags = 0x2;
-
- /* FPU init */
- for(i = 0;i < 8; i++)
- env->fptags[i] = 1;
- env->fpuc = 0x37f;
-
- env->mxcsr = 0x1f80;
-}
-
-void cpu_x86_close(CPUX86State *env)
-{
- free(env);
-}
-
-/***********************************************************/
-/* x86 debug */
-
-static const char *cc_op_str[] = {
- "DYNAMIC",
- "EFLAGS",
-
- "MULB",
- "MULW",
- "MULL",
- "MULQ",
-
- "ADDB",
- "ADDW",
- "ADDL",
- "ADDQ",
-
- "ADCB",
- "ADCW",
- "ADCL",
- "ADCQ",
-
- "SUBB",
- "SUBW",
- "SUBL",
- "SUBQ",
-
- "SBBB",
- "SBBW",
- "SBBL",
- "SBBQ",
-
- "LOGICB",
- "LOGICW",
- "LOGICL",
- "LOGICQ",
-
- "INCB",
- "INCW",
- "INCL",
- "INCQ",
-
- "DECB",
- "DECW",
- "DECL",
- "DECQ",
-
- "SHLB",
- "SHLW",
- "SHLL",
- "SHLQ",
-
- "SARB",
- "SARW",
- "SARL",
- "SARQ",
-};
-
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags)
-{
- int eflags, i, nb;
- char cc_op_name[32];
- static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
-
- eflags = env->eflags;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK) {
- cpu_fprintf(f,
- "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
- "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
- "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
- "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
- "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
- env->regs[R_EAX],
- env->regs[R_EBX],
- env->regs[R_ECX],
- env->regs[R_EDX],
- env->regs[R_ESI],
- env->regs[R_EDI],
- env->regs[R_EBP],
- env->regs[R_ESP],
- env->regs[8],
- env->regs[9],
- env->regs[10],
- env->regs[11],
- env->regs[12],
- env->regs[13],
- env->regs[14],
- env->regs[15],
- env->eip, eflags,
- eflags & DF_MASK ? 'D' : '-',
- eflags & CC_O ? 'O' : '-',
- eflags & CC_S ? 'S' : '-',
- eflags & CC_Z ? 'Z' : '-',
- eflags & CC_A ? 'A' : '-',
- eflags & CC_P ? 'P' : '-',
- eflags & CC_C ? 'C' : '-',
- env->hflags & HF_CPL_MASK,
- (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
- (env->a20_mask >> 20) & 1,
- (env->hflags >> HF_SMM_SHIFT) & 1,
- (env->hflags >> HF_HALTED_SHIFT) & 1);
- } else
-#endif
- {
- cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
- "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
- "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
- (uint32_t)env->regs[R_EAX],
- (uint32_t)env->regs[R_EBX],
- (uint32_t)env->regs[R_ECX],
- (uint32_t)env->regs[R_EDX],
- (uint32_t)env->regs[R_ESI],
- (uint32_t)env->regs[R_EDI],
- (uint32_t)env->regs[R_EBP],
- (uint32_t)env->regs[R_ESP],
- (uint32_t)env->eip, eflags,
- eflags & DF_MASK ? 'D' : '-',
- eflags & CC_O ? 'O' : '-',
- eflags & CC_S ? 'S' : '-',
- eflags & CC_Z ? 'Z' : '-',
- eflags & CC_A ? 'A' : '-',
- eflags & CC_P ? 'P' : '-',
- eflags & CC_C ? 'C' : '-',
- env->hflags & HF_CPL_MASK,
- (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
- (env->a20_mask >> 20) & 1,
- (env->hflags >> HF_SMM_SHIFT) & 1,
- (env->hflags >> HF_HALTED_SHIFT) & 1);
- }
-
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- for(i = 0; i < 6; i++) {
- SegmentCache *sc = &env->segs[i];
- cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
- seg_name[i],
- sc->selector,
- sc->base,
- sc->limit,
- sc->flags);
- }
- cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
- env->ldt.selector,
- env->ldt.base,
- env->ldt.limit,
- env->ldt.flags);
- cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
- env->tr.selector,
- env->tr.base,
- env->tr.limit,
- env->tr.flags);
- cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
- env->gdt.base, env->gdt.limit);
- cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
- env->idt.base, env->idt.limit);
- cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
- (uint32_t)env->cr[0],
- env->cr[2],
- env->cr[3],
- (uint32_t)env->cr[4]);
- } else
-#endif
- {
- for(i = 0; i < 6; i++) {
- SegmentCache *sc = &env->segs[i];
- cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
- seg_name[i],
- sc->selector,
- (uint32_t)sc->base,
- sc->limit,
- sc->flags);
- }
- cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
- env->ldt.selector,
- (uint32_t)env->ldt.base,
- env->ldt.limit,
- env->ldt.flags);
- cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
- env->tr.selector,
- (uint32_t)env->tr.base,
- env->tr.limit,
- env->tr.flags);
- cpu_fprintf(f, "GDT= %08x %08x\n",
- (uint32_t)env->gdt.base, env->gdt.limit);
- cpu_fprintf(f, "IDT= %08x %08x\n",
- (uint32_t)env->idt.base, env->idt.limit);
- cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
- (uint32_t)env->cr[0],
- (uint32_t)env->cr[2],
- (uint32_t)env->cr[3],
- (uint32_t)env->cr[4]);
- }
- if (flags & X86_DUMP_CCOP) {
- if ((unsigned)env->cc_op < CC_OP_NB)
- snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
- else
- snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK) {
- cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
- env->cc_src, env->cc_dst,
- cc_op_name);
- } else
-#endif
- {
- cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
- (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
- cc_op_name);
- }
- }
- if (flags & X86_DUMP_FPU) {
- int fptag;
- fptag = 0;
- for(i = 0; i < 8; i++) {
- fptag |= ((!env->fptags[i]) << i);
- }
- cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
- env->fpuc,
- (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
- env->fpstt,
- fptag,
- env->mxcsr);
- for(i=0;i<8;i++) {
-#if defined(USE_X86LDOUBLE)
- union {
- long double d;
- struct {
- uint64_t lower;
- uint16_t upper;
- } l;
- } tmp;
- tmp.d = env->fpregs[i].d;
- cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
- i, tmp.l.lower, tmp.l.upper);
-#else
- cpu_fprintf(f, "FPR%d=%016" PRIx64,
- i, env->fpregs[i].mmx.q);
-#endif
- if ((i & 1) == 1)
- cpu_fprintf(f, "\n");
- else
- cpu_fprintf(f, " ");
- }
- if (env->hflags & HF_CS64_MASK)
- nb = 16;
- else
- nb = 8;
- for(i=0;i<nb;i++) {
- cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
- i,
- env->xmm_regs[i].XMM_L(3),
- env->xmm_regs[i].XMM_L(2),
- env->xmm_regs[i].XMM_L(1),
- env->xmm_regs[i].XMM_L(0));
- if ((i & 1) == 1)
- cpu_fprintf(f, "\n");
- else
- cpu_fprintf(f, " ");
- }
- }
-}
-
-/***********************************************************/
-/* x86 mmu */
-/* XXX: add PGE support */
-
-void cpu_x86_set_a20(CPUX86State *env, int a20_state)
-{
- a20_state = (a20_state != 0);
- if (a20_state != ((env->a20_mask >> 20) & 1)) {
-#if defined(DEBUG_MMU)
- printf("A20 update: a20=%d\n", a20_state);
-#endif
- /* if the cpu is currently executing code, we must unlink it and
- all the potentially executing TB */
- cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
-
- /* when a20 is changed, all the MMU mappings are invalid, so
- we must flush everything */
- tlb_flush(env, 1);
- env->a20_mask = 0xffefffff | (a20_state << 20);
- }
-}
-
-void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
-{
- int pe_state;
-
-#if defined(DEBUG_MMU)
- printf("CR0 update: CR0=0x%08x\n", new_cr0);
-#endif
- if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
- (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
- tlb_flush(env, 1);
- }
-
-#ifdef TARGET_X86_64
- if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
- (env->efer & MSR_EFER_LME)) {
- /* enter in long mode */
- /* XXX: generate an exception */
- if (!(env->cr[4] & CR4_PAE_MASK))
- return;
- env->efer |= MSR_EFER_LMA;
- env->hflags |= HF_LMA_MASK;
- } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
- (env->efer & MSR_EFER_LMA)) {
- /* exit long mode */
- env->efer &= ~MSR_EFER_LMA;
- env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
- env->eip &= 0xffffffff;
- }
-#endif
- env->cr[0] = new_cr0 | CR0_ET_MASK;
-
- /* update PE flag in hidden flags */
- pe_state = (env->cr[0] & CR0_PE_MASK);
- env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
- /* ensure that ADDSEG is always set in real mode */
- env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
- /* update FPU flags */
- env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
- ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
-}
-
-/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
- the PDPT */
-void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
-{
- env->cr[3] = new_cr3;
- if (env->cr[0] & CR0_PG_MASK) {
-#if defined(DEBUG_MMU)
- printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
-#endif
- tlb_flush(env, 0);
- }
-}
-
-void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
-{
-#if defined(DEBUG_MMU)
- printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
-#endif
- if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
- (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
- tlb_flush(env, 1);
- }
- /* SSE handling */
- if (!(env->cpuid_features & CPUID_SSE))
- new_cr4 &= ~CR4_OSFXSR_MASK;
- if (new_cr4 & CR4_OSFXSR_MASK)
- env->hflags |= HF_OSFXSR_MASK;
- else
- env->hflags &= ~HF_OSFXSR_MASK;
-
- env->cr[4] = new_cr4;
-}
-
-/* XXX: also flush 4MB pages */
-void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
-{
- tlb_flush_page(env, addr);
-}
-
-#if defined(CONFIG_USER_ONLY)
-
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
- int is_write, int is_user, int is_softmmu)
-{
- /* user mode only emulation */
- is_write &= 1;
- env->cr[2] = addr;
- env->error_code = (is_write << PG_ERROR_W_BIT);
- env->error_code |= PG_ERROR_U_MASK;
- env->exception_index = EXCP0E_PAGE;
- return 1;
-}
-
-target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-
-#else
-
-#define PHYS_ADDR_MASK 0xfffff000
-
-/* return value:
- -1 = cannot handle fault
- 0 = nothing more to do
- 1 = generate PF fault
- 2 = soft MMU activation required for this block
-*/
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
- int is_write1, int is_user, int is_softmmu)
-{
- uint64_t ptep, pte;
- uint32_t pdpe_addr, pde_addr, pte_addr;
- int error_code, is_dirty, prot, page_size, ret, is_write;
- unsigned long paddr, page_offset;
- target_ulong vaddr, virt_addr;
-
-#if defined(DEBUG_MMU)
- printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
- addr, is_write1, is_user, env->eip);
-#endif
- is_write = is_write1 & 1;
-
- if (!(env->cr[0] & CR0_PG_MASK)) {
- pte = addr;
- virt_addr = addr & TARGET_PAGE_MASK;
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- page_size = 4096;
- goto do_mapping;
- }
-
- if (env->cr[4] & CR4_PAE_MASK) {
- uint64_t pde, pdpe;
-
- /* XXX: we only use 32 bit physical addresses */
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- uint32_t pml4e_addr;
- uint64_t pml4e;
- int32_t sext;
-
- /* test virtual address sign extension */
- sext = (int64_t)addr >> 47;
- if (sext != 0 && sext != -1) {
- env->error_code = 0;
- env->exception_index = EXCP0D_GPF;
- return 1;
- }
-
- pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
- env->a20_mask;
- pml4e = ldq_phys(pml4e_addr);
- if (!(pml4e & PG_PRESENT_MASK)) {
- error_code = 0;
- goto do_fault;
- }
- if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
- error_code = PG_ERROR_RSVD_MASK;
- goto do_fault;
- }
- if (!(pml4e & PG_ACCESSED_MASK)) {
- pml4e |= PG_ACCESSED_MASK;
- stl_phys_notdirty(pml4e_addr, pml4e);
- }
- ptep = pml4e ^ PG_NX_MASK;
- pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
- env->a20_mask;
- pdpe = ldq_phys(pdpe_addr);
- if (!(pdpe & PG_PRESENT_MASK)) {
- error_code = 0;
- goto do_fault;
- }
- if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
- error_code = PG_ERROR_RSVD_MASK;
- goto do_fault;
- }
- ptep &= pdpe ^ PG_NX_MASK;
- if (!(pdpe & PG_ACCESSED_MASK)) {
- pdpe |= PG_ACCESSED_MASK;
- stl_phys_notdirty(pdpe_addr, pdpe);
- }
- } else
-#endif
- {
- /* XXX: load them when cr3 is loaded ? */
- pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
- env->a20_mask;
- pdpe = ldq_phys(pdpe_addr);
- if (!(pdpe & PG_PRESENT_MASK)) {
- error_code = 0;
- goto do_fault;
- }
- ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
- }
-
- pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
- env->a20_mask;
- pde = ldq_phys(pde_addr);
- if (!(pde & PG_PRESENT_MASK)) {
- error_code = 0;
- goto do_fault;
- }
- if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
- error_code = PG_ERROR_RSVD_MASK;
- goto do_fault;
- }
- ptep &= pde ^ PG_NX_MASK;
- if (pde & PG_PSE_MASK) {
- /* 2 MB page */
- page_size = 2048 * 1024;
- ptep ^= PG_NX_MASK;
- if ((ptep & PG_NX_MASK) && is_write1 == 2)
- goto do_fault_protect;
- if (is_user) {
- if (!(ptep & PG_USER_MASK))
- goto do_fault_protect;
- if (is_write && !(ptep & PG_RW_MASK))
- goto do_fault_protect;
- } else {
- if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(ptep & PG_RW_MASK))
- goto do_fault_protect;
- }
- is_dirty = is_write && !(pde & PG_DIRTY_MASK);
- if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
- pde |= PG_ACCESSED_MASK;
- if (is_dirty)
- pde |= PG_DIRTY_MASK;
- stl_phys_notdirty(pde_addr, pde);
- }
- /* align to page_size */
- pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
- virt_addr = addr & ~(page_size - 1);
- } else {
- /* 4 KB page */
- if (!(pde & PG_ACCESSED_MASK)) {
- pde |= PG_ACCESSED_MASK;
- stl_phys_notdirty(pde_addr, pde);
- }
- pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
- env->a20_mask;
- pte = ldq_phys(pte_addr);
- if (!(pte & PG_PRESENT_MASK)) {
- error_code = 0;
- goto do_fault;
- }
- if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
- error_code = PG_ERROR_RSVD_MASK;
- goto do_fault;
- }
- /* combine pde and pte nx, user and rw protections */
- ptep &= pte ^ PG_NX_MASK;
- ptep ^= PG_NX_MASK;
- if ((ptep & PG_NX_MASK) && is_write1 == 2)
- goto do_fault_protect;
- if (is_user) {
- if (!(ptep & PG_USER_MASK))
- goto do_fault_protect;
- if (is_write && !(ptep & PG_RW_MASK))
- goto do_fault_protect;
- } else {
- if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(ptep & PG_RW_MASK))
- goto do_fault_protect;
- }
- is_dirty = is_write && !(pte & PG_DIRTY_MASK);
- if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
- pte |= PG_ACCESSED_MASK;
- if (is_dirty)
- pte |= PG_DIRTY_MASK;
- stl_phys_notdirty(pte_addr, pte);
- }
- page_size = 4096;
- virt_addr = addr & ~0xfff;
- pte = pte & (PHYS_ADDR_MASK | 0xfff);
- }
- } else {
- uint32_t pde;
-
- /* page directory entry */
- pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) &
- env->a20_mask;
- pde = ldl_phys(pde_addr);
- if (!(pde & PG_PRESENT_MASK)) {
- error_code = 0;
- goto do_fault;
- }
- /* if PSE bit is set, then we use a 4MB page */
- if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
- page_size = 4096 * 1024;
- if (is_user) {
- if (!(pde & PG_USER_MASK))
- goto do_fault_protect;
- if (is_write && !(pde & PG_RW_MASK))
- goto do_fault_protect;
- } else {
- if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(pde & PG_RW_MASK))
- goto do_fault_protect;
- }
- is_dirty = is_write && !(pde & PG_DIRTY_MASK);
- if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
- pde |= PG_ACCESSED_MASK;
- if (is_dirty)
- pde |= PG_DIRTY_MASK;
- stl_phys_notdirty(pde_addr, pde);
- }
-
- pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
- ptep = pte;
- virt_addr = addr & ~(page_size - 1);
- } else {
- if (!(pde & PG_ACCESSED_MASK)) {
- pde |= PG_ACCESSED_MASK;
- stl_phys_notdirty(pde_addr, pde);
- }
-
- /* page directory entry */
- pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
- env->a20_mask;
- pte = ldl_phys(pte_addr);
- if (!(pte & PG_PRESENT_MASK)) {
- error_code = 0;
- goto do_fault;
- }
- /* combine pde and pte user and rw protections */
- ptep = pte & pde;
- if (is_user) {
- if (!(ptep & PG_USER_MASK))
- goto do_fault_protect;
- if (is_write && !(ptep & PG_RW_MASK))
- goto do_fault_protect;
- } else {
- if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(ptep & PG_RW_MASK))
- goto do_fault_protect;
- }
- is_dirty = is_write && !(pte & PG_DIRTY_MASK);
- if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
- pte |= PG_ACCESSED_MASK;
- if (is_dirty)
- pte |= PG_DIRTY_MASK;
- stl_phys_notdirty(pte_addr, pte);
- }
- page_size = 4096;
- virt_addr = addr & ~0xfff;
- }
- }
- /* the page can be put in the TLB */
- prot = PAGE_READ;
- if (!(ptep & PG_NX_MASK))
- prot |= PAGE_EXEC;
- if (pte & PG_DIRTY_MASK) {
- /* only set write access if already dirty... otherwise wait
- for dirty access */
- if (is_user) {
- if (ptep & PG_RW_MASK)
- prot |= PAGE_WRITE;
- } else {
- if (!(env->cr[0] & CR0_WP_MASK) ||
- (ptep & PG_RW_MASK))
- prot |= PAGE_WRITE;
- }
- }
- do_mapping:
- pte = pte & env->a20_mask;
-
- /* Even if 4MB pages, we map only one 4KB page in the cache to
- avoid filling it too fast */
- page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
- paddr = (pte & TARGET_PAGE_MASK) + page_offset;
- vaddr = virt_addr + page_offset;
-
- ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
- return ret;
- do_fault_protect:
- error_code = PG_ERROR_P_MASK;
- do_fault:
- env->cr[2] = addr;
- error_code |= (is_write << PG_ERROR_W_BIT);
- if (is_user)
- error_code |= PG_ERROR_U_MASK;
- if (is_write1 == 2 &&
- (env->efer & MSR_EFER_NXE) &&
- (env->cr[4] & CR4_PAE_MASK))
- error_code |= PG_ERROR_I_D_MASK;
- env->error_code = error_code;
- env->exception_index = EXCP0E_PAGE;
- return 1;
-}
-
-target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
- uint32_t pde_addr, pte_addr;
- uint32_t pde, pte, paddr, page_offset, page_size;
-
- if (env->cr[4] & CR4_PAE_MASK) {
- uint32_t pdpe_addr, pde_addr, pte_addr;
- uint32_t pdpe;
-
- /* XXX: we only use 32 bit physical addresses */
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- uint32_t pml4e_addr, pml4e;
- int32_t sext;
-
- /* test virtual address sign extension */
- sext = (int64_t)addr >> 47;
- if (sext != 0 && sext != -1)
- return -1;
-
- pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
- env->a20_mask;
- pml4e = ldl_phys(pml4e_addr);
- if (!(pml4e & PG_PRESENT_MASK))
- return -1;
-
- pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
- env->a20_mask;
- pdpe = ldl_phys(pdpe_addr);
- if (!(pdpe & PG_PRESENT_MASK))
- return -1;
- } else
-#endif
- {
- pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
- env->a20_mask;
- pdpe = ldl_phys(pdpe_addr);
- if (!(pdpe & PG_PRESENT_MASK))
- return -1;
- }
-
- pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
- env->a20_mask;
- pde = ldl_phys(pde_addr);
- if (!(pde & PG_PRESENT_MASK)) {
- return -1;
- }
- if (pde & PG_PSE_MASK) {
- /* 2 MB page */
- page_size = 2048 * 1024;
- pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
- } else {
- /* 4 KB page */
- pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
- env->a20_mask;
- page_size = 4096;
- pte = ldl_phys(pte_addr);
- }
- } else {
- if (!(env->cr[0] & CR0_PG_MASK)) {
- pte = addr;
- page_size = 4096;
- } else {
- /* page directory entry */
- pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask;
- pde = ldl_phys(pde_addr);
- if (!(pde & PG_PRESENT_MASK))
- return -1;
- if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
- pte = pde & ~0x003ff000; /* align to 4MB */
- page_size = 4096 * 1024;
- } else {
- /* page directory entry */
- pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
- pte = ldl_phys(pte_addr);
- if (!(pte & PG_PRESENT_MASK))
- return -1;
- page_size = 4096;
- }
- }
- pte = pte & env->a20_mask;
- }
-
- page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
- paddr = (pte & TARGET_PAGE_MASK) + page_offset;
- return paddr;
-}
-#endif /* !CONFIG_USER_ONLY */
-
-#if defined(USE_CODE_COPY)
-struct fpstate {
- uint16_t fpuc;
- uint16_t dummy1;
- uint16_t fpus;
- uint16_t dummy2;
- uint16_t fptag;
- uint16_t dummy3;
-
- uint32_t fpip;
- uint32_t fpcs;
- uint32_t fpoo;
- uint32_t fpos;
- uint8_t fpregs1[8 * 10];
-};
-
-void restore_native_fp_state(CPUState *env)
-{
- int fptag, i, j;
- struct fpstate fp1, *fp = &fp1;
-
- fp->fpuc = env->fpuc;
- fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for (i=7; i>=0; i--) {
- fptag <<= 2;
- if (env->fptags[i]) {
- fptag |= 3;
- } else {
- /* the FPU automatically computes it */
- }
- }
- fp->fptag = fptag;
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);
- j = (j + 1) & 7;
- }
- asm volatile ("frstor %0" : "=m" (*fp));
- env->native_fp_regs = 1;
-}
-
-void save_native_fp_state(CPUState *env)
-{
- int fptag, i, j;
- uint16_t fpuc;
- struct fpstate fp1, *fp = &fp1;
-
- asm volatile ("fsave %0" : : "m" (*fp));
- env->fpuc = fp->fpuc;
- env->fpstt = (fp->fpus >> 11) & 7;
- env->fpus = fp->fpus & ~0x3800;
- fptag = fp->fptag;
- for(i = 0;i < 8; i++) {
- env->fptags[i] = ((fptag & 3) == 3);
- fptag >>= 2;
- }
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 10], 10);
- j = (j + 1) & 7;
- }
- /* we must restore the default rounding state */
- /* XXX: we do not restore the exception state */
- fpuc = 0x037f | (env->fpuc & (3 << 10));
- asm volatile("fldcw %0" : : "m" (fpuc));
- env->native_fp_regs = 0;
-}
-#endif
diff --git a/tools/ioemu/target-i386/op.c b/tools/ioemu/target-i386/op.c
deleted file mode 100644
index a8cfce271b..0000000000
--- a/tools/ioemu/target-i386/op.c
+++ /dev/null
@@ -1,2449 +0,0 @@
-/*
- * i386 micro operations
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define ASM_SOFTMMU
-#include "exec.h"
-
-/* n must be a constant to be efficient */
-static inline target_long lshift(target_long x, int n)
-{
- if (n >= 0)
- return x << n;
- else
- return x >> (-n);
-}
-
-/* we define the various pieces of code used by the JIT */
-
-#define REG EAX
-#define REGNAME _EAX
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG ECX
-#define REGNAME _ECX
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG EDX
-#define REGNAME _EDX
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG EBX
-#define REGNAME _EBX
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG ESP
-#define REGNAME _ESP
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG EBP
-#define REGNAME _EBP
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG ESI
-#define REGNAME _ESI
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG EDI
-#define REGNAME _EDI
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#ifdef TARGET_X86_64
-
-#define REG (env->regs[8])
-#define REGNAME _R8
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG (env->regs[9])
-#define REGNAME _R9
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG (env->regs[10])
-#define REGNAME _R10
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG (env->regs[11])
-#define REGNAME _R11
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG (env->regs[12])
-#define REGNAME _R12
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG (env->regs[13])
-#define REGNAME _R13
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG (env->regs[14])
-#define REGNAME _R14
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#define REG (env->regs[15])
-#define REGNAME _R15
-#include "opreg_template.h"
-#undef REG
-#undef REGNAME
-
-#endif
-
-/* operations with flags */
-
-/* update flags with T0 and T1 (add/sub case) */
-void OPPROTO op_update2_cc(void)
-{
- CC_SRC = T1;
- CC_DST = T0;
-}
-
-/* update flags with T0 (logic operation case) */
-void OPPROTO op_update1_cc(void)
-{
- CC_DST = T0;
-}
-
-void OPPROTO op_update_neg_cc(void)
-{
- CC_SRC = -T0;
- CC_DST = T0;
-}
-
-void OPPROTO op_cmpl_T0_T1_cc(void)
-{
- CC_SRC = T1;
- CC_DST = T0 - T1;
-}
-
-void OPPROTO op_update_inc_cc(void)
-{
- CC_SRC = cc_table[CC_OP].compute_c();
- CC_DST = T0;
-}
-
-void OPPROTO op_testl_T0_T1_cc(void)
-{
- CC_DST = T0 & T1;
-}
-
-/* operations without flags */
-
-void OPPROTO op_addl_T0_T1(void)
-{
- T0 += T1;
-}
-
-void OPPROTO op_orl_T0_T1(void)
-{
- T0 |= T1;
-}
-
-void OPPROTO op_andl_T0_T1(void)
-{
- T0 &= T1;
-}
-
-void OPPROTO op_subl_T0_T1(void)
-{
- T0 -= T1;
-}
-
-void OPPROTO op_xorl_T0_T1(void)
-{
- T0 ^= T1;
-}
-
-void OPPROTO op_negl_T0(void)
-{
- T0 = -T0;
-}
-
-void OPPROTO op_incl_T0(void)
-{
- T0++;
-}
-
-void OPPROTO op_decl_T0(void)
-{
- T0--;
-}
-
-void OPPROTO op_notl_T0(void)
-{
- T0 = ~T0;
-}
-
-void OPPROTO op_bswapl_T0(void)
-{
- T0 = bswap32(T0);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_bswapq_T0(void)
-{
- helper_bswapq_T0();
-}
-#endif
-
-/* multiply/divide */
-
-/* XXX: add eflags optimizations */
-/* XXX: add non P4 style flags */
-
-void OPPROTO op_mulb_AL_T0(void)
-{
- unsigned int res;
- res = (uint8_t)EAX * (uint8_t)T0;
- EAX = (EAX & ~0xffff) | res;
- CC_DST = res;
- CC_SRC = (res & 0xff00);
-}
-
-void OPPROTO op_imulb_AL_T0(void)
-{
- int res;
- res = (int8_t)EAX * (int8_t)T0;
- EAX = (EAX & ~0xffff) | (res & 0xffff);
- CC_DST = res;
- CC_SRC = (res != (int8_t)res);
-}
-
-void OPPROTO op_mulw_AX_T0(void)
-{
- unsigned int res;
- res = (uint16_t)EAX * (uint16_t)T0;
- EAX = (EAX & ~0xffff) | (res & 0xffff);
- EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);
- CC_DST = res;
- CC_SRC = res >> 16;
-}
-
-void OPPROTO op_imulw_AX_T0(void)
-{
- int res;
- res = (int16_t)EAX * (int16_t)T0;
- EAX = (EAX & ~0xffff) | (res & 0xffff);
- EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);
- CC_DST = res;
- CC_SRC = (res != (int16_t)res);
-}
-
-void OPPROTO op_mull_EAX_T0(void)
-{
- uint64_t res;
- res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
- EAX = (uint32_t)res;
- EDX = (uint32_t)(res >> 32);
- CC_DST = (uint32_t)res;
- CC_SRC = (uint32_t)(res >> 32);
-}
-
-void OPPROTO op_imull_EAX_T0(void)
-{
- int64_t res;
- res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
- EAX = (uint32_t)(res);
- EDX = (uint32_t)(res >> 32);
- CC_DST = res;
- CC_SRC = (res != (int32_t)res);
-}
-
-void OPPROTO op_imulw_T0_T1(void)
-{
- int res;
- res = (int16_t)T0 * (int16_t)T1;
- T0 = res;
- CC_DST = res;
- CC_SRC = (res != (int16_t)res);
-}
-
-void OPPROTO op_imull_T0_T1(void)
-{
- int64_t res;
- res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
- T0 = res;
- CC_DST = res;
- CC_SRC = (res != (int32_t)res);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_mulq_EAX_T0(void)
-{
- helper_mulq_EAX_T0();
-}
-
-void OPPROTO op_imulq_EAX_T0(void)
-{
- helper_imulq_EAX_T0();
-}
-
-void OPPROTO op_imulq_T0_T1(void)
-{
- helper_imulq_T0_T1();
-}
-#endif
-
-/* division, flags are undefined */
-
-void OPPROTO op_divb_AL_T0(void)
-{
- unsigned int num, den, q, r;
-
- num = (EAX & 0xffff);
- den = (T0 & 0xff);
- if (den == 0) {
- raise_exception(EXCP00_DIVZ);
- }
- q = (num / den);
- if (q > 0xff)
- raise_exception(EXCP00_DIVZ);
- q &= 0xff;
- r = (num % den) & 0xff;
- EAX = (EAX & ~0xffff) | (r << 8) | q;
-}
-
-void OPPROTO op_idivb_AL_T0(void)
-{
- int num, den, q, r;
-
- num = (int16_t)EAX;
- den = (int8_t)T0;
- if (den == 0) {
- raise_exception(EXCP00_DIVZ);
- }
- q = (num / den);
- if (q != (int8_t)q)
- raise_exception(EXCP00_DIVZ);
- q &= 0xff;
- r = (num % den) & 0xff;
- EAX = (EAX & ~0xffff) | (r << 8) | q;
-}
-
-void OPPROTO op_divw_AX_T0(void)
-{
- unsigned int num, den, q, r;
-
- num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
- den = (T0 & 0xffff);
- if (den == 0) {
- raise_exception(EXCP00_DIVZ);
- }
- q = (num / den);
- if (q > 0xffff)
- raise_exception(EXCP00_DIVZ);
- q &= 0xffff;
- r = (num % den) & 0xffff;
- EAX = (EAX & ~0xffff) | q;
- EDX = (EDX & ~0xffff) | r;
-}
-
-void OPPROTO op_idivw_AX_T0(void)
-{
- int num, den, q, r;
-
- num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
- den = (int16_t)T0;
- if (den == 0) {
- raise_exception(EXCP00_DIVZ);
- }
- q = (num / den);
- if (q != (int16_t)q)
- raise_exception(EXCP00_DIVZ);
- q &= 0xffff;
- r = (num % den) & 0xffff;
- EAX = (EAX & ~0xffff) | q;
- EDX = (EDX & ~0xffff) | r;
-}
-
-void OPPROTO op_divl_EAX_T0(void)
-{
- helper_divl_EAX_T0();
-}
-
-void OPPROTO op_idivl_EAX_T0(void)
-{
- helper_idivl_EAX_T0();
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_divq_EAX_T0(void)
-{
- helper_divq_EAX_T0();
-}
-
-void OPPROTO op_idivq_EAX_T0(void)
-{
- helper_idivq_EAX_T0();
-}
-#endif
-
-/* constant load & misc op */
-
-/* XXX: consistent names */
-void OPPROTO op_movl_T0_imu(void)
-{
- T0 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T0_im(void)
-{
- T0 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_addl_T0_im(void)
-{
- T0 += PARAM1;
-}
-
-void OPPROTO op_andl_T0_ffff(void)
-{
- T0 = T0 & 0xffff;
-}
-
-void OPPROTO op_andl_T0_im(void)
-{
- T0 = T0 & PARAM1;
-}
-
-void OPPROTO op_movl_T0_T1(void)
-{
- T0 = T1;
-}
-
-void OPPROTO op_movl_T1_imu(void)
-{
- T1 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T1_im(void)
-{
- T1 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_addl_T1_im(void)
-{
- T1 += PARAM1;
-}
-
-void OPPROTO op_movl_T1_A0(void)
-{
- T1 = A0;
-}
-
-void OPPROTO op_movl_A0_im(void)
-{
- A0 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_addl_A0_im(void)
-{
- A0 = (uint32_t)(A0 + PARAM1);
-}
-
-void OPPROTO op_movl_A0_seg(void)
-{
- A0 = (uint32_t)*(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_addl_A0_seg(void)
-{
- A0 = (uint32_t)(A0 + *(target_ulong *)((char *)env + PARAM1));
-}
-
-void OPPROTO op_addl_A0_AL(void)
-{
- A0 = (uint32_t)(A0 + (EAX & 0xff));
-}
-
-#ifdef WORDS_BIGENDIAN
-typedef union UREG64 {
- struct { uint16_t v3, v2, v1, v0; } w;
- struct { uint32_t v1, v0; } l;
- uint64_t q;
-} UREG64;
-#else
-typedef union UREG64 {
- struct { uint16_t v0, v1, v2, v3; } w;
- struct { uint32_t v0, v1; } l;
- uint64_t q;
-} UREG64;
-#endif
-
-#ifdef TARGET_X86_64
-
-#define PARAMQ1 \
-({\
- UREG64 __p;\
- __p.l.v1 = PARAM1;\
- __p.l.v0 = PARAM2;\
- __p.q;\
-})
-
-void OPPROTO op_movq_T0_im64(void)
-{
- T0 = PARAMQ1;
-}
-
-void OPPROTO op_movq_T1_im64(void)
-{
- T1 = PARAMQ1;
-}
-
-void OPPROTO op_movq_A0_im(void)
-{
- A0 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movq_A0_im64(void)
-{
- A0 = PARAMQ1;
-}
-
-void OPPROTO op_addq_A0_im(void)
-{
- A0 = (A0 + (int32_t)PARAM1);
-}
-
-void OPPROTO op_addq_A0_im64(void)
-{
- A0 = (A0 + PARAMQ1);
-}
-
-void OPPROTO op_movq_A0_seg(void)
-{
- A0 = *(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_addq_A0_seg(void)
-{
- A0 += *(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_addq_A0_AL(void)
-{
- A0 = (A0 + (EAX & 0xff));
-}
-
-#endif
-
-void OPPROTO op_andl_A0_ffff(void)
-{
- A0 = A0 & 0xffff;
-}
-
-/* memory access */
-
-#define MEMSUFFIX _raw
-#include "ops_mem.h"
-
-#if !defined(CONFIG_USER_ONLY)
-#define MEMSUFFIX _kernel
-#include "ops_mem.h"
-
-#define MEMSUFFIX _user
-#include "ops_mem.h"
-#endif
-
-/* indirect jump */
-
-void OPPROTO op_jmp_T0(void)
-{
- EIP = T0;
-}
-
-void OPPROTO op_movl_eip_im(void)
-{
- EIP = (uint32_t)PARAM1;
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_movq_eip_im(void)
-{
- EIP = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movq_eip_im64(void)
-{
- EIP = PARAMQ1;
-}
-#endif
-
-void OPPROTO op_hlt(void)
-{
- helper_hlt();
-}
-
-void OPPROTO op_monitor(void)
-{
- helper_monitor();
-}
-
-void OPPROTO op_mwait(void)
-{
- helper_mwait();
-}
-
-void OPPROTO op_debug(void)
-{
- env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
-}
-
-void OPPROTO op_raise_interrupt(void)
-{
- int intno, next_eip_addend;
- intno = PARAM1;
- next_eip_addend = PARAM2;
- raise_interrupt(intno, 1, 0, next_eip_addend);
-}
-
-void OPPROTO op_raise_exception(void)
-{
- int exception_index;
- exception_index = PARAM1;
- raise_exception(exception_index);
-}
-
-void OPPROTO op_into(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- if (eflags & CC_O) {
- raise_interrupt(EXCP04_INTO, 1, 0, PARAM1);
- }
- FORCE_RET();
-}
-
-void OPPROTO op_cli(void)
-{
- env->eflags &= ~IF_MASK;
-}
-
-void OPPROTO op_sti(void)
-{
- env->eflags |= IF_MASK;
-}
-
-void OPPROTO op_set_inhibit_irq(void)
-{
- env->hflags |= HF_INHIBIT_IRQ_MASK;
-}
-
-void OPPROTO op_reset_inhibit_irq(void)
-{
- env->hflags &= ~HF_INHIBIT_IRQ_MASK;
-}
-
-void OPPROTO op_rsm(void)
-{
- helper_rsm();
-}
-
-#if 0
-/* vm86plus instructions */
-void OPPROTO op_cli_vm(void)
-{
- env->eflags &= ~VIF_MASK;
-}
-
-void OPPROTO op_sti_vm(void)
-{
- env->eflags |= VIF_MASK;
- if (env->eflags & VIP_MASK) {
- EIP = PARAM1;
- raise_exception(EXCP0D_GPF);
- }
- FORCE_RET();
-}
-#endif
-
-void OPPROTO op_boundw(void)
-{
- int low, high, v;
- low = ldsw(A0);
- high = ldsw(A0 + 2);
- v = (int16_t)T0;
- if (v < low || v > high) {
- raise_exception(EXCP05_BOUND);
- }
- FORCE_RET();
-}
-
-void OPPROTO op_boundl(void)
-{
- int low, high, v;
- low = ldl(A0);
- high = ldl(A0 + 4);
- v = T0;
- if (v < low || v > high) {
- raise_exception(EXCP05_BOUND);
- }
- FORCE_RET();
-}
-
-void OPPROTO op_cmpxchg8b(void)
-{
- helper_cmpxchg8b();
-}
-
-void OPPROTO op_movl_T0_0(void)
-{
- T0 = 0;
-}
-
-void OPPROTO op_exit_tb(void)
-{
- EXIT_TB();
-}
-
-/* multiple size ops */
-
-#define ldul ldl
-
-#define SHIFT 0
-#include "ops_template.h"
-#undef SHIFT
-
-#define SHIFT 1
-#include "ops_template.h"
-#undef SHIFT
-
-#define SHIFT 2
-#include "ops_template.h"
-#undef SHIFT
-
-#ifdef TARGET_X86_64
-
-#define SHIFT 3
-#include "ops_template.h"
-#undef SHIFT
-
-#endif
-
-/* sign extend */
-
-void OPPROTO op_movsbl_T0_T0(void)
-{
- T0 = (int8_t)T0;
-}
-
-void OPPROTO op_movzbl_T0_T0(void)
-{
- T0 = (uint8_t)T0;
-}
-
-void OPPROTO op_movswl_T0_T0(void)
-{
- T0 = (int16_t)T0;
-}
-
-void OPPROTO op_movzwl_T0_T0(void)
-{
- T0 = (uint16_t)T0;
-}
-
-void OPPROTO op_movswl_EAX_AX(void)
-{
- EAX = (uint32_t)((int16_t)EAX);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_movslq_T0_T0(void)
-{
- T0 = (int32_t)T0;
-}
-
-void OPPROTO op_movslq_RAX_EAX(void)
-{
- EAX = (int32_t)EAX;
-}
-#endif
-
-void OPPROTO op_movsbw_AX_AL(void)
-{
- EAX = (EAX & ~0xffff) | ((int8_t)EAX & 0xffff);
-}
-
-void OPPROTO op_movslq_EDX_EAX(void)
-{
- EDX = (uint32_t)((int32_t)EAX >> 31);
-}
-
-void OPPROTO op_movswl_DX_AX(void)
-{
- EDX = (EDX & ~0xffff) | (((int16_t)EAX >> 15) & 0xffff);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_movsqo_RDX_RAX(void)
-{
- EDX = (int64_t)EAX >> 63;
-}
-#endif
-
-/* string ops helpers */
-
-void OPPROTO op_addl_ESI_T0(void)
-{
- ESI = (uint32_t)(ESI + T0);
-}
-
-void OPPROTO op_addw_ESI_T0(void)
-{
- ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff);
-}
-
-void OPPROTO op_addl_EDI_T0(void)
-{
- EDI = (uint32_t)(EDI + T0);
-}
-
-void OPPROTO op_addw_EDI_T0(void)
-{
- EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff);
-}
-
-void OPPROTO op_decl_ECX(void)
-{
- ECX = (uint32_t)(ECX - 1);
-}
-
-void OPPROTO op_decw_ECX(void)
-{
- ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_addq_ESI_T0(void)
-{
- ESI = (ESI + T0);
-}
-
-void OPPROTO op_addq_EDI_T0(void)
-{
- EDI = (EDI + T0);
-}
-
-void OPPROTO op_decq_ECX(void)
-{
- ECX--;
-}
-#endif
-
-/* push/pop utils */
-
-void op_addl_A0_SS(void)
-{
- A0 = (uint32_t)(A0 + env->segs[R_SS].base);
-}
-
-void op_subl_A0_2(void)
-{
- A0 = (uint32_t)(A0 - 2);
-}
-
-void op_subl_A0_4(void)
-{
- A0 = (uint32_t)(A0 - 4);
-}
-
-void op_addl_ESP_4(void)
-{
- ESP = (uint32_t)(ESP + 4);
-}
-
-void op_addl_ESP_2(void)
-{
- ESP = (uint32_t)(ESP + 2);
-}
-
-void op_addw_ESP_4(void)
-{
- ESP = (ESP & ~0xffff) | ((ESP + 4) & 0xffff);
-}
-
-void op_addw_ESP_2(void)
-{
- ESP = (ESP & ~0xffff) | ((ESP + 2) & 0xffff);
-}
-
-void op_addl_ESP_im(void)
-{
- ESP = (uint32_t)(ESP + PARAM1);
-}
-
-void op_addw_ESP_im(void)
-{
- ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);
-}
-
-#ifdef TARGET_X86_64
-void op_subq_A0_2(void)
-{
- A0 -= 2;
-}
-
-void op_subq_A0_8(void)
-{
- A0 -= 8;
-}
-
-void op_addq_ESP_8(void)
-{
- ESP += 8;
-}
-
-void op_addq_ESP_im(void)
-{
- ESP += PARAM1;
-}
-#endif
-
-void OPPROTO op_rdtsc(void)
-{
- helper_rdtsc();
-}
-
-void OPPROTO op_cpuid(void)
-{
- helper_cpuid();
-}
-
-void OPPROTO op_enter_level(void)
-{
- helper_enter_level(PARAM1, PARAM2);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_enter64_level(void)
-{
- helper_enter64_level(PARAM1, PARAM2);
-}
-#endif
-
-void OPPROTO op_sysenter(void)
-{
- helper_sysenter();
-}
-
-void OPPROTO op_sysexit(void)
-{
- helper_sysexit();
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_syscall(void)
-{
- helper_syscall(PARAM1);
-}
-
-void OPPROTO op_sysret(void)
-{
- helper_sysret(PARAM1);
-}
-#endif
-
-void OPPROTO op_rdmsr(void)
-{
- helper_rdmsr();
-}
-
-void OPPROTO op_wrmsr(void)
-{
- helper_wrmsr();
-}
-
-/* bcd */
-
-/* XXX: exception */
-void OPPROTO op_aam(void)
-{
- int base = PARAM1;
- int al, ah;
- al = EAX & 0xff;
- ah = al / base;
- al = al % base;
- EAX = (EAX & ~0xffff) | al | (ah << 8);
- CC_DST = al;
-}
-
-void OPPROTO op_aad(void)
-{
- int base = PARAM1;
- int al, ah;
- al = EAX & 0xff;
- ah = (EAX >> 8) & 0xff;
- al = ((ah * base) + al) & 0xff;
- EAX = (EAX & ~0xffff) | al;
- CC_DST = al;
-}
-
-void OPPROTO op_aaa(void)
-{
- int icarry;
- int al, ah, af;
- int eflags;
-
- eflags = cc_table[CC_OP].compute_all();
- af = eflags & CC_A;
- al = EAX & 0xff;
- ah = (EAX >> 8) & 0xff;
-
- icarry = (al > 0xf9);
- if (((al & 0x0f) > 9 ) || af) {
- al = (al + 6) & 0x0f;
- ah = (ah + 1 + icarry) & 0xff;
- eflags |= CC_C | CC_A;
- } else {
- eflags &= ~(CC_C | CC_A);
- al &= 0x0f;
- }
- EAX = (EAX & ~0xffff) | al | (ah << 8);
- CC_SRC = eflags;
- FORCE_RET();
-}
-
-void OPPROTO op_aas(void)
-{
- int icarry;
- int al, ah, af;
- int eflags;
-
- eflags = cc_table[CC_OP].compute_all();
- af = eflags & CC_A;
- al = EAX & 0xff;
- ah = (EAX >> 8) & 0xff;
-
- icarry = (al < 6);
- if (((al & 0x0f) > 9 ) || af) {
- al = (al - 6) & 0x0f;
- ah = (ah - 1 - icarry) & 0xff;
- eflags |= CC_C | CC_A;
- } else {
- eflags &= ~(CC_C | CC_A);
- al &= 0x0f;
- }
- EAX = (EAX & ~0xffff) | al | (ah << 8);
- CC_SRC = eflags;
- FORCE_RET();
-}
-
-void OPPROTO op_daa(void)
-{
- int al, af, cf;
- int eflags;
-
- eflags = cc_table[CC_OP].compute_all();
- cf = eflags & CC_C;
- af = eflags & CC_A;
- al = EAX & 0xff;
-
- eflags = 0;
- if (((al & 0x0f) > 9 ) || af) {
- al = (al + 6) & 0xff;
- eflags |= CC_A;
- }
- if ((al > 0x9f) || cf) {
- al = (al + 0x60) & 0xff;
- eflags |= CC_C;
- }
- EAX = (EAX & ~0xff) | al;
- /* well, speed is not an issue here, so we compute the flags by hand */
- eflags |= (al == 0) << 6; /* zf */
- eflags |= parity_table[al]; /* pf */
- eflags |= (al & 0x80); /* sf */
- CC_SRC = eflags;
- FORCE_RET();
-}
-
-void OPPROTO op_das(void)
-{
- int al, al1, af, cf;
- int eflags;
-
- eflags = cc_table[CC_OP].compute_all();
- cf = eflags & CC_C;
- af = eflags & CC_A;
- al = EAX & 0xff;
-
- eflags = 0;
- al1 = al;
- if (((al & 0x0f) > 9 ) || af) {
- eflags |= CC_A;
- if (al < 6 || cf)
- eflags |= CC_C;
- al = (al - 6) & 0xff;
- }
- if ((al1 > 0x99) || cf) {
- al = (al - 0x60) & 0xff;
- eflags |= CC_C;
- }
- EAX = (EAX & ~0xff) | al;
- /* well, speed is not an issue here, so we compute the flags by hand */
- eflags |= (al == 0) << 6; /* zf */
- eflags |= parity_table[al]; /* pf */
- eflags |= (al & 0x80); /* sf */
- CC_SRC = eflags;
- FORCE_RET();
-}
-
-/* segment handling */
-
-/* never use it with R_CS */
-void OPPROTO op_movl_seg_T0(void)
-{
- load_seg(PARAM1, T0);
-}
-
-/* faster VM86 version */
-void OPPROTO op_movl_seg_T0_vm(void)
-{
- int selector;
- SegmentCache *sc;
-
- selector = T0 & 0xffff;
- /* env->segs[] access */
- sc = (SegmentCache *)((char *)env + PARAM1);
- sc->selector = selector;
- sc->base = (selector << 4);
-}
-
-void OPPROTO op_movl_T0_seg(void)
-{
- T0 = env->segs[PARAM1].selector;
-}
-
-void OPPROTO op_lsl(void)
-{
- helper_lsl();
-}
-
-void OPPROTO op_lar(void)
-{
- helper_lar();
-}
-
-void OPPROTO op_verr(void)
-{
- helper_verr();
-}
-
-void OPPROTO op_verw(void)
-{
- helper_verw();
-}
-
-void OPPROTO op_arpl(void)
-{
- if ((T0 & 3) < (T1 & 3)) {
- /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */
- T0 = (T0 & ~3) | (T1 & 3);
- T1 = CC_Z;
- } else {
- T1 = 0;
- }
- FORCE_RET();
-}
-
-void OPPROTO op_arpl_update(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- CC_SRC = (eflags & ~CC_Z) | T1;
-}
-
-/* T0: segment, T1:eip */
-void OPPROTO op_ljmp_protected_T0_T1(void)
-{
- helper_ljmp_protected_T0_T1(PARAM1);
-}
-
-void OPPROTO op_lcall_real_T0_T1(void)
-{
- helper_lcall_real_T0_T1(PARAM1, PARAM2);
-}
-
-void OPPROTO op_lcall_protected_T0_T1(void)
-{
- helper_lcall_protected_T0_T1(PARAM1, PARAM2);
-}
-
-void OPPROTO op_iret_real(void)
-{
- helper_iret_real(PARAM1);
-}
-
-void OPPROTO op_iret_protected(void)
-{
- helper_iret_protected(PARAM1, PARAM2);
-}
-
-void OPPROTO op_lret_protected(void)
-{
- helper_lret_protected(PARAM1, PARAM2);
-}
-
-void OPPROTO op_lldt_T0(void)
-{
- helper_lldt_T0();
-}
-
-void OPPROTO op_ltr_T0(void)
-{
- helper_ltr_T0();
-}
-
-/* CR registers access */
-void OPPROTO op_movl_crN_T0(void)
-{
- helper_movl_crN_T0(PARAM1);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-void OPPROTO op_movtl_T0_cr8(void)
-{
- T0 = cpu_get_apic_tpr(env);
-}
-#endif
-
-/* DR registers access */
-void OPPROTO op_movl_drN_T0(void)
-{
- helper_movl_drN_T0(PARAM1);
-}
-
-void OPPROTO op_lmsw_T0(void)
-{
- /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
- if already set to one. */
- T0 = (env->cr[0] & ~0xe) | (T0 & 0xf);
- helper_movl_crN_T0(0);
-}
-
-void OPPROTO op_invlpg_A0(void)
-{
- helper_invlpg(A0);
-}
-
-void OPPROTO op_movl_T0_env(void)
-{
- T0 = *(uint32_t *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_movl_env_T0(void)
-{
- *(uint32_t *)((char *)env + PARAM1) = T0;
-}
-
-void OPPROTO op_movl_env_T1(void)
-{
- *(uint32_t *)((char *)env + PARAM1) = T1;
-}
-
-void OPPROTO op_movtl_T0_env(void)
-{
- T0 = *(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_movtl_env_T0(void)
-{
- *(target_ulong *)((char *)env + PARAM1) = T0;
-}
-
-void OPPROTO op_movtl_T1_env(void)
-{
- T1 = *(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_movtl_env_T1(void)
-{
- *(target_ulong *)((char *)env + PARAM1) = T1;
-}
-
-void OPPROTO op_clts(void)
-{
- env->cr[0] &= ~CR0_TS_MASK;
- env->hflags &= ~HF_TS_MASK;
-}
-
-/* flags handling */
-
-void OPPROTO op_goto_tb0(void)
-{
- GOTO_TB(op_goto_tb0, PARAM1, 0);
-}
-
-void OPPROTO op_goto_tb1(void)
-{
- GOTO_TB(op_goto_tb1, PARAM1, 1);
-}
-
-void OPPROTO op_jmp_label(void)
-{
- GOTO_LABEL_PARAM(1);
-}
-
-void OPPROTO op_jnz_T0_label(void)
-{
- if (T0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO op_jz_T0_label(void)
-{
- if (!T0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-/* slow set cases (compute x86 flags) */
-void OPPROTO op_seto_T0_cc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- T0 = (eflags >> 11) & 1;
-}
-
-void OPPROTO op_setb_T0_cc(void)
-{
- T0 = cc_table[CC_OP].compute_c();
-}
-
-void OPPROTO op_setz_T0_cc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- T0 = (eflags >> 6) & 1;
-}
-
-void OPPROTO op_setbe_T0_cc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- T0 = (eflags & (CC_Z | CC_C)) != 0;
-}
-
-void OPPROTO op_sets_T0_cc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- T0 = (eflags >> 7) & 1;
-}
-
-void OPPROTO op_setp_T0_cc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- T0 = (eflags >> 2) & 1;
-}
-
-void OPPROTO op_setl_T0_cc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
-}
-
-void OPPROTO op_setle_T0_cc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
-}
-
-void OPPROTO op_xor_T0_1(void)
-{
- T0 ^= 1;
-}
-
-void OPPROTO op_set_cc_op(void)
-{
- CC_OP = PARAM1;
-}
-
-void OPPROTO op_mov_T0_cc(void)
-{
- T0 = cc_table[CC_OP].compute_all();
-}
-
-/* XXX: clear VIF/VIP in all ops ? */
-
-void OPPROTO op_movl_eflags_T0(void)
-{
- load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));
-}
-
-void OPPROTO op_movw_eflags_T0(void)
-{
- load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
-}
-
-void OPPROTO op_movl_eflags_T0_io(void)
-{
- load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));
-}
-
-void OPPROTO op_movw_eflags_T0_io(void)
-{
- load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);
-}
-
-void OPPROTO op_movl_eflags_T0_cpl0(void)
-{
- load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));
-}
-
-void OPPROTO op_movw_eflags_T0_cpl0(void)
-{
- load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);
-}
-
-#if 0
-/* vm86plus version */
-void OPPROTO op_movw_eflags_T0_vm(void)
-{
- int eflags;
- eflags = T0;
- CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((eflags >> 10) & 1));
- /* we also update some system flags as in user mode */
- env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
- (eflags & FL_UPDATE_MASK16);
- if (eflags & IF_MASK) {
- env->eflags |= VIF_MASK;
- if (env->eflags & VIP_MASK) {
- EIP = PARAM1;
- raise_exception(EXCP0D_GPF);
- }
- }
- FORCE_RET();
-}
-
-void OPPROTO op_movl_eflags_T0_vm(void)
-{
- int eflags;
- eflags = T0;
- CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((eflags >> 10) & 1));
- /* we also update some system flags as in user mode */
- env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
- (eflags & FL_UPDATE_MASK32);
- if (eflags & IF_MASK) {
- env->eflags |= VIF_MASK;
- if (env->eflags & VIP_MASK) {
- EIP = PARAM1;
- raise_exception(EXCP0D_GPF);
- }
- }
- FORCE_RET();
-}
-#endif
-
-/* XXX: compute only O flag */
-void OPPROTO op_movb_eflags_T0(void)
-{
- int of;
- of = cc_table[CC_OP].compute_all() & CC_O;
- CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;
-}
-
-void OPPROTO op_movl_T0_eflags(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- eflags |= (DF & DF_MASK);
- eflags |= env->eflags & ~(VM_MASK | RF_MASK);
- T0 = eflags;
-}
-
-/* vm86plus version */
-#if 0
-void OPPROTO op_movl_T0_eflags_vm(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- eflags |= (DF & DF_MASK);
- eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
- if (env->eflags & VIF_MASK)
- eflags |= IF_MASK;
- T0 = eflags;
-}
-#endif
-
-void OPPROTO op_cld(void)
-{
- DF = 1;
-}
-
-void OPPROTO op_std(void)
-{
- DF = -1;
-}
-
-void OPPROTO op_clc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- eflags &= ~CC_C;
- CC_SRC = eflags;
-}
-
-void OPPROTO op_stc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- eflags |= CC_C;
- CC_SRC = eflags;
-}
-
-void OPPROTO op_cmc(void)
-{
- int eflags;
- eflags = cc_table[CC_OP].compute_all();
- eflags ^= CC_C;
- CC_SRC = eflags;
-}
-
-void OPPROTO op_salc(void)
-{
- int cf;
- cf = cc_table[CC_OP].compute_c();
- EAX = (EAX & ~0xff) | ((-cf) & 0xff);
-}
-
-static int compute_all_eflags(void)
-{
- return CC_SRC;
-}
-
-static int compute_c_eflags(void)
-{
- return CC_SRC & CC_C;
-}
-
-CCTable cc_table[CC_OP_NB] = {
- [CC_OP_DYNAMIC] = { /* should never happen */ },
-
- [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
-
- [CC_OP_MULB] = { compute_all_mulb, compute_c_mull },
- [CC_OP_MULW] = { compute_all_mulw, compute_c_mull },
- [CC_OP_MULL] = { compute_all_mull, compute_c_mull },
-
- [CC_OP_ADDB] = { compute_all_addb, compute_c_addb },
- [CC_OP_ADDW] = { compute_all_addw, compute_c_addw },
- [CC_OP_ADDL] = { compute_all_addl, compute_c_addl },
-
- [CC_OP_ADCB] = { compute_all_adcb, compute_c_adcb },
- [CC_OP_ADCW] = { compute_all_adcw, compute_c_adcw },
- [CC_OP_ADCL] = { compute_all_adcl, compute_c_adcl },
-
- [CC_OP_SUBB] = { compute_all_subb, compute_c_subb },
- [CC_OP_SUBW] = { compute_all_subw, compute_c_subw },
- [CC_OP_SUBL] = { compute_all_subl, compute_c_subl },
-
- [CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb },
- [CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw },
- [CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl },
-
- [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
- [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
- [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
-
- [CC_OP_INCB] = { compute_all_incb, compute_c_incl },
- [CC_OP_INCW] = { compute_all_incw, compute_c_incl },
- [CC_OP_INCL] = { compute_all_incl, compute_c_incl },
-
- [CC_OP_DECB] = { compute_all_decb, compute_c_incl },
- [CC_OP_DECW] = { compute_all_decw, compute_c_incl },
- [CC_OP_DECL] = { compute_all_decl, compute_c_incl },
-
- [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb },
- [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw },
- [CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
-
- [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl },
- [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl },
- [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl },
-
-#ifdef TARGET_X86_64
- [CC_OP_MULQ] = { compute_all_mulq, compute_c_mull },
-
- [CC_OP_ADDQ] = { compute_all_addq, compute_c_addq },
-
- [CC_OP_ADCQ] = { compute_all_adcq, compute_c_adcq },
-
- [CC_OP_SUBQ] = { compute_all_subq, compute_c_subq },
-
- [CC_OP_SBBQ] = { compute_all_sbbq, compute_c_sbbq },
-
- [CC_OP_LOGICQ] = { compute_all_logicq, compute_c_logicq },
-
- [CC_OP_INCQ] = { compute_all_incq, compute_c_incl },
-
- [CC_OP_DECQ] = { compute_all_decq, compute_c_incl },
-
- [CC_OP_SHLQ] = { compute_all_shlq, compute_c_shlq },
-
- [CC_OP_SARQ] = { compute_all_sarq, compute_c_sarl },
-#endif
-};
-
-/* floating point support. Some of the code for complicated x87
- functions comes from the LGPL'ed x86 emulator found in the Willows
- TWIN windows emulator. */
-
-/* fp load FT0 */
-
-void OPPROTO op_flds_FT0_A0(void)
-{
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i32 = ldl(A0);
- FT0 = FP_CONVERT.f;
-#else
- FT0 = ldfl(A0);
-#endif
-}
-
-void OPPROTO op_fldl_FT0_A0(void)
-{
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i64 = ldq(A0);
- FT0 = FP_CONVERT.d;
-#else
- FT0 = ldfq(A0);
-#endif
-}
-
-/* helpers are needed to avoid static constant reference. XXX: find a better way */
-#ifdef USE_INT_TO_FLOAT_HELPERS
-
-void helper_fild_FT0_A0(void)
-{
- FT0 = (CPU86_LDouble)ldsw(A0);
-}
-
-void helper_fildl_FT0_A0(void)
-{
- FT0 = (CPU86_LDouble)((int32_t)ldl(A0));
-}
-
-void helper_fildll_FT0_A0(void)
-{
- FT0 = (CPU86_LDouble)((int64_t)ldq(A0));
-}
-
-void OPPROTO op_fild_FT0_A0(void)
-{
- helper_fild_FT0_A0();
-}
-
-void OPPROTO op_fildl_FT0_A0(void)
-{
- helper_fildl_FT0_A0();
-}
-
-void OPPROTO op_fildll_FT0_A0(void)
-{
- helper_fildll_FT0_A0();
-}
-
-#else
-
-void OPPROTO op_fild_FT0_A0(void)
-{
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i32 = ldsw(A0);
- FT0 = (CPU86_LDouble)FP_CONVERT.i32;
-#else
- FT0 = (CPU86_LDouble)ldsw(A0);
-#endif
-}
-
-void OPPROTO op_fildl_FT0_A0(void)
-{
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i32 = (int32_t) ldl(A0);
- FT0 = (CPU86_LDouble)FP_CONVERT.i32;
-#else
- FT0 = (CPU86_LDouble)((int32_t)ldl(A0));
-#endif
-}
-
-void OPPROTO op_fildll_FT0_A0(void)
-{
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i64 = (int64_t) ldq(A0);
- FT0 = (CPU86_LDouble)FP_CONVERT.i64;
-#else
- FT0 = (CPU86_LDouble)((int64_t)ldq(A0));
-#endif
-}
-#endif
-
-/* fp load ST0 */
-
-void OPPROTO op_flds_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i32 = ldl(A0);
- env->fpregs[new_fpstt].d = FP_CONVERT.f;
-#else
- env->fpregs[new_fpstt].d = ldfl(A0);
-#endif
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void OPPROTO op_fldl_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i64 = ldq(A0);
- env->fpregs[new_fpstt].d = FP_CONVERT.d;
-#else
- env->fpregs[new_fpstt].d = ldfq(A0);
-#endif
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void OPPROTO op_fldt_ST0_A0(void)
-{
- helper_fldt_ST0_A0();
-}
-
-/* helpers are needed to avoid static constant reference. XXX: find a better way */
-#ifdef USE_INT_TO_FLOAT_HELPERS
-
-void helper_fild_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
- env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0);
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void helper_fildl_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
- env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0));
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void helper_fildll_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
- env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0));
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void OPPROTO op_fild_ST0_A0(void)
-{
- helper_fild_ST0_A0();
-}
-
-void OPPROTO op_fildl_ST0_A0(void)
-{
- helper_fildl_ST0_A0();
-}
-
-void OPPROTO op_fildll_ST0_A0(void)
-{
- helper_fildll_ST0_A0();
-}
-
-#else
-
-void OPPROTO op_fild_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i32 = ldsw(A0);
- env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32;
-#else
- env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0);
-#endif
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void OPPROTO op_fildl_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i32 = (int32_t) ldl(A0);
- env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32;
-#else
- env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0));
-#endif
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-void OPPROTO op_fildll_ST0_A0(void)
-{
- int new_fpstt;
- new_fpstt = (env->fpstt - 1) & 7;
-#ifdef USE_FP_CONVERT
- FP_CONVERT.i64 = (int64_t) ldq(A0);
- env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i64;
-#else
- env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0));
-#endif
- env->fpstt = new_fpstt;
- env->fptags[new_fpstt] = 0; /* validate stack entry */
-}
-
-#endif
-
-/* fp store */
-
-void OPPROTO op_fsts_ST0_A0(void)
-{
-#ifdef USE_FP_CONVERT
- FP_CONVERT.f = (float)ST0;
- stfl(A0, FP_CONVERT.f);
-#else
- stfl(A0, (float)ST0);
-#endif
- FORCE_RET();
-}
-
-void OPPROTO op_fstl_ST0_A0(void)
-{
- stfq(A0, (double)ST0);
- FORCE_RET();
-}
-
-void OPPROTO op_fstt_ST0_A0(void)
-{
- helper_fstt_ST0_A0();
-}
-
-void OPPROTO op_fist_ST0_A0(void)
-{
-#if defined(__sparc__) && !defined(__sparc_v9__)
- register CPU86_LDouble d asm("o0");
-#else
- CPU86_LDouble d;
-#endif
- int val;
-
- d = ST0;
- val = floatx_to_int32(d, &env->fp_status);
- if (val != (int16_t)val)
- val = -32768;
- stw(A0, val);
- FORCE_RET();
-}
-
-void OPPROTO op_fistl_ST0_A0(void)
-{
-#if defined(__sparc__) && !defined(__sparc_v9__)
- register CPU86_LDouble d asm("o0");
-#else
- CPU86_LDouble d;
-#endif
- int val;
-
- d = ST0;
- val = floatx_to_int32(d, &env->fp_status);
- stl(A0, val);
- FORCE_RET();
-}
-
-void OPPROTO op_fistll_ST0_A0(void)
-{
-#if defined(__sparc__) && !defined(__sparc_v9__)
- register CPU86_LDouble d asm("o0");
-#else
- CPU86_LDouble d;
-#endif
- int64_t val;
-
- d = ST0;
- val = floatx_to_int64(d, &env->fp_status);
- stq(A0, val);
- FORCE_RET();
-}
-
-void OPPROTO op_fistt_ST0_A0(void)
-{
-#if defined(__sparc__) && !defined(__sparc_v9__)
- register CPU86_LDouble d asm("o0");
-#else
- CPU86_LDouble d;
-#endif
- int val;
-
- d = ST0;
- val = floatx_to_int32_round_to_zero(d, &env->fp_status);
- if (val != (int16_t)val)
- val = -32768;
- stw(A0, val);
- FORCE_RET();
-}
-
-void OPPROTO op_fisttl_ST0_A0(void)
-{
-#if defined(__sparc__) && !defined(__sparc_v9__)
- register CPU86_LDouble d asm("o0");
-#else
- CPU86_LDouble d;
-#endif
- int val;
-
- d = ST0;
- val = floatx_to_int32_round_to_zero(d, &env->fp_status);
- stl(A0, val);
- FORCE_RET();
-}
-
-void OPPROTO op_fisttll_ST0_A0(void)
-{
-#if defined(__sparc__) && !defined(__sparc_v9__)
- register CPU86_LDouble d asm("o0");
-#else
- CPU86_LDouble d;
-#endif
- int64_t val;
-
- d = ST0;
- val = floatx_to_int64_round_to_zero(d, &env->fp_status);
- stq(A0, val);
- FORCE_RET();
-}
-
-void OPPROTO op_fbld_ST0_A0(void)
-{
- helper_fbld_ST0_A0();
-}
-
-void OPPROTO op_fbst_ST0_A0(void)
-{
- helper_fbst_ST0_A0();
-}
-
-/* FPU move */
-
-void OPPROTO op_fpush(void)
-{
- fpush();
-}
-
-void OPPROTO op_fpop(void)
-{
- fpop();
-}
-
-void OPPROTO op_fdecstp(void)
-{
- env->fpstt = (env->fpstt - 1) & 7;
- env->fpus &= (~0x4700);
-}
-
-void OPPROTO op_fincstp(void)
-{
- env->fpstt = (env->fpstt + 1) & 7;
- env->fpus &= (~0x4700);
-}
-
-void OPPROTO op_ffree_STN(void)
-{
- env->fptags[(env->fpstt + PARAM1) & 7] = 1;
-}
-
-void OPPROTO op_fmov_ST0_FT0(void)
-{
- ST0 = FT0;
-}
-
-void OPPROTO op_fmov_FT0_STN(void)
-{
- FT0 = ST(PARAM1);
-}
-
-void OPPROTO op_fmov_ST0_STN(void)
-{
- ST0 = ST(PARAM1);
-}
-
-void OPPROTO op_fmov_STN_ST0(void)
-{
- ST(PARAM1) = ST0;
-}
-
-void OPPROTO op_fxchg_ST0_STN(void)
-{
- CPU86_LDouble tmp;
- tmp = ST(PARAM1);
- ST(PARAM1) = ST0;
- ST0 = tmp;
-}
-
-/* FPU operations */
-
-const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500};
-
-void OPPROTO op_fcom_ST0_FT0(void)
-{
- int ret;
-
- ret = floatx_compare(ST0, FT0, &env->fp_status);
- env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
- FORCE_RET();
-}
-
-void OPPROTO op_fucom_ST0_FT0(void)
-{
- int ret;
-
- ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
- env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1];
- FORCE_RET();
-}
-
-const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
-
-void OPPROTO op_fcomi_ST0_FT0(void)
-{
- int eflags;
- int ret;
-
- ret = floatx_compare(ST0, FT0, &env->fp_status);
- eflags = cc_table[CC_OP].compute_all();
- eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
- CC_SRC = eflags;
- FORCE_RET();
-}
-
-void OPPROTO op_fucomi_ST0_FT0(void)
-{
- int eflags;
- int ret;
-
- ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
- eflags = cc_table[CC_OP].compute_all();
- eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
- CC_SRC = eflags;
- FORCE_RET();
-}
-
-void OPPROTO op_fcmov_ST0_STN_T0(void)
-{
- if (T0) {
- ST0 = ST(PARAM1);
- }
- FORCE_RET();
-}
-
-void OPPROTO op_fadd_ST0_FT0(void)
-{
- ST0 += FT0;
-}
-
-void OPPROTO op_fmul_ST0_FT0(void)
-{
- ST0 *= FT0;
-}
-
-void OPPROTO op_fsub_ST0_FT0(void)
-{
- ST0 -= FT0;
-}
-
-void OPPROTO op_fsubr_ST0_FT0(void)
-{
- ST0 = FT0 - ST0;
-}
-
-void OPPROTO op_fdiv_ST0_FT0(void)
-{
- ST0 = helper_fdiv(ST0, FT0);
-}
-
-void OPPROTO op_fdivr_ST0_FT0(void)
-{
- ST0 = helper_fdiv(FT0, ST0);
-}
-
-/* fp operations between STN and ST0 */
-
-void OPPROTO op_fadd_STN_ST0(void)
-{
- ST(PARAM1) += ST0;
-}
-
-void OPPROTO op_fmul_STN_ST0(void)
-{
- ST(PARAM1) *= ST0;
-}
-
-void OPPROTO op_fsub_STN_ST0(void)
-{
- ST(PARAM1) -= ST0;
-}
-
-void OPPROTO op_fsubr_STN_ST0(void)
-{
- CPU86_LDouble *p;
- p = &ST(PARAM1);
- *p = ST0 - *p;
-}
-
-void OPPROTO op_fdiv_STN_ST0(void)
-{
- CPU86_LDouble *p;
- p = &ST(PARAM1);
- *p = helper_fdiv(*p, ST0);
-}
-
-void OPPROTO op_fdivr_STN_ST0(void)
-{
- CPU86_LDouble *p;
- p = &ST(PARAM1);
- *p = helper_fdiv(ST0, *p);
-}
-
-/* misc FPU operations */
-void OPPROTO op_fchs_ST0(void)
-{
- ST0 = floatx_chs(ST0);
-}
-
-void OPPROTO op_fabs_ST0(void)
-{
- ST0 = floatx_abs(ST0);
-}
-
-void OPPROTO op_fxam_ST0(void)
-{
- helper_fxam_ST0();
-}
-
-void OPPROTO op_fld1_ST0(void)
-{
- ST0 = f15rk[1];
-}
-
-void OPPROTO op_fldl2t_ST0(void)
-{
- ST0 = f15rk[6];
-}
-
-void OPPROTO op_fldl2e_ST0(void)
-{
- ST0 = f15rk[5];
-}
-
-void OPPROTO op_fldpi_ST0(void)
-{
- ST0 = f15rk[2];
-}
-
-void OPPROTO op_fldlg2_ST0(void)
-{
- ST0 = f15rk[3];
-}
-
-void OPPROTO op_fldln2_ST0(void)
-{
- ST0 = f15rk[4];
-}
-
-void OPPROTO op_fldz_ST0(void)
-{
- ST0 = f15rk[0];
-}
-
-void OPPROTO op_fldz_FT0(void)
-{
- FT0 = f15rk[0];
-}
-
-/* associated heplers to reduce generated code length and to simplify
- relocation (FP constants are usually stored in .rodata section) */
-
-void OPPROTO op_f2xm1(void)
-{
- helper_f2xm1();
-}
-
-void OPPROTO op_fyl2x(void)
-{
- helper_fyl2x();
-}
-
-void OPPROTO op_fptan(void)
-{
- helper_fptan();
-}
-
-void OPPROTO op_fpatan(void)
-{
- helper_fpatan();
-}
-
-void OPPROTO op_fxtract(void)
-{
- helper_fxtract();
-}
-
-void OPPROTO op_fprem1(void)
-{
- helper_fprem1();
-}
-
-
-void OPPROTO op_fprem(void)
-{
- helper_fprem();
-}
-
-void OPPROTO op_fyl2xp1(void)
-{
- helper_fyl2xp1();
-}
-
-void OPPROTO op_fsqrt(void)
-{
- helper_fsqrt();
-}
-
-void OPPROTO op_fsincos(void)
-{
- helper_fsincos();
-}
-
-void OPPROTO op_frndint(void)
-{
- helper_frndint();
-}
-
-void OPPROTO op_fscale(void)
-{
- helper_fscale();
-}
-
-void OPPROTO op_fsin(void)
-{
- helper_fsin();
-}
-
-void OPPROTO op_fcos(void)
-{
- helper_fcos();
-}
-
-void OPPROTO op_fnstsw_A0(void)
-{
- int fpus;
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- stw(A0, fpus);
- FORCE_RET();
-}
-
-void OPPROTO op_fnstsw_EAX(void)
-{
- int fpus;
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- EAX = (EAX & ~0xffff) | fpus;
-}
-
-void OPPROTO op_fnstcw_A0(void)
-{
- stw(A0, env->fpuc);
- FORCE_RET();
-}
-
-void OPPROTO op_fldcw_A0(void)
-{
- env->fpuc = lduw(A0);
- update_fp_status();
-}
-
-void OPPROTO op_fclex(void)
-{
- env->fpus &= 0x7f00;
-}
-
-void OPPROTO op_fwait(void)
-{
- if (env->fpus & FPUS_SE)
- fpu_raise_exception();
- FORCE_RET();
-}
-
-void OPPROTO op_fninit(void)
-{
- env->fpus = 0;
- env->fpstt = 0;
- env->fpuc = 0x37f;
- env->fptags[0] = 1;
- env->fptags[1] = 1;
- env->fptags[2] = 1;
- env->fptags[3] = 1;
- env->fptags[4] = 1;
- env->fptags[5] = 1;
- env->fptags[6] = 1;
- env->fptags[7] = 1;
-}
-
-void OPPROTO op_fnstenv_A0(void)
-{
- helper_fstenv(A0, PARAM1);
-}
-
-void OPPROTO op_fldenv_A0(void)
-{
- helper_fldenv(A0, PARAM1);
-}
-
-void OPPROTO op_fnsave_A0(void)
-{
- helper_fsave(A0, PARAM1);
-}
-
-void OPPROTO op_frstor_A0(void)
-{
- helper_frstor(A0, PARAM1);
-}
-
-/* threading support */
-void OPPROTO op_lock(void)
-{
- cpu_lock();
-}
-
-void OPPROTO op_unlock(void)
-{
- cpu_unlock();
-}
-
-/* SSE support */
-static inline void memcpy16(void *d, void *s)
-{
- ((uint32_t *)d)[0] = ((uint32_t *)s)[0];
- ((uint32_t *)d)[1] = ((uint32_t *)s)[1];
- ((uint32_t *)d)[2] = ((uint32_t *)s)[2];
- ((uint32_t *)d)[3] = ((uint32_t *)s)[3];
-}
-
-void OPPROTO op_movo(void)
-{
- /* XXX: badly generated code */
- XMMReg *d, *s;
- d = (XMMReg *)((char *)env + PARAM1);
- s = (XMMReg *)((char *)env + PARAM2);
- memcpy16(d, s);
-}
-
-void OPPROTO op_movq(void)
-{
- uint64_t *d, *s;
- d = (uint64_t *)((char *)env + PARAM1);
- s = (uint64_t *)((char *)env + PARAM2);
- *d = *s;
-}
-
-void OPPROTO op_movl(void)
-{
- uint32_t *d, *s;
- d = (uint32_t *)((char *)env + PARAM1);
- s = (uint32_t *)((char *)env + PARAM2);
- *d = *s;
-}
-
-void OPPROTO op_movq_env_0(void)
-{
- uint64_t *d;
- d = (uint64_t *)((char *)env + PARAM1);
- *d = 0;
-}
-
-void OPPROTO op_fxsave_A0(void)
-{
- helper_fxsave(A0, PARAM1);
-}
-
-void OPPROTO op_fxrstor_A0(void)
-{
- helper_fxrstor(A0, PARAM1);
-}
-
-/* XXX: optimize by storing fptt and fptags in the static cpu state */
-void OPPROTO op_enter_mmx(void)
-{
- env->fpstt = 0;
- *(uint32_t *)(env->fptags) = 0;
- *(uint32_t *)(env->fptags + 4) = 0;
-}
-
-void OPPROTO op_emms(void)
-{
- /* set to empty state */
- *(uint32_t *)(env->fptags) = 0x01010101;
- *(uint32_t *)(env->fptags + 4) = 0x01010101;
-}
-
-#define SHIFT 0
-#include "ops_sse.h"
-
-#define SHIFT 1
-#include "ops_sse.h"
diff --git a/tools/ioemu/target-i386/opreg_template.h b/tools/ioemu/target-i386/opreg_template.h
deleted file mode 100644
index 648063650b..0000000000
--- a/tools/ioemu/target-i386/opreg_template.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * i386 micro operations (templates for various register related
- * operations)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-void OPPROTO glue(op_movl_A0,REGNAME)(void)
-{
- A0 = (uint32_t)REG;
-}
-
-void OPPROTO glue(op_addl_A0,REGNAME)(void)
-{
- A0 = (uint32_t)(A0 + REG);
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s1)(void)
-{
- A0 = (uint32_t)(A0 + (REG << 1));
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s2)(void)
-{
- A0 = (uint32_t)(A0 + (REG << 2));
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s3)(void)
-{
- A0 = (uint32_t)(A0 + (REG << 3));
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(op_movq_A0,REGNAME)(void)
-{
- A0 = REG;
-}
-
-void OPPROTO glue(op_addq_A0,REGNAME)(void)
-{
- A0 = (A0 + REG);
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s1)(void)
-{
- A0 = (A0 + (REG << 1));
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s2)(void)
-{
- A0 = (A0 + (REG << 2));
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s3)(void)
-{
- A0 = (A0 + (REG << 3));
-}
-#endif
-
-void OPPROTO glue(op_movl_T0,REGNAME)(void)
-{
- T0 = REG;
-}
-
-void OPPROTO glue(op_movl_T1,REGNAME)(void)
-{
- T1 = REG;
-}
-
-void OPPROTO glue(op_movh_T0,REGNAME)(void)
-{
- T0 = REG >> 8;
-}
-
-void OPPROTO glue(op_movh_T1,REGNAME)(void)
-{
- T1 = REG >> 8;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_T0)(void)
-{
- REG = (uint32_t)T0;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_T1)(void)
-{
- REG = (uint32_t)T1;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_A0)(void)
-{
- REG = (uint32_t)A0;
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(glue(op_movq,REGNAME),_T0)(void)
-{
- REG = T0;
-}
-
-void OPPROTO glue(glue(op_movq,REGNAME),_T1)(void)
-{
- REG = T1;
-}
-
-void OPPROTO glue(glue(op_movq,REGNAME),_A0)(void)
-{
- REG = A0;
-}
-#endif
-
-/* mov T1 to REG if T0 is true */
-void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
-{
- if (T0)
- REG = (REG & ~0xffff) | (T1 & 0xffff);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_cmovl,REGNAME),_T1_T0)(void)
-{
- if (T0)
- REG = (uint32_t)T1;
- FORCE_RET();
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(glue(op_cmovq,REGNAME),_T1_T0)(void)
-{
- if (T0)
- REG = T1;
- FORCE_RET();
-}
-#endif
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_T0)(void)
-{
- REG = (REG & ~0xffff) | (T0 & 0xffff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_T1)(void)
-{
- REG = (REG & ~0xffff) | (T1 & 0xffff);
-}
-
-/* NOTE: A0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_A0)(void)
-{
- REG = (REG & ~0xffff) | (A0 & 0xffff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movb,REGNAME),_T0)(void)
-{
- REG = (REG & ~0xff) | (T0 & 0xff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movh,REGNAME),_T0)(void)
-{
- REG = (REG & ~0xff00) | ((T0 & 0xff) << 8);
-}
-
-/* NOTE: T1 high order bits are ignored */
-void OPPROTO glue(glue(op_movb,REGNAME),_T1)(void)
-{
- REG = (REG & ~0xff) | (T1 & 0xff);
-}
-
-/* NOTE: T1 high order bits are ignored */
-void OPPROTO glue(glue(op_movh,REGNAME),_T1)(void)
-{
- REG = (REG & ~0xff00) | ((T1 & 0xff) << 8);
-}
-
diff --git a/tools/ioemu/target-i386/ops_mem.h b/tools/ioemu/target-i386/ops_mem.h
deleted file mode 100644
index 7ec84dde89..0000000000
--- a/tools/ioemu/target-i386/ops_mem.h
+++ /dev/null
@@ -1,156 +0,0 @@
-void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldub, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldsb, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(lduw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldsw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = (uint32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldub, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldsb, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(lduw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldsw, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = (uint32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_stb, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stb, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stw, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stw, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stl, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-#if 0
-void OPPROTO glue(glue(op_stb, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stb, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-#endif
-
-void OPPROTO glue(glue(op_stw, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stw, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stl, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-
-/* SSE/MMX support */
-void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _env_A0)(void)
-{
- uint64_t *p;
- p = (uint64_t *)((char *)env + PARAM1);
- *p = glue(ldq, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_stq, MEMSUFFIX), _env_A0)(void)
-{
- uint64_t *p;
- p = (uint64_t *)((char *)env + PARAM1);
- glue(stq, MEMSUFFIX)(A0, *p);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ldo, MEMSUFFIX), _env_A0)(void)
-{
- XMMReg *p;
- p = (XMMReg *)((char *)env + PARAM1);
- p->XMM_Q(0) = glue(ldq, MEMSUFFIX)(A0);
- p->XMM_Q(1) = glue(ldq, MEMSUFFIX)(A0 + 8);
-}
-
-void OPPROTO glue(glue(op_sto, MEMSUFFIX), _env_A0)(void)
-{
- XMMReg *p;
- p = (XMMReg *)((char *)env + PARAM1);
- glue(stq, MEMSUFFIX)(A0, p->XMM_Q(0));
- glue(stq, MEMSUFFIX)(A0 + 8, p->XMM_Q(1));
- FORCE_RET();
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(glue(op_ldsl, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = (int32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldsl, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = (int32_t)glue(ldl, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _T0_A0)(void)
-{
- T0 = glue(ldq, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_ldq, MEMSUFFIX), _T1_A0)(void)
-{
- T1 = glue(ldq, MEMSUFFIX)(A0);
-}
-
-void OPPROTO glue(glue(op_stq, MEMSUFFIX), _T0_A0)(void)
-{
- glue(stq, MEMSUFFIX)(A0, T0);
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_stq, MEMSUFFIX), _T1_A0)(void)
-{
- glue(stq, MEMSUFFIX)(A0, T1);
- FORCE_RET();
-}
-#endif
-
-#undef MEMSUFFIX
diff --git a/tools/ioemu/target-i386/ops_sse.h b/tools/ioemu/target-i386/ops_sse.h
deleted file mode 100644
index df1527c554..0000000000
--- a/tools/ioemu/target-i386/ops_sse.h
+++ /dev/null
@@ -1,1393 +0,0 @@
-/*
- * MMX/SSE/SSE2/PNI support
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#if SHIFT == 0
-#define Reg MMXReg
-#define XMM_ONLY(x...)
-#define B(n) MMX_B(n)
-#define W(n) MMX_W(n)
-#define L(n) MMX_L(n)
-#define Q(n) q
-#define SUFFIX _mmx
-#else
-#define Reg XMMReg
-#define XMM_ONLY(x...) x
-#define B(n) XMM_B(n)
-#define W(n) XMM_W(n)
-#define L(n) XMM_L(n)
-#define Q(n) XMM_Q(n)
-#define SUFFIX _xmm
-#endif
-
-void OPPROTO glue(op_psrlw, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 15) {
- d->Q(0) = 0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
- } else {
- shift = s->B(0);
- d->W(0) >>= shift;
- d->W(1) >>= shift;
- d->W(2) >>= shift;
- d->W(3) >>= shift;
-#if SHIFT == 1
- d->W(4) >>= shift;
- d->W(5) >>= shift;
- d->W(6) >>= shift;
- d->W(7) >>= shift;
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(op_psraw, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 15) {
- shift = 15;
- } else {
- shift = s->B(0);
- }
- d->W(0) = (int16_t)d->W(0) >> shift;
- d->W(1) = (int16_t)d->W(1) >> shift;
- d->W(2) = (int16_t)d->W(2) >> shift;
- d->W(3) = (int16_t)d->W(3) >> shift;
-#if SHIFT == 1
- d->W(4) = (int16_t)d->W(4) >> shift;
- d->W(5) = (int16_t)d->W(5) >> shift;
- d->W(6) = (int16_t)d->W(6) >> shift;
- d->W(7) = (int16_t)d->W(7) >> shift;
-#endif
-}
-
-void OPPROTO glue(op_psllw, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 15) {
- d->Q(0) = 0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
- } else {
- shift = s->B(0);
- d->W(0) <<= shift;
- d->W(1) <<= shift;
- d->W(2) <<= shift;
- d->W(3) <<= shift;
-#if SHIFT == 1
- d->W(4) <<= shift;
- d->W(5) <<= shift;
- d->W(6) <<= shift;
- d->W(7) <<= shift;
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(op_psrld, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 31) {
- d->Q(0) = 0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
- } else {
- shift = s->B(0);
- d->L(0) >>= shift;
- d->L(1) >>= shift;
-#if SHIFT == 1
- d->L(2) >>= shift;
- d->L(3) >>= shift;
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(op_psrad, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 31) {
- shift = 31;
- } else {
- shift = s->B(0);
- }
- d->L(0) = (int32_t)d->L(0) >> shift;
- d->L(1) = (int32_t)d->L(1) >> shift;
-#if SHIFT == 1
- d->L(2) = (int32_t)d->L(2) >> shift;
- d->L(3) = (int32_t)d->L(3) >> shift;
-#endif
-}
-
-void OPPROTO glue(op_pslld, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 31) {
- d->Q(0) = 0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
- } else {
- shift = s->B(0);
- d->L(0) <<= shift;
- d->L(1) <<= shift;
-#if SHIFT == 1
- d->L(2) <<= shift;
- d->L(3) <<= shift;
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(op_psrlq, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 63) {
- d->Q(0) = 0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
- } else {
- shift = s->B(0);
- d->Q(0) >>= shift;
-#if SHIFT == 1
- d->Q(1) >>= shift;
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(op_psllq, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- if (s->Q(0) > 63) {
- d->Q(0) = 0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
- } else {
- shift = s->B(0);
- d->Q(0) <<= shift;
-#if SHIFT == 1
- d->Q(1) <<= shift;
-#endif
- }
- FORCE_RET();
-}
-
-#if SHIFT == 1
-void OPPROTO glue(op_psrldq, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift, i;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- shift = s->L(0);
- if (shift > 16)
- shift = 16;
- for(i = 0; i < 16 - shift; i++)
- d->B(i) = d->B(i + shift);
- for(i = 16 - shift; i < 16; i++)
- d->B(i) = 0;
- FORCE_RET();
-}
-
-void OPPROTO glue(op_pslldq, SUFFIX)(void)
-{
- Reg *d, *s;
- int shift, i;
-
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- shift = s->L(0);
- if (shift > 16)
- shift = 16;
- for(i = 15; i >= shift; i--)
- d->B(i) = d->B(i - shift);
- for(i = 0; i < shift; i++)
- d->B(i) = 0;
- FORCE_RET();
-}
-#endif
-
-#define SSE_OP_B(name, F)\
-void OPPROTO glue(name, SUFFIX) (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->B(0) = F(d->B(0), s->B(0));\
- d->B(1) = F(d->B(1), s->B(1));\
- d->B(2) = F(d->B(2), s->B(2));\
- d->B(3) = F(d->B(3), s->B(3));\
- d->B(4) = F(d->B(4), s->B(4));\
- d->B(5) = F(d->B(5), s->B(5));\
- d->B(6) = F(d->B(6), s->B(6));\
- d->B(7) = F(d->B(7), s->B(7));\
- XMM_ONLY(\
- d->B(8) = F(d->B(8), s->B(8));\
- d->B(9) = F(d->B(9), s->B(9));\
- d->B(10) = F(d->B(10), s->B(10));\
- d->B(11) = F(d->B(11), s->B(11));\
- d->B(12) = F(d->B(12), s->B(12));\
- d->B(13) = F(d->B(13), s->B(13));\
- d->B(14) = F(d->B(14), s->B(14));\
- d->B(15) = F(d->B(15), s->B(15));\
- )\
-}
-
-#define SSE_OP_W(name, F)\
-void OPPROTO glue(name, SUFFIX) (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->W(0) = F(d->W(0), s->W(0));\
- d->W(1) = F(d->W(1), s->W(1));\
- d->W(2) = F(d->W(2), s->W(2));\
- d->W(3) = F(d->W(3), s->W(3));\
- XMM_ONLY(\
- d->W(4) = F(d->W(4), s->W(4));\
- d->W(5) = F(d->W(5), s->W(5));\
- d->W(6) = F(d->W(6), s->W(6));\
- d->W(7) = F(d->W(7), s->W(7));\
- )\
-}
-
-#define SSE_OP_L(name, F)\
-void OPPROTO glue(name, SUFFIX) (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->L(0) = F(d->L(0), s->L(0));\
- d->L(1) = F(d->L(1), s->L(1));\
- XMM_ONLY(\
- d->L(2) = F(d->L(2), s->L(2));\
- d->L(3) = F(d->L(3), s->L(3));\
- )\
-}
-
-#define SSE_OP_Q(name, F)\
-void OPPROTO glue(name, SUFFIX) (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->Q(0) = F(d->Q(0), s->Q(0));\
- XMM_ONLY(\
- d->Q(1) = F(d->Q(1), s->Q(1));\
- )\
-}
-
-#if SHIFT == 0
-static inline int satub(int x)
-{
- if (x < 0)
- return 0;
- else if (x > 255)
- return 255;
- else
- return x;
-}
-
-static inline int satuw(int x)
-{
- if (x < 0)
- return 0;
- else if (x > 65535)
- return 65535;
- else
- return x;
-}
-
-static inline int satsb(int x)
-{
- if (x < -128)
- return -128;
- else if (x > 127)
- return 127;
- else
- return x;
-}
-
-static inline int satsw(int x)
-{
- if (x < -32768)
- return -32768;
- else if (x > 32767)
- return 32767;
- else
- return x;
-}
-
-#define FADD(a, b) ((a) + (b))
-#define FADDUB(a, b) satub((a) + (b))
-#define FADDUW(a, b) satuw((a) + (b))
-#define FADDSB(a, b) satsb((int8_t)(a) + (int8_t)(b))
-#define FADDSW(a, b) satsw((int16_t)(a) + (int16_t)(b))
-
-#define FSUB(a, b) ((a) - (b))
-#define FSUBUB(a, b) satub((a) - (b))
-#define FSUBUW(a, b) satuw((a) - (b))
-#define FSUBSB(a, b) satsb((int8_t)(a) - (int8_t)(b))
-#define FSUBSW(a, b) satsw((int16_t)(a) - (int16_t)(b))
-#define FMINUB(a, b) ((a) < (b)) ? (a) : (b)
-#define FMINSW(a, b) ((int16_t)(a) < (int16_t)(b)) ? (a) : (b)
-#define FMAXUB(a, b) ((a) > (b)) ? (a) : (b)
-#define FMAXSW(a, b) ((int16_t)(a) > (int16_t)(b)) ? (a) : (b)
-
-#define FAND(a, b) (a) & (b)
-#define FANDN(a, b) ((~(a)) & (b))
-#define FOR(a, b) (a) | (b)
-#define FXOR(a, b) (a) ^ (b)
-
-#define FCMPGTB(a, b) (int8_t)(a) > (int8_t)(b) ? -1 : 0
-#define FCMPGTW(a, b) (int16_t)(a) > (int16_t)(b) ? -1 : 0
-#define FCMPGTL(a, b) (int32_t)(a) > (int32_t)(b) ? -1 : 0
-#define FCMPEQ(a, b) (a) == (b) ? -1 : 0
-
-#define FMULLW(a, b) (a) * (b)
-#define FMULHUW(a, b) (a) * (b) >> 16
-#define FMULHW(a, b) (int16_t)(a) * (int16_t)(b) >> 16
-
-#define FAVG(a, b) ((a) + (b) + 1) >> 1
-#endif
-
-SSE_OP_B(op_paddb, FADD)
-SSE_OP_W(op_paddw, FADD)
-SSE_OP_L(op_paddl, FADD)
-SSE_OP_Q(op_paddq, FADD)
-
-SSE_OP_B(op_psubb, FSUB)
-SSE_OP_W(op_psubw, FSUB)
-SSE_OP_L(op_psubl, FSUB)
-SSE_OP_Q(op_psubq, FSUB)
-
-SSE_OP_B(op_paddusb, FADDUB)
-SSE_OP_B(op_paddsb, FADDSB)
-SSE_OP_B(op_psubusb, FSUBUB)
-SSE_OP_B(op_psubsb, FSUBSB)
-
-SSE_OP_W(op_paddusw, FADDUW)
-SSE_OP_W(op_paddsw, FADDSW)
-SSE_OP_W(op_psubusw, FSUBUW)
-SSE_OP_W(op_psubsw, FSUBSW)
-
-SSE_OP_B(op_pminub, FMINUB)
-SSE_OP_B(op_pmaxub, FMAXUB)
-
-SSE_OP_W(op_pminsw, FMINSW)
-SSE_OP_W(op_pmaxsw, FMAXSW)
-
-SSE_OP_Q(op_pand, FAND)
-SSE_OP_Q(op_pandn, FANDN)
-SSE_OP_Q(op_por, FOR)
-SSE_OP_Q(op_pxor, FXOR)
-
-SSE_OP_B(op_pcmpgtb, FCMPGTB)
-SSE_OP_W(op_pcmpgtw, FCMPGTW)
-SSE_OP_L(op_pcmpgtl, FCMPGTL)
-
-SSE_OP_B(op_pcmpeqb, FCMPEQ)
-SSE_OP_W(op_pcmpeqw, FCMPEQ)
-SSE_OP_L(op_pcmpeql, FCMPEQ)
-
-SSE_OP_W(op_pmullw, FMULLW)
-SSE_OP_W(op_pmulhuw, FMULHUW)
-SSE_OP_W(op_pmulhw, FMULHW)
-
-SSE_OP_B(op_pavgb, FAVG)
-SSE_OP_W(op_pavgw, FAVG)
-
-void OPPROTO glue(op_pmuludq, SUFFIX) (void)
-{
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- d->Q(0) = (uint64_t)s->L(0) * (uint64_t)d->L(0);
-#if SHIFT == 1
- d->Q(1) = (uint64_t)s->L(2) * (uint64_t)d->L(2);
-#endif
-}
-
-void OPPROTO glue(op_pmaddwd, SUFFIX) (void)
-{
- int i;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- for(i = 0; i < (2 << SHIFT); i++) {
- d->L(i) = (int16_t)s->W(2*i) * (int16_t)d->W(2*i) +
- (int16_t)s->W(2*i+1) * (int16_t)d->W(2*i+1);
- }
- FORCE_RET();
-}
-
-#if SHIFT == 0
-static inline int abs1(int a)
-{
- if (a < 0)
- return -a;
- else
- return a;
-}
-#endif
-void OPPROTO glue(op_psadbw, SUFFIX) (void)
-{
- unsigned int val;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- val = 0;
- val += abs1(d->B(0) - s->B(0));
- val += abs1(d->B(1) - s->B(1));
- val += abs1(d->B(2) - s->B(2));
- val += abs1(d->B(3) - s->B(3));
- val += abs1(d->B(4) - s->B(4));
- val += abs1(d->B(5) - s->B(5));
- val += abs1(d->B(6) - s->B(6));
- val += abs1(d->B(7) - s->B(7));
- d->Q(0) = val;
-#if SHIFT == 1
- val = 0;
- val += abs1(d->B(8) - s->B(8));
- val += abs1(d->B(9) - s->B(9));
- val += abs1(d->B(10) - s->B(10));
- val += abs1(d->B(11) - s->B(11));
- val += abs1(d->B(12) - s->B(12));
- val += abs1(d->B(13) - s->B(13));
- val += abs1(d->B(14) - s->B(14));
- val += abs1(d->B(15) - s->B(15));
- d->Q(1) = val;
-#endif
-}
-
-void OPPROTO glue(op_maskmov, SUFFIX) (void)
-{
- int i;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- for(i = 0; i < (8 << SHIFT); i++) {
- if (s->B(i) & 0x80)
- stb(A0 + i, d->B(i));
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(op_movl_mm_T0, SUFFIX) (void)
-{
- Reg *d;
- d = (Reg *)((char *)env + PARAM1);
- d->L(0) = T0;
- d->L(1) = 0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
-}
-
-void OPPROTO glue(op_movl_T0_mm, SUFFIX) (void)
-{
- Reg *s;
- s = (Reg *)((char *)env + PARAM1);
- T0 = s->L(0);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(op_movq_mm_T0, SUFFIX) (void)
-{
- Reg *d;
- d = (Reg *)((char *)env + PARAM1);
- d->Q(0) = T0;
-#if SHIFT == 1
- d->Q(1) = 0;
-#endif
-}
-
-void OPPROTO glue(op_movq_T0_mm, SUFFIX) (void)
-{
- Reg *s;
- s = (Reg *)((char *)env + PARAM1);
- T0 = s->Q(0);
-}
-#endif
-
-#if SHIFT == 0
-void OPPROTO glue(op_pshufw, SUFFIX) (void)
-{
- Reg r, *d, *s;
- int order;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- order = PARAM3;
- r.W(0) = s->W(order & 3);
- r.W(1) = s->W((order >> 2) & 3);
- r.W(2) = s->W((order >> 4) & 3);
- r.W(3) = s->W((order >> 6) & 3);
- *d = r;
-}
-#else
-void OPPROTO op_shufps(void)
-{
- Reg r, *d, *s;
- int order;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- order = PARAM3;
- r.L(0) = d->L(order & 3);
- r.L(1) = d->L((order >> 2) & 3);
- r.L(2) = s->L((order >> 4) & 3);
- r.L(3) = s->L((order >> 6) & 3);
- *d = r;
-}
-
-void OPPROTO op_shufpd(void)
-{
- Reg r, *d, *s;
- int order;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- order = PARAM3;
- r.Q(0) = d->Q(order & 1);
- r.Q(1) = s->Q((order >> 1) & 1);
- *d = r;
-}
-
-void OPPROTO glue(op_pshufd, SUFFIX) (void)
-{
- Reg r, *d, *s;
- int order;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- order = PARAM3;
- r.L(0) = s->L(order & 3);
- r.L(1) = s->L((order >> 2) & 3);
- r.L(2) = s->L((order >> 4) & 3);
- r.L(3) = s->L((order >> 6) & 3);
- *d = r;
-}
-
-void OPPROTO glue(op_pshuflw, SUFFIX) (void)
-{
- Reg r, *d, *s;
- int order;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- order = PARAM3;
- r.W(0) = s->W(order & 3);
- r.W(1) = s->W((order >> 2) & 3);
- r.W(2) = s->W((order >> 4) & 3);
- r.W(3) = s->W((order >> 6) & 3);
- r.Q(1) = s->Q(1);
- *d = r;
-}
-
-void OPPROTO glue(op_pshufhw, SUFFIX) (void)
-{
- Reg r, *d, *s;
- int order;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- order = PARAM3;
- r.Q(0) = s->Q(0);
- r.W(4) = s->W(4 + (order & 3));
- r.W(5) = s->W(4 + ((order >> 2) & 3));
- r.W(6) = s->W(4 + ((order >> 4) & 3));
- r.W(7) = s->W(4 + ((order >> 6) & 3));
- *d = r;
-}
-#endif
-
-#if SHIFT == 1
-/* FPU ops */
-/* XXX: not accurate */
-
-#define SSE_OP_S(name, F)\
-void OPPROTO op_ ## name ## ps (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
- d->XMM_S(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
- d->XMM_S(2) = F(32, d->XMM_S(2), s->XMM_S(2));\
- d->XMM_S(3) = F(32, d->XMM_S(3), s->XMM_S(3));\
-}\
-\
-void OPPROTO op_ ## name ## ss (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
-}\
-void OPPROTO op_ ## name ## pd (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
- d->XMM_D(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
-}\
-\
-void OPPROTO op_ ## name ## sd (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
-}
-
-#define FPU_ADD(size, a, b) float ## size ## _add(a, b, &env->sse_status)
-#define FPU_SUB(size, a, b) float ## size ## _sub(a, b, &env->sse_status)
-#define FPU_MUL(size, a, b) float ## size ## _mul(a, b, &env->sse_status)
-#define FPU_DIV(size, a, b) float ## size ## _div(a, b, &env->sse_status)
-#define FPU_MIN(size, a, b) (a) < (b) ? (a) : (b)
-#define FPU_MAX(size, a, b) (a) > (b) ? (a) : (b)
-#define FPU_SQRT(size, a, b) float ## size ## _sqrt(b, &env->sse_status)
-
-SSE_OP_S(add, FPU_ADD)
-SSE_OP_S(sub, FPU_SUB)
-SSE_OP_S(mul, FPU_MUL)
-SSE_OP_S(div, FPU_DIV)
-SSE_OP_S(min, FPU_MIN)
-SSE_OP_S(max, FPU_MAX)
-SSE_OP_S(sqrt, FPU_SQRT)
-
-
-/* float to float conversions */
-void OPPROTO op_cvtps2pd(void)
-{
- float32 s0, s1;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- s0 = s->XMM_S(0);
- s1 = s->XMM_S(1);
- d->XMM_D(0) = float32_to_float64(s0, &env->sse_status);
- d->XMM_D(1) = float32_to_float64(s1, &env->sse_status);
-}
-
-void OPPROTO op_cvtpd2ps(void)
-{
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
- d->XMM_S(1) = float64_to_float32(s->XMM_D(1), &env->sse_status);
- d->Q(1) = 0;
-}
-
-void OPPROTO op_cvtss2sd(void)
-{
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- d->XMM_D(0) = float32_to_float64(s->XMM_S(0), &env->sse_status);
-}
-
-void OPPROTO op_cvtsd2ss(void)
-{
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
- d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
-}
-
-/* integer to float */
-void OPPROTO op_cvtdq2ps(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_S(0) = int32_to_float32(s->XMM_L(0), &env->sse_status);
- d->XMM_S(1) = int32_to_float32(s->XMM_L(1), &env->sse_status);
- d->XMM_S(2) = int32_to_float32(s->XMM_L(2), &env->sse_status);
- d->XMM_S(3) = int32_to_float32(s->XMM_L(3), &env->sse_status);
-}
-
-void OPPROTO op_cvtdq2pd(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- int32_t l0, l1;
- l0 = (int32_t)s->XMM_L(0);
- l1 = (int32_t)s->XMM_L(1);
- d->XMM_D(0) = int32_to_float64(l0, &env->sse_status);
- d->XMM_D(1) = int32_to_float64(l1, &env->sse_status);
-}
-
-void OPPROTO op_cvtpi2ps(void)
-{
- XMMReg *d = (Reg *)((char *)env + PARAM1);
- MMXReg *s = (MMXReg *)((char *)env + PARAM2);
- d->XMM_S(0) = int32_to_float32(s->MMX_L(0), &env->sse_status);
- d->XMM_S(1) = int32_to_float32(s->MMX_L(1), &env->sse_status);
-}
-
-void OPPROTO op_cvtpi2pd(void)
-{
- XMMReg *d = (Reg *)((char *)env + PARAM1);
- MMXReg *s = (MMXReg *)((char *)env + PARAM2);
- d->XMM_D(0) = int32_to_float64(s->MMX_L(0), &env->sse_status);
- d->XMM_D(1) = int32_to_float64(s->MMX_L(1), &env->sse_status);
-}
-
-void OPPROTO op_cvtsi2ss(void)
-{
- XMMReg *d = (Reg *)((char *)env + PARAM1);
- d->XMM_S(0) = int32_to_float32(T0, &env->sse_status);
-}
-
-void OPPROTO op_cvtsi2sd(void)
-{
- XMMReg *d = (Reg *)((char *)env + PARAM1);
- d->XMM_D(0) = int32_to_float64(T0, &env->sse_status);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_cvtsq2ss(void)
-{
- XMMReg *d = (Reg *)((char *)env + PARAM1);
- d->XMM_S(0) = int64_to_float32(T0, &env->sse_status);
-}
-
-void OPPROTO op_cvtsq2sd(void)
-{
- XMMReg *d = (Reg *)((char *)env + PARAM1);
- d->XMM_D(0) = int64_to_float64(T0, &env->sse_status);
-}
-#endif
-
-/* float to integer */
-void OPPROTO op_cvtps2dq(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
- d->XMM_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
- d->XMM_L(2) = float32_to_int32(s->XMM_S(2), &env->sse_status);
- d->XMM_L(3) = float32_to_int32(s->XMM_S(3), &env->sse_status);
-}
-
-void OPPROTO op_cvtpd2dq(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
- d->XMM_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
- d->XMM_Q(1) = 0;
-}
-
-void OPPROTO op_cvtps2pi(void)
-{
- MMXReg *d = (MMXReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->MMX_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
- d->MMX_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
-}
-
-void OPPROTO op_cvtpd2pi(void)
-{
- MMXReg *d = (MMXReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->MMX_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
- d->MMX_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
-}
-
-void OPPROTO op_cvtss2si(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float32_to_int32(s->XMM_S(0), &env->sse_status);
-}
-
-void OPPROTO op_cvtsd2si(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float64_to_int32(s->XMM_D(0), &env->sse_status);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_cvtss2sq(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float32_to_int64(s->XMM_S(0), &env->sse_status);
-}
-
-void OPPROTO op_cvtsd2sq(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float64_to_int64(s->XMM_D(0), &env->sse_status);
-}
-#endif
-
-/* float to integer truncated */
-void OPPROTO op_cvttps2dq(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
- d->XMM_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
- d->XMM_L(2) = float32_to_int32_round_to_zero(s->XMM_S(2), &env->sse_status);
- d->XMM_L(3) = float32_to_int32_round_to_zero(s->XMM_S(3), &env->sse_status);
-}
-
-void OPPROTO op_cvttpd2dq(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
- d->XMM_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
- d->XMM_Q(1) = 0;
-}
-
-void OPPROTO op_cvttps2pi(void)
-{
- MMXReg *d = (MMXReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->MMX_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
- d->MMX_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
-}
-
-void OPPROTO op_cvttpd2pi(void)
-{
- MMXReg *d = (MMXReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->MMX_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
- d->MMX_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
-}
-
-void OPPROTO op_cvttss2si(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
-}
-
-void OPPROTO op_cvttsd2si(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_cvttss2sq(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status);
-}
-
-void OPPROTO op_cvttsd2sq(void)
-{
- XMMReg *s = (XMMReg *)((char *)env + PARAM1);
- T0 = float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status);
-}
-#endif
-
-void OPPROTO op_rsqrtps(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
- d->XMM_S(1) = approx_rsqrt(s->XMM_S(1));
- d->XMM_S(2) = approx_rsqrt(s->XMM_S(2));
- d->XMM_S(3) = approx_rsqrt(s->XMM_S(3));
-}
-
-void OPPROTO op_rsqrtss(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
-}
-
-void OPPROTO op_rcpps(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_S(0) = approx_rcp(s->XMM_S(0));
- d->XMM_S(1) = approx_rcp(s->XMM_S(1));
- d->XMM_S(2) = approx_rcp(s->XMM_S(2));
- d->XMM_S(3) = approx_rcp(s->XMM_S(3));
-}
-
-void OPPROTO op_rcpss(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_S(0) = approx_rcp(s->XMM_S(0));
-}
-
-void OPPROTO op_haddps(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- XMMReg r;
- r.XMM_S(0) = d->XMM_S(0) + d->XMM_S(1);
- r.XMM_S(1) = d->XMM_S(2) + d->XMM_S(3);
- r.XMM_S(2) = s->XMM_S(0) + s->XMM_S(1);
- r.XMM_S(3) = s->XMM_S(2) + s->XMM_S(3);
- *d = r;
-}
-
-void OPPROTO op_haddpd(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- XMMReg r;
- r.XMM_D(0) = d->XMM_D(0) + d->XMM_D(1);
- r.XMM_D(1) = s->XMM_D(0) + s->XMM_D(1);
- *d = r;
-}
-
-void OPPROTO op_hsubps(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- XMMReg r;
- r.XMM_S(0) = d->XMM_S(0) - d->XMM_S(1);
- r.XMM_S(1) = d->XMM_S(2) - d->XMM_S(3);
- r.XMM_S(2) = s->XMM_S(0) - s->XMM_S(1);
- r.XMM_S(3) = s->XMM_S(2) - s->XMM_S(3);
- *d = r;
-}
-
-void OPPROTO op_hsubpd(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- XMMReg r;
- r.XMM_D(0) = d->XMM_D(0) - d->XMM_D(1);
- r.XMM_D(1) = s->XMM_D(0) - s->XMM_D(1);
- *d = r;
-}
-
-void OPPROTO op_addsubps(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_S(0) = d->XMM_S(0) - s->XMM_S(0);
- d->XMM_S(1) = d->XMM_S(1) + s->XMM_S(1);
- d->XMM_S(2) = d->XMM_S(2) - s->XMM_S(2);
- d->XMM_S(3) = d->XMM_S(3) + s->XMM_S(3);
-}
-
-void OPPROTO op_addsubpd(void)
-{
- XMMReg *d = (XMMReg *)((char *)env + PARAM1);
- XMMReg *s = (XMMReg *)((char *)env + PARAM2);
- d->XMM_D(0) = d->XMM_D(0) - s->XMM_D(0);
- d->XMM_D(1) = d->XMM_D(1) + s->XMM_D(1);
-}
-
-/* XXX: unordered */
-#define SSE_OP_CMP(name, F)\
-void OPPROTO op_ ## name ## ps (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
- d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
- d->XMM_L(2) = F(32, d->XMM_S(2), s->XMM_S(2));\
- d->XMM_L(3) = F(32, d->XMM_S(3), s->XMM_S(3));\
-}\
-\
-void OPPROTO op_ ## name ## ss (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
-}\
-void OPPROTO op_ ## name ## pd (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
- d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
-}\
-\
-void OPPROTO op_ ## name ## sd (void)\
-{\
- Reg *d, *s;\
- d = (Reg *)((char *)env + PARAM1);\
- s = (Reg *)((char *)env + PARAM2);\
- d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
-}
-
-#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
-#define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
-#define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
-#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0
-#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
-#define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
-#define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
-#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1
-
-SSE_OP_CMP(cmpeq, FPU_CMPEQ)
-SSE_OP_CMP(cmplt, FPU_CMPLT)
-SSE_OP_CMP(cmple, FPU_CMPLE)
-SSE_OP_CMP(cmpunord, FPU_CMPUNORD)
-SSE_OP_CMP(cmpneq, FPU_CMPNEQ)
-SSE_OP_CMP(cmpnlt, FPU_CMPNLT)
-SSE_OP_CMP(cmpnle, FPU_CMPNLE)
-SSE_OP_CMP(cmpord, FPU_CMPORD)
-
-const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
-
-void OPPROTO op_ucomiss(void)
-{
- int ret;
- float32 s0, s1;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- s0 = d->XMM_S(0);
- s1 = s->XMM_S(0);
- ret = float32_compare_quiet(s0, s1, &env->sse_status);
- CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
-}
-
-void OPPROTO op_comiss(void)
-{
- int ret;
- float32 s0, s1;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- s0 = d->XMM_S(0);
- s1 = s->XMM_S(0);
- ret = float32_compare(s0, s1, &env->sse_status);
- CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
-}
-
-void OPPROTO op_ucomisd(void)
-{
- int ret;
- float64 d0, d1;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- d0 = d->XMM_D(0);
- d1 = s->XMM_D(0);
- ret = float64_compare_quiet(d0, d1, &env->sse_status);
- CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
-}
-
-void OPPROTO op_comisd(void)
-{
- int ret;
- float64 d0, d1;
- Reg *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- d0 = d->XMM_D(0);
- d1 = s->XMM_D(0);
- ret = float64_compare(d0, d1, &env->sse_status);
- CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
-}
-
-void OPPROTO op_movmskps(void)
-{
- int b0, b1, b2, b3;
- Reg *s;
- s = (Reg *)((char *)env + PARAM1);
- b0 = s->XMM_L(0) >> 31;
- b1 = s->XMM_L(1) >> 31;
- b2 = s->XMM_L(2) >> 31;
- b3 = s->XMM_L(3) >> 31;
- T0 = b0 | (b1 << 1) | (b2 << 2) | (b3 << 3);
-}
-
-void OPPROTO op_movmskpd(void)
-{
- int b0, b1;
- Reg *s;
- s = (Reg *)((char *)env + PARAM1);
- b0 = s->XMM_L(1) >> 31;
- b1 = s->XMM_L(3) >> 31;
- T0 = b0 | (b1 << 1);
-}
-
-#endif
-
-void OPPROTO glue(op_pmovmskb, SUFFIX)(void)
-{
- Reg *s;
- s = (Reg *)((char *)env + PARAM1);
- T0 = 0;
- T0 |= (s->XMM_B(0) >> 7);
- T0 |= (s->XMM_B(1) >> 6) & 0x02;
- T0 |= (s->XMM_B(2) >> 5) & 0x04;
- T0 |= (s->XMM_B(3) >> 4) & 0x08;
- T0 |= (s->XMM_B(4) >> 3) & 0x10;
- T0 |= (s->XMM_B(5) >> 2) & 0x20;
- T0 |= (s->XMM_B(6) >> 1) & 0x40;
- T0 |= (s->XMM_B(7)) & 0x80;
-#if SHIFT == 1
- T0 |= (s->XMM_B(8) << 1) & 0x0100;
- T0 |= (s->XMM_B(9) << 2) & 0x0200;
- T0 |= (s->XMM_B(10) << 3) & 0x0400;
- T0 |= (s->XMM_B(11) << 4) & 0x0800;
- T0 |= (s->XMM_B(12) << 5) & 0x1000;
- T0 |= (s->XMM_B(13) << 6) & 0x2000;
- T0 |= (s->XMM_B(14) << 7) & 0x4000;
- T0 |= (s->XMM_B(15) << 8) & 0x8000;
-#endif
-}
-
-void OPPROTO glue(op_pinsrw, SUFFIX) (void)
-{
- Reg *d = (Reg *)((char *)env + PARAM1);
- int pos = PARAM2;
-
- d->W(pos) = T0;
-}
-
-void OPPROTO glue(op_pextrw, SUFFIX) (void)
-{
- Reg *s = (Reg *)((char *)env + PARAM1);
- int pos = PARAM2;
-
- T0 = s->W(pos);
-}
-
-void OPPROTO glue(op_packsswb, SUFFIX) (void)
-{
- Reg r, *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- r.B(0) = satsb((int16_t)d->W(0));
- r.B(1) = satsb((int16_t)d->W(1));
- r.B(2) = satsb((int16_t)d->W(2));
- r.B(3) = satsb((int16_t)d->W(3));
-#if SHIFT == 1
- r.B(4) = satsb((int16_t)d->W(4));
- r.B(5) = satsb((int16_t)d->W(5));
- r.B(6) = satsb((int16_t)d->W(6));
- r.B(7) = satsb((int16_t)d->W(7));
-#endif
- r.B((4 << SHIFT) + 0) = satsb((int16_t)s->W(0));
- r.B((4 << SHIFT) + 1) = satsb((int16_t)s->W(1));
- r.B((4 << SHIFT) + 2) = satsb((int16_t)s->W(2));
- r.B((4 << SHIFT) + 3) = satsb((int16_t)s->W(3));
-#if SHIFT == 1
- r.B(12) = satsb((int16_t)s->W(4));
- r.B(13) = satsb((int16_t)s->W(5));
- r.B(14) = satsb((int16_t)s->W(6));
- r.B(15) = satsb((int16_t)s->W(7));
-#endif
- *d = r;
-}
-
-void OPPROTO glue(op_packuswb, SUFFIX) (void)
-{
- Reg r, *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- r.B(0) = satub((int16_t)d->W(0));
- r.B(1) = satub((int16_t)d->W(1));
- r.B(2) = satub((int16_t)d->W(2));
- r.B(3) = satub((int16_t)d->W(3));
-#if SHIFT == 1
- r.B(4) = satub((int16_t)d->W(4));
- r.B(5) = satub((int16_t)d->W(5));
- r.B(6) = satub((int16_t)d->W(6));
- r.B(7) = satub((int16_t)d->W(7));
-#endif
- r.B((4 << SHIFT) + 0) = satub((int16_t)s->W(0));
- r.B((4 << SHIFT) + 1) = satub((int16_t)s->W(1));
- r.B((4 << SHIFT) + 2) = satub((int16_t)s->W(2));
- r.B((4 << SHIFT) + 3) = satub((int16_t)s->W(3));
-#if SHIFT == 1
- r.B(12) = satub((int16_t)s->W(4));
- r.B(13) = satub((int16_t)s->W(5));
- r.B(14) = satub((int16_t)s->W(6));
- r.B(15) = satub((int16_t)s->W(7));
-#endif
- *d = r;
-}
-
-void OPPROTO glue(op_packssdw, SUFFIX) (void)
-{
- Reg r, *d, *s;
- d = (Reg *)((char *)env + PARAM1);
- s = (Reg *)((char *)env + PARAM2);
-
- r.W(0) = satsw(d->L(0));
- r.W(1) = satsw(d->L(1));
-#if SHIFT == 1
- r.W(2) = satsw(d->L(2));
- r.W(3) = satsw(d->L(3));
-#endif
- r.W((2 << SHIFT) + 0) = satsw(s->L(0));
- r.W((2 << SHIFT) + 1) = satsw(s->L(1));
-#if SHIFT == 1
- r.W(6) = satsw(s->L(2));
- r.W(7) = satsw(s->L(3));
-#endif
- *d = r;
-}
-
-#define UNPCK_OP(base_name, base) \
- \
-void OPPROTO glue(op_punpck ## base_name ## bw, SUFFIX) (void) \
-{ \
- Reg r, *d, *s; \
- d = (Reg *)((char *)env + PARAM1); \
- s = (Reg *)((char *)env + PARAM2); \
- \
- r.B(0) = d->B((base << (SHIFT + 2)) + 0); \
- r.B(1) = s->B((base << (SHIFT + 2)) + 0); \
- r.B(2) = d->B((base << (SHIFT + 2)) + 1); \
- r.B(3) = s->B((base << (SHIFT + 2)) + 1); \
- r.B(4) = d->B((base << (SHIFT + 2)) + 2); \
- r.B(5) = s->B((base << (SHIFT + 2)) + 2); \
- r.B(6) = d->B((base << (SHIFT + 2)) + 3); \
- r.B(7) = s->B((base << (SHIFT + 2)) + 3); \
-XMM_ONLY( \
- r.B(8) = d->B((base << (SHIFT + 2)) + 4); \
- r.B(9) = s->B((base << (SHIFT + 2)) + 4); \
- r.B(10) = d->B((base << (SHIFT + 2)) + 5); \
- r.B(11) = s->B((base << (SHIFT + 2)) + 5); \
- r.B(12) = d->B((base << (SHIFT + 2)) + 6); \
- r.B(13) = s->B((base << (SHIFT + 2)) + 6); \
- r.B(14) = d->B((base << (SHIFT + 2)) + 7); \
- r.B(15) = s->B((base << (SHIFT + 2)) + 7); \
-) \
- *d = r; \
-} \
- \
-void OPPROTO glue(op_punpck ## base_name ## wd, SUFFIX) (void) \
-{ \
- Reg r, *d, *s; \
- d = (Reg *)((char *)env + PARAM1); \
- s = (Reg *)((char *)env + PARAM2); \
- \
- r.W(0) = d->W((base << (SHIFT + 1)) + 0); \
- r.W(1) = s->W((base << (SHIFT + 1)) + 0); \
- r.W(2) = d->W((base << (SHIFT + 1)) + 1); \
- r.W(3) = s->W((base << (SHIFT + 1)) + 1); \
-XMM_ONLY( \
- r.W(4) = d->W((base << (SHIFT + 1)) + 2); \
- r.W(5) = s->W((base << (SHIFT + 1)) + 2); \
- r.W(6) = d->W((base << (SHIFT + 1)) + 3); \
- r.W(7) = s->W((base << (SHIFT + 1)) + 3); \
-) \
- *d = r; \
-} \
- \
-void OPPROTO glue(op_punpck ## base_name ## dq, SUFFIX) (void) \
-{ \
- Reg r, *d, *s; \
- d = (Reg *)((char *)env + PARAM1); \
- s = (Reg *)((char *)env + PARAM2); \
- \
- r.L(0) = d->L((base << SHIFT) + 0); \
- r.L(1) = s->L((base << SHIFT) + 0); \
-XMM_ONLY( \
- r.L(2) = d->L((base << SHIFT) + 1); \
- r.L(3) = s->L((base << SHIFT) + 1); \
-) \
- *d = r; \
-} \
- \
-XMM_ONLY( \
-void OPPROTO glue(op_punpck ## base_name ## qdq, SUFFIX) (void) \
-{ \
- Reg r, *d, *s; \
- d = (Reg *)((char *)env + PARAM1); \
- s = (Reg *)((char *)env + PARAM2); \
- \
- r.Q(0) = d->Q(base); \
- r.Q(1) = s->Q(base); \
- *d = r; \
-} \
-)
-
-UNPCK_OP(l, 0)
-UNPCK_OP(h, 1)
-
-#undef SHIFT
-#undef XMM_ONLY
-#undef Reg
-#undef B
-#undef W
-#undef L
-#undef Q
-#undef SUFFIX
diff --git a/tools/ioemu/target-i386/ops_template.h b/tools/ioemu/target-i386/ops_template.h
deleted file mode 100644
index 373b77a245..0000000000
--- a/tools/ioemu/target-i386/ops_template.h
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * i386 micro operations (included several times to generate
- * different operand sizes)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#define DATA_BITS (1 << (3 + SHIFT))
-#define SHIFT_MASK (DATA_BITS - 1)
-#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
-#if DATA_BITS <= 32
-#define SHIFT1_MASK 0x1f
-#else
-#define SHIFT1_MASK 0x3f
-#endif
-
-#if DATA_BITS == 8
-#define SUFFIX b
-#define DATA_TYPE uint8_t
-#define DATA_STYPE int8_t
-#define DATA_MASK 0xff
-#elif DATA_BITS == 16
-#define SUFFIX w
-#define DATA_TYPE uint16_t
-#define DATA_STYPE int16_t
-#define DATA_MASK 0xffff
-#elif DATA_BITS == 32
-#define SUFFIX l
-#define DATA_TYPE uint32_t
-#define DATA_STYPE int32_t
-#define DATA_MASK 0xffffffff
-#elif DATA_BITS == 64
-#define SUFFIX q
-#define DATA_TYPE uint64_t
-#define DATA_STYPE int64_t
-#define DATA_MASK 0xffffffffffffffffULL
-#else
-#error unhandled operand size
-#endif
-
-/* dynamic flags computation */
-
-static int glue(compute_all_add, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_SRC;
- src2 = CC_DST - CC_SRC;
- cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_add, SUFFIX)(void)
-{
- int cf;
- target_long src1;
- src1 = CC_SRC;
- cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
- return cf;
-}
-
-static int glue(compute_all_adc, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_SRC;
- src2 = CC_DST - CC_SRC - 1;
- cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_adc, SUFFIX)(void)
-{
- int cf;
- target_long src1;
- src1 = CC_SRC;
- cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
- return cf;
-}
-
-static int glue(compute_all_sub, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_sub, SUFFIX)(void)
-{
- int cf;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
- return cf;
-}
-
-static int glue(compute_all_sbb, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC + 1;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_sbb, SUFFIX)(void)
-{
- int cf;
- target_long src1, src2;
- src1 = CC_DST + CC_SRC + 1;
- src2 = CC_SRC;
- cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
- return cf;
-}
-
-static int glue(compute_all_logic, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = 0;
- pf = parity_table[(uint8_t)CC_DST];
- af = 0;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = 0;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_logic, SUFFIX)(void)
-{
- return 0;
-}
-
-static int glue(compute_all_inc, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST - 1;
- src2 = 1;
- cf = CC_SRC;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
- return cf | pf | af | zf | sf | of;
-}
-
-#if DATA_BITS == 32
-static int glue(compute_c_inc, SUFFIX)(void)
-{
- return CC_SRC;
-}
-#endif
-
-static int glue(compute_all_dec, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- target_long src1, src2;
- src1 = CC_DST + 1;
- src2 = 1;
- cf = CC_SRC;
- pf = parity_table[(uint8_t)CC_DST];
- af = (CC_DST ^ src1 ^ src2) & 0x10;
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_all_shl, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
- pf = parity_table[(uint8_t)CC_DST];
- af = 0; /* undefined */
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- /* of is defined if shift count == 1 */
- of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-static int glue(compute_c_shl, SUFFIX)(void)
-{
- return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
-}
-
-#if DATA_BITS == 32
-static int glue(compute_c_sar, SUFFIX)(void)
-{
- return CC_SRC & 1;
-}
-#endif
-
-static int glue(compute_all_sar, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = CC_SRC & 1;
- pf = parity_table[(uint8_t)CC_DST];
- af = 0; /* undefined */
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- /* of is defined if shift count == 1 */
- of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
- return cf | pf | af | zf | sf | of;
-}
-
-#if DATA_BITS == 32
-static int glue(compute_c_mul, SUFFIX)(void)
-{
- int cf;
- cf = (CC_SRC != 0);
- return cf;
-}
-#endif
-
-/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
- CF are modified and it is slower to do that. */
-static int glue(compute_all_mul, SUFFIX)(void)
-{
- int cf, pf, af, zf, sf, of;
- cf = (CC_SRC != 0);
- pf = parity_table[(uint8_t)CC_DST];
- af = 0; /* undefined */
- zf = ((DATA_TYPE)CC_DST == 0) << 6;
- sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
- of = cf << 11;
- return cf | pf | af | zf | sf | of;
-}
-
-/* various optimized jumps cases */
-
-void OPPROTO glue(op_jb_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jz_sub, SUFFIX)(void)
-{
- if ((DATA_TYPE)CC_DST == 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jnz_sub, SUFFIX)(void)
-{
- if ((DATA_TYPE)CC_DST != 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_js_sub, SUFFIX)(void)
-{
- if (CC_DST & SIGN_MASK)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jl_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jle_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-/* oldies */
-
-#if DATA_BITS >= 16
-
-void OPPROTO glue(op_loopnz, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX != 0 && !(T0 & CC_Z))
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_loopz, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX != 0 && (T0 & CC_Z))
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX == 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-void OPPROTO glue(op_jnz_ecx, SUFFIX)(void)
-{
- if ((DATA_TYPE)ECX != 0)
- GOTO_LABEL_PARAM(1);
- FORCE_RET();
-}
-
-#endif
-
-/* various optimized set cases */
-
-void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
-}
-
-void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
-{
- T0 = ((DATA_TYPE)CC_DST == 0);
-}
-
-void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
-}
-
-void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
-{
- T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
-}
-
-void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
-}
-
-void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
-{
- target_long src1, src2;
- src1 = CC_DST + CC_SRC;
- src2 = CC_SRC;
-
- T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
-}
-
-/* shifts */
-
-void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT1_MASK;
- T0 = T0 << count;
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT1_MASK;
- T0 &= DATA_MASK;
- T0 = T0 >> count;
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- src = (DATA_STYPE)T0;
- T0 = src >> count;
- FORCE_RET();
-}
-
-#undef MEM_WRITE
-#include "ops_template_mem.h"
-
-#define MEM_WRITE 0
-#include "ops_template_mem.h"
-
-#if !defined(CONFIG_USER_ONLY)
-#define MEM_WRITE 1
-#include "ops_template_mem.h"
-
-#define MEM_WRITE 2
-#include "ops_template_mem.h"
-#endif
-
-/* bit operations */
-#if DATA_BITS >= 16
-
-void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- CC_SRC = T0 >> count;
-}
-
-void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- T1 = T0 >> count;
- T0 |= (((target_long)1) << count);
-}
-
-void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- T1 = T0 >> count;
- T0 &= ~(((target_long)1) << count);
-}
-
-void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- T1 = T0 >> count;
- T0 ^= (((target_long)1) << count);
-}
-
-void OPPROTO glue(glue(op_add_bit, SUFFIX), _A0_T1)(void)
-{
- A0 += ((DATA_STYPE)T1 >> (3 + SHIFT)) << SHIFT;
-}
-
-void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
-{
- int count;
- target_long res;
-
- res = T0 & DATA_MASK;
- if (res != 0) {
- count = 0;
- while ((res & 1) == 0) {
- count++;
- res >>= 1;
- }
- T1 = count;
- CC_DST = 1; /* ZF = 0 */
- } else {
- CC_DST = 0; /* ZF = 1 */
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
-{
- int count;
- target_long res;
-
- res = T0 & DATA_MASK;
- if (res != 0) {
- count = DATA_BITS - 1;
- while ((res & SIGN_MASK) == 0) {
- count--;
- res <<= 1;
- }
- T1 = count;
- CC_DST = 1; /* ZF = 0 */
- } else {
- CC_DST = 0; /* ZF = 1 */
- }
- FORCE_RET();
-}
-
-#endif
-
-#if DATA_BITS == 32
-void OPPROTO op_update_bt_cc(void)
-{
- CC_SRC = T1;
-}
-#endif
-
-/* string operations */
-
-void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
-{
- T0 = DF << SHIFT;
-}
-
-/* port I/O */
-#if DATA_BITS <= 32
-void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
-{
- glue(cpu_out, SUFFIX)(env, T0, T1 & DATA_MASK);
-}
-
-void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
-{
- T1 = glue(cpu_in, SUFFIX)(env, T0);
-}
-
-void OPPROTO glue(glue(op_in, SUFFIX), _DX_T0)(void)
-{
- T0 = glue(cpu_in, SUFFIX)(env, EDX & 0xffff);
-}
-
-void OPPROTO glue(glue(op_out, SUFFIX), _DX_T0)(void)
-{
- glue(cpu_out, SUFFIX)(env, EDX & 0xffff, T0);
-}
-
-void OPPROTO glue(glue(op_check_io, SUFFIX), _T0)(void)
-{
- glue(glue(check_io, SUFFIX), _T0)();
-}
-
-void OPPROTO glue(glue(op_check_io, SUFFIX), _DX)(void)
-{
- glue(glue(check_io, SUFFIX), _DX)();
-}
-#endif
-
-#undef DATA_BITS
-#undef SHIFT_MASK
-#undef SHIFT1_MASK
-#undef SIGN_MASK
-#undef DATA_TYPE
-#undef DATA_STYPE
-#undef DATA_MASK
-#undef SUFFIX
diff --git a/tools/ioemu/target-i386/ops_template_mem.h b/tools/ioemu/target-i386/ops_template_mem.h
deleted file mode 100644
index 9f72a8c965..0000000000
--- a/tools/ioemu/target-i386/ops_template_mem.h
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * i386 micro operations (included several times to generate
- * different operand sizes)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifdef MEM_WRITE
-
-#if MEM_WRITE == 0
-
-#if DATA_BITS == 8
-#define MEM_SUFFIX b_raw
-#elif DATA_BITS == 16
-#define MEM_SUFFIX w_raw
-#elif DATA_BITS == 32
-#define MEM_SUFFIX l_raw
-#elif DATA_BITS == 64
-#define MEM_SUFFIX q_raw
-#endif
-
-#elif MEM_WRITE == 1
-
-#if DATA_BITS == 8
-#define MEM_SUFFIX b_kernel
-#elif DATA_BITS == 16
-#define MEM_SUFFIX w_kernel
-#elif DATA_BITS == 32
-#define MEM_SUFFIX l_kernel
-#elif DATA_BITS == 64
-#define MEM_SUFFIX q_kernel
-#endif
-
-#elif MEM_WRITE == 2
-
-#if DATA_BITS == 8
-#define MEM_SUFFIX b_user
-#elif DATA_BITS == 16
-#define MEM_SUFFIX w_user
-#elif DATA_BITS == 32
-#define MEM_SUFFIX l_user
-#elif DATA_BITS == 64
-#define MEM_SUFFIX q_user
-#endif
-
-#else
-
-#error invalid MEM_WRITE
-
-#endif
-
-#else
-
-#define MEM_SUFFIX SUFFIX
-
-#endif
-
-void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- if (T1 & SHIFT1_MASK) {
- count = T1 & SHIFT_MASK;
- src = T0;
- T0 &= DATA_MASK;
- T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#else
- /* gcc 3.2 workaround. This is really a bug in gcc. */
- asm volatile("" : : "r" (T0));
-#endif
- CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- (T0 & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- if (T1 & SHIFT1_MASK) {
- count = T1 & SHIFT_MASK;
- src = T0;
- T0 &= DATA_MASK;
- T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#else
- /* gcc 3.2 workaround. This is really a bug in gcc. */
- asm volatile("" : : "r" (T0));
-#endif
- CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((T0 >> (DATA_BITS - 1)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count, eflags;
- target_ulong src;
- target_long res;
-
- count = T1 & SHIFT1_MASK;
-#if DATA_BITS == 16
- count = rclw_table[count];
-#elif DATA_BITS == 8
- count = rclb_table[count];
-#endif
- if (count) {
- eflags = cc_table[CC_OP].compute_all();
- T0 &= DATA_MASK;
- src = T0;
- res = (T0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
- if (count > 1)
- res |= T0 >> (DATA_BITS + 1 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((src >> (DATA_BITS - count)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count, eflags;
- target_ulong src;
- target_long res;
-
- count = T1 & SHIFT1_MASK;
-#if DATA_BITS == 16
- count = rclw_table[count];
-#elif DATA_BITS == 8
- count = rclb_table[count];
-#endif
- if (count) {
- eflags = cc_table[CC_OP].compute_all();
- T0 &= DATA_MASK;
- src = T0;
- res = (T0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
- if (count > 1)
- res |= T0 << (DATA_BITS + 1 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((src >> (count - 1)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- if (count) {
- src = (DATA_TYPE)T0 << (count - 1);
- T0 = T0 << count;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = src;
- CC_DST = T0;
- CC_OP = CC_OP_SHLB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- if (count) {
- T0 &= DATA_MASK;
- src = T0 >> (count - 1);
- T0 = T0 >> count;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = src;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- target_long src;
-
- count = T1 & SHIFT1_MASK;
- if (count) {
- src = (DATA_STYPE)T0;
- T0 = src >> count;
- src = src >> (count - 1);
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = src;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
-#if DATA_BITS == 16
-/* XXX: overflow flag might be incorrect in some cases in shldw */
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- unsigned int res, tmp;
- count = PARAM1;
- T1 &= 0xffff;
- res = T1 | (T0 << 16);
- tmp = res >> (32 - count);
- res <<= count;
- if (count > 16)
- res |= T1 << (count - 16);
- T0 = res >> 16;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- unsigned int res, tmp;
- count = ECX & 0x1f;
- if (count) {
- T1 &= 0xffff;
- res = T1 | (T0 << 16);
- tmp = res >> (32 - count);
- res <<= count;
- if (count > 16)
- res |= T1 << (count - 16);
- T0 = res >> 16;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- unsigned int res, tmp;
-
- count = PARAM1;
- res = (T0 & 0xffff) | (T1 << 16);
- tmp = res >> (count - 1);
- res >>= count;
- if (count > 16)
- res |= T1 << (32 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- unsigned int res, tmp;
-
- count = ECX & 0x1f;
- if (count) {
- res = (T0 & 0xffff) | (T1 << 16);
- tmp = res >> (count - 1);
- res >>= count;
- if (count > 16)
- res |= T1 << (32 - count);
- T0 = res;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-#endif
-
-#if DATA_BITS >= 32
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = PARAM1;
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 << (count - 1);
- T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = ECX & SHIFT1_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 << (count - 1);
- T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SHLB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = PARAM1;
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 >> (count - 1);
- T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
-}
-
-
-void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- target_long tmp;
-
- count = ECX & SHIFT1_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- tmp = T0 >> (count - 1);
- T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = tmp;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-#endif
-
-/* carry add/sub (we only need to set CC_OP differently) */
-
-void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int cf;
- cf = cc_table[CC_OP].compute_c();
- T0 = T0 + T1 + cf;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = T1;
- CC_DST = T0;
- CC_OP = CC_OP_ADDB + SHIFT + cf * 4;
-}
-
-void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
-{
- int cf;
- cf = cc_table[CC_OP].compute_c();
- T0 = T0 - T1 - cf;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- CC_SRC = T1;
- CC_DST = T0;
- CC_OP = CC_OP_SUBB + SHIFT + cf * 4;
-}
-
-void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
-{
- target_ulong src, dst;
-
- src = T0;
- dst = EAX - T0;
- if ((DATA_TYPE)dst == 0) {
- T0 = T1;
-#ifdef MEM_WRITE
- glue(st, MEM_SUFFIX)(A0, T0);
-#endif
- } else {
- EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
- }
- CC_SRC = src;
- CC_DST = dst;
- FORCE_RET();
-}
-
-#undef MEM_SUFFIX
-#undef MEM_WRITE
diff --git a/tools/ioemu/target-i386/translate-copy.c b/tools/ioemu/target-i386/translate-copy.c
deleted file mode 100644
index cf8bd5ab3f..0000000000
--- a/tools/ioemu/target-i386/translate-copy.c
+++ /dev/null
@@ -1,1323 +0,0 @@
-/*
- * i386 on i386 translation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-
-#ifdef USE_CODE_COPY
-
-#include <signal.h>
-#include <sys/mman.h>
-#include <sys/ucontext.h>
-
-extern char exec_loop;
-
-/* operand size */
-enum {
- OT_BYTE = 0,
- OT_WORD,
- OT_LONG,
- OT_QUAD,
-};
-
-#define PREFIX_REPZ 0x01
-#define PREFIX_REPNZ 0x02
-#define PREFIX_LOCK 0x04
-#define PREFIX_DATA 0x08
-#define PREFIX_ADR 0x10
-
-typedef struct DisasContext {
- /* current insn context */
- int override; /* -1 if no override */
- int prefix;
- int aflag, dflag;
- target_ulong pc; /* pc = eip + cs_base */
- int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
- static state change (stop translation) */
- /* code output */
- uint8_t *gen_code_ptr;
- uint8_t *gen_code_start;
-
- /* current block context */
- target_ulong cs_base; /* base of CS segment */
- int pe; /* protected mode */
- int code32; /* 32 bit code segment */
- int f_st; /* currently unused */
- int vm86; /* vm86 mode */
- int cpl;
- int iopl;
- int flags;
- struct TranslationBlock *tb;
-} DisasContext;
-
-#define CPU_FIELD_OFFSET(field) offsetof(CPUState, field)
-
-#define CPU_SEG 0x64 /* fs override */
-
-static inline void gb(DisasContext *s, uint32_t val)
-{
- *s->gen_code_ptr++ = val;
-}
-
-static inline void gw(DisasContext *s, uint32_t val)
-{
- *s->gen_code_ptr++ = val;
- *s->gen_code_ptr++ = val >> 8;
-}
-
-static inline void gl(DisasContext *s, uint32_t val)
-{
- *s->gen_code_ptr++ = val;
- *s->gen_code_ptr++ = val >> 8;
- *s->gen_code_ptr++ = val >> 16;
- *s->gen_code_ptr++ = val >> 24;
-}
-
-static inline void gjmp(DisasContext *s, long val)
-{
- gb(s, 0xe9); /* jmp */
- gl(s, val - (long)(s->gen_code_ptr + 4));
-}
-
-static inline void gen_movl_addr_im(DisasContext *s,
- uint32_t addr, uint32_t val)
-{
- gb(s, CPU_SEG); /* seg movl im, addr */
- gb(s, 0xc7);
- gb(s, 0x05);
- gl(s, addr);
- gl(s, val);
-}
-
-static inline void gen_movw_addr_im(DisasContext *s,
- uint32_t addr, uint32_t val)
-{
- gb(s, CPU_SEG); /* seg movl im, addr */
- gb(s, 0x66);
- gb(s, 0xc7);
- gb(s, 0x05);
- gl(s, addr);
- gw(s, val);
-}
-
-
-static void gen_jmp(DisasContext *s, uint32_t target_eip)
-{
- TranslationBlock *tb = s->tb;
-
- gb(s, 0xe9); /* jmp */
- tb->tb_jmp_offset[0] = s->gen_code_ptr - s->gen_code_start;
- gl(s, 0);
-
- tb->tb_next_offset[0] = s->gen_code_ptr - s->gen_code_start;
- gen_movl_addr_im(s, CPU_FIELD_OFFSET(eip), target_eip);
- gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), (uint32_t)tb);
- gjmp(s, (long)&exec_loop);
-
- s->is_jmp = 1;
-}
-
-static void gen_jcc(DisasContext *s, int op,
- uint32_t target_eip, uint32_t next_eip)
-{
- TranslationBlock *tb = s->tb;
-
- gb(s, 0x0f); /* jcc */
- gb(s, 0x80 + op);
- tb->tb_jmp_offset[0] = s->gen_code_ptr - s->gen_code_start;
- gl(s, 0);
- gb(s, 0xe9); /* jmp */
- tb->tb_jmp_offset[1] = s->gen_code_ptr - s->gen_code_start;
- gl(s, 0);
-
- tb->tb_next_offset[0] = s->gen_code_ptr - s->gen_code_start;
- gen_movl_addr_im(s, CPU_FIELD_OFFSET(eip), target_eip);
- gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), (uint32_t)tb);
- gjmp(s, (long)&exec_loop);
-
- tb->tb_next_offset[1] = s->gen_code_ptr - s->gen_code_start;
- gen_movl_addr_im(s, CPU_FIELD_OFFSET(eip), next_eip);
- gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), (uint32_t)tb | 1);
- gjmp(s, (long)&exec_loop);
-
- s->is_jmp = 1;
-}
-
-static void gen_eob(DisasContext *s)
-{
- gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), 0);
- gjmp(s, (long)&exec_loop);
-
- s->is_jmp = 1;
-}
-
-static inline void gen_lea_modrm(DisasContext *s, int modrm)
-{
- int havesib;
- int base, disp;
- int index;
- int scale;
- int mod, rm, code;
-
- mod = (modrm >> 6) & 3;
- rm = modrm & 7;
-
- if (s->aflag) {
-
- havesib = 0;
- base = rm;
- index = 0;
- scale = 0;
-
- if (base == 4) {
- havesib = 1;
- code = ldub_code(s->pc++);
- scale = (code >> 6) & 3;
- index = (code >> 3) & 7;
- base = code & 7;
- }
-
- switch (mod) {
- case 0:
- if (base == 5) {
- base = -1;
- disp = ldl_code(s->pc);
- s->pc += 4;
- } else {
- disp = 0;
- }
- break;
- case 1:
- disp = (int8_t)ldub_code(s->pc++);
- break;
- default:
- case 2:
- disp = ldl_code(s->pc);
- s->pc += 4;
- break;
- }
-
- } else {
- switch (mod) {
- case 0:
- if (rm == 6) {
- disp = lduw_code(s->pc);
- s->pc += 2;
- } else {
- disp = 0;
- }
- break;
- case 1:
- disp = (int8_t)ldub_code(s->pc++);
- break;
- default:
- case 2:
- disp = lduw_code(s->pc);
- s->pc += 2;
- break;
- }
- }
-}
-
-static inline void parse_modrm(DisasContext *s, int modrm)
-{
- if ((modrm & 0xc0) != 0xc0)
- gen_lea_modrm(s, modrm);
-}
-
-static inline uint32_t insn_get(DisasContext *s, int ot)
-{
- uint32_t ret;
-
- switch(ot) {
- case OT_BYTE:
- ret = ldub_code(s->pc);
- s->pc++;
- break;
- case OT_WORD:
- ret = lduw_code(s->pc);
- s->pc += 2;
- break;
- default:
- case OT_LONG:
- ret = ldl_code(s->pc);
- s->pc += 4;
- break;
- }
- return ret;
-}
-
-/* convert one instruction. s->is_jmp is set if the translation must
- be stopped. */
-static int disas_insn(DisasContext *s)
-{
- target_ulong pc_start, pc_tmp, pc_start_insn;
- int b, prefixes, aflag, dflag, next_eip, val;
- int ot;
- int modrm, mod, op, rm;
-
- pc_start = s->pc;
- prefixes = 0;
- aflag = s->code32;
- dflag = s->code32;
- s->override = -1;
- next_byte:
- b = ldub_code(s->pc);
- s->pc++;
- /* check prefixes */
- switch (b) {
- case 0xf3:
- prefixes |= PREFIX_REPZ;
- goto next_byte;
- case 0xf2:
- prefixes |= PREFIX_REPNZ;
- goto next_byte;
- case 0xf0:
- prefixes |= PREFIX_LOCK;
- goto next_byte;
- case 0x2e:
- s->override = R_CS;
- goto next_byte;
- case 0x36:
- s->override = R_SS;
- goto next_byte;
- case 0x3e:
- s->override = R_DS;
- goto next_byte;
- case 0x26:
- s->override = R_ES;
- goto next_byte;
- case 0x64:
- s->override = R_FS;
- goto next_byte;
- case 0x65:
- s->override = R_GS;
- goto next_byte;
- case 0x66:
- prefixes |= PREFIX_DATA;
- goto next_byte;
- case 0x67:
- prefixes |= PREFIX_ADR;
- goto next_byte;
- }
-
- if (prefixes & PREFIX_DATA)
- dflag ^= 1;
- if (prefixes & PREFIX_ADR)
- aflag ^= 1;
-
- s->prefix = prefixes;
- s->aflag = aflag;
- s->dflag = dflag;
-
- /* lock generation */
- if (prefixes & PREFIX_LOCK)
- goto unsupported_op;
- if (s->override == R_FS || s->override == R_GS || s->override == R_CS)
- goto unsupported_op;
-
- pc_start_insn = s->pc - 1;
- /* now check op code */
- reswitch:
- switch(b) {
- case 0x0f:
- /**************************/
- /* extended op code */
- b = ldub_code(s->pc++) | 0x100;
- goto reswitch;
-
- /**************************/
- /* arith & logic */
- case 0x00 ... 0x05:
- case 0x08 ... 0x0d:
- case 0x10 ... 0x15:
- case 0x18 ... 0x1d:
- case 0x20 ... 0x25:
- case 0x28 ... 0x2d:
- case 0x30 ... 0x35:
- case 0x38 ... 0x3d:
- {
- int f;
- f = (b >> 1) & 3;
-
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
-
- switch(f) {
- case 0: /* OP Ev, Gv */
- modrm = ldub_code(s->pc++);
- parse_modrm(s, modrm);
- break;
- case 1: /* OP Gv, Ev */
- modrm = ldub_code(s->pc++);
- parse_modrm(s, modrm);
- break;
- case 2: /* OP A, Iv */
- insn_get(s, ot);
- break;
- }
- }
- break;
-
- case 0x80: /* GRP1 */
- case 0x81:
- case 0x82:
- case 0x83:
- {
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
-
- modrm = ldub_code(s->pc++);
- parse_modrm(s, modrm);
-
- switch(b) {
- default:
- case 0x80:
- case 0x81:
- case 0x82:
- insn_get(s, ot);
- break;
- case 0x83:
- insn_get(s, OT_BYTE);
- break;
- }
- }
- break;
-
- /**************************/
- /* inc, dec, and other misc arith */
- case 0x40 ... 0x47: /* inc Gv */
- break;
- case 0x48 ... 0x4f: /* dec Gv */
- break;
- case 0xf6: /* GRP3 */
- case 0xf7:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
-
- modrm = ldub_code(s->pc++);
- op = (modrm >> 3) & 7;
- parse_modrm(s, modrm);
-
- switch(op) {
- case 0: /* test */
- insn_get(s, ot);
- break;
- case 2: /* not */
- break;
- case 3: /* neg */
- break;
- case 4: /* mul */
- break;
- case 5: /* imul */
- break;
- case 6: /* div */
- break;
- case 7: /* idiv */
- break;
- default:
- goto illegal_op;
- }
- break;
-
- case 0xfe: /* GRP4 */
- case 0xff: /* GRP5 */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
-
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- op = (modrm >> 3) & 7;
- if (op >= 2 && b == 0xfe) {
- goto illegal_op;
- }
- pc_tmp = s->pc;
- parse_modrm(s, modrm);
-
- switch(op) {
- case 0: /* inc Ev */
- break;
- case 1: /* dec Ev */
- break;
- case 2: /* call Ev */
- /* XXX: optimize and handle MEM exceptions specifically
- fs movl %eax, regs[0]
- movl Ev, %eax
- pushl next_eip
- fs movl %eax, eip
- */
- goto unsupported_op;
- case 3: /* lcall Ev */
- goto unsupported_op;
- case 4: /* jmp Ev */
- /* XXX: optimize and handle MEM exceptions specifically
- fs movl %eax, regs[0]
- movl Ev, %eax
- fs movl %eax, eip
- */
- goto unsupported_op;
- case 5: /* ljmp Ev */
- goto unsupported_op;
- case 6: /* push Ev */
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0xa8: /* test eAX, Iv */
- case 0xa9:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- insn_get(s, ot);
- break;
-
- case 0x98: /* CWDE/CBW */
- break;
- case 0x99: /* CDQ/CWD */
- break;
- case 0x1af: /* imul Gv, Ev */
- case 0x69: /* imul Gv, Ev, I */
- case 0x6b:
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- parse_modrm(s, modrm);
- if (b == 0x69) {
- insn_get(s, ot);
- } else if (b == 0x6b) {
- insn_get(s, OT_BYTE);
- } else {
- }
- break;
-
- case 0x84: /* test Ev, Gv */
- case 0x85:
-
- case 0x1c0:
- case 0x1c1: /* xadd Ev, Gv */
-
- case 0x1b0:
- case 0x1b1: /* cmpxchg Ev, Gv */
-
- case 0x8f: /* pop Ev */
-
- case 0x88:
- case 0x89: /* mov Gv, Ev */
-
- case 0x8a:
- case 0x8b: /* mov Ev, Gv */
-
- case 0x1b6: /* movzbS Gv, Eb */
- case 0x1b7: /* movzwS Gv, Eb */
- case 0x1be: /* movsbS Gv, Eb */
- case 0x1bf: /* movswS Gv, Eb */
-
- case 0x86:
- case 0x87: /* xchg Ev, Gv */
-
- case 0xd0:
- case 0xd1: /* shift Ev,1 */
-
- case 0xd2:
- case 0xd3: /* shift Ev,cl */
-
- case 0x1a5: /* shld cl */
- case 0x1ad: /* shrd cl */
-
- case 0x190 ... 0x19f: /* setcc Gv */
-
- /* XXX: emulate cmov if not available ? */
- case 0x140 ... 0x14f: /* cmov Gv, Ev */
-
- case 0x1a3: /* bt Gv, Ev */
- case 0x1ab: /* bts */
- case 0x1b3: /* btr */
- case 0x1bb: /* btc */
-
- case 0x1bc: /* bsf */
- case 0x1bd: /* bsr */
-
- modrm = ldub_code(s->pc++);
- parse_modrm(s, modrm);
- break;
-
- case 0x1c7: /* cmpxchg8b */
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- parse_modrm(s, modrm);
- break;
-
- /**************************/
- /* push/pop */
- case 0x50 ... 0x57: /* push */
- case 0x58 ... 0x5f: /* pop */
- case 0x60: /* pusha */
- case 0x61: /* popa */
- break;
-
- case 0x68: /* push Iv */
- case 0x6a:
- ot = dflag ? OT_LONG : OT_WORD;
- if (b == 0x68)
- insn_get(s, ot);
- else
- insn_get(s, OT_BYTE);
- break;
- case 0xc8: /* enter */
- lduw_code(s->pc);
- s->pc += 2;
- ldub_code(s->pc++);
- break;
- case 0xc9: /* leave */
- break;
-
- case 0x06: /* push es */
- case 0x0e: /* push cs */
- case 0x16: /* push ss */
- case 0x1e: /* push ds */
- /* XXX: optimize:
- push segs[n].selector
- */
- goto unsupported_op;
- case 0x1a0: /* push fs */
- case 0x1a8: /* push gs */
- goto unsupported_op;
- case 0x07: /* pop es */
- case 0x17: /* pop ss */
- case 0x1f: /* pop ds */
- goto unsupported_op;
- case 0x1a1: /* pop fs */
- case 0x1a9: /* pop gs */
- goto unsupported_op;
- case 0x8e: /* mov seg, Gv */
- /* XXX: optimize:
- fs movl r, regs[]
- movl segs[].selector, r
- mov r, Gv
- fs movl regs[], r
- */
- goto unsupported_op;
- case 0x8c: /* mov Gv, seg */
- goto unsupported_op;
- case 0xc4: /* les Gv */
- op = R_ES;
- goto do_lxx;
- case 0xc5: /* lds Gv */
- op = R_DS;
- goto do_lxx;
- case 0x1b2: /* lss Gv */
- op = R_SS;
- goto do_lxx;
- case 0x1b4: /* lfs Gv */
- op = R_FS;
- goto do_lxx;
- case 0x1b5: /* lgs Gv */
- op = R_GS;
- do_lxx:
- goto unsupported_op;
- /************************/
- /* floats */
- case 0xd8 ... 0xdf:
-#if 1
- /* currently not stable enough */
- goto unsupported_op;
-#else
- if (s->flags & (HF_EM_MASK | HF_TS_MASK))
- goto unsupported_op;
-#endif
-#if 0
- /* for testing FPU context switch */
- {
- static int count;
- count = (count + 1) % 3;
- if (count != 0)
- goto unsupported_op;
- }
-#endif
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = modrm & 7;
- op = ((b & 7) << 3) | ((modrm >> 3) & 7);
- if (mod != 3) {
- /* memory op */
- parse_modrm(s, modrm);
- switch(op) {
- case 0x00 ... 0x07: /* fxxxs */
- case 0x10 ... 0x17: /* fixxxl */
- case 0x20 ... 0x27: /* fxxxl */
- case 0x30 ... 0x37: /* fixxx */
- break;
- case 0x08: /* flds */
- case 0x0a: /* fsts */
- case 0x0b: /* fstps */
- case 0x18: /* fildl */
- case 0x1a: /* fistl */
- case 0x1b: /* fistpl */
- case 0x28: /* fldl */
- case 0x2a: /* fstl */
- case 0x2b: /* fstpl */
- case 0x38: /* filds */
- case 0x3a: /* fists */
- case 0x3b: /* fistps */
- case 0x0c: /* fldenv mem */
- case 0x0d: /* fldcw mem */
- case 0x0e: /* fnstenv mem */
- case 0x0f: /* fnstcw mem */
- case 0x1d: /* fldt mem */
- case 0x1f: /* fstpt mem */
- case 0x2c: /* frstor mem */
- case 0x2e: /* fnsave mem */
- case 0x2f: /* fnstsw mem */
- case 0x3c: /* fbld */
- case 0x3e: /* fbstp */
- case 0x3d: /* fildll */
- case 0x3f: /* fistpll */
- break;
- default:
- goto illegal_op;
- }
- } else {
- /* register float ops */
- switch(op) {
- case 0x08: /* fld sti */
- case 0x09: /* fxchg sti */
- break;
- case 0x0a: /* grp d9/2 */
- switch(rm) {
- case 0: /* fnop */
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x0c: /* grp d9/4 */
- switch(rm) {
- case 0: /* fchs */
- case 1: /* fabs */
- case 4: /* ftst */
- case 5: /* fxam */
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x0d: /* grp d9/5 */
- switch(rm) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x0e: /* grp d9/6 */
- break;
- case 0x0f: /* grp d9/7 */
- break;
- case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
- case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
- case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
- break;
- case 0x02: /* fcom */
- break;
- case 0x03: /* fcomp */
- break;
- case 0x15: /* da/5 */
- switch(rm) {
- case 1: /* fucompp */
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x1c:
- switch(rm) {
- case 0: /* feni (287 only, just do nop here) */
- case 1: /* fdisi (287 only, just do nop here) */
- goto unsupported_op;
- case 2: /* fclex */
- case 3: /* fninit */
- case 4: /* fsetpm (287 only, just do nop here) */
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x1d: /* fucomi */
- break;
- case 0x1e: /* fcomi */
- break;
- case 0x28: /* ffree sti */
- break;
- case 0x2a: /* fst sti */
- break;
- case 0x2b: /* fstp sti */
- break;
- case 0x2c: /* fucom st(i) */
- break;
- case 0x2d: /* fucomp st(i) */
- break;
- case 0x33: /* de/3 */
- switch(rm) {
- case 1: /* fcompp */
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x3c: /* df/4 */
- switch(rm) {
- case 0:
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x3d: /* fucomip */
- break;
- case 0x3e: /* fcomip */
- break;
- case 0x10 ... 0x13: /* fcmovxx */
- case 0x18 ... 0x1b:
- break;
- default:
- goto illegal_op;
- }
- }
- s->tb->cflags |= CF_TB_FP_USED;
- break;
-
- /**************************/
- /* mov */
- case 0xc6:
- case 0xc7: /* mov Ev, Iv */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- parse_modrm(s, modrm);
- insn_get(s, ot);
- break;
-
- case 0x8d: /* lea */
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- parse_modrm(s, modrm);
- break;
-
- case 0xa0: /* mov EAX, Ov */
- case 0xa1:
- case 0xa2: /* mov Ov, EAX */
- case 0xa3:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- if (s->aflag)
- insn_get(s, OT_LONG);
- else
- insn_get(s, OT_WORD);
- break;
- case 0xd7: /* xlat */
- break;
- case 0xb0 ... 0xb7: /* mov R, Ib */
- insn_get(s, OT_BYTE);
- break;
- case 0xb8 ... 0xbf: /* mov R, Iv */
- ot = dflag ? OT_LONG : OT_WORD;
- insn_get(s, ot);
- break;
-
- case 0x91 ... 0x97: /* xchg R, EAX */
- break;
-
- /************************/
- /* shifts */
- case 0xc0:
- case 0xc1: /* shift Ev,imm */
-
- case 0x1a4: /* shld imm */
- case 0x1ac: /* shrd imm */
- modrm = ldub_code(s->pc++);
- parse_modrm(s, modrm);
- ldub_code(s->pc++);
- break;
-
- /************************/
- /* string ops */
-
- case 0xa4: /* movsS */
- case 0xa5:
- break;
-
- case 0xaa: /* stosS */
- case 0xab:
- break;
-
- case 0xac: /* lodsS */
- case 0xad:
- break;
-
- case 0xae: /* scasS */
- case 0xaf:
- break;
-
- case 0xa6: /* cmpsS */
- case 0xa7:
- break;
-
- case 0x6c: /* insS */
- case 0x6d:
- goto unsupported_op;
-
- case 0x6e: /* outsS */
- case 0x6f:
- goto unsupported_op;
-
- /************************/
- /* port I/O */
- case 0xe4:
- case 0xe5:
- goto unsupported_op;
-
- case 0xe6:
- case 0xe7:
- goto unsupported_op;
-
- case 0xec:
- case 0xed:
- goto unsupported_op;
-
- case 0xee:
- case 0xef:
- goto unsupported_op;
-
- /************************/
- /* control */
-#if 0
- case 0xc2: /* ret im */
- val = ldsw_code(s->pc);
- s->pc += 2;
- gen_pop_T0(s);
- gen_stack_update(s, val + (2 << s->dflag));
- if (s->dflag == 0)
- gen_op_andl_T0_ffff();
- gen_op_jmp_T0();
- gen_eob(s);
- break;
-#endif
-
- case 0xc3: /* ret */
- gb(s, CPU_SEG);
- if (!s->dflag)
- gb(s, 0x66); /* d16 */
- gb(s, 0x8f); /* pop addr */
- gb(s, 0x05);
- gl(s, CPU_FIELD_OFFSET(eip));
- if (!s->dflag) {
- /* reset high bits of EIP */
- gen_movw_addr_im(s, CPU_FIELD_OFFSET(eip) + 2, 0);
- }
- gen_eob(s);
- goto no_copy;
- case 0xca: /* lret im */
- case 0xcb: /* lret */
- case 0xcf: /* iret */
- case 0x9a: /* lcall im */
- case 0xea: /* ljmp im */
- goto unsupported_op;
-
- case 0xe8: /* call im */
- ot = dflag ? OT_LONG : OT_WORD;
- val = insn_get(s, ot);
- next_eip = s->pc - s->cs_base;
- val += next_eip;
- if (s->dflag) {
- gb(s, 0x68); /* pushl imm */
- gl(s, next_eip);
- } else {
- gb(s, 0x66); /* pushw imm */
- gb(s, 0x68);
- gw(s, next_eip);
- val &= 0xffff;
- }
- gen_jmp(s, val);
- goto no_copy;
- case 0xe9: /* jmp */
- ot = dflag ? OT_LONG : OT_WORD;
- val = insn_get(s, ot);
- val += s->pc - s->cs_base;
- if (s->dflag == 0)
- val = val & 0xffff;
- gen_jmp(s, val);
- goto no_copy;
- case 0xeb: /* jmp Jb */
- val = (int8_t)insn_get(s, OT_BYTE);
- val += s->pc - s->cs_base;
- if (s->dflag == 0)
- val = val & 0xffff;
- gen_jmp(s, val);
- goto no_copy;
- case 0x70 ... 0x7f: /* jcc Jb */
- val = (int8_t)insn_get(s, OT_BYTE);
- goto do_jcc;
- case 0x180 ... 0x18f: /* jcc Jv */
- if (dflag) {
- val = insn_get(s, OT_LONG);
- } else {
- val = (int16_t)insn_get(s, OT_WORD);
- }
- do_jcc:
- next_eip = s->pc - s->cs_base;
- val += next_eip;
- if (s->dflag == 0)
- val &= 0xffff;
- gen_jcc(s, b & 0xf, val, next_eip);
- goto no_copy;
-
- /************************/
- /* flags */
- case 0x9c: /* pushf */
- /* XXX: put specific code ? */
- goto unsupported_op;
- case 0x9d: /* popf */
- goto unsupported_op;
-
- case 0x9e: /* sahf */
- case 0x9f: /* lahf */
- case 0xf5: /* cmc */
- case 0xf8: /* clc */
- case 0xf9: /* stc */
- case 0xfc: /* cld */
- case 0xfd: /* std */
- break;
-
- /************************/
- /* bit operations */
- case 0x1ba: /* bt/bts/btr/btc Gv, im */
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- op = (modrm >> 3) & 7;
- parse_modrm(s, modrm);
- /* load shift */
- ldub_code(s->pc++);
- if (op < 4)
- goto illegal_op;
- break;
- /************************/
- /* bcd */
- case 0x27: /* daa */
- break;
- case 0x2f: /* das */
- break;
- case 0x37: /* aaa */
- break;
- case 0x3f: /* aas */
- break;
- case 0xd4: /* aam */
- ldub_code(s->pc++);
- break;
- case 0xd5: /* aad */
- ldub_code(s->pc++);
- break;
- /************************/
- /* misc */
- case 0x90: /* nop */
- break;
- case 0x9b: /* fwait */
- if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
- (HF_MP_MASK | HF_TS_MASK)) {
- goto unsupported_op;
- }
- break;
- case 0xcc: /* int3 */
- goto unsupported_op;
- case 0xcd: /* int N */
- goto unsupported_op;
- case 0xce: /* into */
- goto unsupported_op;
- case 0xf1: /* icebp (undocumented, exits to external debugger) */
- goto unsupported_op;
- case 0xfa: /* cli */
- goto unsupported_op;
- case 0xfb: /* sti */
- goto unsupported_op;
- case 0x62: /* bound */
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- parse_modrm(s, modrm);
- break;
- case 0x1c8 ... 0x1cf: /* bswap reg */
- break;
- case 0xd6: /* salc */
- break;
- case 0xe0: /* loopnz */
- case 0xe1: /* loopz */
- case 0xe2: /* loop */
- case 0xe3: /* jecxz */
- goto unsupported_op;
-
- case 0x130: /* wrmsr */
- case 0x132: /* rdmsr */
- goto unsupported_op;
- case 0x131: /* rdtsc */
- goto unsupported_op;
- case 0x1a2: /* cpuid */
- goto unsupported_op;
- case 0xf4: /* hlt */
- goto unsupported_op;
- case 0x100:
- goto unsupported_op;
- case 0x101:
- goto unsupported_op;
- case 0x108: /* invd */
- case 0x109: /* wbinvd */
- goto unsupported_op;
- case 0x63: /* arpl */
- goto unsupported_op;
- case 0x102: /* lar */
- case 0x103: /* lsl */
- goto unsupported_op;
- case 0x118:
- goto unsupported_op;
- case 0x120: /* mov reg, crN */
- case 0x122: /* mov crN, reg */
- goto unsupported_op;
- case 0x121: /* mov reg, drN */
- case 0x123: /* mov drN, reg */
- goto unsupported_op;
- case 0x106: /* clts */
- goto unsupported_op;
- default:
- goto illegal_op;
- }
-
- /* just copy the code */
-
- /* no override yet */
- if (!s->dflag)
- gb(s, 0x66);
- if (!s->aflag)
- gb(s, 0x67);
- if (prefixes & PREFIX_REPZ)
- gb(s, 0xf3);
- else if (prefixes & PREFIX_REPNZ)
- gb(s, 0xf2);
- {
- int len, i;
- len = s->pc - pc_start_insn;
- for(i = 0; i < len; i++) {
- *s->gen_code_ptr++ = ldub_code(pc_start_insn + i);
- }
- }
- no_copy:
- return 0;
- illegal_op:
- unsupported_op:
- /* fall back to slower code gen necessary */
- s->pc = pc_start;
- return -1;
-}
-
-#define GEN_CODE_MAX_SIZE 8192
-#define GEN_CODE_MAX_INSN_SIZE 512
-
-static inline int gen_intermediate_code_internal(CPUState *env,
- TranslationBlock *tb,
- uint8_t *gen_code_ptr,
- int *gen_code_size_ptr,
- int search_pc,
- uint8_t *tc_ptr)
-{
- DisasContext dc1, *dc = &dc1;
- target_ulong pc_insn, pc_start, cs_base;
- uint8_t *gen_code_end;
- int flags, ret;
-
- if (env->nb_breakpoints > 0 ||
- env->singlestep_enabled)
- return -1;
- flags = tb->flags;
- if (flags & (HF_TF_MASK | HF_ADDSEG_MASK |
- HF_SOFTMMU_MASK | HF_INHIBIT_IRQ_MASK))
- return -1;
- if (!(flags & HF_SS32_MASK))
- return -1;
- if (tb->cflags & CF_SINGLE_INSN)
- return -1;
- gen_code_end = gen_code_ptr +
- GEN_CODE_MAX_SIZE - GEN_CODE_MAX_INSN_SIZE;
- dc->gen_code_ptr = gen_code_ptr;
- dc->gen_code_start = gen_code_ptr;
-
- /* generate intermediate code */
- pc_start = tb->pc;
- cs_base = tb->cs_base;
- dc->pc = pc_start;
- dc->cs_base = cs_base;
- dc->pe = (flags >> HF_PE_SHIFT) & 1;
- dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
- dc->f_st = 0;
- dc->vm86 = (flags >> VM_SHIFT) & 1;
- dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
- dc->iopl = (flags >> IOPL_SHIFT) & 3;
- dc->tb = tb;
- dc->flags = flags;
-
- dc->is_jmp = 0;
-
- for(;;) {
- pc_insn = dc->pc;
- ret = disas_insn(dc);
- if (ret < 0) {
- /* unsupported insn */
- if (dc->pc == pc_start) {
- /* if first instruction, signal that no copying was done */
- return -1;
- } else {
- gen_jmp(dc, dc->pc - dc->cs_base);
- dc->is_jmp = 1;
- }
- }
- if (search_pc) {
- /* search pc mode */
- if (tc_ptr < dc->gen_code_ptr) {
- env->eip = pc_insn - cs_base;
- return 0;
- }
- }
- /* stop translation if indicated */
- if (dc->is_jmp)
- break;
- /* if too long translation, stop generation */
- if (dc->gen_code_ptr >= gen_code_end ||
- (dc->pc - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
- gen_jmp(dc, dc->pc - dc->cs_base);
- break;
- }
- }
-
-#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "----------------\n");
- fprintf(logfile, "IN: COPY: %s fpu=%d\n",
- lookup_symbol(pc_start),
- tb->cflags & CF_TB_FP_USED ? 1 : 0);
- target_disas(logfile, pc_start, dc->pc - pc_start, !dc->code32);
- fprintf(logfile, "\n");
- }
-#endif
-
- if (!search_pc) {
- *gen_code_size_ptr = dc->gen_code_ptr - dc->gen_code_start;
- tb->size = dc->pc - pc_start;
- tb->cflags |= CF_CODE_COPY;
- return 0;
- } else {
- return -1;
- }
-}
-
-/* generate code by just copying data. Return -1 if cannot generate
- any code. Return 0 if code was generated */
-int cpu_gen_code_copy(CPUState *env, TranslationBlock *tb,
- int max_code_size, int *gen_code_size_ptr)
-{
- /* generate machine code */
- tb->tb_next_offset[0] = 0xffff;
- tb->tb_next_offset[1] = 0xffff;
-#ifdef USE_DIRECT_JUMP
- /* the following two entries are optional (only used for string ops) */
- tb->tb_jmp_offset[2] = 0xffff;
- tb->tb_jmp_offset[3] = 0xffff;
-#endif
- return gen_intermediate_code_internal(env, tb,
- tb->tc_ptr, gen_code_size_ptr,
- 0, NULL);
-}
-
-static uint8_t dummy_gen_code_buf[GEN_CODE_MAX_SIZE];
-
-int cpu_restore_state_copy(TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc)
-{
- struct ucontext *uc = puc;
- int ret, eflags;
-
- /* find opc index corresponding to search_pc */
- if (searched_pc < (unsigned long)tb->tc_ptr)
- return -1;
- searched_pc = searched_pc - (long)tb->tc_ptr + (long)dummy_gen_code_buf;
- ret = gen_intermediate_code_internal(env, tb,
- dummy_gen_code_buf, NULL,
- 1, (uint8_t *)searched_pc);
- if (ret < 0)
- return ret;
- /* restore all the CPU state from the CPU context from the
- signal. The FPU context stays in the host CPU. */
-
- env->regs[R_EAX] = uc->uc_mcontext.gregs[REG_EAX];
- env->regs[R_ECX] = uc->uc_mcontext.gregs[REG_ECX];
- env->regs[R_EDX] = uc->uc_mcontext.gregs[REG_EDX];
- env->regs[R_EBX] = uc->uc_mcontext.gregs[REG_EBX];
- env->regs[R_ESP] = uc->uc_mcontext.gregs[REG_ESP];
- env->regs[R_EBP] = uc->uc_mcontext.gregs[REG_EBP];
- env->regs[R_ESI] = uc->uc_mcontext.gregs[REG_ESI];
- env->regs[R_EDI] = uc->uc_mcontext.gregs[REG_EDI];
- eflags = uc->uc_mcontext.gregs[REG_EFL];
- env->df = 1 - (2 * ((eflags >> 10) & 1));
- env->cc_src = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- env->cc_op = CC_OP_EFLAGS;
- return 0;
-}
-
-#endif /* USE_CODE_COPY */
diff --git a/tools/ioemu/target-i386/translate.c b/tools/ioemu/target-i386/translate.c
deleted file mode 100644
index 735acb0e47..0000000000
--- a/tools/ioemu/target-i386/translate.c
+++ /dev/null
@@ -1,6621 +0,0 @@
-/*
- * i386 translation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <signal.h>
-#include <assert.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-
-/* XXX: move that elsewhere */
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
-
-#define PREFIX_REPZ 0x01
-#define PREFIX_REPNZ 0x02
-#define PREFIX_LOCK 0x04
-#define PREFIX_DATA 0x08
-#define PREFIX_ADR 0x10
-
-#ifdef TARGET_X86_64
-#define X86_64_ONLY(x) x
-#define X86_64_DEF(x...) x
-#define CODE64(s) ((s)->code64)
-#define REX_X(s) ((s)->rex_x)
-#define REX_B(s) ((s)->rex_b)
-/* XXX: gcc generates push/pop in some opcodes, so we cannot use them */
-#if 1
-#define BUGGY_64(x) NULL
-#endif
-#else
-#define X86_64_ONLY(x) NULL
-#define X86_64_DEF(x...)
-#define CODE64(s) 0
-#define REX_X(s) 0
-#define REX_B(s) 0
-#endif
-
-#ifdef TARGET_X86_64
-static int x86_64_hregs;
-#endif
-
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
-#endif
-
-typedef struct DisasContext {
- /* current insn context */
- int override; /* -1 if no override */
- int prefix;
- int aflag, dflag;
- target_ulong pc; /* pc = eip + cs_base */
- int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
- static state change (stop translation) */
- /* current block context */
- target_ulong cs_base; /* base of CS segment */
- int pe; /* protected mode */
- int code32; /* 32 bit code segment */
-#ifdef TARGET_X86_64
- int lma; /* long mode active */
- int code64; /* 64 bit code segment */
- int rex_x, rex_b;
-#endif
- int ss32; /* 32 bit stack segment */
- int cc_op; /* current CC operation */
- int addseg; /* non zero if either DS/ES/SS have a non zero base */
- int f_st; /* currently unused */
- int vm86; /* vm86 mode */
- int cpl;
- int iopl;
- int tf; /* TF cpu flag */
- int singlestep_enabled; /* "hardware" single step enabled */
- int jmp_opt; /* use direct block chaining for direct jumps */
- int mem_index; /* select memory access functions */
- int flags; /* all execution flags */
- struct TranslationBlock *tb;
- int popl_esp_hack; /* for correct popl with esp base handling */
- int rip_offset; /* only used in x86_64, but left for simplicity */
- int cpuid_features;
- int cpuid_ext_features;
-} DisasContext;
-
-static void gen_eob(DisasContext *s);
-static void gen_jmp(DisasContext *s, target_ulong eip);
-static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
-
-/* i386 arith/logic operations */
-enum {
- OP_ADDL,
- OP_ORL,
- OP_ADCL,
- OP_SBBL,
- OP_ANDL,
- OP_SUBL,
- OP_XORL,
- OP_CMPL,
-};
-
-/* i386 shift ops */
-enum {
- OP_ROL,
- OP_ROR,
- OP_RCL,
- OP_RCR,
- OP_SHL,
- OP_SHR,
- OP_SHL1, /* undocumented */
- OP_SAR = 7,
-};
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
- NB_OPS,
-};
-
-#include "gen-op.h"
-
-/* operand size */
-enum {
- OT_BYTE = 0,
- OT_WORD,
- OT_LONG,
- OT_QUAD,
-};
-
-enum {
- /* I386 int registers */
- OR_EAX, /* MUST be even numbered */
- OR_ECX,
- OR_EDX,
- OR_EBX,
- OR_ESP,
- OR_EBP,
- OR_ESI,
- OR_EDI,
-
- OR_TMP0 = 16, /* temporary operand register */
- OR_TMP1,
- OR_A0, /* temporary register used when doing address evaluation */
-};
-
-#ifdef TARGET_X86_64
-
-#define NB_OP_SIZES 4
-
-#define DEF_REGS(prefix, suffix) \
- prefix ## EAX ## suffix,\
- prefix ## ECX ## suffix,\
- prefix ## EDX ## suffix,\
- prefix ## EBX ## suffix,\
- prefix ## ESP ## suffix,\
- prefix ## EBP ## suffix,\
- prefix ## ESI ## suffix,\
- prefix ## EDI ## suffix,\
- prefix ## R8 ## suffix,\
- prefix ## R9 ## suffix,\
- prefix ## R10 ## suffix,\
- prefix ## R11 ## suffix,\
- prefix ## R12 ## suffix,\
- prefix ## R13 ## suffix,\
- prefix ## R14 ## suffix,\
- prefix ## R15 ## suffix,
-
-#define DEF_BREGS(prefixb, prefixh, suffix) \
- \
-static void prefixb ## ESP ## suffix ## _wrapper(void) \
-{ \
- if (x86_64_hregs) \
- prefixb ## ESP ## suffix (); \
- else \
- prefixh ## EAX ## suffix (); \
-} \
- \
-static void prefixb ## EBP ## suffix ## _wrapper(void) \
-{ \
- if (x86_64_hregs) \
- prefixb ## EBP ## suffix (); \
- else \
- prefixh ## ECX ## suffix (); \
-} \
- \
-static void prefixb ## ESI ## suffix ## _wrapper(void) \
-{ \
- if (x86_64_hregs) \
- prefixb ## ESI ## suffix (); \
- else \
- prefixh ## EDX ## suffix (); \
-} \
- \
-static void prefixb ## EDI ## suffix ## _wrapper(void) \
-{ \
- if (x86_64_hregs) \
- prefixb ## EDI ## suffix (); \
- else \
- prefixh ## EBX ## suffix (); \
-}
-
-DEF_BREGS(gen_op_movb_, gen_op_movh_, _T0)
-DEF_BREGS(gen_op_movb_, gen_op_movh_, _T1)
-DEF_BREGS(gen_op_movl_T0_, gen_op_movh_T0_, )
-DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )
-
-#else /* !TARGET_X86_64 */
-
-#define NB_OP_SIZES 3
-
-#define DEF_REGS(prefix, suffix) \
- prefix ## EAX ## suffix,\
- prefix ## ECX ## suffix,\
- prefix ## EDX ## suffix,\
- prefix ## EBX ## suffix,\
- prefix ## ESP ## suffix,\
- prefix ## EBP ## suffix,\
- prefix ## ESI ## suffix,\
- prefix ## EDI ## suffix,
-
-#endif /* !TARGET_X86_64 */
-
-static GenOpFunc *gen_op_mov_reg_T0[NB_OP_SIZES][CPU_NB_REGS] = {
- [OT_BYTE] = {
- gen_op_movb_EAX_T0,
- gen_op_movb_ECX_T0,
- gen_op_movb_EDX_T0,
- gen_op_movb_EBX_T0,
-#ifdef TARGET_X86_64
- gen_op_movb_ESP_T0_wrapper,
- gen_op_movb_EBP_T0_wrapper,
- gen_op_movb_ESI_T0_wrapper,
- gen_op_movb_EDI_T0_wrapper,
- gen_op_movb_R8_T0,
- gen_op_movb_R9_T0,
- gen_op_movb_R10_T0,
- gen_op_movb_R11_T0,
- gen_op_movb_R12_T0,
- gen_op_movb_R13_T0,
- gen_op_movb_R14_T0,
- gen_op_movb_R15_T0,
-#else
- gen_op_movh_EAX_T0,
- gen_op_movh_ECX_T0,
- gen_op_movh_EDX_T0,
- gen_op_movh_EBX_T0,
-#endif
- },
- [OT_WORD] = {
- DEF_REGS(gen_op_movw_, _T0)
- },
- [OT_LONG] = {
- DEF_REGS(gen_op_movl_, _T0)
- },
-#ifdef TARGET_X86_64
- [OT_QUAD] = {
- DEF_REGS(gen_op_movq_, _T0)
- },
-#endif
-};
-
-static GenOpFunc *gen_op_mov_reg_T1[NB_OP_SIZES][CPU_NB_REGS] = {
- [OT_BYTE] = {
- gen_op_movb_EAX_T1,
- gen_op_movb_ECX_T1,
- gen_op_movb_EDX_T1,
- gen_op_movb_EBX_T1,
-#ifdef TARGET_X86_64
- gen_op_movb_ESP_T1_wrapper,
- gen_op_movb_EBP_T1_wrapper,
- gen_op_movb_ESI_T1_wrapper,
- gen_op_movb_EDI_T1_wrapper,
- gen_op_movb_R8_T1,
- gen_op_movb_R9_T1,
- gen_op_movb_R10_T1,
- gen_op_movb_R11_T1,
- gen_op_movb_R12_T1,
- gen_op_movb_R13_T1,
- gen_op_movb_R14_T1,
- gen_op_movb_R15_T1,
-#else
- gen_op_movh_EAX_T1,
- gen_op_movh_ECX_T1,
- gen_op_movh_EDX_T1,
- gen_op_movh_EBX_T1,
-#endif
- },
- [OT_WORD] = {
- DEF_REGS(gen_op_movw_, _T1)
- },
- [OT_LONG] = {
- DEF_REGS(gen_op_movl_, _T1)
- },
-#ifdef TARGET_X86_64
- [OT_QUAD] = {
- DEF_REGS(gen_op_movq_, _T1)
- },
-#endif
-};
-
-static GenOpFunc *gen_op_mov_reg_A0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
- [0] = {
- DEF_REGS(gen_op_movw_, _A0)
- },
- [1] = {
- DEF_REGS(gen_op_movl_, _A0)
- },
-#ifdef TARGET_X86_64
- [2] = {
- DEF_REGS(gen_op_movq_, _A0)
- },
-#endif
-};
-
-static GenOpFunc *gen_op_mov_TN_reg[NB_OP_SIZES][2][CPU_NB_REGS] =
-{
- [OT_BYTE] = {
- {
- gen_op_movl_T0_EAX,
- gen_op_movl_T0_ECX,
- gen_op_movl_T0_EDX,
- gen_op_movl_T0_EBX,
-#ifdef TARGET_X86_64
- gen_op_movl_T0_ESP_wrapper,
- gen_op_movl_T0_EBP_wrapper,
- gen_op_movl_T0_ESI_wrapper,
- gen_op_movl_T0_EDI_wrapper,
- gen_op_movl_T0_R8,
- gen_op_movl_T0_R9,
- gen_op_movl_T0_R10,
- gen_op_movl_T0_R11,
- gen_op_movl_T0_R12,
- gen_op_movl_T0_R13,
- gen_op_movl_T0_R14,
- gen_op_movl_T0_R15,
-#else
- gen_op_movh_T0_EAX,
- gen_op_movh_T0_ECX,
- gen_op_movh_T0_EDX,
- gen_op_movh_T0_EBX,
-#endif
- },
- {
- gen_op_movl_T1_EAX,
- gen_op_movl_T1_ECX,
- gen_op_movl_T1_EDX,
- gen_op_movl_T1_EBX,
-#ifdef TARGET_X86_64
- gen_op_movl_T1_ESP_wrapper,
- gen_op_movl_T1_EBP_wrapper,
- gen_op_movl_T1_ESI_wrapper,
- gen_op_movl_T1_EDI_wrapper,
- gen_op_movl_T1_R8,
- gen_op_movl_T1_R9,
- gen_op_movl_T1_R10,
- gen_op_movl_T1_R11,
- gen_op_movl_T1_R12,
- gen_op_movl_T1_R13,
- gen_op_movl_T1_R14,
- gen_op_movl_T1_R15,
-#else
- gen_op_movh_T1_EAX,
- gen_op_movh_T1_ECX,
- gen_op_movh_T1_EDX,
- gen_op_movh_T1_EBX,
-#endif
- },
- },
- [OT_WORD] = {
- {
- DEF_REGS(gen_op_movl_T0_, )
- },
- {
- DEF_REGS(gen_op_movl_T1_, )
- },
- },
- [OT_LONG] = {
- {
- DEF_REGS(gen_op_movl_T0_, )
- },
- {
- DEF_REGS(gen_op_movl_T1_, )
- },
- },
-#ifdef TARGET_X86_64
- [OT_QUAD] = {
- {
- DEF_REGS(gen_op_movl_T0_, )
- },
- {
- DEF_REGS(gen_op_movl_T1_, )
- },
- },
-#endif
-};
-
-static GenOpFunc *gen_op_movl_A0_reg[CPU_NB_REGS] = {
- DEF_REGS(gen_op_movl_A0_, )
-};
-
-static GenOpFunc *gen_op_addl_A0_reg_sN[4][CPU_NB_REGS] = {
- [0] = {
- DEF_REGS(gen_op_addl_A0_, )
- },
- [1] = {
- DEF_REGS(gen_op_addl_A0_, _s1)
- },
- [2] = {
- DEF_REGS(gen_op_addl_A0_, _s2)
- },
- [3] = {
- DEF_REGS(gen_op_addl_A0_, _s3)
- },
-};
-
-#ifdef TARGET_X86_64
-static GenOpFunc *gen_op_movq_A0_reg[CPU_NB_REGS] = {
- DEF_REGS(gen_op_movq_A0_, )
-};
-
-static GenOpFunc *gen_op_addq_A0_reg_sN[4][CPU_NB_REGS] = {
- [0] = {
- DEF_REGS(gen_op_addq_A0_, )
- },
- [1] = {
- DEF_REGS(gen_op_addq_A0_, _s1)
- },
- [2] = {
- DEF_REGS(gen_op_addq_A0_, _s2)
- },
- [3] = {
- DEF_REGS(gen_op_addq_A0_, _s3)
- },
-};
-#endif
-
-static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
- [0] = {
- DEF_REGS(gen_op_cmovw_, _T1_T0)
- },
- [1] = {
- DEF_REGS(gen_op_cmovl_, _T1_T0)
- },
-#ifdef TARGET_X86_64
- [2] = {
- DEF_REGS(gen_op_cmovq_, _T1_T0)
- },
-#endif
-};
-
-static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
- NULL,
- gen_op_orl_T0_T1,
- NULL,
- NULL,
- gen_op_andl_T0_T1,
- NULL,
- gen_op_xorl_T0_T1,
- NULL,
-};
-
-#define DEF_ARITHC(SUFFIX)\
- {\
- gen_op_adcb ## SUFFIX ## _T0_T1_cc,\
- gen_op_sbbb ## SUFFIX ## _T0_T1_cc,\
- },\
- {\
- gen_op_adcw ## SUFFIX ## _T0_T1_cc,\
- gen_op_sbbw ## SUFFIX ## _T0_T1_cc,\
- },\
- {\
- gen_op_adcl ## SUFFIX ## _T0_T1_cc,\
- gen_op_sbbl ## SUFFIX ## _T0_T1_cc,\
- },\
- {\
- X86_64_ONLY(gen_op_adcq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_sbbq ## SUFFIX ## _T0_T1_cc),\
- },
-
-static GenOpFunc *gen_op_arithc_T0_T1_cc[4][2] = {
- DEF_ARITHC( )
-};
-
-static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3 * 4][2] = {
- DEF_ARITHC(_raw)
-#ifndef CONFIG_USER_ONLY
- DEF_ARITHC(_kernel)
- DEF_ARITHC(_user)
-#endif
-};
-
-static const int cc_op_arithb[8] = {
- CC_OP_ADDB,
- CC_OP_LOGICB,
- CC_OP_ADDB,
- CC_OP_SUBB,
- CC_OP_LOGICB,
- CC_OP_SUBB,
- CC_OP_LOGICB,
- CC_OP_SUBB,
-};
-
-#define DEF_CMPXCHG(SUFFIX)\
- gen_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc,\
- gen_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc,\
- gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc,\
- X86_64_ONLY(gen_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc),
-
-static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[4] = {
- DEF_CMPXCHG( )
-};
-
-static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3 * 4] = {
- DEF_CMPXCHG(_raw)
-#ifndef CONFIG_USER_ONLY
- DEF_CMPXCHG(_kernel)
- DEF_CMPXCHG(_user)
-#endif
-};
-
-#define DEF_SHIFT(SUFFIX)\
- {\
- gen_op_rolb ## SUFFIX ## _T0_T1_cc,\
- gen_op_rorb ## SUFFIX ## _T0_T1_cc,\
- gen_op_rclb ## SUFFIX ## _T0_T1_cc,\
- gen_op_rcrb ## SUFFIX ## _T0_T1_cc,\
- gen_op_shlb ## SUFFIX ## _T0_T1_cc,\
- gen_op_shrb ## SUFFIX ## _T0_T1_cc,\
- gen_op_shlb ## SUFFIX ## _T0_T1_cc,\
- gen_op_sarb ## SUFFIX ## _T0_T1_cc,\
- },\
- {\
- gen_op_rolw ## SUFFIX ## _T0_T1_cc,\
- gen_op_rorw ## SUFFIX ## _T0_T1_cc,\
- gen_op_rclw ## SUFFIX ## _T0_T1_cc,\
- gen_op_rcrw ## SUFFIX ## _T0_T1_cc,\
- gen_op_shlw ## SUFFIX ## _T0_T1_cc,\
- gen_op_shrw ## SUFFIX ## _T0_T1_cc,\
- gen_op_shlw ## SUFFIX ## _T0_T1_cc,\
- gen_op_sarw ## SUFFIX ## _T0_T1_cc,\
- },\
- {\
- gen_op_roll ## SUFFIX ## _T0_T1_cc,\
- gen_op_rorl ## SUFFIX ## _T0_T1_cc,\
- gen_op_rcll ## SUFFIX ## _T0_T1_cc,\
- gen_op_rcrl ## SUFFIX ## _T0_T1_cc,\
- gen_op_shll ## SUFFIX ## _T0_T1_cc,\
- gen_op_shrl ## SUFFIX ## _T0_T1_cc,\
- gen_op_shll ## SUFFIX ## _T0_T1_cc,\
- gen_op_sarl ## SUFFIX ## _T0_T1_cc,\
- },\
- {\
- X86_64_ONLY(gen_op_rolq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_rorq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_rclq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_rcrq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_shrq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
- X86_64_ONLY(gen_op_sarq ## SUFFIX ## _T0_T1_cc),\
- },
-
-static GenOpFunc *gen_op_shift_T0_T1_cc[4][8] = {
- DEF_SHIFT( )
-};
-
-static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = {
- DEF_SHIFT(_raw)
-#ifndef CONFIG_USER_ONLY
- DEF_SHIFT(_kernel)
- DEF_SHIFT(_user)
-#endif
-};
-
-#define DEF_SHIFTD(SUFFIX, op)\
- {\
- NULL,\
- NULL,\
- },\
- {\
- gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
- gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
- },\
- {\
- gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
- gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
- },\
- {\
-X86_64_DEF(gen_op_shldq ## SUFFIX ## _T0_T1_ ## op ## _cc,\
- gen_op_shrdq ## SUFFIX ## _T0_T1_ ## op ## _cc,)\
- },
-
-static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = {
- DEF_SHIFTD(, im)
-};
-
-static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[4][2] = {
- DEF_SHIFTD(, ECX)
-};
-
-static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[3 * 4][2] = {
- DEF_SHIFTD(_raw, im)
-#ifndef CONFIG_USER_ONLY
- DEF_SHIFTD(_kernel, im)
- DEF_SHIFTD(_user, im)
-#endif
-};
-
-static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[3 * 4][2] = {
- DEF_SHIFTD(_raw, ECX)
-#ifndef CONFIG_USER_ONLY
- DEF_SHIFTD(_kernel, ECX)
- DEF_SHIFTD(_user, ECX)
-#endif
-};
-
-static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = {
- [0] = {
- gen_op_btw_T0_T1_cc,
- gen_op_btsw_T0_T1_cc,
- gen_op_btrw_T0_T1_cc,
- gen_op_btcw_T0_T1_cc,
- },
- [1] = {
- gen_op_btl_T0_T1_cc,
- gen_op_btsl_T0_T1_cc,
- gen_op_btrl_T0_T1_cc,
- gen_op_btcl_T0_T1_cc,
- },
-#ifdef TARGET_X86_64
- [2] = {
- gen_op_btq_T0_T1_cc,
- gen_op_btsq_T0_T1_cc,
- gen_op_btrq_T0_T1_cc,
- gen_op_btcq_T0_T1_cc,
- },
-#endif
-};
-
-static GenOpFunc *gen_op_add_bit_A0_T1[3] = {
- gen_op_add_bitw_A0_T1,
- gen_op_add_bitl_A0_T1,
- X86_64_ONLY(gen_op_add_bitq_A0_T1),
-};
-
-static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
- [0] = {
- gen_op_bsfw_T0_cc,
- gen_op_bsrw_T0_cc,
- },
- [1] = {
- gen_op_bsfl_T0_cc,
- gen_op_bsrl_T0_cc,
- },
-#ifdef TARGET_X86_64
- [2] = {
- gen_op_bsfq_T0_cc,
- gen_op_bsrq_T0_cc,
- },
-#endif
-};
-
-static GenOpFunc *gen_op_lds_T0_A0[3 * 4] = {
- gen_op_ldsb_raw_T0_A0,
- gen_op_ldsw_raw_T0_A0,
- X86_64_ONLY(gen_op_ldsl_raw_T0_A0),
- NULL,
-#ifndef CONFIG_USER_ONLY
- gen_op_ldsb_kernel_T0_A0,
- gen_op_ldsw_kernel_T0_A0,
- X86_64_ONLY(gen_op_ldsl_kernel_T0_A0),
- NULL,
-
- gen_op_ldsb_user_T0_A0,
- gen_op_ldsw_user_T0_A0,
- X86_64_ONLY(gen_op_ldsl_user_T0_A0),
- NULL,
-#endif
-};
-
-static GenOpFunc *gen_op_ldu_T0_A0[3 * 4] = {
- gen_op_ldub_raw_T0_A0,
- gen_op_lduw_raw_T0_A0,
- NULL,
- NULL,
-
-#ifndef CONFIG_USER_ONLY
- gen_op_ldub_kernel_T0_A0,
- gen_op_lduw_kernel_T0_A0,
- NULL,
- NULL,
-
- gen_op_ldub_user_T0_A0,
- gen_op_lduw_user_T0_A0,
- NULL,
- NULL,
-#endif
-};
-
-/* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
-static GenOpFunc *gen_op_ld_T0_A0[3 * 4] = {
- gen_op_ldub_raw_T0_A0,
- gen_op_lduw_raw_T0_A0,
- gen_op_ldl_raw_T0_A0,
- X86_64_ONLY(gen_op_ldq_raw_T0_A0),
-
-#ifndef CONFIG_USER_ONLY
- gen_op_ldub_kernel_T0_A0,
- gen_op_lduw_kernel_T0_A0,
- gen_op_ldl_kernel_T0_A0,
- X86_64_ONLY(gen_op_ldq_kernel_T0_A0),
-
- gen_op_ldub_user_T0_A0,
- gen_op_lduw_user_T0_A0,
- gen_op_ldl_user_T0_A0,
- X86_64_ONLY(gen_op_ldq_user_T0_A0),
-#endif
-};
-
-static GenOpFunc *gen_op_ld_T1_A0[3 * 4] = {
- gen_op_ldub_raw_T1_A0,
- gen_op_lduw_raw_T1_A0,
- gen_op_ldl_raw_T1_A0,
- X86_64_ONLY(gen_op_ldq_raw_T1_A0),
-
-#ifndef CONFIG_USER_ONLY
- gen_op_ldub_kernel_T1_A0,
- gen_op_lduw_kernel_T1_A0,
- gen_op_ldl_kernel_T1_A0,
- X86_64_ONLY(gen_op_ldq_kernel_T1_A0),
-
- gen_op_ldub_user_T1_A0,
- gen_op_lduw_user_T1_A0,
- gen_op_ldl_user_T1_A0,
- X86_64_ONLY(gen_op_ldq_user_T1_A0),
-#endif
-};
-
-static GenOpFunc *gen_op_st_T0_A0[3 * 4] = {
- gen_op_stb_raw_T0_A0,
- gen_op_stw_raw_T0_A0,
- gen_op_stl_raw_T0_A0,
- X86_64_ONLY(gen_op_stq_raw_T0_A0),
-
-#ifndef CONFIG_USER_ONLY
- gen_op_stb_kernel_T0_A0,
- gen_op_stw_kernel_T0_A0,
- gen_op_stl_kernel_T0_A0,
- X86_64_ONLY(gen_op_stq_kernel_T0_A0),
-
- gen_op_stb_user_T0_A0,
- gen_op_stw_user_T0_A0,
- gen_op_stl_user_T0_A0,
- X86_64_ONLY(gen_op_stq_user_T0_A0),
-#endif
-};
-
-static GenOpFunc *gen_op_st_T1_A0[3 * 4] = {
- NULL,
- gen_op_stw_raw_T1_A0,
- gen_op_stl_raw_T1_A0,
- X86_64_ONLY(gen_op_stq_raw_T1_A0),
-
-#ifndef CONFIG_USER_ONLY
- NULL,
- gen_op_stw_kernel_T1_A0,
- gen_op_stl_kernel_T1_A0,
- X86_64_ONLY(gen_op_stq_kernel_T1_A0),
-
- NULL,
- gen_op_stw_user_T1_A0,
- gen_op_stl_user_T1_A0,
- X86_64_ONLY(gen_op_stq_user_T1_A0),
-#endif
-};
-
-static inline void gen_jmp_im(target_ulong pc)
-{
-#ifdef TARGET_X86_64
- if (pc == (uint32_t)pc) {
- gen_op_movl_eip_im(pc);
- } else if (pc == (int32_t)pc) {
- gen_op_movq_eip_im(pc);
- } else {
- gen_op_movq_eip_im64(pc >> 32, pc);
- }
-#else
- gen_op_movl_eip_im(pc);
-#endif
-}
-
-static inline void gen_string_movl_A0_ESI(DisasContext *s)
-{
- int override;
-
- override = s->override;
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- if (override >= 0) {
- gen_op_movq_A0_seg(offsetof(CPUX86State,segs[override].base));
- gen_op_addq_A0_reg_sN[0][R_ESI]();
- } else {
- gen_op_movq_A0_reg[R_ESI]();
- }
- } else
-#endif
- if (s->aflag) {
- /* 32 bit address */
- if (s->addseg && override < 0)
- override = R_DS;
- if (override >= 0) {
- gen_op_movl_A0_seg(offsetof(CPUX86State,segs[override].base));
- gen_op_addl_A0_reg_sN[0][R_ESI]();
- } else {
- gen_op_movl_A0_reg[R_ESI]();
- }
- } else {
- /* 16 address, always override */
- if (override < 0)
- override = R_DS;
- gen_op_movl_A0_reg[R_ESI]();
- gen_op_andl_A0_ffff();
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
- }
-}
-
-static inline void gen_string_movl_A0_EDI(DisasContext *s)
-{
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_movq_A0_reg[R_EDI]();
- } else
-#endif
- if (s->aflag) {
- if (s->addseg) {
- gen_op_movl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
- gen_op_addl_A0_reg_sN[0][R_EDI]();
- } else {
- gen_op_movl_A0_reg[R_EDI]();
- }
- } else {
- gen_op_movl_A0_reg[R_EDI]();
- gen_op_andl_A0_ffff();
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
- }
-}
-
-static GenOpFunc *gen_op_movl_T0_Dshift[4] = {
- gen_op_movl_T0_Dshiftb,
- gen_op_movl_T0_Dshiftw,
- gen_op_movl_T0_Dshiftl,
- X86_64_ONLY(gen_op_movl_T0_Dshiftq),
-};
-
-static GenOpFunc1 *gen_op_jnz_ecx[3] = {
- gen_op_jnz_ecxw,
- gen_op_jnz_ecxl,
- X86_64_ONLY(gen_op_jnz_ecxq),
-};
-
-static GenOpFunc1 *gen_op_jz_ecx[3] = {
- gen_op_jz_ecxw,
- gen_op_jz_ecxl,
- X86_64_ONLY(gen_op_jz_ecxq),
-};
-
-static GenOpFunc *gen_op_dec_ECX[3] = {
- gen_op_decw_ECX,
- gen_op_decl_ECX,
- X86_64_ONLY(gen_op_decq_ECX),
-};
-
-static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = {
- {
- gen_op_jnz_subb,
- gen_op_jnz_subw,
- gen_op_jnz_subl,
- X86_64_ONLY(gen_op_jnz_subq),
- },
- {
- gen_op_jz_subb,
- gen_op_jz_subw,
- gen_op_jz_subl,
- X86_64_ONLY(gen_op_jz_subq),
- },
-};
-
-static GenOpFunc *gen_op_in_DX_T0[3] = {
- gen_op_inb_DX_T0,
- gen_op_inw_DX_T0,
- gen_op_inl_DX_T0,
-};
-
-static GenOpFunc *gen_op_out_DX_T0[3] = {
- gen_op_outb_DX_T0,
- gen_op_outw_DX_T0,
- gen_op_outl_DX_T0,
-};
-
-static GenOpFunc *gen_op_in[3] = {
- gen_op_inb_T0_T1,
- gen_op_inw_T0_T1,
- gen_op_inl_T0_T1,
-};
-
-static GenOpFunc *gen_op_out[3] = {
- gen_op_outb_T0_T1,
- gen_op_outw_T0_T1,
- gen_op_outl_T0_T1,
-};
-
-static GenOpFunc *gen_check_io_T0[3] = {
- gen_op_check_iob_T0,
- gen_op_check_iow_T0,
- gen_op_check_iol_T0,
-};
-
-static GenOpFunc *gen_check_io_DX[3] = {
- gen_op_check_iob_DX,
- gen_op_check_iow_DX,
- gen_op_check_iol_DX,
-};
-
-static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_eip)
-{
- if (s->pe && (s->cpl > s->iopl || s->vm86)) {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(cur_eip);
- if (use_dx)
- gen_check_io_DX[ot]();
- else
- gen_check_io_T0[ot]();
- }
-}
-
-static inline void gen_movs(DisasContext *s, int ot)
-{
- gen_string_movl_A0_ESI(s);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- gen_string_movl_A0_EDI(s);
- gen_op_st_T0_A0[ot + s->mem_index]();
- gen_op_movl_T0_Dshift[ot]();
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_ESI_T0();
- gen_op_addq_EDI_T0();
- } else
-#endif
- if (s->aflag) {
- gen_op_addl_ESI_T0();
- gen_op_addl_EDI_T0();
- } else {
- gen_op_addw_ESI_T0();
- gen_op_addw_EDI_T0();
- }
-}
-
-static inline void gen_update_cc_op(DisasContext *s)
-{
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
-}
-
-/* XXX: does not work with gdbstub "ice" single step - not a
- serious problem */
-static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
-{
- int l1, l2;
-
- l1 = gen_new_label();
- l2 = gen_new_label();
- gen_op_jnz_ecx[s->aflag](l1);
- gen_set_label(l2);
- gen_jmp_tb(s, next_eip, 1);
- gen_set_label(l1);
- return l2;
-}
-
-static inline void gen_stos(DisasContext *s, int ot)
-{
- gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
- gen_string_movl_A0_EDI(s);
- gen_op_st_T0_A0[ot + s->mem_index]();
- gen_op_movl_T0_Dshift[ot]();
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_EDI_T0();
- } else
-#endif
- if (s->aflag) {
- gen_op_addl_EDI_T0();
- } else {
- gen_op_addw_EDI_T0();
- }
-}
-
-static inline void gen_lods(DisasContext *s, int ot)
-{
- gen_string_movl_A0_ESI(s);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- gen_op_mov_reg_T0[ot][R_EAX]();
- gen_op_movl_T0_Dshift[ot]();
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_ESI_T0();
- } else
-#endif
- if (s->aflag) {
- gen_op_addl_ESI_T0();
- } else {
- gen_op_addw_ESI_T0();
- }
-}
-
-static inline void gen_scas(DisasContext *s, int ot)
-{
- gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
- gen_string_movl_A0_EDI(s);
- gen_op_ld_T1_A0[ot + s->mem_index]();
- gen_op_cmpl_T0_T1_cc();
- gen_op_movl_T0_Dshift[ot]();
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_EDI_T0();
- } else
-#endif
- if (s->aflag) {
- gen_op_addl_EDI_T0();
- } else {
- gen_op_addw_EDI_T0();
- }
-}
-
-static inline void gen_cmps(DisasContext *s, int ot)
-{
- gen_string_movl_A0_ESI(s);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- gen_string_movl_A0_EDI(s);
- gen_op_ld_T1_A0[ot + s->mem_index]();
- gen_op_cmpl_T0_T1_cc();
- gen_op_movl_T0_Dshift[ot]();
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_ESI_T0();
- gen_op_addq_EDI_T0();
- } else
-#endif
- if (s->aflag) {
- gen_op_addl_ESI_T0();
- gen_op_addl_EDI_T0();
- } else {
- gen_op_addw_ESI_T0();
- gen_op_addw_EDI_T0();
- }
-}
-
-static inline void gen_ins(DisasContext *s, int ot)
-{
- gen_string_movl_A0_EDI(s);
- gen_op_movl_T0_0();
- gen_op_st_T0_A0[ot + s->mem_index]();
- gen_op_in_DX_T0[ot]();
- gen_op_st_T0_A0[ot + s->mem_index]();
- gen_op_movl_T0_Dshift[ot]();
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_EDI_T0();
- } else
-#endif
- if (s->aflag) {
- gen_op_addl_EDI_T0();
- } else {
- gen_op_addw_EDI_T0();
- }
-}
-
-static inline void gen_outs(DisasContext *s, int ot)
-{
- gen_string_movl_A0_ESI(s);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- gen_op_out_DX_T0[ot]();
- gen_op_movl_T0_Dshift[ot]();
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_ESI_T0();
- } else
-#endif
- if (s->aflag) {
- gen_op_addl_ESI_T0();
- } else {
- gen_op_addw_ESI_T0();
- }
-}
-
-/* same method as Valgrind : we generate jumps to current or next
- instruction */
-#define GEN_REPZ(op) \
-static inline void gen_repz_ ## op(DisasContext *s, int ot, \
- target_ulong cur_eip, target_ulong next_eip) \
-{ \
- int l2;\
- gen_update_cc_op(s); \
- l2 = gen_jz_ecx_string(s, next_eip); \
- gen_ ## op(s, ot); \
- gen_op_dec_ECX[s->aflag](); \
- /* a loop would cause two single step exceptions if ECX = 1 \
- before rep string_insn */ \
- if (!s->jmp_opt) \
- gen_op_jz_ecx[s->aflag](l2); \
- gen_jmp(s, cur_eip); \
-}
-
-#define GEN_REPZ2(op) \
-static inline void gen_repz_ ## op(DisasContext *s, int ot, \
- target_ulong cur_eip, \
- target_ulong next_eip, \
- int nz) \
-{ \
- int l2;\
- gen_update_cc_op(s); \
- l2 = gen_jz_ecx_string(s, next_eip); \
- gen_ ## op(s, ot); \
- gen_op_dec_ECX[s->aflag](); \
- gen_op_set_cc_op(CC_OP_SUBB + ot); \
- gen_op_string_jnz_sub[nz][ot](l2);\
- if (!s->jmp_opt) \
- gen_op_jz_ecx[s->aflag](l2); \
- gen_jmp(s, cur_eip); \
-}
-
-GEN_REPZ(movs)
-GEN_REPZ(stos)
-GEN_REPZ(lods)
-GEN_REPZ(ins)
-GEN_REPZ(outs)
-GEN_REPZ2(scas)
-GEN_REPZ2(cmps)
-
-enum {
- JCC_O,
- JCC_B,
- JCC_Z,
- JCC_BE,
- JCC_S,
- JCC_P,
- JCC_L,
- JCC_LE,
-};
-
-static GenOpFunc1 *gen_jcc_sub[4][8] = {
- [OT_BYTE] = {
- NULL,
- gen_op_jb_subb,
- gen_op_jz_subb,
- gen_op_jbe_subb,
- gen_op_js_subb,
- NULL,
- gen_op_jl_subb,
- gen_op_jle_subb,
- },
- [OT_WORD] = {
- NULL,
- gen_op_jb_subw,
- gen_op_jz_subw,
- gen_op_jbe_subw,
- gen_op_js_subw,
- NULL,
- gen_op_jl_subw,
- gen_op_jle_subw,
- },
- [OT_LONG] = {
- NULL,
- gen_op_jb_subl,
- gen_op_jz_subl,
- gen_op_jbe_subl,
- gen_op_js_subl,
- NULL,
- gen_op_jl_subl,
- gen_op_jle_subl,
- },
-#ifdef TARGET_X86_64
- [OT_QUAD] = {
- NULL,
- BUGGY_64(gen_op_jb_subq),
- gen_op_jz_subq,
- BUGGY_64(gen_op_jbe_subq),
- gen_op_js_subq,
- NULL,
- BUGGY_64(gen_op_jl_subq),
- BUGGY_64(gen_op_jle_subq),
- },
-#endif
-};
-static GenOpFunc1 *gen_op_loop[3][4] = {
- [0] = {
- gen_op_loopnzw,
- gen_op_loopzw,
- gen_op_jnz_ecxw,
- },
- [1] = {
- gen_op_loopnzl,
- gen_op_loopzl,
- gen_op_jnz_ecxl,
- },
-#ifdef TARGET_X86_64
- [2] = {
- gen_op_loopnzq,
- gen_op_loopzq,
- gen_op_jnz_ecxq,
- },
-#endif
-};
-
-static GenOpFunc *gen_setcc_slow[8] = {
- gen_op_seto_T0_cc,
- gen_op_setb_T0_cc,
- gen_op_setz_T0_cc,
- gen_op_setbe_T0_cc,
- gen_op_sets_T0_cc,
- gen_op_setp_T0_cc,
- gen_op_setl_T0_cc,
- gen_op_setle_T0_cc,
-};
-
-static GenOpFunc *gen_setcc_sub[4][8] = {
- [OT_BYTE] = {
- NULL,
- gen_op_setb_T0_subb,
- gen_op_setz_T0_subb,
- gen_op_setbe_T0_subb,
- gen_op_sets_T0_subb,
- NULL,
- gen_op_setl_T0_subb,
- gen_op_setle_T0_subb,
- },
- [OT_WORD] = {
- NULL,
- gen_op_setb_T0_subw,
- gen_op_setz_T0_subw,
- gen_op_setbe_T0_subw,
- gen_op_sets_T0_subw,
- NULL,
- gen_op_setl_T0_subw,
- gen_op_setle_T0_subw,
- },
- [OT_LONG] = {
- NULL,
- gen_op_setb_T0_subl,
- gen_op_setz_T0_subl,
- gen_op_setbe_T0_subl,
- gen_op_sets_T0_subl,
- NULL,
- gen_op_setl_T0_subl,
- gen_op_setle_T0_subl,
- },
-#ifdef TARGET_X86_64
- [OT_QUAD] = {
- NULL,
- gen_op_setb_T0_subq,
- gen_op_setz_T0_subq,
- gen_op_setbe_T0_subq,
- gen_op_sets_T0_subq,
- NULL,
- gen_op_setl_T0_subq,
- gen_op_setle_T0_subq,
- },
-#endif
-};
-
-static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
- gen_op_fadd_ST0_FT0,
- gen_op_fmul_ST0_FT0,
- gen_op_fcom_ST0_FT0,
- gen_op_fcom_ST0_FT0,
- gen_op_fsub_ST0_FT0,
- gen_op_fsubr_ST0_FT0,
- gen_op_fdiv_ST0_FT0,
- gen_op_fdivr_ST0_FT0,
-};
-
-/* NOTE the exception in "r" op ordering */
-static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
- gen_op_fadd_STN_ST0,
- gen_op_fmul_STN_ST0,
- NULL,
- NULL,
- gen_op_fsubr_STN_ST0,
- gen_op_fsub_STN_ST0,
- gen_op_fdivr_STN_ST0,
- gen_op_fdiv_STN_ST0,
-};
-
-/* if d == OR_TMP0, it means memory operand (address in A0) */
-static void gen_op(DisasContext *s1, int op, int ot, int d)
-{
- GenOpFunc *gen_update_cc;
-
- if (d != OR_TMP0) {
- gen_op_mov_TN_reg[ot][0][d]();
- } else {
- gen_op_ld_T0_A0[ot + s1->mem_index]();
- }
- switch(op) {
- case OP_ADCL:
- case OP_SBBL:
- if (s1->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s1->cc_op);
- if (d != OR_TMP0) {
- gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
- gen_op_mov_reg_T0[ot][d]();
- } else {
- gen_op_arithc_mem_T0_T1_cc[ot + s1->mem_index][op - OP_ADCL]();
- }
- s1->cc_op = CC_OP_DYNAMIC;
- goto the_end;
- case OP_ADDL:
- gen_op_addl_T0_T1();
- s1->cc_op = CC_OP_ADDB + ot;
- gen_update_cc = gen_op_update2_cc;
- break;
- case OP_SUBL:
- gen_op_subl_T0_T1();
- s1->cc_op = CC_OP_SUBB + ot;
- gen_update_cc = gen_op_update2_cc;
- break;
- default:
- case OP_ANDL:
- case OP_ORL:
- case OP_XORL:
- gen_op_arith_T0_T1_cc[op]();
- s1->cc_op = CC_OP_LOGICB + ot;
- gen_update_cc = gen_op_update1_cc;
- break;
- case OP_CMPL:
- gen_op_cmpl_T0_T1_cc();
- s1->cc_op = CC_OP_SUBB + ot;
- gen_update_cc = NULL;
- break;
- }
- if (op != OP_CMPL) {
- if (d != OR_TMP0)
- gen_op_mov_reg_T0[ot][d]();
- else
- gen_op_st_T0_A0[ot + s1->mem_index]();
- }
- /* the flags update must happen after the memory write (precise
- exception support) */
- if (gen_update_cc)
- gen_update_cc();
- the_end: ;
-}
-
-/* if d == OR_TMP0, it means memory operand (address in A0) */
-static void gen_inc(DisasContext *s1, int ot, int d, int c)
-{
- if (d != OR_TMP0)
- gen_op_mov_TN_reg[ot][0][d]();
- else
- gen_op_ld_T0_A0[ot + s1->mem_index]();
- if (s1->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s1->cc_op);
- if (c > 0) {
- gen_op_incl_T0();
- s1->cc_op = CC_OP_INCB + ot;
- } else {
- gen_op_decl_T0();
- s1->cc_op = CC_OP_DECB + ot;
- }
- if (d != OR_TMP0)
- gen_op_mov_reg_T0[ot][d]();
- else
- gen_op_st_T0_A0[ot + s1->mem_index]();
- gen_op_update_inc_cc();
-}
-
-static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
-{
- if (d != OR_TMP0)
- gen_op_mov_TN_reg[ot][0][d]();
- else
- gen_op_ld_T0_A0[ot + s1->mem_index]();
- if (s != OR_TMP1)
- gen_op_mov_TN_reg[ot][1][s]();
- /* for zero counts, flags are not updated, so must do it dynamically */
- if (s1->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s1->cc_op);
-
- if (d != OR_TMP0)
- gen_op_shift_T0_T1_cc[ot][op]();
- else
- gen_op_shift_mem_T0_T1_cc[ot + s1->mem_index][op]();
- if (d != OR_TMP0)
- gen_op_mov_reg_T0[ot][d]();
- s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
-}
-
-static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
-{
- /* currently not optimized */
- gen_op_movl_T1_im(c);
- gen_shift(s1, op, ot, d, OR_TMP1);
-}
-
-static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
-{
- target_long disp;
- int havesib;
- int base;
- int index;
- int scale;
- int opreg;
- int mod, rm, code, override, must_add_seg;
-
- override = s->override;
- must_add_seg = s->addseg;
- if (override >= 0)
- must_add_seg = 1;
- mod = (modrm >> 6) & 3;
- rm = modrm & 7;
-
- if (s->aflag) {
-
- havesib = 0;
- base = rm;
- index = 0;
- scale = 0;
-
- if (base == 4) {
- havesib = 1;
- code = ldub_code(s->pc++);
- scale = (code >> 6) & 3;
- index = ((code >> 3) & 7) | REX_X(s);
- base = (code & 7);
- }
- base |= REX_B(s);
-
- switch (mod) {
- case 0:
- if ((base & 7) == 5) {
- base = -1;
- disp = (int32_t)ldl_code(s->pc);
- s->pc += 4;
- if (CODE64(s) && !havesib) {
- disp += s->pc + s->rip_offset;
- }
- } else {
- disp = 0;
- }
- break;
- case 1:
- disp = (int8_t)ldub_code(s->pc++);
- break;
- default:
- case 2:
- disp = ldl_code(s->pc);
- s->pc += 4;
- break;
- }
-
- if (base >= 0) {
- /* for correct popl handling with esp */
- if (base == 4 && s->popl_esp_hack)
- disp += s->popl_esp_hack;
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_movq_A0_reg[base]();
- if (disp != 0) {
- if ((int32_t)disp == disp)
- gen_op_addq_A0_im(disp);
- else
- gen_op_addq_A0_im64(disp >> 32, disp);
- }
- } else
-#endif
- {
- gen_op_movl_A0_reg[base]();
- if (disp != 0)
- gen_op_addl_A0_im(disp);
- }
- } else {
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- if ((int32_t)disp == disp)
- gen_op_movq_A0_im(disp);
- else
- gen_op_movq_A0_im64(disp >> 32, disp);
- } else
-#endif
- {
- gen_op_movl_A0_im(disp);
- }
- }
- /* XXX: index == 4 is always invalid */
- if (havesib && (index != 4 || scale != 0)) {
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_A0_reg_sN[scale][index]();
- } else
-#endif
- {
- gen_op_addl_A0_reg_sN[scale][index]();
- }
- }
- if (must_add_seg) {
- if (override < 0) {
- if (base == R_EBP || base == R_ESP)
- override = R_SS;
- else
- override = R_DS;
- }
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
- } else
-#endif
- {
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
- }
- }
- } else {
- switch (mod) {
- case 0:
- if (rm == 6) {
- disp = lduw_code(s->pc);
- s->pc += 2;
- gen_op_movl_A0_im(disp);
- rm = 0; /* avoid SS override */
- goto no_rm;
- } else {
- disp = 0;
- }
- break;
- case 1:
- disp = (int8_t)ldub_code(s->pc++);
- break;
- default:
- case 2:
- disp = lduw_code(s->pc);
- s->pc += 2;
- break;
- }
- switch(rm) {
- case 0:
- gen_op_movl_A0_reg[R_EBX]();
- gen_op_addl_A0_reg_sN[0][R_ESI]();
- break;
- case 1:
- gen_op_movl_A0_reg[R_EBX]();
- gen_op_addl_A0_reg_sN[0][R_EDI]();
- break;
- case 2:
- gen_op_movl_A0_reg[R_EBP]();
- gen_op_addl_A0_reg_sN[0][R_ESI]();
- break;
- case 3:
- gen_op_movl_A0_reg[R_EBP]();
- gen_op_addl_A0_reg_sN[0][R_EDI]();
- break;
- case 4:
- gen_op_movl_A0_reg[R_ESI]();
- break;
- case 5:
- gen_op_movl_A0_reg[R_EDI]();
- break;
- case 6:
- gen_op_movl_A0_reg[R_EBP]();
- break;
- default:
- case 7:
- gen_op_movl_A0_reg[R_EBX]();
- break;
- }
- if (disp != 0)
- gen_op_addl_A0_im(disp);
- gen_op_andl_A0_ffff();
- no_rm:
- if (must_add_seg) {
- if (override < 0) {
- if (rm == 2 || rm == 3 || rm == 6)
- override = R_SS;
- else
- override = R_DS;
- }
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
- }
- }
-
- opreg = OR_A0;
- disp = 0;
- *reg_ptr = opreg;
- *offset_ptr = disp;
-}
-
-static void gen_nop_modrm(DisasContext *s, int modrm)
-{
- int mod, rm, base, code;
-
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- return;
- rm = modrm & 7;
-
- if (s->aflag) {
-
- base = rm;
-
- if (base == 4) {
- code = ldub_code(s->pc++);
- base = (code & 7);
- }
-
- switch (mod) {
- case 0:
- if (base == 5) {
- s->pc += 4;
- }
- break;
- case 1:
- s->pc++;
- break;
- default:
- case 2:
- s->pc += 4;
- break;
- }
- } else {
- switch (mod) {
- case 0:
- if (rm == 6) {
- s->pc += 2;
- }
- break;
- case 1:
- s->pc++;
- break;
- default:
- case 2:
- s->pc += 2;
- break;
- }
- }
-}
-
-/* used for LEA and MOV AX, mem */
-static void gen_add_A0_ds_seg(DisasContext *s)
-{
- int override, must_add_seg;
- must_add_seg = s->addseg;
- override = R_DS;
- if (s->override >= 0) {
- override = s->override;
- must_add_seg = 1;
- } else {
- override = R_DS;
- }
- if (must_add_seg) {
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
- } else
-#endif
- {
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
- }
- }
-}
-
-/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
- OR_TMP0 */
-static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
-{
- int mod, rm, opreg, disp;
-
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- if (mod == 3) {
- if (is_store) {
- if (reg != OR_TMP0)
- gen_op_mov_TN_reg[ot][0][reg]();
- gen_op_mov_reg_T0[ot][rm]();
- } else {
- gen_op_mov_TN_reg[ot][0][rm]();
- if (reg != OR_TMP0)
- gen_op_mov_reg_T0[ot][reg]();
- }
- } else {
- gen_lea_modrm(s, modrm, &opreg, &disp);
- if (is_store) {
- if (reg != OR_TMP0)
- gen_op_mov_TN_reg[ot][0][reg]();
- gen_op_st_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_ld_T0_A0[ot + s->mem_index]();
- if (reg != OR_TMP0)
- gen_op_mov_reg_T0[ot][reg]();
- }
- }
-}
-
-static inline uint32_t insn_get(DisasContext *s, int ot)
-{
- uint32_t ret;
-
- switch(ot) {
- case OT_BYTE:
- ret = ldub_code(s->pc);
- s->pc++;
- break;
- case OT_WORD:
- ret = lduw_code(s->pc);
- s->pc += 2;
- break;
- default:
- case OT_LONG:
- ret = ldl_code(s->pc);
- s->pc += 4;
- break;
- }
- return ret;
-}
-
-static inline int insn_const_size(unsigned int ot)
-{
- if (ot <= OT_LONG)
- return 1 << ot;
- else
- return 4;
-}
-
-static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
-{
- TranslationBlock *tb;
- target_ulong pc;
-
- pc = s->cs_base + eip;
- tb = s->tb;
- /* NOTE: we handle the case where the TB spans two pages here */
- if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
- (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) {
- /* jump to same page: we can use a direct jump */
- if (tb_num == 0)
- gen_op_goto_tb0(TBPARAM(tb));
- else
- gen_op_goto_tb1(TBPARAM(tb));
- gen_jmp_im(eip);
- gen_op_movl_T0_im((long)tb + tb_num);
- gen_op_exit_tb();
- } else {
- /* jump to another page: currently not optimized */
- gen_jmp_im(eip);
- gen_eob(s);
- }
-}
-
-static inline void gen_jcc(DisasContext *s, int b,
- target_ulong val, target_ulong next_eip)
-{
- TranslationBlock *tb;
- int inv, jcc_op;
- GenOpFunc1 *func;
- target_ulong tmp;
- int l1, l2;
-
- inv = b & 1;
- jcc_op = (b >> 1) & 7;
-
- if (s->jmp_opt) {
- switch(s->cc_op) {
- /* we optimize the cmp/jcc case */
- case CC_OP_SUBB:
- case CC_OP_SUBW:
- case CC_OP_SUBL:
- case CC_OP_SUBQ:
- func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
- break;
-
- /* some jumps are easy to compute */
- case CC_OP_ADDB:
- case CC_OP_ADDW:
- case CC_OP_ADDL:
- case CC_OP_ADDQ:
-
- case CC_OP_ADCB:
- case CC_OP_ADCW:
- case CC_OP_ADCL:
- case CC_OP_ADCQ:
-
- case CC_OP_SBBB:
- case CC_OP_SBBW:
- case CC_OP_SBBL:
- case CC_OP_SBBQ:
-
- case CC_OP_LOGICB:
- case CC_OP_LOGICW:
- case CC_OP_LOGICL:
- case CC_OP_LOGICQ:
-
- case CC_OP_INCB:
- case CC_OP_INCW:
- case CC_OP_INCL:
- case CC_OP_INCQ:
-
- case CC_OP_DECB:
- case CC_OP_DECW:
- case CC_OP_DECL:
- case CC_OP_DECQ:
-
- case CC_OP_SHLB:
- case CC_OP_SHLW:
- case CC_OP_SHLL:
- case CC_OP_SHLQ:
-
- case CC_OP_SARB:
- case CC_OP_SARW:
- case CC_OP_SARL:
- case CC_OP_SARQ:
- switch(jcc_op) {
- case JCC_Z:
- func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
- break;
- case JCC_S:
- func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
- break;
- default:
- func = NULL;
- break;
- }
- break;
- default:
- func = NULL;
- break;
- }
-
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
-
- if (!func) {
- gen_setcc_slow[jcc_op]();
- func = gen_op_jnz_T0_label;
- }
-
- if (inv) {
- tmp = val;
- val = next_eip;
- next_eip = tmp;
- }
- tb = s->tb;
-
- l1 = gen_new_label();
- func(l1);
-
- gen_goto_tb(s, 0, next_eip);
-
- gen_set_label(l1);
- gen_goto_tb(s, 1, val);
-
- s->is_jmp = 3;
- } else {
-
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_setcc_slow[jcc_op]();
- if (inv) {
- tmp = val;
- val = next_eip;
- next_eip = tmp;
- }
- l1 = gen_new_label();
- l2 = gen_new_label();
- gen_op_jnz_T0_label(l1);
- gen_jmp_im(next_eip);
- gen_op_jmp_label(l2);
- gen_set_label(l1);
- gen_jmp_im(val);
- gen_set_label(l2);
- gen_eob(s);
- }
-}
-
-static void gen_setcc(DisasContext *s, int b)
-{
- int inv, jcc_op;
- GenOpFunc *func;
-
- inv = b & 1;
- jcc_op = (b >> 1) & 7;
- switch(s->cc_op) {
- /* we optimize the cmp/jcc case */
- case CC_OP_SUBB:
- case CC_OP_SUBW:
- case CC_OP_SUBL:
- case CC_OP_SUBQ:
- func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
- if (!func)
- goto slow_jcc;
- break;
-
- /* some jumps are easy to compute */
- case CC_OP_ADDB:
- case CC_OP_ADDW:
- case CC_OP_ADDL:
- case CC_OP_ADDQ:
-
- case CC_OP_LOGICB:
- case CC_OP_LOGICW:
- case CC_OP_LOGICL:
- case CC_OP_LOGICQ:
-
- case CC_OP_INCB:
- case CC_OP_INCW:
- case CC_OP_INCL:
- case CC_OP_INCQ:
-
- case CC_OP_DECB:
- case CC_OP_DECW:
- case CC_OP_DECL:
- case CC_OP_DECQ:
-
- case CC_OP_SHLB:
- case CC_OP_SHLW:
- case CC_OP_SHLL:
- case CC_OP_SHLQ:
- switch(jcc_op) {
- case JCC_Z:
- func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
- break;
- case JCC_S:
- func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
- break;
- default:
- goto slow_jcc;
- }
- break;
- default:
- slow_jcc:
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- func = gen_setcc_slow[jcc_op];
- break;
- }
- func();
- if (inv) {
- gen_op_xor_T0_1();
- }
-}
-
-/* move T0 to seg_reg and compute if the CPU state may change. Never
- call this function with seg_reg == R_CS */
-static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
-{
- if (s->pe && !s->vm86) {
- /* XXX: optimize by finding processor state dynamically */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(cur_eip);
- gen_op_movl_seg_T0(seg_reg);
- /* abort translation because the addseg value may change or
- because ss32 may change. For R_SS, translation must always
- stop as a special handling must be done to disable hardware
- interrupts for the next instruction */
- if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
- s->is_jmp = 3;
- } else {
- gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
- if (seg_reg == R_SS)
- s->is_jmp = 3;
- }
-}
-
-static inline void gen_stack_update(DisasContext *s, int addend)
-{
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- if (addend == 8)
- gen_op_addq_ESP_8();
- else
- gen_op_addq_ESP_im(addend);
- } else
-#endif
- if (s->ss32) {
- if (addend == 2)
- gen_op_addl_ESP_2();
- else if (addend == 4)
- gen_op_addl_ESP_4();
- else
- gen_op_addl_ESP_im(addend);
- } else {
- if (addend == 2)
- gen_op_addw_ESP_2();
- else if (addend == 4)
- gen_op_addw_ESP_4();
- else
- gen_op_addw_ESP_im(addend);
- }
-}
-
-/* generate a push. It depends on ss32, addseg and dflag */
-static void gen_push_T0(DisasContext *s)
-{
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- gen_op_movq_A0_reg[R_ESP]();
- if (s->dflag) {
- gen_op_subq_A0_8();
- gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
- } else {
- gen_op_subq_A0_2();
- gen_op_st_T0_A0[OT_WORD + s->mem_index]();
- }
- gen_op_movq_ESP_A0();
- } else
-#endif
- {
- gen_op_movl_A0_reg[R_ESP]();
- if (!s->dflag)
- gen_op_subl_A0_2();
- else
- gen_op_subl_A0_4();
- if (s->ss32) {
- if (s->addseg) {
- gen_op_movl_T1_A0();
- gen_op_addl_A0_SS();
- }
- } else {
- gen_op_andl_A0_ffff();
- gen_op_movl_T1_A0();
- gen_op_addl_A0_SS();
- }
- gen_op_st_T0_A0[s->dflag + 1 + s->mem_index]();
- if (s->ss32 && !s->addseg)
- gen_op_movl_ESP_A0();
- else
- gen_op_mov_reg_T1[s->ss32 + 1][R_ESP]();
- }
-}
-
-/* generate a push. It depends on ss32, addseg and dflag */
-/* slower version for T1, only used for call Ev */
-static void gen_push_T1(DisasContext *s)
-{
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- gen_op_movq_A0_reg[R_ESP]();
- if (s->dflag) {
- gen_op_subq_A0_8();
- gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
- } else {
- gen_op_subq_A0_2();
- gen_op_st_T0_A0[OT_WORD + s->mem_index]();
- }
- gen_op_movq_ESP_A0();
- } else
-#endif
- {
- gen_op_movl_A0_reg[R_ESP]();
- if (!s->dflag)
- gen_op_subl_A0_2();
- else
- gen_op_subl_A0_4();
- if (s->ss32) {
- if (s->addseg) {
- gen_op_addl_A0_SS();
- }
- } else {
- gen_op_andl_A0_ffff();
- gen_op_addl_A0_SS();
- }
- gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
-
- if (s->ss32 && !s->addseg)
- gen_op_movl_ESP_A0();
- else
- gen_stack_update(s, (-2) << s->dflag);
- }
-}
-
-/* two step pop is necessary for precise exceptions */
-static void gen_pop_T0(DisasContext *s)
-{
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- gen_op_movq_A0_reg[R_ESP]();
- gen_op_ld_T0_A0[(s->dflag ? OT_QUAD : OT_WORD) + s->mem_index]();
- } else
-#endif
- {
- gen_op_movl_A0_reg[R_ESP]();
- if (s->ss32) {
- if (s->addseg)
- gen_op_addl_A0_SS();
- } else {
- gen_op_andl_A0_ffff();
- gen_op_addl_A0_SS();
- }
- gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index]();
- }
-}
-
-static void gen_pop_update(DisasContext *s)
-{
-#ifdef TARGET_X86_64
- if (CODE64(s) && s->dflag) {
- gen_stack_update(s, 8);
- } else
-#endif
- {
- gen_stack_update(s, 2 << s->dflag);
- }
-}
-
-static void gen_stack_A0(DisasContext *s)
-{
- gen_op_movl_A0_ESP();
- if (!s->ss32)
- gen_op_andl_A0_ffff();
- gen_op_movl_T1_A0();
- if (s->addseg)
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
-}
-
-/* NOTE: wrap around in 16 bit not fully handled */
-static void gen_pusha(DisasContext *s)
-{
- int i;
- gen_op_movl_A0_ESP();
- gen_op_addl_A0_im(-16 << s->dflag);
- if (!s->ss32)
- gen_op_andl_A0_ffff();
- gen_op_movl_T1_A0();
- if (s->addseg)
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
- for(i = 0;i < 8; i++) {
- gen_op_mov_TN_reg[OT_LONG][0][7 - i]();
- gen_op_st_T0_A0[OT_WORD + s->dflag + s->mem_index]();
- gen_op_addl_A0_im(2 << s->dflag);
- }
- gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
-}
-
-/* NOTE: wrap around in 16 bit not fully handled */
-static void gen_popa(DisasContext *s)
-{
- int i;
- gen_op_movl_A0_ESP();
- if (!s->ss32)
- gen_op_andl_A0_ffff();
- gen_op_movl_T1_A0();
- gen_op_addl_T1_im(16 << s->dflag);
- if (s->addseg)
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
- for(i = 0;i < 8; i++) {
- /* ESP is not reloaded */
- if (i != 3) {
- gen_op_ld_T0_A0[OT_WORD + s->dflag + s->mem_index]();
- gen_op_mov_reg_T0[OT_WORD + s->dflag][7 - i]();
- }
- gen_op_addl_A0_im(2 << s->dflag);
- }
- gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
-}
-
-static void gen_enter(DisasContext *s, int esp_addend, int level)
-{
- int ot, opsize;
-
- level &= 0x1f;
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- ot = s->dflag ? OT_QUAD : OT_WORD;
- opsize = 1 << ot;
-
- gen_op_movl_A0_ESP();
- gen_op_addq_A0_im(-opsize);
- gen_op_movl_T1_A0();
-
- /* push bp */
- gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
- gen_op_st_T0_A0[ot + s->mem_index]();
- if (level) {
- gen_op_enter64_level(level, (ot == OT_QUAD));
- }
- gen_op_mov_reg_T1[ot][R_EBP]();
- gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
- gen_op_mov_reg_T1[OT_QUAD][R_ESP]();
- } else
-#endif
- {
- ot = s->dflag + OT_WORD;
- opsize = 2 << s->dflag;
-
- gen_op_movl_A0_ESP();
- gen_op_addl_A0_im(-opsize);
- if (!s->ss32)
- gen_op_andl_A0_ffff();
- gen_op_movl_T1_A0();
- if (s->addseg)
- gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
- /* push bp */
- gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
- gen_op_st_T0_A0[ot + s->mem_index]();
- if (level) {
- gen_op_enter_level(level, s->dflag);
- }
- gen_op_mov_reg_T1[ot][R_EBP]();
- gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
- gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
- }
-}
-
-static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
-{
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(cur_eip);
- gen_op_raise_exception(trapno);
- s->is_jmp = 3;
-}
-
-/* an interrupt is different from an exception because of the
- priviledge checks */
-static void gen_interrupt(DisasContext *s, int intno,
- target_ulong cur_eip, target_ulong next_eip)
-{
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(cur_eip);
- gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip));
- s->is_jmp = 3;
-}
-
-static void gen_debug(DisasContext *s, target_ulong cur_eip)
-{
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(cur_eip);
- gen_op_debug();
- s->is_jmp = 3;
-}
-
-/* generate a generic end of block. Trace exception is also generated
- if needed */
-static void gen_eob(DisasContext *s)
-{
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
- gen_op_reset_inhibit_irq();
- }
- if (s->singlestep_enabled) {
- gen_op_debug();
- } else if (s->tf) {
- gen_op_raise_exception(EXCP01_SSTP);
- } else {
- gen_op_movl_T0_0();
- gen_op_exit_tb();
- }
- s->is_jmp = 3;
-}
-
-/* generate a jump to eip. No segment change must happen before as a
- direct call to the next block may occur */
-static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
-{
- if (s->jmp_opt) {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_goto_tb(s, tb_num, eip);
- s->is_jmp = 3;
- } else {
- gen_jmp_im(eip);
- gen_eob(s);
- }
-}
-
-static void gen_jmp(DisasContext *s, target_ulong eip)
-{
- gen_jmp_tb(s, eip, 0);
-}
-
-static void gen_movtl_T0_im(target_ulong val)
-{
-#ifdef TARGET_X86_64
- if ((int32_t)val == val) {
- gen_op_movl_T0_im(val);
- } else {
- gen_op_movq_T0_im64(val >> 32, val);
- }
-#else
- gen_op_movl_T0_im(val);
-#endif
-}
-
-static void gen_movtl_T1_im(target_ulong val)
-{
-#ifdef TARGET_X86_64
- if ((int32_t)val == val) {
- gen_op_movl_T1_im(val);
- } else {
- gen_op_movq_T1_im64(val >> 32, val);
- }
-#else
- gen_op_movl_T1_im(val);
-#endif
-}
-
-static void gen_add_A0_im(DisasContext *s, int val)
-{
-#ifdef TARGET_X86_64
- if (CODE64(s))
- gen_op_addq_A0_im(val);
- else
-#endif
- gen_op_addl_A0_im(val);
-}
-
-static GenOpFunc1 *gen_ldq_env_A0[3] = {
- gen_op_ldq_raw_env_A0,
-#ifndef CONFIG_USER_ONLY
- gen_op_ldq_kernel_env_A0,
- gen_op_ldq_user_env_A0,
-#endif
-};
-
-static GenOpFunc1 *gen_stq_env_A0[3] = {
- gen_op_stq_raw_env_A0,
-#ifndef CONFIG_USER_ONLY
- gen_op_stq_kernel_env_A0,
- gen_op_stq_user_env_A0,
-#endif
-};
-
-static GenOpFunc1 *gen_ldo_env_A0[3] = {
- gen_op_ldo_raw_env_A0,
-#ifndef CONFIG_USER_ONLY
- gen_op_ldo_kernel_env_A0,
- gen_op_ldo_user_env_A0,
-#endif
-};
-
-static GenOpFunc1 *gen_sto_env_A0[3] = {
- gen_op_sto_raw_env_A0,
-#ifndef CONFIG_USER_ONLY
- gen_op_sto_kernel_env_A0,
- gen_op_sto_user_env_A0,
-#endif
-};
-
-#define SSE_SPECIAL ((GenOpFunc2 *)1)
-
-#define MMX_OP2(x) { gen_op_ ## x ## _mmx, gen_op_ ## x ## _xmm }
-#define SSE_FOP(x) { gen_op_ ## x ## ps, gen_op_ ## x ## pd, \
- gen_op_ ## x ## ss, gen_op_ ## x ## sd, }
-
-static GenOpFunc2 *sse_op_table1[256][4] = {
- /* pure SSE operations */
- [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
- [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
- [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
- [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
- [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm },
- [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm },
- [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
- [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
-
- [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
- [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
- [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
- [0x2b] = { SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd */
- [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
- [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
- [0x2e] = { gen_op_ucomiss, gen_op_ucomisd },
- [0x2f] = { gen_op_comiss, gen_op_comisd },
- [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
- [0x51] = SSE_FOP(sqrt),
- [0x52] = { gen_op_rsqrtps, NULL, gen_op_rsqrtss, NULL },
- [0x53] = { gen_op_rcpps, NULL, gen_op_rcpss, NULL },
- [0x54] = { gen_op_pand_xmm, gen_op_pand_xmm }, /* andps, andpd */
- [0x55] = { gen_op_pandn_xmm, gen_op_pandn_xmm }, /* andnps, andnpd */
- [0x56] = { gen_op_por_xmm, gen_op_por_xmm }, /* orps, orpd */
- [0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
- [0x58] = SSE_FOP(add),
- [0x59] = SSE_FOP(mul),
- [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps,
- gen_op_cvtss2sd, gen_op_cvtsd2ss },
- [0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
- [0x5c] = SSE_FOP(sub),
- [0x5d] = SSE_FOP(min),
- [0x5e] = SSE_FOP(div),
- [0x5f] = SSE_FOP(max),
-
- [0xc2] = SSE_FOP(cmpeq),
- [0xc6] = { (GenOpFunc2 *)gen_op_shufps, (GenOpFunc2 *)gen_op_shufpd },
-
- /* MMX ops and their SSE extensions */
- [0x60] = MMX_OP2(punpcklbw),
- [0x61] = MMX_OP2(punpcklwd),
- [0x62] = MMX_OP2(punpckldq),
- [0x63] = MMX_OP2(packsswb),
- [0x64] = MMX_OP2(pcmpgtb),
- [0x65] = MMX_OP2(pcmpgtw),
- [0x66] = MMX_OP2(pcmpgtl),
- [0x67] = MMX_OP2(packuswb),
- [0x68] = MMX_OP2(punpckhbw),
- [0x69] = MMX_OP2(punpckhwd),
- [0x6a] = MMX_OP2(punpckhdq),
- [0x6b] = MMX_OP2(packssdw),
- [0x6c] = { NULL, gen_op_punpcklqdq_xmm },
- [0x6d] = { NULL, gen_op_punpckhqdq_xmm },
- [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
- [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
- [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx,
- (GenOpFunc2 *)gen_op_pshufd_xmm,
- (GenOpFunc2 *)gen_op_pshufhw_xmm,
- (GenOpFunc2 *)gen_op_pshuflw_xmm },
- [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
- [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
- [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
- [0x74] = MMX_OP2(pcmpeqb),
- [0x75] = MMX_OP2(pcmpeqw),
- [0x76] = MMX_OP2(pcmpeql),
- [0x77] = { SSE_SPECIAL }, /* emms */
- [0x7c] = { NULL, gen_op_haddpd, NULL, gen_op_haddps },
- [0x7d] = { NULL, gen_op_hsubpd, NULL, gen_op_hsubps },
- [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
- [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
- [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
- [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
- [0xd0] = { NULL, gen_op_addsubpd, NULL, gen_op_addsubps },
- [0xd1] = MMX_OP2(psrlw),
- [0xd2] = MMX_OP2(psrld),
- [0xd3] = MMX_OP2(psrlq),
- [0xd4] = MMX_OP2(paddq),
- [0xd5] = MMX_OP2(pmullw),
- [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
- [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
- [0xd8] = MMX_OP2(psubusb),
- [0xd9] = MMX_OP2(psubusw),
- [0xda] = MMX_OP2(pminub),
- [0xdb] = MMX_OP2(pand),
- [0xdc] = MMX_OP2(paddusb),
- [0xdd] = MMX_OP2(paddusw),
- [0xde] = MMX_OP2(pmaxub),
- [0xdf] = MMX_OP2(pandn),
- [0xe0] = MMX_OP2(pavgb),
- [0xe1] = MMX_OP2(psraw),
- [0xe2] = MMX_OP2(psrad),
- [0xe3] = MMX_OP2(pavgw),
- [0xe4] = MMX_OP2(pmulhuw),
- [0xe5] = MMX_OP2(pmulhw),
- [0xe6] = { NULL, gen_op_cvttpd2dq, gen_op_cvtdq2pd, gen_op_cvtpd2dq },
- [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
- [0xe8] = MMX_OP2(psubsb),
- [0xe9] = MMX_OP2(psubsw),
- [0xea] = MMX_OP2(pminsw),
- [0xeb] = MMX_OP2(por),
- [0xec] = MMX_OP2(paddsb),
- [0xed] = MMX_OP2(paddsw),
- [0xee] = MMX_OP2(pmaxsw),
- [0xef] = MMX_OP2(pxor),
- [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
- [0xf1] = MMX_OP2(psllw),
- [0xf2] = MMX_OP2(pslld),
- [0xf3] = MMX_OP2(psllq),
- [0xf4] = MMX_OP2(pmuludq),
- [0xf5] = MMX_OP2(pmaddwd),
- [0xf6] = MMX_OP2(psadbw),
- [0xf7] = MMX_OP2(maskmov),
- [0xf8] = MMX_OP2(psubb),
- [0xf9] = MMX_OP2(psubw),
- [0xfa] = MMX_OP2(psubl),
- [0xfb] = MMX_OP2(psubq),
- [0xfc] = MMX_OP2(paddb),
- [0xfd] = MMX_OP2(paddw),
- [0xfe] = MMX_OP2(paddl),
-};
-
-static GenOpFunc2 *sse_op_table2[3 * 8][2] = {
- [0 + 2] = MMX_OP2(psrlw),
- [0 + 4] = MMX_OP2(psraw),
- [0 + 6] = MMX_OP2(psllw),
- [8 + 2] = MMX_OP2(psrld),
- [8 + 4] = MMX_OP2(psrad),
- [8 + 6] = MMX_OP2(pslld),
- [16 + 2] = MMX_OP2(psrlq),
- [16 + 3] = { NULL, gen_op_psrldq_xmm },
- [16 + 6] = MMX_OP2(psllq),
- [16 + 7] = { NULL, gen_op_pslldq_xmm },
-};
-
-static GenOpFunc1 *sse_op_table3[4 * 3] = {
- gen_op_cvtsi2ss,
- gen_op_cvtsi2sd,
- X86_64_ONLY(gen_op_cvtsq2ss),
- X86_64_ONLY(gen_op_cvtsq2sd),
-
- gen_op_cvttss2si,
- gen_op_cvttsd2si,
- X86_64_ONLY(gen_op_cvttss2sq),
- X86_64_ONLY(gen_op_cvttsd2sq),
-
- gen_op_cvtss2si,
- gen_op_cvtsd2si,
- X86_64_ONLY(gen_op_cvtss2sq),
- X86_64_ONLY(gen_op_cvtsd2sq),
-};
-
-static GenOpFunc2 *sse_op_table4[8][4] = {
- SSE_FOP(cmpeq),
- SSE_FOP(cmplt),
- SSE_FOP(cmple),
- SSE_FOP(cmpunord),
- SSE_FOP(cmpneq),
- SSE_FOP(cmpnlt),
- SSE_FOP(cmpnle),
- SSE_FOP(cmpord),
-};
-
-static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
-{
- int b1, op1_offset, op2_offset, is_xmm, val, ot;
- int modrm, mod, rm, reg, reg_addr, offset_addr;
- GenOpFunc2 *sse_op2;
- GenOpFunc3 *sse_op3;
-
- b &= 0xff;
- if (s->prefix & PREFIX_DATA)
- b1 = 1;
- else if (s->prefix & PREFIX_REPZ)
- b1 = 2;
- else if (s->prefix & PREFIX_REPNZ)
- b1 = 3;
- else
- b1 = 0;
- sse_op2 = sse_op_table1[b][b1];
- if (!sse_op2)
- goto illegal_op;
- if (b <= 0x5f || b == 0xc6 || b == 0xc2) {
- is_xmm = 1;
- } else {
- if (b1 == 0) {
- /* MMX case */
- is_xmm = 0;
- } else {
- is_xmm = 1;
- }
- }
- /* simple MMX/SSE operation */
- if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
- return;
- }
- if (s->flags & HF_EM_MASK) {
- illegal_op:
- gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
- return;
- }
- if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
- goto illegal_op;
- if (b == 0x77) {
- /* emms */
- gen_op_emms();
- return;
- }
- /* prepare MMX state (XXX: optimize by storing fptt and fptags in
- the static cpu state) */
- if (!is_xmm) {
- gen_op_enter_mmx();
- }
-
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7);
- if (is_xmm)
- reg |= rex_r;
- mod = (modrm >> 6) & 3;
- if (sse_op2 == SSE_SPECIAL) {
- b |= (b1 << 8);
- switch(b) {
- case 0x0e7: /* movntq */
- if (mod == 3)
- goto illegal_op;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
- break;
- case 0x1e7: /* movntdq */
- case 0x02b: /* movntps */
- case 0x12b: /* movntps */
- case 0x3f0: /* lddqu */
- if (mod == 3)
- goto illegal_op;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
- break;
- case 0x6e: /* movd mm, ea */
-#ifdef TARGET_X86_64
- if (s->dflag == 2) {
- gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
- gen_op_movq_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
- } else
-#endif
- {
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
- gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
- }
- break;
- case 0x16e: /* movd xmm, ea */
-#ifdef TARGET_X86_64
- if (s->dflag == 2) {
- gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
- gen_op_movq_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
- } else
-#endif
- {
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
- gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
- }
- break;
- case 0x6f: /* movq mm, ea */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
- } else {
- rm = (modrm & 7);
- gen_op_movq(offsetof(CPUX86State,fpregs[reg].mmx),
- offsetof(CPUX86State,fpregs[rm].mmx));
- }
- break;
- case 0x010: /* movups */
- case 0x110: /* movupd */
- case 0x028: /* movaps */
- case 0x128: /* movapd */
- case 0x16f: /* movdqa xmm, ea */
- case 0x26f: /* movdqu xmm, ea */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
- offsetof(CPUX86State,xmm_regs[rm]));
- }
- break;
- case 0x210: /* movss xmm, ea */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
- gen_op_movl_T0_0();
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
- }
- break;
- case 0x310: /* movsd xmm, ea */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- gen_op_movl_T0_0();
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
- }
- break;
- case 0x012: /* movlps */
- case 0x112: /* movlpd */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- } else {
- /* movhlps */
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
- }
- break;
- case 0x212: /* movsldup */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
- }
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
- break;
- case 0x312: /* movddup */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
- }
- gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- break;
- case 0x016: /* movhps */
- case 0x116: /* movhpd */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
- } else {
- /* movlhps */
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
- }
- break;
- case 0x216: /* movshdup */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
- }
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
- gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
- break;
- case 0x7e: /* movd ea, mm */
-#ifdef TARGET_X86_64
- if (s->dflag == 2) {
- gen_op_movq_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
- gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
- } else
-#endif
- {
- gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
- }
- break;
- case 0x17e: /* movd ea, xmm */
-#ifdef TARGET_X86_64
- if (s->dflag == 2) {
- gen_op_movq_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
- gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
- } else
-#endif
- {
- gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
- }
- break;
- case 0x27e: /* movq xmm, ea */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
- offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
- }
- gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
- break;
- case 0x7f: /* movq ea, mm */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
- } else {
- rm = (modrm & 7);
- gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
- offsetof(CPUX86State,fpregs[reg].mmx));
- }
- break;
- case 0x011: /* movups */
- case 0x111: /* movupd */
- case 0x029: /* movaps */
- case 0x129: /* movapd */
- case 0x17f: /* movdqa ea, xmm */
- case 0x27f: /* movdqu ea, xmm */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
- offsetof(CPUX86State,xmm_regs[reg]));
- }
- break;
- case 0x211: /* movss ea, xmm */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
- gen_op_st_T0_A0[OT_LONG + s->mem_index]();
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
- }
- break;
- case 0x311: /* movsd ea, xmm */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- }
- break;
- case 0x013: /* movlps */
- case 0x113: /* movlpd */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- } else {
- goto illegal_op;
- }
- break;
- case 0x017: /* movhps */
- case 0x117: /* movhpd */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
- } else {
- goto illegal_op;
- }
- break;
- case 0x71: /* shift mm, im */
- case 0x72:
- case 0x73:
- case 0x171: /* shift xmm, im */
- case 0x172:
- case 0x173:
- val = ldub_code(s->pc++);
- if (is_xmm) {
- gen_op_movl_T0_im(val);
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
- gen_op_movl_T0_0();
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(1)));
- op1_offset = offsetof(CPUX86State,xmm_t0);
- } else {
- gen_op_movl_T0_im(val);
- gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(0)));
- gen_op_movl_T0_0();
- gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(1)));
- op1_offset = offsetof(CPUX86State,mmx_t0);
- }
- sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
- if (!sse_op2)
- goto illegal_op;
- if (is_xmm) {
- rm = (modrm & 7) | REX_B(s);
- op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
- } else {
- rm = (modrm & 7);
- op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
- }
- sse_op2(op2_offset, op1_offset);
- break;
- case 0x050: /* movmskps */
- rm = (modrm & 7) | REX_B(s);
- gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm]));
- gen_op_mov_reg_T0[OT_LONG][reg]();
- break;
- case 0x150: /* movmskpd */
- rm = (modrm & 7) | REX_B(s);
- gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm]));
- gen_op_mov_reg_T0[OT_LONG][reg]();
- break;
- case 0x02a: /* cvtpi2ps */
- case 0x12a: /* cvtpi2pd */
- gen_op_enter_mmx();
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- op2_offset = offsetof(CPUX86State,mmx_t0);
- gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
- } else {
- rm = (modrm & 7);
- op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
- }
- op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
- switch(b >> 8) {
- case 0x0:
- gen_op_cvtpi2ps(op1_offset, op2_offset);
- break;
- default:
- case 0x1:
- gen_op_cvtpi2pd(op1_offset, op2_offset);
- break;
- }
- break;
- case 0x22a: /* cvtsi2ss */
- case 0x32a: /* cvtsi2sd */
- ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
- sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)](op1_offset);
- break;
- case 0x02c: /* cvttps2pi */
- case 0x12c: /* cvttpd2pi */
- case 0x02d: /* cvtps2pi */
- case 0x12d: /* cvtpd2pi */
- gen_op_enter_mmx();
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- op2_offset = offsetof(CPUX86State,xmm_t0);
- gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
- } else {
- rm = (modrm & 7) | REX_B(s);
- op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
- }
- op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
- switch(b) {
- case 0x02c:
- gen_op_cvttps2pi(op1_offset, op2_offset);
- break;
- case 0x12c:
- gen_op_cvttpd2pi(op1_offset, op2_offset);
- break;
- case 0x02d:
- gen_op_cvtps2pi(op1_offset, op2_offset);
- break;
- case 0x12d:
- gen_op_cvtpd2pi(op1_offset, op2_offset);
- break;
- }
- break;
- case 0x22c: /* cvttss2si */
- case 0x32c: /* cvttsd2si */
- case 0x22d: /* cvtss2si */
- case 0x32d: /* cvtsd2si */
- ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- if ((b >> 8) & 1) {
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
- } else {
- gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
- }
- op2_offset = offsetof(CPUX86State,xmm_t0);
- } else {
- rm = (modrm & 7) | REX_B(s);
- op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
- }
- sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
- (b & 1) * 4](op2_offset);
- gen_op_mov_reg_T0[ot][reg]();
- break;
- case 0xc4: /* pinsrw */
- case 0x1c4:
- s->rip_offset = 1;
- gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- val = ldub_code(s->pc++);
- if (b1) {
- val &= 7;
- gen_op_pinsrw_xmm(offsetof(CPUX86State,xmm_regs[reg]), val);
- } else {
- val &= 3;
- gen_op_pinsrw_mmx(offsetof(CPUX86State,fpregs[reg].mmx), val);
- }
- break;
- case 0xc5: /* pextrw */
- case 0x1c5:
- if (mod != 3)
- goto illegal_op;
- val = ldub_code(s->pc++);
- if (b1) {
- val &= 7;
- rm = (modrm & 7) | REX_B(s);
- gen_op_pextrw_xmm(offsetof(CPUX86State,xmm_regs[rm]), val);
- } else {
- val &= 3;
- rm = (modrm & 7);
- gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
- }
- reg = ((modrm >> 3) & 7) | rex_r;
- gen_op_mov_reg_T0[OT_LONG][reg]();
- break;
- case 0x1d6: /* movq ea, xmm */
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
- offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
- gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
- }
- break;
- case 0x2d6: /* movq2dq */
- gen_op_enter_mmx();
- rm = (modrm & 7);
- gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
- offsetof(CPUX86State,fpregs[rm].mmx));
- gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
- break;
- case 0x3d6: /* movdq2q */
- gen_op_enter_mmx();
- rm = (modrm & 7) | REX_B(s);
- gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
- offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
- break;
- case 0xd7: /* pmovmskb */
- case 0x1d7:
- if (mod != 3)
- goto illegal_op;
- if (b1) {
- rm = (modrm & 7) | REX_B(s);
- gen_op_pmovmskb_xmm(offsetof(CPUX86State,xmm_regs[rm]));
- } else {
- rm = (modrm & 7);
- gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
- }
- reg = ((modrm >> 3) & 7) | rex_r;
- gen_op_mov_reg_T0[OT_LONG][reg]();
- break;
- default:
- goto illegal_op;
- }
- } else {
- /* generic MMX or SSE operation */
- switch(b) {
- case 0xf7:
- /* maskmov : we must prepare A0 */
- if (mod != 3)
- goto illegal_op;
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_movq_A0_reg[R_EDI]();
- } else
-#endif
- {
- gen_op_movl_A0_reg[R_EDI]();
- if (s->aflag == 0)
- gen_op_andl_A0_ffff();
- }
- gen_add_A0_ds_seg(s);
- break;
- case 0x70: /* pshufx insn */
- case 0xc6: /* pshufx insn */
- case 0xc2: /* compare insns */
- s->rip_offset = 1;
- break;
- default:
- break;
- }
- if (is_xmm) {
- op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- op2_offset = offsetof(CPUX86State,xmm_t0);
- if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
- b == 0xc2)) {
- /* specific case for SSE single instructions */
- if (b1 == 2) {
- /* 32 bit access */
- gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
- gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
- } else {
- /* 64 bit access */
- gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_D(0)));
- }
- } else {
- gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
- }
- } else {
- rm = (modrm & 7) | REX_B(s);
- op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
- }
- } else {
- op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- op2_offset = offsetof(CPUX86State,mmx_t0);
- gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
- } else {
- rm = (modrm & 7);
- op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
- }
- }
- switch(b) {
- case 0x70: /* pshufx insn */
- case 0xc6: /* pshufx insn */
- val = ldub_code(s->pc++);
- sse_op3 = (GenOpFunc3 *)sse_op2;
- sse_op3(op1_offset, op2_offset, val);
- break;
- case 0xc2:
- /* compare insns */
- val = ldub_code(s->pc++);
- if (val >= 8)
- goto illegal_op;
- sse_op2 = sse_op_table4[val][b1];
- sse_op2(op1_offset, op2_offset);
- break;
- default:
- sse_op2(op1_offset, op2_offset);
- break;
- }
- if (b == 0x2e || b == 0x2f) {
- s->cc_op = CC_OP_EFLAGS;
- }
- }
-}
-
-
-/* convert one instruction. s->is_jmp is set if the translation must
- be stopped. Return the next pc value */
-static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
-{
- int b, prefixes, aflag, dflag;
- int shift, ot;
- int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
- target_ulong next_eip, tval;
- int rex_w, rex_r;
-
- s->pc = pc_start;
- prefixes = 0;
- aflag = s->code32;
- dflag = s->code32;
- s->override = -1;
- rex_w = -1;
- rex_r = 0;
-#ifdef TARGET_X86_64
- s->rex_x = 0;
- s->rex_b = 0;
- x86_64_hregs = 0;
-#endif
- s->rip_offset = 0; /* for relative ip address */
- next_byte:
- b = ldub_code(s->pc);
- s->pc++;
- /* check prefixes */
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- switch (b) {
- case 0xf3:
- prefixes |= PREFIX_REPZ;
- goto next_byte;
- case 0xf2:
- prefixes |= PREFIX_REPNZ;
- goto next_byte;
- case 0xf0:
- prefixes |= PREFIX_LOCK;
- goto next_byte;
- case 0x2e:
- s->override = R_CS;
- goto next_byte;
- case 0x36:
- s->override = R_SS;
- goto next_byte;
- case 0x3e:
- s->override = R_DS;
- goto next_byte;
- case 0x26:
- s->override = R_ES;
- goto next_byte;
- case 0x64:
- s->override = R_FS;
- goto next_byte;
- case 0x65:
- s->override = R_GS;
- goto next_byte;
- case 0x66:
- prefixes |= PREFIX_DATA;
- goto next_byte;
- case 0x67:
- prefixes |= PREFIX_ADR;
- goto next_byte;
- case 0x40 ... 0x4f:
- /* REX prefix */
- rex_w = (b >> 3) & 1;
- rex_r = (b & 0x4) << 1;
- s->rex_x = (b & 0x2) << 2;
- REX_B(s) = (b & 0x1) << 3;
- x86_64_hregs = 1; /* select uniform byte register addressing */
- goto next_byte;
- }
- if (rex_w == 1) {
- /* 0x66 is ignored if rex.w is set */
- dflag = 2;
- } else {
- if (prefixes & PREFIX_DATA)
- dflag ^= 1;
- }
- if (!(prefixes & PREFIX_ADR))
- aflag = 2;
- } else
-#endif
- {
- switch (b) {
- case 0xf3:
- prefixes |= PREFIX_REPZ;
- goto next_byte;
- case 0xf2:
- prefixes |= PREFIX_REPNZ;
- goto next_byte;
- case 0xf0:
- prefixes |= PREFIX_LOCK;
- goto next_byte;
- case 0x2e:
- s->override = R_CS;
- goto next_byte;
- case 0x36:
- s->override = R_SS;
- goto next_byte;
- case 0x3e:
- s->override = R_DS;
- goto next_byte;
- case 0x26:
- s->override = R_ES;
- goto next_byte;
- case 0x64:
- s->override = R_FS;
- goto next_byte;
- case 0x65:
- s->override = R_GS;
- goto next_byte;
- case 0x66:
- prefixes |= PREFIX_DATA;
- goto next_byte;
- case 0x67:
- prefixes |= PREFIX_ADR;
- goto next_byte;
- }
- if (prefixes & PREFIX_DATA)
- dflag ^= 1;
- if (prefixes & PREFIX_ADR)
- aflag ^= 1;
- }
-
- s->prefix = prefixes;
- s->aflag = aflag;
- s->dflag = dflag;
-
- /* lock generation */
- if (prefixes & PREFIX_LOCK)
- gen_op_lock();
-
- /* now check op code */
- reswitch:
- switch(b) {
- case 0x0f:
- /**************************/
- /* extended op code */
- b = ldub_code(s->pc++) | 0x100;
- goto reswitch;
-
- /**************************/
- /* arith & logic */
- case 0x00 ... 0x05:
- case 0x08 ... 0x0d:
- case 0x10 ... 0x15:
- case 0x18 ... 0x1d:
- case 0x20 ... 0x25:
- case 0x28 ... 0x2d:
- case 0x30 ... 0x35:
- case 0x38 ... 0x3d:
- {
- int op, f, val;
- op = (b >> 3) & 7;
- f = (b >> 1) & 3;
-
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- switch(f) {
- case 0: /* OP Ev, Gv */
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- opreg = OR_TMP0;
- } else if (op == OP_XORL && rm == reg) {
- xor_zero:
- /* xor reg, reg optimisation */
- gen_op_movl_T0_0();
- s->cc_op = CC_OP_LOGICB + ot;
- gen_op_mov_reg_T0[ot][reg]();
- gen_op_update1_cc();
- break;
- } else {
- opreg = rm;
- }
- gen_op_mov_TN_reg[ot][1][reg]();
- gen_op(s, op, ot, opreg);
- break;
- case 1: /* OP Gv, Ev */
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- reg = ((modrm >> 3) & 7) | rex_r;
- rm = (modrm & 7) | REX_B(s);
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T1_A0[ot + s->mem_index]();
- } else if (op == OP_XORL && rm == reg) {
- goto xor_zero;
- } else {
- gen_op_mov_TN_reg[ot][1][rm]();
- }
- gen_op(s, op, ot, reg);
- break;
- case 2: /* OP A, Iv */
- val = insn_get(s, ot);
- gen_op_movl_T1_im(val);
- gen_op(s, op, ot, OR_EAX);
- break;
- }
- }
- break;
-
- case 0x80: /* GRP1 */
- case 0x81:
- case 0x82:
- case 0x83:
- {
- int val;
-
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- op = (modrm >> 3) & 7;
-
- if (mod != 3) {
- if (b == 0x83)
- s->rip_offset = 1;
- else
- s->rip_offset = insn_const_size(ot);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- opreg = OR_TMP0;
- } else {
- opreg = rm;
- }
-
- switch(b) {
- default:
- case 0x80:
- case 0x81:
- case 0x82:
- val = insn_get(s, ot);
- break;
- case 0x83:
- val = (int8_t)insn_get(s, OT_BYTE);
- break;
- }
- gen_op_movl_T1_im(val);
- gen_op(s, op, ot, opreg);
- }
- break;
-
- /**************************/
- /* inc, dec, and other misc arith */
- case 0x40 ... 0x47: /* inc Gv */
- ot = dflag ? OT_LONG : OT_WORD;
- gen_inc(s, ot, OR_EAX + (b & 7), 1);
- break;
- case 0x48 ... 0x4f: /* dec Gv */
- ot = dflag ? OT_LONG : OT_WORD;
- gen_inc(s, ot, OR_EAX + (b & 7), -1);
- break;
- case 0xf6: /* GRP3 */
- case 0xf7:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- op = (modrm >> 3) & 7;
- if (mod != 3) {
- if (op == 0)
- s->rip_offset = insn_const_size(ot);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_TN_reg[ot][0][rm]();
- }
-
- switch(op) {
- case 0: /* test */
- val = insn_get(s, ot);
- gen_op_movl_T1_im(val);
- gen_op_testl_T0_T1_cc();
- s->cc_op = CC_OP_LOGICB + ot;
- break;
- case 2: /* not */
- gen_op_notl_T0();
- if (mod != 3) {
- gen_op_st_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_reg_T0[ot][rm]();
- }
- break;
- case 3: /* neg */
- gen_op_negl_T0();
- if (mod != 3) {
- gen_op_st_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_reg_T0[ot][rm]();
- }
- gen_op_update_neg_cc();
- s->cc_op = CC_OP_SUBB + ot;
- break;
- case 4: /* mul */
- switch(ot) {
- case OT_BYTE:
- gen_op_mulb_AL_T0();
- s->cc_op = CC_OP_MULB;
- break;
- case OT_WORD:
- gen_op_mulw_AX_T0();
- s->cc_op = CC_OP_MULW;
- break;
- default:
- case OT_LONG:
- gen_op_mull_EAX_T0();
- s->cc_op = CC_OP_MULL;
- break;
-#ifdef TARGET_X86_64
- case OT_QUAD:
- gen_op_mulq_EAX_T0();
- s->cc_op = CC_OP_MULQ;
- break;
-#endif
- }
- break;
- case 5: /* imul */
- switch(ot) {
- case OT_BYTE:
- gen_op_imulb_AL_T0();
- s->cc_op = CC_OP_MULB;
- break;
- case OT_WORD:
- gen_op_imulw_AX_T0();
- s->cc_op = CC_OP_MULW;
- break;
- default:
- case OT_LONG:
- gen_op_imull_EAX_T0();
- s->cc_op = CC_OP_MULL;
- break;
-#ifdef TARGET_X86_64
- case OT_QUAD:
- gen_op_imulq_EAX_T0();
- s->cc_op = CC_OP_MULQ;
- break;
-#endif
- }
- break;
- case 6: /* div */
- switch(ot) {
- case OT_BYTE:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_divb_AL_T0();
- break;
- case OT_WORD:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_divw_AX_T0();
- break;
- default:
- case OT_LONG:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_divl_EAX_T0();
- break;
-#ifdef TARGET_X86_64
- case OT_QUAD:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_divq_EAX_T0();
- break;
-#endif
- }
- break;
- case 7: /* idiv */
- switch(ot) {
- case OT_BYTE:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_idivb_AL_T0();
- break;
- case OT_WORD:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_idivw_AX_T0();
- break;
- default:
- case OT_LONG:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_idivl_EAX_T0();
- break;
-#ifdef TARGET_X86_64
- case OT_QUAD:
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_idivq_EAX_T0();
- break;
-#endif
- }
- break;
- default:
- goto illegal_op;
- }
- break;
-
- case 0xfe: /* GRP4 */
- case 0xff: /* GRP5 */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- op = (modrm >> 3) & 7;
- if (op >= 2 && b == 0xfe) {
- goto illegal_op;
- }
- if (CODE64(s)) {
- if (op == 2 || op == 4) {
- /* operand size for jumps is 64 bit */
- ot = OT_QUAD;
- } else if (op == 3 || op == 5) {
- /* for call calls, the operand is 16 or 32 bit, even
- in long mode */
- ot = dflag ? OT_LONG : OT_WORD;
- } else if (op == 6) {
- /* default push size is 64 bit */
- ot = dflag ? OT_QUAD : OT_WORD;
- }
- }
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- if (op >= 2 && op != 3 && op != 5)
- gen_op_ld_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_TN_reg[ot][0][rm]();
- }
-
- switch(op) {
- case 0: /* inc Ev */
- if (mod != 3)
- opreg = OR_TMP0;
- else
- opreg = rm;
- gen_inc(s, ot, opreg, 1);
- break;
- case 1: /* dec Ev */
- if (mod != 3)
- opreg = OR_TMP0;
- else
- opreg = rm;
- gen_inc(s, ot, opreg, -1);
- break;
- case 2: /* call Ev */
- /* XXX: optimize if memory (no 'and' is necessary) */
- if (s->dflag == 0)
- gen_op_andl_T0_ffff();
- next_eip = s->pc - s->cs_base;
- gen_movtl_T1_im(next_eip);
- gen_push_T1(s);
- gen_op_jmp_T0();
- gen_eob(s);
- break;
- case 3: /* lcall Ev */
- gen_op_ld_T1_A0[ot + s->mem_index]();
- gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
- gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
- do_lcall:
- if (s->pe && !s->vm86) {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start);
- } else {
- gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
- }
- gen_eob(s);
- break;
- case 4: /* jmp Ev */
- if (s->dflag == 0)
- gen_op_andl_T0_ffff();
- gen_op_jmp_T0();
- gen_eob(s);
- break;
- case 5: /* ljmp Ev */
- gen_op_ld_T1_A0[ot + s->mem_index]();
- gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
- gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
- do_ljmp:
- if (s->pe && !s->vm86) {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_ljmp_protected_T0_T1(s->pc - pc_start);
- } else {
- gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
- gen_op_movl_T0_T1();
- gen_op_jmp_T0();
- }
- gen_eob(s);
- break;
- case 6: /* push Ev */
- gen_push_T0(s);
- break;
- default:
- goto illegal_op;
- }
- break;
-
- case 0x84: /* test Ev, Gv */
- case 0x85:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- reg = ((modrm >> 3) & 7) | rex_r;
-
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- gen_op_mov_TN_reg[ot][1][reg]();
- gen_op_testl_T0_T1_cc();
- s->cc_op = CC_OP_LOGICB + ot;
- break;
-
- case 0xa8: /* test eAX, Iv */
- case 0xa9:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- val = insn_get(s, ot);
-
- gen_op_mov_TN_reg[ot][0][OR_EAX]();
- gen_op_movl_T1_im(val);
- gen_op_testl_T0_T1_cc();
- s->cc_op = CC_OP_LOGICB + ot;
- break;
-
- case 0x98: /* CWDE/CBW */
-#ifdef TARGET_X86_64
- if (dflag == 2) {
- gen_op_movslq_RAX_EAX();
- } else
-#endif
- if (dflag == 1)
- gen_op_movswl_EAX_AX();
- else
- gen_op_movsbw_AX_AL();
- break;
- case 0x99: /* CDQ/CWD */
-#ifdef TARGET_X86_64
- if (dflag == 2) {
- gen_op_movsqo_RDX_RAX();
- } else
-#endif
- if (dflag == 1)
- gen_op_movslq_EDX_EAX();
- else
- gen_op_movswl_DX_AX();
- break;
- case 0x1af: /* imul Gv, Ev */
- case 0x69: /* imul Gv, Ev, I */
- case 0x6b:
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- if (b == 0x69)
- s->rip_offset = insn_const_size(ot);
- else if (b == 0x6b)
- s->rip_offset = 1;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- if (b == 0x69) {
- val = insn_get(s, ot);
- gen_op_movl_T1_im(val);
- } else if (b == 0x6b) {
- val = (int8_t)insn_get(s, OT_BYTE);
- gen_op_movl_T1_im(val);
- } else {
- gen_op_mov_TN_reg[ot][1][reg]();
- }
-
-#ifdef TARGET_X86_64
- if (ot == OT_QUAD) {
- gen_op_imulq_T0_T1();
- } else
-#endif
- if (ot == OT_LONG) {
- gen_op_imull_T0_T1();
- } else {
- gen_op_imulw_T0_T1();
- }
- gen_op_mov_reg_T0[ot][reg]();
- s->cc_op = CC_OP_MULB + ot;
- break;
- case 0x1c0:
- case 0x1c1: /* xadd Ev, Gv */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- if (mod == 3) {
- rm = (modrm & 7) | REX_B(s);
- gen_op_mov_TN_reg[ot][0][reg]();
- gen_op_mov_TN_reg[ot][1][rm]();
- gen_op_addl_T0_T1();
- gen_op_mov_reg_T1[ot][reg]();
- gen_op_mov_reg_T0[ot][rm]();
- } else {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_mov_TN_reg[ot][0][reg]();
- gen_op_ld_T1_A0[ot + s->mem_index]();
- gen_op_addl_T0_T1();
- gen_op_st_T0_A0[ot + s->mem_index]();
- gen_op_mov_reg_T1[ot][reg]();
- }
- gen_op_update2_cc();
- s->cc_op = CC_OP_ADDB + ot;
- break;
- case 0x1b0:
- case 0x1b1: /* cmpxchg Ev, Gv */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- gen_op_mov_TN_reg[ot][1][reg]();
- if (mod == 3) {
- rm = (modrm & 7) | REX_B(s);
- gen_op_mov_TN_reg[ot][0][rm]();
- gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
- gen_op_mov_reg_T0[ot][rm]();
- } else {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index]();
- }
- s->cc_op = CC_OP_SUBB + ot;
- break;
- case 0x1c7: /* cmpxchg8b */
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_cmpxchg8b();
- s->cc_op = CC_OP_EFLAGS;
- break;
-
- /**************************/
- /* push/pop */
- case 0x50 ... 0x57: /* push */
- gen_op_mov_TN_reg[OT_LONG][0][(b & 7) | REX_B(s)]();
- gen_push_T0(s);
- break;
- case 0x58 ... 0x5f: /* pop */
- if (CODE64(s)) {
- ot = dflag ? OT_QUAD : OT_WORD;
- } else {
- ot = dflag + OT_WORD;
- }
- gen_pop_T0(s);
- /* NOTE: order is important for pop %sp */
- gen_pop_update(s);
- gen_op_mov_reg_T0[ot][(b & 7) | REX_B(s)]();
- break;
- case 0x60: /* pusha */
- if (CODE64(s))
- goto illegal_op;
- gen_pusha(s);
- break;
- case 0x61: /* popa */
- if (CODE64(s))
- goto illegal_op;
- gen_popa(s);
- break;
- case 0x68: /* push Iv */
- case 0x6a:
- if (CODE64(s)) {
- ot = dflag ? OT_QUAD : OT_WORD;
- } else {
- ot = dflag + OT_WORD;
- }
- if (b == 0x68)
- val = insn_get(s, ot);
- else
- val = (int8_t)insn_get(s, OT_BYTE);
- gen_op_movl_T0_im(val);
- gen_push_T0(s);
- break;
- case 0x8f: /* pop Ev */
- if (CODE64(s)) {
- ot = dflag ? OT_QUAD : OT_WORD;
- } else {
- ot = dflag + OT_WORD;
- }
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- gen_pop_T0(s);
- if (mod == 3) {
- /* NOTE: order is important for pop %sp */
- gen_pop_update(s);
- rm = (modrm & 7) | REX_B(s);
- gen_op_mov_reg_T0[ot][rm]();
- } else {
- /* NOTE: order is important too for MMU exceptions */
- s->popl_esp_hack = 1 << ot;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
- s->popl_esp_hack = 0;
- gen_pop_update(s);
- }
- break;
- case 0xc8: /* enter */
- {
- int level;
- val = lduw_code(s->pc);
- s->pc += 2;
- level = ldub_code(s->pc++);
- gen_enter(s, val, level);
- }
- break;
- case 0xc9: /* leave */
- /* XXX: exception not precise (ESP is updated before potential exception) */
- if (CODE64(s)) {
- gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
- gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
- } else if (s->ss32) {
- gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
- gen_op_mov_reg_T0[OT_LONG][R_ESP]();
- } else {
- gen_op_mov_TN_reg[OT_WORD][0][R_EBP]();
- gen_op_mov_reg_T0[OT_WORD][R_ESP]();
- }
- gen_pop_T0(s);
- if (CODE64(s)) {
- ot = dflag ? OT_QUAD : OT_WORD;
- } else {
- ot = dflag + OT_WORD;
- }
- gen_op_mov_reg_T0[ot][R_EBP]();
- gen_pop_update(s);
- break;
- case 0x06: /* push es */
- case 0x0e: /* push cs */
- case 0x16: /* push ss */
- case 0x1e: /* push ds */
- if (CODE64(s))
- goto illegal_op;
- gen_op_movl_T0_seg(b >> 3);
- gen_push_T0(s);
- break;
- case 0x1a0: /* push fs */
- case 0x1a8: /* push gs */
- gen_op_movl_T0_seg((b >> 3) & 7);
- gen_push_T0(s);
- break;
- case 0x07: /* pop es */
- case 0x17: /* pop ss */
- case 0x1f: /* pop ds */
- if (CODE64(s))
- goto illegal_op;
- reg = b >> 3;
- gen_pop_T0(s);
- gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
- gen_pop_update(s);
- if (reg == R_SS) {
- /* if reg == SS, inhibit interrupts/trace. */
- /* If several instructions disable interrupts, only the
- _first_ does it */
- if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- gen_op_set_inhibit_irq();
- s->tf = 0;
- }
- if (s->is_jmp) {
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- break;
- case 0x1a1: /* pop fs */
- case 0x1a9: /* pop gs */
- gen_pop_T0(s);
- gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
- gen_pop_update(s);
- if (s->is_jmp) {
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- break;
-
- /**************************/
- /* mov */
- case 0x88:
- case 0x89: /* mov Gv, Ev */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
-
- /* generate a generic store */
- gen_ldst_modrm(s, modrm, ot, reg, 1);
- break;
- case 0xc6:
- case 0xc7: /* mov Ev, Iv */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- if (mod != 3) {
- s->rip_offset = insn_const_size(ot);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- }
- val = insn_get(s, ot);
- gen_op_movl_T0_im(val);
- if (mod != 3)
- gen_op_st_T0_A0[ot + s->mem_index]();
- else
- gen_op_mov_reg_T0[ot][(modrm & 7) | REX_B(s)]();
- break;
- case 0x8a:
- case 0x8b: /* mov Ev, Gv */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = OT_WORD + dflag;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
-
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- gen_op_mov_reg_T0[ot][reg]();
- break;
- case 0x8e: /* mov seg, Gv */
- modrm = ldub_code(s->pc++);
- reg = (modrm >> 3) & 7;
- if (reg >= 6 || reg == R_CS)
- goto illegal_op;
- gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
- if (reg == R_SS) {
- /* if reg == SS, inhibit interrupts/trace */
- /* If several instructions disable interrupts, only the
- _first_ does it */
- if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- gen_op_set_inhibit_irq();
- s->tf = 0;
- }
- if (s->is_jmp) {
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- break;
- case 0x8c: /* mov Gv, seg */
- modrm = ldub_code(s->pc++);
- reg = (modrm >> 3) & 7;
- mod = (modrm >> 6) & 3;
- if (reg >= 6)
- goto illegal_op;
- gen_op_movl_T0_seg(reg);
- if (mod == 3)
- ot = OT_WORD + dflag;
- else
- ot = OT_WORD;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
- break;
-
- case 0x1b6: /* movzbS Gv, Eb */
- case 0x1b7: /* movzwS Gv, Eb */
- case 0x1be: /* movsbS Gv, Eb */
- case 0x1bf: /* movswS Gv, Eb */
- {
- int d_ot;
- /* d_ot is the size of destination */
- d_ot = dflag + OT_WORD;
- /* ot is the size of source */
- ot = (b & 1) + OT_BYTE;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
-
- if (mod == 3) {
- gen_op_mov_TN_reg[ot][0][rm]();
- switch(ot | (b & 8)) {
- case OT_BYTE:
- gen_op_movzbl_T0_T0();
- break;
- case OT_BYTE | 8:
- gen_op_movsbl_T0_T0();
- break;
- case OT_WORD:
- gen_op_movzwl_T0_T0();
- break;
- default:
- case OT_WORD | 8:
- gen_op_movswl_T0_T0();
- break;
- }
- gen_op_mov_reg_T0[d_ot][reg]();
- } else {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- if (b & 8) {
- gen_op_lds_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_ldu_T0_A0[ot + s->mem_index]();
- }
- gen_op_mov_reg_T0[d_ot][reg]();
- }
- }
- break;
-
- case 0x8d: /* lea */
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- reg = ((modrm >> 3) & 7) | rex_r;
- /* we must ensure that no segment is added */
- s->override = -1;
- val = s->addseg;
- s->addseg = 0;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- s->addseg = val;
- gen_op_mov_reg_A0[ot - OT_WORD][reg]();
- break;
-
- case 0xa0: /* mov EAX, Ov */
- case 0xa1:
- case 0xa2: /* mov Ov, EAX */
- case 0xa3:
- {
- target_ulong offset_addr;
-
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- offset_addr = ldq_code(s->pc);
- s->pc += 8;
- if (offset_addr == (int32_t)offset_addr)
- gen_op_movq_A0_im(offset_addr);
- else
- gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
- } else
-#endif
- {
- if (s->aflag) {
- offset_addr = insn_get(s, OT_LONG);
- } else {
- offset_addr = insn_get(s, OT_WORD);
- }
- gen_op_movl_A0_im(offset_addr);
- }
- gen_add_A0_ds_seg(s);
- if ((b & 2) == 0) {
- gen_op_ld_T0_A0[ot + s->mem_index]();
- gen_op_mov_reg_T0[ot][R_EAX]();
- } else {
- gen_op_mov_TN_reg[ot][0][R_EAX]();
- gen_op_st_T0_A0[ot + s->mem_index]();
- }
- }
- break;
- case 0xd7: /* xlat */
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_movq_A0_reg[R_EBX]();
- gen_op_addq_A0_AL();
- } else
-#endif
- {
- gen_op_movl_A0_reg[R_EBX]();
- gen_op_addl_A0_AL();
- if (s->aflag == 0)
- gen_op_andl_A0_ffff();
- }
- gen_add_A0_ds_seg(s);
- gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
- gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
- break;
- case 0xb0 ... 0xb7: /* mov R, Ib */
- val = insn_get(s, OT_BYTE);
- gen_op_movl_T0_im(val);
- gen_op_mov_reg_T0[OT_BYTE][(b & 7) | REX_B(s)]();
- break;
- case 0xb8 ... 0xbf: /* mov R, Iv */
-#ifdef TARGET_X86_64
- if (dflag == 2) {
- uint64_t tmp;
- /* 64 bit case */
- tmp = ldq_code(s->pc);
- s->pc += 8;
- reg = (b & 7) | REX_B(s);
- gen_movtl_T0_im(tmp);
- gen_op_mov_reg_T0[OT_QUAD][reg]();
- } else
-#endif
- {
- ot = dflag ? OT_LONG : OT_WORD;
- val = insn_get(s, ot);
- reg = (b & 7) | REX_B(s);
- gen_op_movl_T0_im(val);
- gen_op_mov_reg_T0[ot][reg]();
- }
- break;
-
- case 0x91 ... 0x97: /* xchg R, EAX */
- ot = dflag + OT_WORD;
- reg = (b & 7) | REX_B(s);
- rm = R_EAX;
- goto do_xchg_reg;
- case 0x86:
- case 0x87: /* xchg Ev, Gv */
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- if (mod == 3) {
- rm = (modrm & 7) | REX_B(s);
- do_xchg_reg:
- gen_op_mov_TN_reg[ot][0][reg]();
- gen_op_mov_TN_reg[ot][1][rm]();
- gen_op_mov_reg_T0[ot][rm]();
- gen_op_mov_reg_T1[ot][reg]();
- } else {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_mov_TN_reg[ot][0][reg]();
- /* for xchg, lock is implicit */
- if (!(prefixes & PREFIX_LOCK))
- gen_op_lock();
- gen_op_ld_T1_A0[ot + s->mem_index]();
- gen_op_st_T0_A0[ot + s->mem_index]();
- if (!(prefixes & PREFIX_LOCK))
- gen_op_unlock();
- gen_op_mov_reg_T1[ot][reg]();
- }
- break;
- case 0xc4: /* les Gv */
- if (CODE64(s))
- goto illegal_op;
- op = R_ES;
- goto do_lxx;
- case 0xc5: /* lds Gv */
- if (CODE64(s))
- goto illegal_op;
- op = R_DS;
- goto do_lxx;
- case 0x1b2: /* lss Gv */
- op = R_SS;
- goto do_lxx;
- case 0x1b4: /* lfs Gv */
- op = R_FS;
- goto do_lxx;
- case 0x1b5: /* lgs Gv */
- op = R_GS;
- do_lxx:
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T1_A0[ot + s->mem_index]();
- gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
- /* load the segment first to handle exceptions properly */
- gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
- gen_movl_seg_T0(s, op, pc_start - s->cs_base);
- /* then put the data */
- gen_op_mov_reg_T1[ot][reg]();
- if (s->is_jmp) {
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- break;
-
- /************************/
- /* shifts */
- case 0xc0:
- case 0xc1:
- /* shift Ev,Ib */
- shift = 2;
- grp2:
- {
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- op = (modrm >> 3) & 7;
-
- if (mod != 3) {
- if (shift == 2) {
- s->rip_offset = 1;
- }
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- opreg = OR_TMP0;
- } else {
- opreg = (modrm & 7) | REX_B(s);
- }
-
- /* simpler op */
- if (shift == 0) {
- gen_shift(s, op, ot, opreg, OR_ECX);
- } else {
- if (shift == 2) {
- shift = ldub_code(s->pc++);
- }
- gen_shifti(s, op, ot, opreg, shift);
- }
- }
- break;
- case 0xd0:
- case 0xd1:
- /* shift Ev,1 */
- shift = 1;
- goto grp2;
- case 0xd2:
- case 0xd3:
- /* shift Ev,cl */
- shift = 0;
- goto grp2;
-
- case 0x1a4: /* shld imm */
- op = 0;
- shift = 1;
- goto do_shiftd;
- case 0x1a5: /* shld cl */
- op = 0;
- shift = 0;
- goto do_shiftd;
- case 0x1ac: /* shrd imm */
- op = 1;
- shift = 1;
- goto do_shiftd;
- case 0x1ad: /* shrd cl */
- op = 1;
- shift = 0;
- do_shiftd:
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- reg = ((modrm >> 3) & 7) | rex_r;
-
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_TN_reg[ot][0][rm]();
- }
- gen_op_mov_TN_reg[ot][1][reg]();
-
- if (shift) {
- val = ldub_code(s->pc++);
- if (ot == OT_QUAD)
- val &= 0x3f;
- else
- val &= 0x1f;
- if (val) {
- if (mod == 3)
- gen_op_shiftd_T0_T1_im_cc[ot][op](val);
- else
- gen_op_shiftd_mem_T0_T1_im_cc[ot + s->mem_index][op](val);
- if (op == 0 && ot != OT_WORD)
- s->cc_op = CC_OP_SHLB + ot;
- else
- s->cc_op = CC_OP_SARB + ot;
- }
- } else {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- if (mod == 3)
- gen_op_shiftd_T0_T1_ECX_cc[ot][op]();
- else
- gen_op_shiftd_mem_T0_T1_ECX_cc[ot + s->mem_index][op]();
- s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
- }
- if (mod == 3) {
- gen_op_mov_reg_T0[ot][rm]();
- }
- break;
-
- /************************/
- /* floats */
- case 0xd8 ... 0xdf:
- if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
- /* if CR0.EM or CR0.TS are set, generate an FPU exception */
- /* XXX: what to do if illegal op ? */
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
- break;
- }
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- rm = modrm & 7;
- op = ((b & 7) << 3) | ((modrm >> 3) & 7);
- if (mod != 3) {
- /* memory op */
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- switch(op) {
- case 0x00 ... 0x07: /* fxxxs */
- case 0x10 ... 0x17: /* fixxxl */
- case 0x20 ... 0x27: /* fxxxl */
- case 0x30 ... 0x37: /* fixxx */
- {
- int op1;
- op1 = op & 7;
-
- switch(op >> 4) {
- case 0:
- gen_op_flds_FT0_A0();
- break;
- case 1:
- gen_op_fildl_FT0_A0();
- break;
- case 2:
- gen_op_fldl_FT0_A0();
- break;
- case 3:
- default:
- gen_op_fild_FT0_A0();
- break;
- }
-
- gen_op_fp_arith_ST0_FT0[op1]();
- if (op1 == 3) {
- /* fcomp needs pop */
- gen_op_fpop();
- }
- }
- break;
- case 0x08: /* flds */
- case 0x0a: /* fsts */
- case 0x0b: /* fstps */
- case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
- case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
- case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
- switch(op & 7) {
- case 0:
- switch(op >> 4) {
- case 0:
- gen_op_flds_ST0_A0();
- break;
- case 1:
- gen_op_fildl_ST0_A0();
- break;
- case 2:
- gen_op_fldl_ST0_A0();
- break;
- case 3:
- default:
- gen_op_fild_ST0_A0();
- break;
- }
- break;
- case 1:
- switch(op >> 4) {
- case 1:
- gen_op_fisttl_ST0_A0();
- break;
- case 2:
- gen_op_fisttll_ST0_A0();
- break;
- case 3:
- default:
- gen_op_fistt_ST0_A0();
- }
- gen_op_fpop();
- break;
- default:
- switch(op >> 4) {
- case 0:
- gen_op_fsts_ST0_A0();
- break;
- case 1:
- gen_op_fistl_ST0_A0();
- break;
- case 2:
- gen_op_fstl_ST0_A0();
- break;
- case 3:
- default:
- gen_op_fist_ST0_A0();
- break;
- }
- if ((op & 7) == 3)
- gen_op_fpop();
- break;
- }
- break;
- case 0x0c: /* fldenv mem */
- gen_op_fldenv_A0(s->dflag);
- break;
- case 0x0d: /* fldcw mem */
- gen_op_fldcw_A0();
- break;
- case 0x0e: /* fnstenv mem */
- gen_op_fnstenv_A0(s->dflag);
- break;
- case 0x0f: /* fnstcw mem */
- gen_op_fnstcw_A0();
- break;
- case 0x1d: /* fldt mem */
- gen_op_fldt_ST0_A0();
- break;
- case 0x1f: /* fstpt mem */
- gen_op_fstt_ST0_A0();
- gen_op_fpop();
- break;
- case 0x2c: /* frstor mem */
- gen_op_frstor_A0(s->dflag);
- break;
- case 0x2e: /* fnsave mem */
- gen_op_fnsave_A0(s->dflag);
- break;
- case 0x2f: /* fnstsw mem */
- gen_op_fnstsw_A0();
- break;
- case 0x3c: /* fbld */
- gen_op_fbld_ST0_A0();
- break;
- case 0x3e: /* fbstp */
- gen_op_fbst_ST0_A0();
- gen_op_fpop();
- break;
- case 0x3d: /* fildll */
- gen_op_fildll_ST0_A0();
- break;
- case 0x3f: /* fistpll */
- gen_op_fistll_ST0_A0();
- gen_op_fpop();
- break;
- default:
- goto illegal_op;
- }
- } else {
- /* register float ops */
- opreg = rm;
-
- switch(op) {
- case 0x08: /* fld sti */
- gen_op_fpush();
- gen_op_fmov_ST0_STN((opreg + 1) & 7);
- break;
- case 0x09: /* fxchg sti */
- case 0x29: /* fxchg4 sti, undocumented op */
- case 0x39: /* fxchg7 sti, undocumented op */
- gen_op_fxchg_ST0_STN(opreg);
- break;
- case 0x0a: /* grp d9/2 */
- switch(rm) {
- case 0: /* fnop */
- /* check exceptions (FreeBSD FPU probe) */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_fwait();
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x0c: /* grp d9/4 */
- switch(rm) {
- case 0: /* fchs */
- gen_op_fchs_ST0();
- break;
- case 1: /* fabs */
- gen_op_fabs_ST0();
- break;
- case 4: /* ftst */
- gen_op_fldz_FT0();
- gen_op_fcom_ST0_FT0();
- break;
- case 5: /* fxam */
- gen_op_fxam_ST0();
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x0d: /* grp d9/5 */
- {
- switch(rm) {
- case 0:
- gen_op_fpush();
- gen_op_fld1_ST0();
- break;
- case 1:
- gen_op_fpush();
- gen_op_fldl2t_ST0();
- break;
- case 2:
- gen_op_fpush();
- gen_op_fldl2e_ST0();
- break;
- case 3:
- gen_op_fpush();
- gen_op_fldpi_ST0();
- break;
- case 4:
- gen_op_fpush();
- gen_op_fldlg2_ST0();
- break;
- case 5:
- gen_op_fpush();
- gen_op_fldln2_ST0();
- break;
- case 6:
- gen_op_fpush();
- gen_op_fldz_ST0();
- break;
- default:
- goto illegal_op;
- }
- }
- break;
- case 0x0e: /* grp d9/6 */
- switch(rm) {
- case 0: /* f2xm1 */
- gen_op_f2xm1();
- break;
- case 1: /* fyl2x */
- gen_op_fyl2x();
- break;
- case 2: /* fptan */
- gen_op_fptan();
- break;
- case 3: /* fpatan */
- gen_op_fpatan();
- break;
- case 4: /* fxtract */
- gen_op_fxtract();
- break;
- case 5: /* fprem1 */
- gen_op_fprem1();
- break;
- case 6: /* fdecstp */
- gen_op_fdecstp();
- break;
- default:
- case 7: /* fincstp */
- gen_op_fincstp();
- break;
- }
- break;
- case 0x0f: /* grp d9/7 */
- switch(rm) {
- case 0: /* fprem */
- gen_op_fprem();
- break;
- case 1: /* fyl2xp1 */
- gen_op_fyl2xp1();
- break;
- case 2: /* fsqrt */
- gen_op_fsqrt();
- break;
- case 3: /* fsincos */
- gen_op_fsincos();
- break;
- case 5: /* fscale */
- gen_op_fscale();
- break;
- case 4: /* frndint */
- gen_op_frndint();
- break;
- case 6: /* fsin */
- gen_op_fsin();
- break;
- default:
- case 7: /* fcos */
- gen_op_fcos();
- break;
- }
- break;
- case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
- case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
- case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
- {
- int op1;
-
- op1 = op & 7;
- if (op >= 0x20) {
- gen_op_fp_arith_STN_ST0[op1](opreg);
- if (op >= 0x30)
- gen_op_fpop();
- } else {
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fp_arith_ST0_FT0[op1]();
- }
- }
- break;
- case 0x02: /* fcom */
- case 0x22: /* fcom2, undocumented op */
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fcom_ST0_FT0();
- break;
- case 0x03: /* fcomp */
- case 0x23: /* fcomp3, undocumented op */
- case 0x32: /* fcomp5, undocumented op */
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fcom_ST0_FT0();
- gen_op_fpop();
- break;
- case 0x15: /* da/5 */
- switch(rm) {
- case 1: /* fucompp */
- gen_op_fmov_FT0_STN(1);
- gen_op_fucom_ST0_FT0();
- gen_op_fpop();
- gen_op_fpop();
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x1c:
- switch(rm) {
- case 0: /* feni (287 only, just do nop here) */
- break;
- case 1: /* fdisi (287 only, just do nop here) */
- break;
- case 2: /* fclex */
- gen_op_fclex();
- break;
- case 3: /* fninit */
- gen_op_fninit();
- break;
- case 4: /* fsetpm (287 only, just do nop here) */
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x1d: /* fucomi */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fucomi_ST0_FT0();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x1e: /* fcomi */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fcomi_ST0_FT0();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x28: /* ffree sti */
- gen_op_ffree_STN(opreg);
- break;
- case 0x2a: /* fst sti */
- gen_op_fmov_STN_ST0(opreg);
- break;
- case 0x2b: /* fstp sti */
- case 0x0b: /* fstp1 sti, undocumented op */
- case 0x3a: /* fstp8 sti, undocumented op */
- case 0x3b: /* fstp9 sti, undocumented op */
- gen_op_fmov_STN_ST0(opreg);
- gen_op_fpop();
- break;
- case 0x2c: /* fucom st(i) */
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fucom_ST0_FT0();
- break;
- case 0x2d: /* fucomp st(i) */
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fucom_ST0_FT0();
- gen_op_fpop();
- break;
- case 0x33: /* de/3 */
- switch(rm) {
- case 1: /* fcompp */
- gen_op_fmov_FT0_STN(1);
- gen_op_fcom_ST0_FT0();
- gen_op_fpop();
- gen_op_fpop();
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x38: /* ffreep sti, undocumented op */
- gen_op_ffree_STN(opreg);
- gen_op_fpop();
- break;
- case 0x3c: /* df/4 */
- switch(rm) {
- case 0:
- gen_op_fnstsw_EAX();
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x3d: /* fucomip */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fucomi_ST0_FT0();
- gen_op_fpop();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x3e: /* fcomip */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_fmov_FT0_STN(opreg);
- gen_op_fcomi_ST0_FT0();
- gen_op_fpop();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x10 ... 0x13: /* fcmovxx */
- case 0x18 ... 0x1b:
- {
- int op1;
- const static uint8_t fcmov_cc[8] = {
- (JCC_B << 1),
- (JCC_Z << 1),
- (JCC_BE << 1),
- (JCC_P << 1),
- };
- op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
- gen_setcc(s, op1);
- gen_op_fcmov_ST0_STN_T0(opreg);
- }
- break;
- default:
- goto illegal_op;
- }
- }
-#ifdef USE_CODE_COPY
- s->tb->cflags |= CF_TB_FP_USED;
-#endif
- break;
- /************************/
- /* string ops */
-
- case 0xa4: /* movsS */
- case 0xa5:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
- } else {
- gen_movs(s, ot);
- }
- break;
-
- case 0xaa: /* stosS */
- case 0xab:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
-
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
- } else {
- gen_stos(s, ot);
- }
- break;
- case 0xac: /* lodsS */
- case 0xad:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
- } else {
- gen_lods(s, ot);
- }
- break;
- case 0xae: /* scasS */
- case 0xaf:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- if (prefixes & PREFIX_REPNZ) {
- gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
- } else if (prefixes & PREFIX_REPZ) {
- gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
- } else {
- gen_scas(s, ot);
- s->cc_op = CC_OP_SUBB + ot;
- }
- break;
-
- case 0xa6: /* cmpsS */
- case 0xa7:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag + OT_WORD;
- if (prefixes & PREFIX_REPNZ) {
- gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
- } else if (prefixes & PREFIX_REPZ) {
- gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
- } else {
- gen_cmps(s, ot);
- s->cc_op = CC_OP_SUBB + ot;
- }
- break;
- case 0x6c: /* insS */
- case 0x6d:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- gen_check_io(s, ot, 1, pc_start - s->cs_base);
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
- } else {
- gen_ins(s, ot);
- }
- break;
- case 0x6e: /* outsS */
- case 0x6f:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- gen_check_io(s, ot, 1, pc_start - s->cs_base);
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
- } else {
- gen_outs(s, ot);
- }
- break;
-
- /************************/
- /* port I/O */
- case 0xe4:
- case 0xe5:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- val = ldub_code(s->pc++);
- gen_op_movl_T0_im(val);
- gen_check_io(s, ot, 0, pc_start - s->cs_base);
- gen_op_in[ot]();
- gen_op_mov_reg_T1[ot][R_EAX]();
- break;
- case 0xe6:
- case 0xe7:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- val = ldub_code(s->pc++);
- gen_op_movl_T0_im(val);
- gen_check_io(s, ot, 0, pc_start - s->cs_base);
- gen_op_mov_TN_reg[ot][1][R_EAX]();
- gen_op_out[ot]();
- break;
- case 0xec:
- case 0xed:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
- gen_op_andl_T0_ffff();
- gen_check_io(s, ot, 0, pc_start - s->cs_base);
- gen_op_in[ot]();
- gen_op_mov_reg_T1[ot][R_EAX]();
- break;
- case 0xee:
- case 0xef:
- if ((b & 1) == 0)
- ot = OT_BYTE;
- else
- ot = dflag ? OT_LONG : OT_WORD;
- gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
- gen_op_andl_T0_ffff();
- gen_check_io(s, ot, 0, pc_start - s->cs_base);
- gen_op_mov_TN_reg[ot][1][R_EAX]();
- gen_op_out[ot]();
- break;
-
- /************************/
- /* control */
- case 0xc2: /* ret im */
- val = ldsw_code(s->pc);
- s->pc += 2;
- gen_pop_T0(s);
- if (CODE64(s) && s->dflag)
- s->dflag = 2;
- gen_stack_update(s, val + (2 << s->dflag));
- if (s->dflag == 0)
- gen_op_andl_T0_ffff();
- gen_op_jmp_T0();
- gen_eob(s);
- break;
- case 0xc3: /* ret */
- gen_pop_T0(s);
- gen_pop_update(s);
- if (s->dflag == 0)
- gen_op_andl_T0_ffff();
- gen_op_jmp_T0();
- gen_eob(s);
- break;
- case 0xca: /* lret im */
- val = ldsw_code(s->pc);
- s->pc += 2;
- do_lret:
- if (s->pe && !s->vm86) {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_lret_protected(s->dflag, val);
- } else {
- gen_stack_A0(s);
- /* pop offset */
- gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
- if (s->dflag == 0)
- gen_op_andl_T0_ffff();
- /* NOTE: keeping EIP updated is not a problem in case of
- exception */
- gen_op_jmp_T0();
- /* pop selector */
- gen_op_addl_A0_im(2 << s->dflag);
- gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
- gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
- /* add stack offset */
- gen_stack_update(s, val + (4 << s->dflag));
- }
- gen_eob(s);
- break;
- case 0xcb: /* lret */
- val = 0;
- goto do_lret;
- case 0xcf: /* iret */
- if (!s->pe) {
- /* real mode */
- gen_op_iret_real(s->dflag);
- s->cc_op = CC_OP_EFLAGS;
- } else if (s->vm86) {
- if (s->iopl != 3) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_op_iret_real(s->dflag);
- s->cc_op = CC_OP_EFLAGS;
- }
- } else {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
- s->cc_op = CC_OP_EFLAGS;
- }
- gen_eob(s);
- break;
- case 0xe8: /* call im */
- {
- if (dflag)
- tval = (int32_t)insn_get(s, OT_LONG);
- else
- tval = (int16_t)insn_get(s, OT_WORD);
- next_eip = s->pc - s->cs_base;
- tval += next_eip;
- if (s->dflag == 0)
- tval &= 0xffff;
- gen_movtl_T0_im(next_eip);
- gen_push_T0(s);
- gen_jmp(s, tval);
- }
- break;
- case 0x9a: /* lcall im */
- {
- unsigned int selector, offset;
-
- if (CODE64(s))
- goto illegal_op;
- ot = dflag ? OT_LONG : OT_WORD;
- offset = insn_get(s, ot);
- selector = insn_get(s, OT_WORD);
-
- gen_op_movl_T0_im(selector);
- gen_op_movl_T1_imu(offset);
- }
- goto do_lcall;
- case 0xe9: /* jmp im */
- if (dflag)
- tval = (int32_t)insn_get(s, OT_LONG);
- else
- tval = (int16_t)insn_get(s, OT_WORD);
- tval += s->pc - s->cs_base;
- if (s->dflag == 0)
- tval &= 0xffff;
- gen_jmp(s, tval);
- break;
- case 0xea: /* ljmp im */
- {
- unsigned int selector, offset;
-
- if (CODE64(s))
- goto illegal_op;
- ot = dflag ? OT_LONG : OT_WORD;
- offset = insn_get(s, ot);
- selector = insn_get(s, OT_WORD);
-
- gen_op_movl_T0_im(selector);
- gen_op_movl_T1_imu(offset);
- }
- goto do_ljmp;
- case 0xeb: /* jmp Jb */
- tval = (int8_t)insn_get(s, OT_BYTE);
- tval += s->pc - s->cs_base;
- if (s->dflag == 0)
- tval &= 0xffff;
- gen_jmp(s, tval);
- break;
- case 0x70 ... 0x7f: /* jcc Jb */
- tval = (int8_t)insn_get(s, OT_BYTE);
- goto do_jcc;
- case 0x180 ... 0x18f: /* jcc Jv */
- if (dflag) {
- tval = (int32_t)insn_get(s, OT_LONG);
- } else {
- tval = (int16_t)insn_get(s, OT_WORD);
- }
- do_jcc:
- next_eip = s->pc - s->cs_base;
- tval += next_eip;
- if (s->dflag == 0)
- tval &= 0xffff;
- gen_jcc(s, b, tval, next_eip);
- break;
-
- case 0x190 ... 0x19f: /* setcc Gv */
- modrm = ldub_code(s->pc++);
- gen_setcc(s, b);
- gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
- break;
- case 0x140 ... 0x14f: /* cmov Gv, Ev */
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- gen_setcc(s, b);
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T1_A0[ot + s->mem_index]();
- } else {
- rm = (modrm & 7) | REX_B(s);
- gen_op_mov_TN_reg[ot][1][rm]();
- }
- gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
- break;
-
- /************************/
- /* flags */
- case 0x9c: /* pushf */
- if (s->vm86 && s->iopl != 3) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_movl_T0_eflags();
- gen_push_T0(s);
- }
- break;
- case 0x9d: /* popf */
- if (s->vm86 && s->iopl != 3) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_pop_T0(s);
- if (s->cpl == 0) {
- if (s->dflag) {
- gen_op_movl_eflags_T0_cpl0();
- } else {
- gen_op_movw_eflags_T0_cpl0();
- }
- } else {
- if (s->cpl <= s->iopl) {
- if (s->dflag) {
- gen_op_movl_eflags_T0_io();
- } else {
- gen_op_movw_eflags_T0_io();
- }
- } else {
- if (s->dflag) {
- gen_op_movl_eflags_T0();
- } else {
- gen_op_movw_eflags_T0();
- }
- }
- }
- gen_pop_update(s);
- s->cc_op = CC_OP_EFLAGS;
- /* abort translation because TF flag may change */
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- break;
- case 0x9e: /* sahf */
- if (CODE64(s))
- goto illegal_op;
- gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_movb_eflags_T0();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x9f: /* lahf */
- if (CODE64(s))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_movl_T0_eflags();
- gen_op_mov_reg_T0[OT_BYTE][R_AH]();
- break;
- case 0xf5: /* cmc */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_cmc();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0xf8: /* clc */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_clc();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0xf9: /* stc */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_stc();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0xfc: /* cld */
- gen_op_cld();
- break;
- case 0xfd: /* std */
- gen_op_std();
- break;
-
- /************************/
- /* bit operations */
- case 0x1ba: /* bt/bts/btr/btc Gv, im */
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- op = (modrm >> 3) & 7;
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- if (mod != 3) {
- s->rip_offset = 1;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_TN_reg[ot][0][rm]();
- }
- /* load shift */
- val = ldub_code(s->pc++);
- gen_op_movl_T1_im(val);
- if (op < 4)
- goto illegal_op;
- op -= 4;
- gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
- s->cc_op = CC_OP_SARB + ot;
- if (op != 0) {
- if (mod != 3)
- gen_op_st_T0_A0[ot + s->mem_index]();
- else
- gen_op_mov_reg_T0[ot][rm]();
- gen_op_update_bt_cc();
- }
- break;
- case 0x1a3: /* bt Gv, Ev */
- op = 0;
- goto do_btx;
- case 0x1ab: /* bts */
- op = 1;
- goto do_btx;
- case 0x1b3: /* btr */
- op = 2;
- goto do_btx;
- case 0x1bb: /* btc */
- op = 3;
- do_btx:
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
- gen_op_mov_TN_reg[OT_LONG][1][reg]();
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- /* specific case: we need to add a displacement */
- gen_op_add_bit_A0_T1[ot - OT_WORD]();
- gen_op_ld_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_TN_reg[ot][0][rm]();
- }
- gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
- s->cc_op = CC_OP_SARB + ot;
- if (op != 0) {
- if (mod != 3)
- gen_op_st_T0_A0[ot + s->mem_index]();
- else
- gen_op_mov_reg_T0[ot][rm]();
- gen_op_update_bt_cc();
- }
- break;
- case 0x1bc: /* bsf */
- case 0x1bd: /* bsr */
- ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- /* NOTE: in order to handle the 0 case, we must load the
- result. It could be optimized with a generated jump */
- gen_op_mov_TN_reg[ot][1][reg]();
- gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
- gen_op_mov_reg_T1[ot][reg]();
- s->cc_op = CC_OP_LOGICB + ot;
- break;
- /************************/
- /* bcd */
- case 0x27: /* daa */
- if (CODE64(s))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_daa();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x2f: /* das */
- if (CODE64(s))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_das();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x37: /* aaa */
- if (CODE64(s))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_aaa();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0x3f: /* aas */
- if (CODE64(s))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_aas();
- s->cc_op = CC_OP_EFLAGS;
- break;
- case 0xd4: /* aam */
- if (CODE64(s))
- goto illegal_op;
- val = ldub_code(s->pc++);
- gen_op_aam(val);
- s->cc_op = CC_OP_LOGICB;
- break;
- case 0xd5: /* aad */
- if (CODE64(s))
- goto illegal_op;
- val = ldub_code(s->pc++);
- gen_op_aad(val);
- s->cc_op = CC_OP_LOGICB;
- break;
- /************************/
- /* misc */
- case 0x90: /* nop */
- /* XXX: xchg + rex handling */
- /* XXX: correct lock test for all insn */
- if (prefixes & PREFIX_LOCK)
- goto illegal_op;
- break;
- case 0x9b: /* fwait */
- if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
- (HF_MP_MASK | HF_TS_MASK)) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
- } else {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_fwait();
- }
- break;
- case 0xcc: /* int3 */
- gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
- break;
- case 0xcd: /* int N */
- val = ldub_code(s->pc++);
- if (s->vm86 && s->iopl != 3) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
- }
- break;
- case 0xce: /* into */
- if (CODE64(s))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_into(s->pc - pc_start);
- break;
- case 0xf1: /* icebp (undocumented, exits to external debugger) */
-#if 1
- gen_debug(s, pc_start - s->cs_base);
-#else
- /* start debug */
- tb_flush(cpu_single_env);
- cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
-#endif
- break;
- case 0xfa: /* cli */
- if (!s->vm86) {
- if (s->cpl <= s->iopl) {
- gen_op_cli();
- } else {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- }
- } else {
- if (s->iopl == 3) {
- gen_op_cli();
- } else {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- }
- }
- break;
- case 0xfb: /* sti */
- if (!s->vm86) {
- if (s->cpl <= s->iopl) {
- gen_sti:
- gen_op_sti();
- /* interruptions are enabled only the first insn after sti */
- /* If several instructions disable interrupts, only the
- _first_ does it */
- if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- gen_op_set_inhibit_irq();
- /* give a chance to handle pending irqs */
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- } else {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- }
- } else {
- if (s->iopl == 3) {
- goto gen_sti;
- } else {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- }
- }
- break;
- case 0x62: /* bound */
- if (CODE64(s))
- goto illegal_op;
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = (modrm >> 3) & 7;
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- gen_op_mov_TN_reg[ot][0][reg]();
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_jmp_im(pc_start - s->cs_base);
- if (ot == OT_WORD)
- gen_op_boundw();
- else
- gen_op_boundl();
- break;
- case 0x1c8 ... 0x1cf: /* bswap reg */
- reg = (b & 7) | REX_B(s);
-#ifdef TARGET_X86_64
- if (dflag == 2) {
- gen_op_mov_TN_reg[OT_QUAD][0][reg]();
- gen_op_bswapq_T0();
- gen_op_mov_reg_T0[OT_QUAD][reg]();
- } else
-#endif
- {
- gen_op_mov_TN_reg[OT_LONG][0][reg]();
- gen_op_bswapl_T0();
- gen_op_mov_reg_T0[OT_LONG][reg]();
- }
- break;
- case 0xd6: /* salc */
- if (CODE64(s))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_salc();
- break;
- case 0xe0: /* loopnz */
- case 0xe1: /* loopz */
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- /* FALL THRU */
- case 0xe2: /* loop */
- case 0xe3: /* jecxz */
- {
- int l1, l2;
-
- tval = (int8_t)insn_get(s, OT_BYTE);
- next_eip = s->pc - s->cs_base;
- tval += next_eip;
- if (s->dflag == 0)
- tval &= 0xffff;
-
- l1 = gen_new_label();
- l2 = gen_new_label();
- b &= 3;
- if (b == 3) {
- gen_op_jz_ecx[s->aflag](l1);
- } else {
- gen_op_dec_ECX[s->aflag]();
- if (b <= 1)
- gen_op_mov_T0_cc();
- gen_op_loop[s->aflag][b](l1);
- }
-
- gen_jmp_im(next_eip);
- gen_op_jmp_label(l2);
- gen_set_label(l1);
- gen_jmp_im(tval);
- gen_set_label(l2);
- gen_eob(s);
- }
- break;
- case 0x130: /* wrmsr */
- case 0x132: /* rdmsr */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- if (b & 2)
- gen_op_rdmsr();
- else
- gen_op_wrmsr();
- }
- break;
- case 0x131: /* rdtsc */
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_rdtsc();
- break;
- case 0x134: /* sysenter */
- if (CODE64(s))
- goto illegal_op;
- if (!s->pe) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_sysenter();
- gen_eob(s);
- }
- break;
- case 0x135: /* sysexit */
- if (CODE64(s))
- goto illegal_op;
- if (!s->pe) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_sysexit();
- gen_eob(s);
- }
- break;
-#ifdef TARGET_X86_64
- case 0x105: /* syscall */
- /* XXX: is it usable in real mode ? */
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_syscall(s->pc - pc_start);
- gen_eob(s);
- break;
- case 0x107: /* sysret */
- if (!s->pe) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_sysret(s->dflag);
- /* condition codes are modified only in long mode */
- if (s->lma)
- s->cc_op = CC_OP_EFLAGS;
- gen_eob(s);
- }
- break;
-#endif
- case 0x1a2: /* cpuid */
- gen_op_cpuid();
- break;
- case 0xf4: /* hlt */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_jmp_im(s->pc - s->cs_base);
- gen_op_hlt();
- s->is_jmp = 3;
- }
- break;
- case 0x100:
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- op = (modrm >> 3) & 7;
- switch(op) {
- case 0: /* sldt */
- if (!s->pe || s->vm86)
- goto illegal_op;
- gen_op_movl_T0_env(offsetof(CPUX86State,ldt.selector));
- ot = OT_WORD;
- if (mod == 3)
- ot += s->dflag;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
- break;
- case 2: /* lldt */
- if (!s->pe || s->vm86)
- goto illegal_op;
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_lldt_T0();
- }
- break;
- case 1: /* str */
- if (!s->pe || s->vm86)
- goto illegal_op;
- gen_op_movl_T0_env(offsetof(CPUX86State,tr.selector));
- ot = OT_WORD;
- if (mod == 3)
- ot += s->dflag;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
- break;
- case 3: /* ltr */
- if (!s->pe || s->vm86)
- goto illegal_op;
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- gen_jmp_im(pc_start - s->cs_base);
- gen_op_ltr_T0();
- }
- break;
- case 4: /* verr */
- case 5: /* verw */
- if (!s->pe || s->vm86)
- goto illegal_op;
- gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- if (op == 4)
- gen_op_verr();
- else
- gen_op_verw();
- s->cc_op = CC_OP_EFLAGS;
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x101:
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- op = (modrm >> 3) & 7;
- rm = modrm & 7;
- switch(op) {
- case 0: /* sgdt */
- if (mod == 3)
- goto illegal_op;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_movl_T0_env(offsetof(CPUX86State, gdt.limit));
- gen_op_st_T0_A0[OT_WORD + s->mem_index]();
- gen_add_A0_im(s, 2);
- gen_op_movtl_T0_env(offsetof(CPUX86State, gdt.base));
- if (!s->dflag)
- gen_op_andl_T0_im(0xffffff);
- gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
- break;
- case 1:
- if (mod == 3) {
- switch (rm) {
- case 0: /* monitor */
- if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
- s->cpl != 0)
- goto illegal_op;
- gen_jmp_im(pc_start - s->cs_base);
-#ifdef TARGET_X86_64
- if (s->aflag == 2) {
- gen_op_movq_A0_reg[R_EBX]();
- gen_op_addq_A0_AL();
- } else
-#endif
- {
- gen_op_movl_A0_reg[R_EBX]();
- gen_op_addl_A0_AL();
- if (s->aflag == 0)
- gen_op_andl_A0_ffff();
- }
- gen_add_A0_ds_seg(s);
- gen_op_monitor();
- break;
- case 1: /* mwait */
- if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
- s->cpl != 0)
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_jmp_im(s->pc - s->cs_base);
- gen_op_mwait();
- gen_eob(s);
- break;
- default:
- goto illegal_op;
- }
- } else { /* sidt */
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_movl_T0_env(offsetof(CPUX86State, idt.limit));
- gen_op_st_T0_A0[OT_WORD + s->mem_index]();
- gen_add_A0_im(s, 2);
- gen_op_movtl_T0_env(offsetof(CPUX86State, idt.base));
- if (!s->dflag)
- gen_op_andl_T0_im(0xffffff);
- gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
- }
- break;
- case 2: /* lgdt */
- case 3: /* lidt */
- if (mod == 3)
- goto illegal_op;
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
- gen_add_A0_im(s, 2);
- gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
- if (!s->dflag)
- gen_op_andl_T0_im(0xffffff);
- if (op == 2) {
- gen_op_movtl_env_T0(offsetof(CPUX86State,gdt.base));
- gen_op_movl_env_T1(offsetof(CPUX86State,gdt.limit));
- } else {
- gen_op_movtl_env_T0(offsetof(CPUX86State,idt.base));
- gen_op_movl_env_T1(offsetof(CPUX86State,idt.limit));
- }
- }
- break;
- case 4: /* smsw */
- gen_op_movl_T0_env(offsetof(CPUX86State,cr[0]));
- gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
- break;
- case 6: /* lmsw */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- gen_op_lmsw_T0();
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- break;
- case 7: /* invlpg */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- if (mod == 3) {
-#ifdef TARGET_X86_64
- if (CODE64(s) && rm == 0) {
- /* swapgs */
- gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base));
- gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase));
- gen_op_movtl_env_T1(offsetof(CPUX86State,segs[R_GS].base));
- gen_op_movtl_env_T0(offsetof(CPUX86State,kernelgsbase));
- } else
-#endif
- {
- goto illegal_op;
- }
- } else {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_invlpg_A0();
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- }
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x108: /* invd */
- case 0x109: /* wbinvd */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- /* nothing to do */
- }
- break;
- case 0x63: /* arpl or movslS (x86_64) */
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- int d_ot;
- /* d_ot is the size of destination */
- d_ot = dflag + OT_WORD;
-
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- mod = (modrm >> 6) & 3;
- rm = (modrm & 7) | REX_B(s);
-
- if (mod == 3) {
- gen_op_mov_TN_reg[OT_LONG][0][rm]();
- /* sign extend */
- if (d_ot == OT_QUAD)
- gen_op_movslq_T0_T0();
- gen_op_mov_reg_T0[d_ot][reg]();
- } else {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- if (d_ot == OT_QUAD) {
- gen_op_lds_T0_A0[OT_LONG + s->mem_index]();
- } else {
- gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
- }
- gen_op_mov_reg_T0[d_ot][reg]();
- }
- } else
-#endif
- {
- if (!s->pe || s->vm86)
- goto illegal_op;
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = (modrm >> 3) & 7;
- mod = (modrm >> 6) & 3;
- rm = modrm & 7;
- if (mod != 3) {
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_TN_reg[ot][0][rm]();
- }
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- gen_op_arpl();
- s->cc_op = CC_OP_EFLAGS;
- if (mod != 3) {
- gen_op_st_T0_A0[ot + s->mem_index]();
- } else {
- gen_op_mov_reg_T0[ot][rm]();
- }
- gen_op_arpl_update();
- }
- break;
- case 0x102: /* lar */
- case 0x103: /* lsl */
- if (!s->pe || s->vm86)
- goto illegal_op;
- ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
- reg = ((modrm >> 3) & 7) | rex_r;
- gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- gen_op_mov_TN_reg[ot][1][reg]();
- if (s->cc_op != CC_OP_DYNAMIC)
- gen_op_set_cc_op(s->cc_op);
- if (b == 0x102)
- gen_op_lar();
- else
- gen_op_lsl();
- s->cc_op = CC_OP_EFLAGS;
- gen_op_mov_reg_T1[ot][reg]();
- break;
- case 0x118:
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- op = (modrm >> 3) & 7;
- switch(op) {
- case 0: /* prefetchnta */
- case 1: /* prefetchnt0 */
- case 2: /* prefetchnt0 */
- case 3: /* prefetchnt0 */
- if (mod == 3)
- goto illegal_op;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- /* nothing more to do */
- break;
- default: /* nop (multi byte) */
- gen_nop_modrm(s, modrm);
- break;
- }
- break;
- case 0x119 ... 0x11f: /* nop (multi byte) */
- modrm = ldub_code(s->pc++);
- gen_nop_modrm(s, modrm);
- break;
- case 0x120: /* mov reg, crN */
- case 0x122: /* mov crN, reg */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- modrm = ldub_code(s->pc++);
- if ((modrm & 0xc0) != 0xc0)
- goto illegal_op;
- rm = (modrm & 7) | REX_B(s);
- reg = ((modrm >> 3) & 7) | rex_r;
- if (CODE64(s))
- ot = OT_QUAD;
- else
- ot = OT_LONG;
- switch(reg) {
- case 0:
- case 2:
- case 3:
- case 4:
- case 8:
- if (b & 2) {
- gen_op_mov_TN_reg[ot][0][rm]();
- gen_op_movl_crN_T0(reg);
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- } else {
-#if !defined(CONFIG_USER_ONLY)
- if (reg == 8)
- gen_op_movtl_T0_cr8();
- else
-#endif
- gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
- gen_op_mov_reg_T0[ot][rm]();
- }
- break;
- default:
- goto illegal_op;
- }
- }
- break;
- case 0x121: /* mov reg, drN */
- case 0x123: /* mov drN, reg */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- modrm = ldub_code(s->pc++);
- if ((modrm & 0xc0) != 0xc0)
- goto illegal_op;
- rm = (modrm & 7) | REX_B(s);
- reg = ((modrm >> 3) & 7) | rex_r;
- if (CODE64(s))
- ot = OT_QUAD;
- else
- ot = OT_LONG;
- /* XXX: do it dynamically with CR4.DE bit */
- if (reg == 4 || reg == 5 || reg >= 8)
- goto illegal_op;
- if (b & 2) {
- gen_op_mov_TN_reg[ot][0][rm]();
- gen_op_movl_drN_T0(reg);
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- } else {
- gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
- gen_op_mov_reg_T0[ot][rm]();
- }
- }
- break;
- case 0x106: /* clts */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
- } else {
- gen_op_clts();
- /* abort block because static cpu state changed */
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
- }
- break;
- /* MMX/SSE/SSE2/PNI support */
- case 0x1c3: /* MOVNTI reg, mem */
- if (!(s->cpuid_features & CPUID_SSE2))
- goto illegal_op;
- ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- if (mod == 3)
- goto illegal_op;
- reg = ((modrm >> 3) & 7) | rex_r;
- /* generate a generic store */
- gen_ldst_modrm(s, modrm, ot, reg, 1);
- break;
- case 0x1ae:
- modrm = ldub_code(s->pc++);
- mod = (modrm >> 6) & 3;
- op = (modrm >> 3) & 7;
- switch(op) {
- case 0: /* fxsave */
- if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
- (s->flags & HF_EM_MASK))
- goto illegal_op;
- if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
- break;
- }
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_fxsave_A0((s->dflag == 2));
- break;
- case 1: /* fxrstor */
- if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
- (s->flags & HF_EM_MASK))
- goto illegal_op;
- if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
- break;
- }
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_fxrstor_A0((s->dflag == 2));
- break;
- case 2: /* ldmxcsr */
- case 3: /* stmxcsr */
- if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
- break;
- }
- if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
- mod == 3)
- goto illegal_op;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- if (op == 2) {
- gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
- gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
- } else {
- gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
- gen_op_st_T0_A0[OT_LONG + s->mem_index]();
- }
- break;
- case 5: /* lfence */
- case 6: /* mfence */
- if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
- goto illegal_op;
- break;
- case 7: /* sfence / clflush */
- if ((modrm & 0xc7) == 0xc0) {
- /* sfence */
- if (!(s->cpuid_features & CPUID_SSE))
- goto illegal_op;
- } else {
- /* clflush */
- if (!(s->cpuid_features & CPUID_CLFLUSH))
- goto illegal_op;
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- }
- break;
- default:
- goto illegal_op;
- }
- break;
- case 0x10d: /* prefetch */
- modrm = ldub_code(s->pc++);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- /* ignore for now */
- break;
- case 0x1aa: /* rsm */
- if (!(s->flags & HF_SMM_MASK))
- goto illegal_op;
- if (s->cc_op != CC_OP_DYNAMIC) {
- gen_op_set_cc_op(s->cc_op);
- s->cc_op = CC_OP_DYNAMIC;
- }
- gen_jmp_im(s->pc - s->cs_base);
- gen_op_rsm();
- gen_eob(s);
- break;
- case 0x110 ... 0x117:
- case 0x128 ... 0x12f:
- case 0x150 ... 0x177:
- case 0x17c ... 0x17f:
- case 0x1c2:
- case 0x1c4 ... 0x1c6:
- case 0x1d0 ... 0x1fe:
- gen_sse(s, b, pc_start, rex_r);
- break;
- default:
- goto illegal_op;
- }
- /* lock generation */
- if (s->prefix & PREFIX_LOCK)
- gen_op_unlock();
- return s->pc;
- illegal_op:
- if (s->prefix & PREFIX_LOCK)
- gen_op_unlock();
- /* XXX: ensure that no lock was generated */
- gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
- return s->pc;
-}
-
-#define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
-#define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
-
-/* flags read by an operation */
-static uint16_t opc_read_flags[NB_OPS] = {
- [INDEX_op_aas] = CC_A,
- [INDEX_op_aaa] = CC_A,
- [INDEX_op_das] = CC_A | CC_C,
- [INDEX_op_daa] = CC_A | CC_C,
-
- /* subtle: due to the incl/decl implementation, C is used */
- [INDEX_op_update_inc_cc] = CC_C,
-
- [INDEX_op_into] = CC_O,
-
- [INDEX_op_jb_subb] = CC_C,
- [INDEX_op_jb_subw] = CC_C,
- [INDEX_op_jb_subl] = CC_C,
-
- [INDEX_op_jz_subb] = CC_Z,
- [INDEX_op_jz_subw] = CC_Z,
- [INDEX_op_jz_subl] = CC_Z,
-
- [INDEX_op_jbe_subb] = CC_Z | CC_C,
- [INDEX_op_jbe_subw] = CC_Z | CC_C,
- [INDEX_op_jbe_subl] = CC_Z | CC_C,
-
- [INDEX_op_js_subb] = CC_S,
- [INDEX_op_js_subw] = CC_S,
- [INDEX_op_js_subl] = CC_S,
-
- [INDEX_op_jl_subb] = CC_O | CC_S,
- [INDEX_op_jl_subw] = CC_O | CC_S,
- [INDEX_op_jl_subl] = CC_O | CC_S,
-
- [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
- [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
- [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
-
- [INDEX_op_loopnzw] = CC_Z,
- [INDEX_op_loopnzl] = CC_Z,
- [INDEX_op_loopzw] = CC_Z,
- [INDEX_op_loopzl] = CC_Z,
-
- [INDEX_op_seto_T0_cc] = CC_O,
- [INDEX_op_setb_T0_cc] = CC_C,
- [INDEX_op_setz_T0_cc] = CC_Z,
- [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
- [INDEX_op_sets_T0_cc] = CC_S,
- [INDEX_op_setp_T0_cc] = CC_P,
- [INDEX_op_setl_T0_cc] = CC_O | CC_S,
- [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
-
- [INDEX_op_setb_T0_subb] = CC_C,
- [INDEX_op_setb_T0_subw] = CC_C,
- [INDEX_op_setb_T0_subl] = CC_C,
-
- [INDEX_op_setz_T0_subb] = CC_Z,
- [INDEX_op_setz_T0_subw] = CC_Z,
- [INDEX_op_setz_T0_subl] = CC_Z,
-
- [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
- [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
- [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
-
- [INDEX_op_sets_T0_subb] = CC_S,
- [INDEX_op_sets_T0_subw] = CC_S,
- [INDEX_op_sets_T0_subl] = CC_S,
-
- [INDEX_op_setl_T0_subb] = CC_O | CC_S,
- [INDEX_op_setl_T0_subw] = CC_O | CC_S,
- [INDEX_op_setl_T0_subl] = CC_O | CC_S,
-
- [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
- [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
- [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
-
- [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
- [INDEX_op_cmc] = CC_C,
- [INDEX_op_salc] = CC_C,
-
- /* needed for correct flag optimisation before string ops */
- [INDEX_op_jnz_ecxw] = CC_OSZAPC,
- [INDEX_op_jnz_ecxl] = CC_OSZAPC,
- [INDEX_op_jz_ecxw] = CC_OSZAPC,
- [INDEX_op_jz_ecxl] = CC_OSZAPC,
-
-#ifdef TARGET_X86_64
- [INDEX_op_jb_subq] = CC_C,
- [INDEX_op_jz_subq] = CC_Z,
- [INDEX_op_jbe_subq] = CC_Z | CC_C,
- [INDEX_op_js_subq] = CC_S,
- [INDEX_op_jl_subq] = CC_O | CC_S,
- [INDEX_op_jle_subq] = CC_O | CC_S | CC_Z,
-
- [INDEX_op_loopnzq] = CC_Z,
- [INDEX_op_loopzq] = CC_Z,
-
- [INDEX_op_setb_T0_subq] = CC_C,
- [INDEX_op_setz_T0_subq] = CC_Z,
- [INDEX_op_setbe_T0_subq] = CC_Z | CC_C,
- [INDEX_op_sets_T0_subq] = CC_S,
- [INDEX_op_setl_T0_subq] = CC_O | CC_S,
- [INDEX_op_setle_T0_subq] = CC_O | CC_S | CC_Z,
-
- [INDEX_op_jnz_ecxq] = CC_OSZAPC,
- [INDEX_op_jz_ecxq] = CC_OSZAPC,
-#endif
-
-#define DEF_READF(SUFFIX)\
- [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\
- X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
- [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\
- X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
-\
- [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\
- X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
- [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\
- [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,\
- X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_C,)
-
- DEF_READF( )
- DEF_READF(_raw)
-#ifndef CONFIG_USER_ONLY
- DEF_READF(_kernel)
- DEF_READF(_user)
-#endif
-};
-
-/* flags written by an operation */
-static uint16_t opc_write_flags[NB_OPS] = {
- [INDEX_op_update2_cc] = CC_OSZAPC,
- [INDEX_op_update1_cc] = CC_OSZAPC,
- [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
- [INDEX_op_update_neg_cc] = CC_OSZAPC,
- /* subtle: due to the incl/decl implementation, C is used */
- [INDEX_op_update_inc_cc] = CC_OSZAPC,
- [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
-
- [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
- [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
- [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_mulq_EAX_T0] = CC_OSZAPC,)
- [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
- [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
- [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_imulq_EAX_T0] = CC_OSZAPC,)
- [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
- [INDEX_op_imull_T0_T1] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
-
- /* sse */
- [INDEX_op_ucomiss] = CC_OSZAPC,
- [INDEX_op_ucomisd] = CC_OSZAPC,
- [INDEX_op_comiss] = CC_OSZAPC,
- [INDEX_op_comisd] = CC_OSZAPC,
-
- /* bcd */
- [INDEX_op_aam] = CC_OSZAPC,
- [INDEX_op_aad] = CC_OSZAPC,
- [INDEX_op_aas] = CC_OSZAPC,
- [INDEX_op_aaa] = CC_OSZAPC,
- [INDEX_op_das] = CC_OSZAPC,
- [INDEX_op_daa] = CC_OSZAPC,
-
- [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
- [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
- [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
- [INDEX_op_movw_eflags_T0_io] = CC_OSZAPC,
- [INDEX_op_movl_eflags_T0_io] = CC_OSZAPC,
- [INDEX_op_movw_eflags_T0_cpl0] = CC_OSZAPC,
- [INDEX_op_movl_eflags_T0_cpl0] = CC_OSZAPC,
- [INDEX_op_clc] = CC_C,
- [INDEX_op_stc] = CC_C,
- [INDEX_op_cmc] = CC_C,
-
- [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
- [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_btq_T0_T1_cc] = CC_OSZAPC,)
- [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
- [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_btsq_T0_T1_cc] = CC_OSZAPC,)
- [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
- [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_btrq_T0_T1_cc] = CC_OSZAPC,)
- [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
- [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_btcq_T0_T1_cc] = CC_OSZAPC,)
-
- [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
- [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_bsfq_T0_cc] = CC_OSZAPC,)
- [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
- [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_bsrq_T0_cc] = CC_OSZAPC,)
-
- [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
- [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
- [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
- X86_64_DEF([INDEX_op_cmpxchgq_T0_T1_EAX_cc] = CC_OSZAPC,)
-
- [INDEX_op_cmpxchg8b] = CC_Z,
- [INDEX_op_lar] = CC_Z,
- [INDEX_op_lsl] = CC_Z,
- [INDEX_op_verr] = CC_Z,
- [INDEX_op_verw] = CC_Z,
- [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C,
- [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C,
-
-#define DEF_WRITEF(SUFFIX)\
- [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
- [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
-\
- [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
- [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
-\
- [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
- [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
- X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
-\
- [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_shlq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
-\
- [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_shrq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
-\
- [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_sarq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
-\
- [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
- [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
- [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
- [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
-\
- [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
- [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
- [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
- [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
-\
- [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
- [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
- [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
- X86_64_DEF([INDEX_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,)
-
-
- DEF_WRITEF( )
- DEF_WRITEF(_raw)
-#ifndef CONFIG_USER_ONLY
- DEF_WRITEF(_kernel)
- DEF_WRITEF(_user)
-#endif
-};
-
-/* simpler form of an operation if no flags need to be generated */
-static uint16_t opc_simpler[NB_OPS] = {
- [INDEX_op_update2_cc] = INDEX_op_nop,
- [INDEX_op_update1_cc] = INDEX_op_nop,
- [INDEX_op_update_neg_cc] = INDEX_op_nop,
-#if 0
- /* broken: CC_OP logic must be rewritten */
- [INDEX_op_update_inc_cc] = INDEX_op_nop,
-#endif
-
- [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
- [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
- [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
- X86_64_DEF([INDEX_op_shlq_T0_T1_cc] = INDEX_op_shlq_T0_T1,)
-
- [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
- [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
- [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
- X86_64_DEF([INDEX_op_shrq_T0_T1_cc] = INDEX_op_shrq_T0_T1,)
-
- [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
- [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
- [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
- X86_64_DEF([INDEX_op_sarq_T0_T1_cc] = INDEX_op_sarq_T0_T1,)
-
-#define DEF_SIMPLER(SUFFIX)\
- [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\
- [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\
- [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\
- X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolq ## SUFFIX ## _T0_T1,)\
-\
- [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\
- [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\
- [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,\
- X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorq ## SUFFIX ## _T0_T1,)
-
- DEF_SIMPLER( )
- DEF_SIMPLER(_raw)
-#ifndef CONFIG_USER_ONLY
- DEF_SIMPLER(_kernel)
- DEF_SIMPLER(_user)
-#endif
-};
-
-void optimize_flags_init(void)
-{
- int i;
- /* put default values in arrays */
- for(i = 0; i < NB_OPS; i++) {
- if (opc_simpler[i] == 0)
- opc_simpler[i] = i;
- }
-}
-
-/* CPU flags computation optimization: we move backward thru the
- generated code to see which flags are needed. The operation is
- modified if suitable */
-static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
-{
- uint16_t *opc_ptr;
- int live_flags, write_flags, op;
-
- opc_ptr = opc_buf + opc_buf_len;
- /* live_flags contains the flags needed by the next instructions
- in the code. At the end of the bloc, we consider that all the
- flags are live. */
- live_flags = CC_OSZAPC;
- while (opc_ptr > opc_buf) {
- op = *--opc_ptr;
- /* if none of the flags written by the instruction is used,
- then we can try to find a simpler instruction */
- write_flags = opc_write_flags[op];
- if ((live_flags & write_flags) == 0) {
- *opc_ptr = opc_simpler[op];
- }
- /* compute the live flags before the instruction */
- live_flags &= ~write_flags;
- live_flags |= opc_read_flags[op];
- }
-}
-
-/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
- basic block 'tb'. If search_pc is TRUE, also generate PC
- information for each intermediate instruction. */
-static inline int gen_intermediate_code_internal(CPUState *env,
- TranslationBlock *tb,
- int search_pc)
-{
- DisasContext dc1, *dc = &dc1;
- target_ulong pc_ptr;
- uint16_t *gen_opc_end;
- int flags, j, lj, cflags;
- target_ulong pc_start;
- target_ulong cs_base;
-
- /* generate intermediate code */
- pc_start = tb->pc;
- cs_base = tb->cs_base;
- flags = tb->flags;
- cflags = tb->cflags;
-
- dc->pe = (flags >> HF_PE_SHIFT) & 1;
- dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
- dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
- dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
- dc->f_st = 0;
- dc->vm86 = (flags >> VM_SHIFT) & 1;
- dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
- dc->iopl = (flags >> IOPL_SHIFT) & 3;
- dc->tf = (flags >> TF_SHIFT) & 1;
- dc->singlestep_enabled = env->singlestep_enabled;
- dc->cc_op = CC_OP_DYNAMIC;
- dc->cs_base = cs_base;
- dc->tb = tb;
- dc->popl_esp_hack = 0;
- /* select memory access functions */
- dc->mem_index = 0;
- if (flags & HF_SOFTMMU_MASK) {
- if (dc->cpl == 3)
- dc->mem_index = 2 * 4;
- else
- dc->mem_index = 1 * 4;
- }
- dc->cpuid_features = env->cpuid_features;
- dc->cpuid_ext_features = env->cpuid_ext_features;
-#ifdef TARGET_X86_64
- dc->lma = (flags >> HF_LMA_SHIFT) & 1;
- dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
-#endif
- dc->flags = flags;
- dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
- (flags & HF_INHIBIT_IRQ_MASK)
-#ifndef CONFIG_SOFTMMU
- || (flags & HF_SOFTMMU_MASK)
-#endif
- );
-#if 0
- /* check addseg logic */
- if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
- printf("ERROR addseg\n");
-#endif
-
- gen_opc_ptr = gen_opc_buf;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
- gen_opparam_ptr = gen_opparam_buf;
- nb_gen_labels = 0;
-
- dc->is_jmp = DISAS_NEXT;
- pc_ptr = pc_start;
- lj = -1;
-
- for(;;) {
- if (env->nb_breakpoints > 0) {
- for(j = 0; j < env->nb_breakpoints; j++) {
- if (env->breakpoints[j] == pc_ptr) {
- gen_debug(dc, pc_ptr - dc->cs_base);
- break;
- }
- }
- }
- if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
- if (lj < j) {
- lj++;
- while (lj < j)
- gen_opc_instr_start[lj++] = 0;
- }
- gen_opc_pc[lj] = pc_ptr;
- gen_opc_cc_op[lj] = dc->cc_op;
- gen_opc_instr_start[lj] = 1;
- }
- pc_ptr = disas_insn(dc, pc_ptr);
- /* stop translation if indicated */
- if (dc->is_jmp)
- break;
- /* if single step mode, we generate only one instruction and
- generate an exception */
- /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
- the flag and abort the translation to give the irqs a
- change to be happen */
- if (dc->tf || dc->singlestep_enabled ||
- (flags & HF_INHIBIT_IRQ_MASK) ||
- (cflags & CF_SINGLE_INSN)) {
- gen_jmp_im(pc_ptr - dc->cs_base);
- gen_eob(dc);
- break;
- }
- /* if too long translation, stop generation too */
- if (gen_opc_ptr >= gen_opc_end ||
- (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
- gen_jmp_im(pc_ptr - dc->cs_base);
- gen_eob(dc);
- break;
- }
- }
- *gen_opc_ptr = INDEX_op_end;
- /* we don't forget to fill the last values */
- if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
- lj++;
- while (lj <= j)
- gen_opc_instr_start[lj++] = 0;
- }
-
-#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_CPU) {
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- }
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- int disas_flags;
- fprintf(logfile, "----------------\n");
- fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
-#ifdef TARGET_X86_64
- if (dc->code64)
- disas_flags = 2;
- else
-#endif
- disas_flags = !dc->code32;
- target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
- fprintf(logfile, "\n");
- if (loglevel & CPU_LOG_TB_OP) {
- fprintf(logfile, "OP:\n");
- dump_ops(gen_opc_buf, gen_opparam_buf);
- fprintf(logfile, "\n");
- }
- }
-#endif
-
- /* optimize flag computations */
- optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
-
-#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_OP_OPT) {
- fprintf(logfile, "AFTER FLAGS OPT:\n");
- dump_ops(gen_opc_buf, gen_opparam_buf);
- fprintf(logfile, "\n");
- }
-#endif
- if (!search_pc)
- tb->size = pc_ptr - pc_start;
- return 0;
-}
-
-int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
-{
- return gen_intermediate_code_internal(env, tb, 0);
-}
-
-int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
-{
- return gen_intermediate_code_internal(env, tb, 1);
-}
-
diff --git a/tools/ioemu/tests/.CVS/Entries b/tools/ioemu/tests/.CVS/Entries
deleted file mode 100644
index 791a84dc77..0000000000
--- a/tools/ioemu/tests/.CVS/Entries
+++ /dev/null
@@ -1,19 +0,0 @@
-/.cvsignore/1.4/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/Makefile/1.40/Thu May 3 17:18:16 2007//Trelease_0_9_0
-/hello-arm.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/hello-i386.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/hello-mips.c/1.1/Thu Dec 14 14:48:11 2006//Trelease_0_9_0
-/linux-test.c/1.3/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/pi_10.com/1.1/Thu May 3 17:18:16 2007/-kb/Trelease_0_9_0
-/qruncom.c/1.4/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/runcom.c/1.3/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/sha1.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/test-i386-code16.S/1.3/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/test-i386-muldiv.h/1.2/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/test-i386-shift.h/1.5/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/test-i386-vm86.S/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/test-i386.c/1.53/Thu May 3 17:18:16 2007//Trelease_0_9_0
-/test-i386.h/1.2/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/test_path.c/1.1/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-/testthread.c/1.2/Wed Oct 18 10:11:21 2006//Trelease_0_9_0
-D
diff --git a/tools/ioemu/tests/.CVS/Repository b/tools/ioemu/tests/.CVS/Repository
deleted file mode 100644
index 37b7123ea1..0000000000
--- a/tools/ioemu/tests/.CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-qemu/tests
diff --git a/tools/ioemu/tests/.CVS/Root b/tools/ioemu/tests/.CVS/Root
deleted file mode 100644
index e8a9815e6a..0000000000
--- a/tools/ioemu/tests/.CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@cvs.savannah.nongnu.org:/sources/qemu
diff --git a/tools/ioemu/tests/.CVS/Tag b/tools/ioemu/tests/.CVS/Tag
deleted file mode 100644
index eed9f4a4fb..0000000000
--- a/tools/ioemu/tests/.CVS/Tag
+++ /dev/null
@@ -1 +0,0 @@
-Nrelease_0_9_0
diff --git a/tools/ioemu/tests/.cvsignore b/tools/ioemu/tests/.cvsignore
deleted file mode 100644
index 18a82986cc..0000000000
--- a/tools/ioemu/tests/.cvsignore
+++ /dev/null
@@ -1,23 +0,0 @@
- gmon.out
- testsig
- hello-i386
- hello-arm
- sha1.test.c
- sha1.c
- test-i386
- sha1
- testclone
- .gdb_history
- testthread
- test-i386.s
- test-i386.ref
- sha1-i386
- runcom
- debug.com
- test-i386.out
- speed.txt
- test-i386.ref.P3
- pi_10.com
- test-i386.ref.P4
- ldso.c
- test_path
diff --git a/tools/ioemu/tests/Makefile b/tools/ioemu/tests/Makefile
deleted file mode 100644
index 1f67ac5d21..0000000000
--- a/tools/ioemu/tests/Makefile
+++ /dev/null
@@ -1,100 +0,0 @@
--include ../config-host.mak
-
-CFLAGS=-Wall -O2 -g
-#CFLAGS+=-msse2
-LDFLAGS=
-
-ifeq ($(ARCH),i386)
-TESTS=linux-test testthread sha1-i386 test-i386 runcom
-endif
-ifeq ($(ARCH),x86_64)
-TESTS=test-x86_64
-endif
-TESTS+=sha1# test_path
-#TESTS+=test_path
-
-QEMU=../i386-linux-user/qemu-i386
-
-all: $(TESTS)
-
-hello-i386: hello-i386.c
- $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
- strip $@
-
-testthread: testthread.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
-
-test_path: test_path.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
- ./$@ || { rm $@; exit 1; }
-
-# i386/x86_64 emulation test (test various opcodes) */
-test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
- test-i386.h test-i386-shift.h test-i386-muldiv.h
- $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ \
- test-i386.c test-i386-code16.S test-i386-vm86.S -lm
-
-test-x86_64: test-i386.c \
- test-i386.h test-i386-shift.h test-i386-muldiv.h
- $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c -lm
-
-ifeq ($(ARCH),i386)
-test: test-i386
- ./test-i386 > test-i386.ref
-else
-test:
-endif
- $(QEMU) test-i386 > test-i386.out
- @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
-ifeq ($(ARCH),i386)
- $(QEMU) -no-code-copy test-i386 > test-i386.out
- @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK (no code copy)"; fi
-endif
-
-# generic Linux and CPU test
-linux-test: linux-test.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
-
-# speed test
-sha1-i386: sha1.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-
-sha1: sha1.c
- $(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-
-speed: sha1 sha1-i386
- time ./sha1
- time $(QEMU) ./sha1-i386
-
-# vm86 test
-runcom: runcom.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-
-# NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
-qruncom: qruncom.c ../i386-user/libqemu.a
- $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
- -o $@ $< -L../i386-user -lqemu -lm
-
-# arm test
-hello-arm: hello-arm.o
- arm-linux-ld -o $@ $<
-
-hello-arm.o: hello-arm.c
- arm-linux-gcc -Wall -g -O2 -c -o $@ $<
-
-# MIPS test
-hello-mips: hello-mips.c
- mips-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
-
-hello-mipsel: hello-mips.c
- mipsel-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
-
-# XXX: find a way to compile easily a test for each arch
-test2:
- @set -e; for arch in i386 arm armeb sparc ppc mips mipsel; do \
- ../$${arch}-linux-user/qemu-$${arch} $${arch}/ls -l linux-test.c ; \
- done
-
-clean:
- rm -f *~ *.o test-i386.out test-i386.ref \
- test-x86_64.log test-x86_64.ref qruncom $(TESTS)
diff --git a/tools/ioemu/tests/hello-arm.c b/tools/ioemu/tests/hello-arm.c
deleted file mode 100644
index f84e6cb368..0000000000
--- a/tools/ioemu/tests/hello-arm.c
+++ /dev/null
@@ -1,113 +0,0 @@
-#define __NR_SYSCALL_BASE 0x900000
-#define __NR_exit1 (__NR_SYSCALL_BASE+ 1)
-#define __NR_write (__NR_SYSCALL_BASE+ 4)
-
-#define __sys2(x) #x
-#define __sys1(x) __sys2(x)
-
-#ifndef __syscall
-#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t"
-#endif
-
-#define __syscall_return(type, res) \
-do { \
- return (type) (res); \
-} while (0)
-
-#define _syscall0(type,name) \
-type name(void) { \
- long __res; \
- __asm__ __volatile__ ( \
- __syscall(name) \
- "mov %0,r0" \
- :"=r" (__res) : : "r0","lr"); \
- __syscall_return(type,__res); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- __syscall(name) \
- "mov %0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)) \
- : "r0","lr"); \
- __syscall_return(type,__res); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)) \
- : "r0","r1","lr"); \
- __syscall_return(type,__res); \
-}
-
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- "mov\tr2,%3\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)) \
- : "r0","r1","r2","lr"); \
- __syscall_return(type,__res); \
-}
-
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- "mov\tr2,%3\n\t" \
- "mov\tr3,%4\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)) \
- : "r0","r1","r2","r3","lr"); \
- __syscall_return(type,__res); \
-}
-
-
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- "mov\tr2,%3\n\t" \
- "mov\tr3,%4\n\t" \
- "mov\tr4,%5\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)), \
- "r" ((long)(arg5)) \
- : "r0","r1","r2","r3","r4","lr"); \
- __syscall_return(type,__res); \
-}
-
-_syscall1(int,exit1,int,status);
-_syscall3(int,write,int,fd,const char *,buf, int, len);
-
-void _start(void)
-{
- write(1, "Hello World\n", 12);
- exit1(0);
-}
diff --git a/tools/ioemu/tests/hello-i386.c b/tools/ioemu/tests/hello-i386.c
deleted file mode 100644
index e00245d3fe..0000000000
--- a/tools/ioemu/tests/hello-i386.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <asm/unistd.h>
-
-extern inline volatile void exit(int status)
-{
- int __res;
- __asm__ volatile ("movl %%ecx,%%ebx\n"\
- "int $0x80" \
- : "=a" (__res) : "0" (__NR_exit),"c" ((long)(status)));
-}
-
-extern inline int write(int fd, const char * buf, int len)
-{
- int status;
- __asm__ volatile ("pushl %%ebx\n"\
- "movl %%esi,%%ebx\n"\
- "int $0x80\n" \
- "popl %%ebx\n"\
- : "=a" (status) \
- : "0" (__NR_write),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len)));
-}
-
-void _start(void)
-{
- write(1, "Hello World\n", 12);
- exit(0);
-}
diff --git a/tools/ioemu/tests/hello-mips.c b/tools/ioemu/tests/hello-mips.c
deleted file mode 100644
index f8256730dd..0000000000
--- a/tools/ioemu/tests/hello-mips.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-* MIPS o32 Linux syscall example
-*
-* http://www.linux-mips.org/wiki/RISC/os
-* http://www.linux-mips.org/wiki/MIPSABIHistory
-* http://www.linux.com/howtos/Assembly-HOWTO/mips.shtml
-*
-* mipsel-linux-gcc -nostdlib -mno-abicalls -fno-PIC -mabi=32 \
-* -O2 -static -o hello-mips hello-mips.c
-*
-*/
-#define __NR_SYSCALL_BASE 4000
-#define __NR_exit (__NR_SYSCALL_BASE+ 1)
-#define __NR_write (__NR_SYSCALL_BASE+ 4)
-
-static inline void exit1(int status)
-{
- register unsigned long __a0 asm("$4") = (unsigned long) status;
-
- __asm__ __volatile__ (
- " .set push \n"
- " .set noreorder \n"
- " li $2, %0 \n"
- " syscall \n"
- " .set pop "
- :
- : "i" (__NR_exit), "r" (__a0)
- : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
- "memory");
-}
-
-static inline int write(int fd, const char *buf, int len)
-{
- register unsigned long __a0 asm("$4") = (unsigned long) fd;
- register unsigned long __a1 asm("$5") = (unsigned long) buf;
- register unsigned long __a2 asm("$6") = (unsigned long) len;
- register unsigned long __a3 asm("$7");
- unsigned long __v0;
-
- __asm__ __volatile__ (
- " .set push \n"
- " .set noreorder \n"
- " li $2, %2 \n"
- " syscall \n"
- " move %0, $2 \n"
- " .set pop "
- : "=r" (__v0), "=r" (__a3)
- : "i" (__NR_write), "r" (__a0), "r" (__a1), "r" (__a2)
- : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
- "memory");
-
-/* if (__a3 == 0) */
- return (int) __v0;
-/*
- errno = __v0;
- return -1;
- */
-}
-
-void __start(void)
-{
- write (1, "Hello, World!\n", 14);
- exit1 (42);
-}
diff --git a/tools/ioemu/tests/linux-test.c b/tools/ioemu/tests/linux-test.c
deleted file mode 100644
index 6ca9029650..0000000000
--- a/tools/ioemu/tests/linux-test.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * linux and CPU test
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <utime.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sched.h>
-#include <dirent.h>
-#include <setjmp.h>
-#include <sys/shm.h>
-
-#define TESTPATH "/tmp/linux-test.tmp"
-#define TESTPORT 7654
-#define STACK_SIZE 16384
-
-void error1(const char *filename, int line, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", filename, line);
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- exit(1);
-}
-
-int __chk_error(const char *filename, int line, int ret)
-{
- if (ret < 0) {
- error1(filename, line, "%m (ret=%d, errno=%d)",
- ret, errno);
- }
- return ret;
-}
-
-#define error(fmt, args...) error1(__FILE__, __LINE__, fmt, ##args)
-
-#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
-
-/*******************************************************/
-
-#define FILE_BUF_SIZE 300
-
-void test_file(void)
-{
- int fd, i, len, ret;
- uint8_t buf[FILE_BUF_SIZE];
- uint8_t buf2[FILE_BUF_SIZE];
- uint8_t buf3[FILE_BUF_SIZE];
- char cur_dir[1024];
- struct stat st;
- struct utimbuf tbuf;
- struct iovec vecs[2];
- DIR *dir;
- struct dirent *de;
-
- /* clean up, just in case */
- unlink(TESTPATH "/file1");
- unlink(TESTPATH "/file2");
- unlink(TESTPATH "/file3");
- rmdir(TESTPATH);
-
- if (getcwd(cur_dir, sizeof(cur_dir)) == NULL)
- error("getcwd");
-
- chk_error(mkdir(TESTPATH, 0755));
-
- chk_error(chdir(TESTPATH));
-
- /* open/read/write/close/readv/writev/lseek */
-
- fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644));
- for(i=0;i < FILE_BUF_SIZE; i++)
- buf[i] = i;
- len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2));
- if (len != (FILE_BUF_SIZE / 2))
- error("write");
- vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2);
- vecs[0].iov_len = 16;
- vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16;
- vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16;
- len = chk_error(writev(fd, vecs, 2));
- if (len != (FILE_BUF_SIZE / 2))
- error("writev");
- chk_error(close(fd));
-
- chk_error(rename("file1", "file2"));
-
- fd = chk_error(open("file2", O_RDONLY));
-
- len = chk_error(read(fd, buf2, FILE_BUF_SIZE));
- if (len != FILE_BUF_SIZE)
- error("read");
- if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0)
- error("memcmp");
-
-#define FOFFSET 16
- ret = chk_error(lseek(fd, FOFFSET, SEEK_SET));
- if (ret != 16)
- error("lseek");
- vecs[0].iov_base = buf3;
- vecs[0].iov_len = 32;
- vecs[1].iov_base = buf3 + 32;
- vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32;
- len = chk_error(readv(fd, vecs, 2));
- if (len != FILE_BUF_SIZE - FOFFSET)
- error("readv");
- if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0)
- error("memcmp");
-
- chk_error(close(fd));
-
- /* access */
- chk_error(access("file2", R_OK));
-
- /* stat/chmod/utime/truncate */
-
- chk_error(chmod("file2", 0600));
- tbuf.actime = 1001;
- tbuf.modtime = 1000;
- chk_error(truncate("file2", 100));
- chk_error(utime("file2", &tbuf));
- chk_error(stat("file2", &st));
- if (st.st_size != 100)
- error("stat size");
- if (!S_ISREG(st.st_mode))
- error("stat mode");
- if ((st.st_mode & 0777) != 0600)
- error("stat mode2");
- if (st.st_atime != 1001 ||
- st.st_mtime != 1000)
- error("stat time");
-
- chk_error(stat(TESTPATH, &st));
- if (!S_ISDIR(st.st_mode))
- error("stat mode");
-
- /* fstat */
- fd = chk_error(open("file2", O_RDWR));
- chk_error(ftruncate(fd, 50));
- chk_error(fstat(fd, &st));
- chk_error(close(fd));
-
- if (st.st_size != 50)
- error("stat size");
- if (!S_ISREG(st.st_mode))
- error("stat mode");
-
- /* symlink/lstat */
- chk_error(symlink("file2", "file3"));
- chk_error(lstat("file3", &st));
- if (!S_ISLNK(st.st_mode))
- error("stat mode");
-
- /* getdents */
- dir = opendir(TESTPATH);
- if (!dir)
- error("opendir");
- len = 0;
- for(;;) {
- de = readdir(dir);
- if (!de)
- break;
- if (strcmp(de->d_name, ".") != 0 &&
- strcmp(de->d_name, "..") != 0 &&
- strcmp(de->d_name, "file2") != 0 &&
- strcmp(de->d_name, "file3") != 0)
- error("readdir");
- len++;
- }
- closedir(dir);
- if (len != 4)
- error("readdir");
-
- chk_error(unlink("file3"));
- chk_error(unlink("file2"));
- chk_error(chdir(cur_dir));
- chk_error(rmdir(TESTPATH));
-}
-
-void test_fork(void)
-{
- int pid, status;
-
- pid = chk_error(fork());
- if (pid == 0) {
- /* child */
- exit(2);
- }
- chk_error(waitpid(pid, &status, 0));
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 2)
- error("waitpid status=0x%x", status);
-}
-
-void test_time(void)
-{
- struct timeval tv, tv2;
- struct timespec ts, rem;
- struct rusage rusg1, rusg2;
- int ti, i;
-
- chk_error(gettimeofday(&tv, NULL));
- rem.tv_sec = 1;
- ts.tv_sec = 0;
- ts.tv_nsec = 20 * 1000000;
- chk_error(nanosleep(&ts, &rem));
- if (rem.tv_sec != 1)
- error("nanosleep");
- chk_error(gettimeofday(&tv2, NULL));
- ti = tv2.tv_sec - tv.tv_sec;
- if (ti >= 2)
- error("gettimeofday");
-
- chk_error(getrusage(RUSAGE_SELF, &rusg1));
- for(i = 0;i < 10000; i++);
- chk_error(getrusage(RUSAGE_SELF, &rusg2));
- if ((rusg2.ru_utime.tv_sec - rusg1.ru_utime.tv_sec) < 0 ||
- (rusg2.ru_stime.tv_sec - rusg1.ru_stime.tv_sec) < 0)
- error("getrusage");
-}
-
-void pstrcpy(char *buf, int buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-/* strcat and truncate. */
-char *pstrcat(char *buf, int buf_size, const char *s)
-{
- int len;
- len = strlen(buf);
- if (len < buf_size)
- pstrcpy(buf + len, buf_size - len, s);
- return buf;
-}
-
-int server_socket(void)
-{
- int val, fd;
- struct sockaddr_in sockaddr;
-
- /* server socket */
- fd = chk_error(socket(PF_INET, SOCK_STREAM, 0));
-
- val = 1;
- chk_error(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)));
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(TESTPORT);
- sockaddr.sin_addr.s_addr = 0;
- chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)));
- chk_error(listen(fd, 0));
- return fd;
-
-}
-
-int client_socket(void)
-{
- int fd;
- struct sockaddr_in sockaddr;
-
- /* server socket */
- fd = chk_error(socket(PF_INET, SOCK_STREAM, 0));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(TESTPORT);
- inet_aton("127.0.0.1", &sockaddr.sin_addr);
- chk_error(connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)));
- return fd;
-}
-
-const char socket_msg[] = "hello socket\n";
-
-void test_socket(void)
-{
- int server_fd, client_fd, fd, pid, ret, val;
- struct sockaddr_in sockaddr;
- socklen_t len;
- char buf[512];
-
- server_fd = server_socket();
-
- /* test a few socket options */
- len = sizeof(val);
- chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len));
- if (val != SOCK_STREAM)
- error("getsockopt");
-
- pid = chk_error(fork());
- if (pid == 0) {
- client_fd = client_socket();
- send(client_fd, socket_msg, sizeof(socket_msg), 0);
- close(client_fd);
- exit(0);
- }
- len = sizeof(sockaddr);
- fd = chk_error(accept(server_fd, (struct sockaddr *)&sockaddr, &len));
-
- ret = chk_error(recv(fd, buf, sizeof(buf), 0));
- if (ret != sizeof(socket_msg))
- error("recv");
- if (memcmp(buf, socket_msg, sizeof(socket_msg)) != 0)
- error("socket_msg");
- chk_error(close(fd));
- chk_error(close(server_fd));
-}
-
-#define WCOUNT_MAX 512
-
-void test_pipe(void)
-{
- fd_set rfds, wfds;
- int fds[2], fd_max, ret;
- uint8_t ch;
- int wcount, rcount;
-
- chk_error(pipe(fds));
- chk_error(fcntl(fds[0], F_SETFL, O_NONBLOCK));
- chk_error(fcntl(fds[1], F_SETFL, O_NONBLOCK));
- wcount = 0;
- rcount = 0;
- for(;;) {
- FD_ZERO(&rfds);
- fd_max = fds[0];
- FD_SET(fds[0], &rfds);
-
- FD_ZERO(&wfds);
- FD_SET(fds[1], &wfds);
- if (fds[1] > fd_max)
- fd_max = fds[1];
-
- ret = chk_error(select(fd_max + 1, &rfds, &wfds, NULL, NULL));
- if (ret > 0) {
- if (FD_ISSET(fds[0], &rfds)) {
- chk_error(read(fds[0], &ch, 1));
- rcount++;
- if (rcount >= WCOUNT_MAX)
- break;
- }
- if (FD_ISSET(fds[1], &wfds)) {
- ch = 'a';
- chk_error(write(fds[0], &ch, 1));
- wcount++;
- }
- }
- }
- chk_error(close(fds[0]));
- chk_error(close(fds[1]));
-}
-
-int thread1_res;
-int thread2_res;
-
-int thread1_func(void *arg)
-{
- int i;
- for(i=0;i<5;i++) {
- thread1_res++;
- usleep(10 * 1000);
- }
- return 0;
-}
-
-int thread2_func(void *arg)
-{
- int i;
- for(i=0;i<6;i++) {
- thread2_res++;
- usleep(10 * 1000);
- }
- return 0;
-}
-
-void test_clone(void)
-{
- uint8_t *stack1, *stack2;
- int pid1, pid2, status1, status2;
-
- stack1 = malloc(STACK_SIZE);
- pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE,
- CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"));
-
- stack2 = malloc(STACK_SIZE);
- pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE,
- CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"));
-
- while (waitpid(pid1, &status1, 0) != pid1);
- while (waitpid(pid2, &status2, 0) != pid2);
- if (thread1_res != 5 ||
- thread2_res != 6)
- error("clone");
-}
-
-/***********************************/
-
-volatile int alarm_count;
-jmp_buf jmp_env;
-
-void sig_alarm(int sig)
-{
- if (sig != SIGALRM)
- error("signal");
- alarm_count++;
-}
-
-void sig_segv(int sig, siginfo_t *info, void *puc)
-{
- if (sig != SIGSEGV)
- error("signal");
- longjmp(jmp_env, 1);
-}
-
-void test_signal(void)
-{
- struct sigaction act;
- struct itimerval it, oit;
-
- /* timer test */
-
- alarm_count = 0;
-
- act.sa_handler = sig_alarm;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- chk_error(sigaction(SIGALRM, &act, NULL));
-
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 10 * 1000;
- it.it_value.tv_sec = 0;
- it.it_value.tv_usec = 10 * 1000;
- chk_error(setitimer(ITIMER_REAL, &it, NULL));
- chk_error(getitimer(ITIMER_REAL, &oit));
- if (oit.it_value.tv_sec != it.it_value.tv_sec ||
- oit.it_value.tv_usec != it.it_value.tv_usec)
- error("itimer");
-
- while (alarm_count < 5) {
- usleep(10 * 1000);
- }
-
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 0;
- it.it_value.tv_sec = 0;
- it.it_value.tv_usec = 0;
- memset(&oit, 0xff, sizeof(oit));
- chk_error(setitimer(ITIMER_REAL, &it, &oit));
- if (oit.it_value.tv_sec != 0 ||
- oit.it_value.tv_usec != 10 * 1000)
- error("setitimer");
-
- /* SIGSEGV test */
- act.sa_sigaction = sig_segv;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
- chk_error(sigaction(SIGSEGV, &act, NULL));
- if (setjmp(jmp_env) == 0) {
- *(uint8_t *)0 = 0;
- }
-
- act.sa_handler = SIG_DFL;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- chk_error(sigaction(SIGSEGV, &act, NULL));
-}
-
-#define SHM_SIZE 32768
-
-void test_shm(void)
-{
- void *ptr;
- int shmid;
-
- shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777));
- ptr = shmat(shmid, NULL, 0);
- if (!ptr)
- error("shmat");
-
- memset(ptr, 0, SHM_SIZE);
-
- chk_error(shmctl(shmid, IPC_RMID, 0));
- chk_error(shmdt(ptr));
-}
-
-int main(int argc, char **argv)
-{
- test_file();
- test_fork();
- test_time();
- test_socket();
- // test_clone();
- test_signal();
- test_shm();
- return 0;
-}
diff --git a/tools/ioemu/tests/qruncom.c b/tools/ioemu/tests/qruncom.c
deleted file mode 100644
index 421e6a99f2..0000000000
--- a/tools/ioemu/tests/qruncom.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Example of use of user mode libqemu: launch a basic .com DOS
- * executable
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <signal.h>
-#include <malloc.h>
-
-#include "cpu.h"
-
-//#define SIGTEST
-
-void cpu_outb(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
-}
-
-void cpu_outw(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
-}
-
-void cpu_outl(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
-}
-
-int cpu_inb(CPUState *env, int addr)
-{
- fprintf(stderr, "inb: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_inw(CPUState *env, int addr)
-{
- fprintf(stderr, "inw: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_inl(CPUState *env, int addr)
-{
- fprintf(stderr, "inl: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_get_pic_interrupt(CPUState *env)
-{
- return -1;
-}
-
-uint64_t cpu_get_tsc(CPUState *env)
-{
- return 0;
-}
-
-static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
- unsigned long addr, unsigned int sel)
-{
- unsigned int e1, e2;
- e1 = (addr & 0xffff) | (sel << 16);
- e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
- stl((uint8_t *)ptr, e1);
- stl((uint8_t *)ptr + 4, e2);
-}
-
-uint64_t idt_table[256];
-
-/* only dpl matters as we do only user space emulation */
-static void set_idt(int n, unsigned int dpl)
-{
- set_gate(idt_table + n, 0, dpl, 0, 0);
-}
-
-void qemu_free(void *ptr)
-{
- free(ptr);
-}
-
-void *qemu_malloc(size_t size)
-{
- return malloc(size);
-}
-
-void *qemu_mallocz(size_t size)
-{
- void *ptr;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- memset(ptr, 0, size);
- return ptr;
-}
-
-void *qemu_vmalloc(size_t size)
-{
- return memalign(4096, size);
-}
-
-void qemu_vfree(void *ptr)
-{
- free(ptr);
-}
-
-void qemu_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-}
-
-/* XXX: this is a bug in helper2.c */
-int errno;
-
-/**********************************************/
-
-#define COM_BASE_ADDR 0x10100
-
-void usage(void)
-{
- printf("qruncom version 0.1 (c) 2003 Fabrice Bellard\n"
- "usage: qruncom file.com\n"
- "user mode libqemu demo: run simple .com DOS executables\n");
- exit(1);
-}
-
-static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
-{
- return (uint8_t *)((seg << 4) + (reg & 0xffff));
-}
-
-static inline void pushw(CPUState *env, int val)
-{
- env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | ((env->regs[R_ESP] - 2) & 0xffff);
- *(uint16_t *)seg_to_linear(env->segs[R_SS].selector, env->regs[R_ESP]) = val;
-}
-
-static void host_segv_handler(int host_signum, siginfo_t *info,
- void *puc)
-{
- if (cpu_signal_handler(host_signum, info, puc)) {
- return;
- }
- abort();
-}
-
-int main(int argc, char **argv)
-{
- uint8_t *vm86_mem;
- const char *filename;
- int fd, ret, seg;
- CPUState *env;
-
- if (argc != 2)
- usage();
- filename = argv[1];
-
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
- MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
- if (vm86_mem == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
-
- /* load the MSDOS .com executable */
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- perror(filename);
- exit(1);
- }
- ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256);
- if (ret < 0) {
- perror("read");
- exit(1);
- }
- close(fd);
-
- /* install exception handler for CPU emulator */
- {
- struct sigaction act;
-
- sigfillset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
- // act.sa_flags |= SA_ONSTACK;
-
- act.sa_sigaction = host_segv_handler;
- sigaction(SIGSEGV, &act, NULL);
- sigaction(SIGBUS, &act, NULL);
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
- sigaction(SIGFPE, &act, NULL);
-#endif
- }
-
- // cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_TB_OUT_ASM | CPU_LOG_EXEC);
-
- env = cpu_init();
-
- /* disable code copy to simplify debugging */
- code_copy_enabled = 0;
-
- /* set user mode state (XXX: should be done automatically by
- cpu_init ?) */
- env->user_mode_only = 1;
-
- cpu_x86_set_cpl(env, 3);
-
- env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
- /* NOTE: hflags duplicates some of the virtual CPU state */
- env->hflags |= HF_PE_MASK | VM_MASK;
-
- /* flags setup : we activate the IRQs by default as in user
- mode. We also activate the VM86 flag to run DOS code */
- env->eflags |= IF_MASK | VM_MASK;
-
- /* init basic registers */
- env->eip = 0x100;
- env->regs[R_ESP] = 0xfffe;
- seg = (COM_BASE_ADDR - 0x100) >> 4;
-
- cpu_x86_load_seg_cache(env, R_CS, seg,
- (seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_SS, seg,
- (seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_DS, seg,
- (seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_ES, seg,
- (seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_FS, seg,
- (seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_GS, seg,
- (seg << 4), 0xffff, 0);
-
- /* exception support */
- env->idt.base = (unsigned long)idt_table;
- env->idt.limit = sizeof(idt_table) - 1;
- set_idt(0, 0);
- set_idt(1, 0);
- set_idt(2, 0);
- set_idt(3, 3);
- set_idt(4, 3);
- set_idt(5, 3);
- set_idt(6, 0);
- set_idt(7, 0);
- set_idt(8, 0);
- set_idt(9, 0);
- set_idt(10, 0);
- set_idt(11, 0);
- set_idt(12, 0);
- set_idt(13, 0);
- set_idt(14, 0);
- set_idt(15, 0);
- set_idt(16, 0);
- set_idt(17, 0);
- set_idt(18, 0);
- set_idt(19, 0);
-
- /* put return code */
- *seg_to_linear(env->segs[R_CS].selector, 0) = 0xb4; /* mov ah, $0 */
- *seg_to_linear(env->segs[R_CS].selector, 1) = 0x00;
- *seg_to_linear(env->segs[R_CS].selector, 2) = 0xcd; /* int $0x21 */
- *seg_to_linear(env->segs[R_CS].selector, 3) = 0x21;
- pushw(env, 0x0000);
-
- /* the value of these registers seem to be assumed by pi_10.com */
- env->regs[R_ESI] = 0x100;
- env->regs[R_ECX] = 0xff;
- env->regs[R_EBP] = 0x0900;
- env->regs[R_EDI] = 0xfffe;
-
- /* inform the emulator of the mmaped memory */
- page_set_flags(0x00000000, 0x110000,
- PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID);
-
- for(;;) {
- ret = cpu_x86_exec(env);
- switch(ret) {
- case EXCP0D_GPF:
- {
- int int_num, ah;
- int_num = *(uint8_t *)(env->segs[R_CS].base + env->eip + 1);
- if (int_num != 0x21)
- goto unknown_int;
- ah = (env->regs[R_EAX] >> 8) & 0xff;
- switch(ah) {
- case 0x00: /* exit */
- exit(0);
- case 0x02: /* write char */
- {
- uint8_t c = env->regs[R_EDX];
- write(1, &c, 1);
- }
- break;
- case 0x09: /* write string */
- {
- uint8_t c;
- for(;;) {
- c = *seg_to_linear(env->segs[R_DS].selector, env->regs[R_EAX]);
- if (c == '$')
- break;
- write(1, &c, 1);
- }
- env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | '$';
- }
- break;
- default:
- unknown_int:
- fprintf(stderr, "unsupported int 0x%02x\n", int_num);
- cpu_dump_state(env, stderr, fprintf, 0);
- // exit(1);
- }
- env->eip += 2;
- }
- break;
- default:
- fprintf(stderr, "unhandled cpu_exec return code (0x%x)\n", ret);
- cpu_dump_state(env, stderr, fprintf, 0);
- exit(1);
- }
- }
-}
diff --git a/tools/ioemu/tests/runcom.c b/tools/ioemu/tests/runcom.c
deleted file mode 100644
index 43deeca098..0000000000
--- a/tools/ioemu/tests/runcom.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Simple example of use of vm86: launch a basic .com DOS executable
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <signal.h>
-
-#include <linux/unistd.h>
-#include <asm/vm86.h>
-
-//#define SIGTEST
-
-#undef __syscall_return
-#define __syscall_return(type, res) \
-do { \
- return (type) (res); \
-} while (0)
-
-_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
-
-#define COM_BASE_ADDR 0x10100
-
-void usage(void)
-{
- printf("runcom version 0.1 (c) 2003 Fabrice Bellard\n"
- "usage: runcom file.com\n"
- "VM86 Run simple .com DOS executables (linux vm86 test mode)\n");
- exit(1);
-}
-
-static inline void set_bit(uint8_t *a, unsigned int bit)
-{
- a[bit / 8] |= (1 << (bit % 8));
-}
-
-static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
-{
- return (uint8_t *)((seg << 4) + (reg & 0xffff));
-}
-
-static inline void pushw(struct vm86_regs *r, int val)
-{
- r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
- *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
-}
-
-void dump_regs(struct vm86_regs *r)
-{
- fprintf(stderr,
- "EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
- "ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n"
- "EIP=%08lx EFL=%08lx\n"
- "CS=%04x DS=%04x ES=%04x SS=%04x FS=%04x GS=%04x\n",
- r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi, r->ebp, r->esp,
- r->eip, r->eflags,
- r->cs, r->ds, r->es, r->ss, r->fs, r->gs);
-}
-
-#ifdef SIGTEST
-void alarm_handler(int sig)
-{
- fprintf(stderr, "alarm signal=%d\n", sig);
- alarm(1);
-}
-#endif
-
-int main(int argc, char **argv)
-{
- uint8_t *vm86_mem;
- const char *filename;
- int fd, ret, seg;
- struct vm86plus_struct ctx;
- struct vm86_regs *r;
-
- if (argc != 2)
- usage();
- filename = argv[1];
-
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
- MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
- if (vm86_mem == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
-#ifdef SIGTEST
- {
- struct sigaction act;
-
- act.sa_handler = alarm_handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- sigaction(SIGALRM, &act, NULL);
- alarm(1);
- }
-#endif
-
- /* load the MSDOS .com executable */
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- perror(filename);
- exit(1);
- }
- ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256);
- if (ret < 0) {
- perror("read");
- exit(1);
- }
- close(fd);
-
- memset(&ctx, 0, sizeof(ctx));
- /* init basic registers */
- r = &ctx.regs;
- r->eip = 0x100;
- r->esp = 0xfffe;
- seg = (COM_BASE_ADDR - 0x100) >> 4;
- r->cs = seg;
- r->ss = seg;
- r->ds = seg;
- r->es = seg;
- r->fs = seg;
- r->gs = seg;
- r->eflags = VIF_MASK;
-
- /* put return code */
- set_bit((uint8_t *)&ctx.int_revectored, 0x21);
- *seg_to_linear(r->cs, 0) = 0xb4; /* mov ah, $0 */
- *seg_to_linear(r->cs, 1) = 0x00;
- *seg_to_linear(r->cs, 2) = 0xcd; /* int $0x21 */
- *seg_to_linear(r->cs, 3) = 0x21;
- pushw(&ctx.regs, 0x0000);
-
- /* the value of these registers seem to be assumed by pi_10.com */
- r->esi = 0x100;
- r->ecx = 0xff;
- r->ebp = 0x0900;
- r->edi = 0xfffe;
-
- for(;;) {
- ret = vm86(VM86_ENTER, &ctx);
- switch(VM86_TYPE(ret)) {
- case VM86_INTx:
- {
- int int_num, ah;
-
- int_num = VM86_ARG(ret);
- if (int_num != 0x21)
- goto unknown_int;
- ah = (r->eax >> 8) & 0xff;
- switch(ah) {
- case 0x00: /* exit */
- exit(0);
- case 0x02: /* write char */
- {
- uint8_t c = r->edx;
- write(1, &c, 1);
- }
- break;
- case 0x09: /* write string */
- {
- uint8_t c;
- for(;;) {
- c = *seg_to_linear(r->ds, r->edx);
- if (c == '$')
- break;
- write(1, &c, 1);
- }
- r->eax = (r->eax & ~0xff) | '$';
- }
- break;
- default:
- unknown_int:
- fprintf(stderr, "unsupported int 0x%02x\n", int_num);
- dump_regs(&ctx.regs);
- // exit(1);
- }
- }
- break;
- case VM86_SIGNAL:
- /* a signal came, we just ignore that */
- break;
- case VM86_STI:
- break;
- default:
- fprintf(stderr, "unhandled vm86 return code (0x%x)\n", ret);
- dump_regs(&ctx.regs);
- exit(1);
- }
- }
-}
diff --git a/tools/ioemu/tests/sha1.c b/tools/ioemu/tests/sha1.c
deleted file mode 100644
index 31b001920d..0000000000
--- a/tools/ioemu/tests/sha1.c
+++ /dev/null
@@ -1,242 +0,0 @@
-
-/* from valgrind tests */
-
-/* ================ sha1.c ================ */
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-
-Test Vectors (from FIPS PUB 180-1)
-"abc"
- A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-A million repetitions of "a"
- 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
-/* #define SHA1HANDSOFF * Copies data before messing with it. */
-
-#define SHA1HANDSOFF
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h> /* for u_int*_t */
-
-/* ================ sha1.h ================ */
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-*/
-
-typedef struct {
- u_int32_t state[5];
- u_int32_t count[2];
- unsigned char buffer[64];
-} SHA1_CTX;
-
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);
-void SHA1Init(SHA1_CTX* context);
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len);
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
-/* ================ end of sha1.h ================ */
-#include <endian.h>
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
- |(rol(block->l[i],8)&0x00FF00FF))
-#elif BYTE_ORDER == BIG_ENDIAN
-#define blk0(i) block->l[i]
-#else
-#error "Endianness not defined!"
-#endif
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
- ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
-{
-u_int32_t a, b, c, d, e;
-typedef union {
- unsigned char c[64];
- u_int32_t l[16];
-} CHAR64LONG16;
-#ifdef SHA1HANDSOFF
-CHAR64LONG16 block[1]; /* use array to appear as a pointer */
- memcpy(block, buffer, 64);
-#else
- /* The following had better never be used because it causes the
- * pointer-to-const buffer to be cast into a pointer to non-const.
- * And the result is written through. I threw a "const" in, hoping
- * this will cause a diagnostic.
- */
-CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
-#endif
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- /* Wipe variables */
- a = b = c = d = e = 0;
-#ifdef SHA1HANDSOFF
- memset(block, '\0', sizeof(block));
-#endif
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void SHA1Init(SHA1_CTX* context)
-{
- /* SHA1 initialization constants */
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
-}
-
-
-/* Run your data through this. */
-
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
-{
-u_int32_t i;
-u_int32_t j;
-
- j = context->count[0];
- if ((context->count[0] += len << 3) < j)
- context->count[1]++;
- context->count[1] += (len>>29);
- j = (j >> 3) & 63;
- if ((j + len) > 63) {
- memcpy(&context->buffer[j], data, (i = 64-j));
- SHA1Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64) {
- SHA1Transform(context->state, &data[i]);
- }
- j = 0;
- }
- else i = 0;
- memcpy(&context->buffer[j], &data[i], len - i);
-}
-
-
-/* Add padding and return the message digest. */
-
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
-{
-unsigned i;
-unsigned char finalcount[8];
-unsigned char c;
-
-#if 0 /* untested "improvement" by DHR */
- /* Convert context->count to a sequence of bytes
- * in finalcount. Second element first, but
- * big-endian order within element.
- * But we do it all backwards.
- */
- unsigned char *fcp = &finalcount[8];
-
- for (i = 0; i < 2; i++)
- {
- u_int32_t t = context->count[i];
- int j;
-
- for (j = 0; j < 4; t >>= 8, j++)
- *--fcp = (unsigned char) t
- }
-#else
- for (i = 0; i < 8; i++) {
- finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- }
-#endif
- c = 0200;
- SHA1Update(context, &c, 1);
- while ((context->count[0] & 504) != 448) {
- c = 0000;
- SHA1Update(context, &c, 1);
- }
- SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++) {
- digest[i] = (unsigned char)
- ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
- /* Wipe variables */
- memset(context, '\0', sizeof(*context));
- memset(&finalcount, '\0', sizeof(finalcount));
-}
-/* ================ end of sha1.c ================ */
-
-#define BUFSIZE 4096
-
-int
-main(int argc, char **argv)
-{
- SHA1_CTX ctx;
- unsigned char hash[20], buf[BUFSIZE];
- int i;
-
- for(i=0;i<BUFSIZE;i++)
- buf[i] = i;
-
- SHA1Init(&ctx);
- for(i=0;i<1000;i++)
- SHA1Update(&ctx, buf, BUFSIZE);
- SHA1Final(hash, &ctx);
-
- printf("SHA1=");
- for(i=0;i<20;i++)
- printf("%02x", hash[i]);
- printf("\n");
- return 0;
-}
-
-
diff --git a/tools/ioemu/tests/test-i386-code16.S b/tools/ioemu/tests/test-i386-code16.S
deleted file mode 100644
index e400e73fd9..0000000000
--- a/tools/ioemu/tests/test-i386-code16.S
+++ /dev/null
@@ -1,79 +0,0 @@
- .code16
- .globl code16_start
- .globl code16_end
-
-CS_SEG = 0xf
-
-code16_start:
-
- .globl code16_func1
-
- /* basic test */
-code16_func1 = . - code16_start
- mov $1, %eax
- data32 lret
-
-/* test push/pop in 16 bit mode */
- .globl code16_func2
-code16_func2 = . - code16_start
- xor %eax, %eax
- mov $0x12345678, %ebx
- movl %esp, %ecx
- push %bx
- subl %esp, %ecx
- pop %ax
- data32 lret
-
-/* test various jmp opcodes */
- .globl code16_func3
-code16_func3 = . - code16_start
- jmp 1f
- nop
-1:
- mov $4, %eax
- mov $0x12345678, %ebx
- xor %bx, %bx
- jz 2f
- add $2, %ax
-2:
-
- call myfunc
-
- lcall $CS_SEG, $(myfunc2 - code16_start)
-
- ljmp $CS_SEG, $(myjmp1 - code16_start)
-myjmp1_next:
-
- cs lcall myfunc2_addr - code16_start
-
- cs ljmp myjmp2_addr - code16_start
-myjmp2_next:
-
- data32 lret
-
-myfunc2_addr:
- .short myfunc2 - code16_start
- .short CS_SEG
-
-myjmp2_addr:
- .short myjmp2 - code16_start
- .short CS_SEG
-
-myjmp1:
- add $8, %ax
- jmp myjmp1_next
-
-myjmp2:
- add $16, %ax
- jmp myjmp2_next
-
-myfunc:
- add $1, %ax
- ret
-
-myfunc2:
- add $4, %ax
- lret
-
-
-code16_end:
diff --git a/tools/ioemu/tests/test-i386-muldiv.h b/tools/ioemu/tests/test-i386-muldiv.h
deleted file mode 100644
index fd0d991341..0000000000
--- a/tools/ioemu/tests/test-i386-muldiv.h
+++ /dev/null
@@ -1,76 +0,0 @@
-
-void glue(glue(test_, OP), b)(long op0, long op1)
-{
- long res, s1, s0, flags;
- s0 = op0;
- s1 = op1;
- res = s0;
- flags = 0;
- asm ("push %4\n\t"
- "popf\n\t"
- stringify(OP)"b %b2\n\t"
- "pushf\n\t"
- "pop %1\n\t"
- : "=a" (res), "=g" (flags)
- : "q" (s1), "0" (res), "1" (flags));
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
- stringify(OP) "b", s0, s1, res, flags & CC_MASK);
-}
-
-void glue(glue(test_, OP), w)(long op0h, long op0, long op1)
-{
- long res, s1, flags, resh;
- s1 = op1;
- resh = op0h;
- res = op0;
- flags = 0;
- asm ("push %5\n\t"
- "popf\n\t"
- stringify(OP) "w %w3\n\t"
- "pushf\n\t"
- "pop %1\n\t"
- : "=a" (res), "=g" (flags), "=d" (resh)
- : "q" (s1), "0" (res), "1" (flags), "2" (resh));
- printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
- stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK);
-}
-
-void glue(glue(test_, OP), l)(long op0h, long op0, long op1)
-{
- long res, s1, flags, resh;
- s1 = op1;
- resh = op0h;
- res = op0;
- flags = 0;
- asm ("push %5\n\t"
- "popf\n\t"
- stringify(OP) "l %k3\n\t"
- "pushf\n\t"
- "pop %1\n\t"
- : "=a" (res), "=g" (flags), "=d" (resh)
- : "q" (s1), "0" (res), "1" (flags), "2" (resh));
- printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
- stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK);
-}
-
-#if defined(__x86_64__)
-void glue(glue(test_, OP), q)(long op0h, long op0, long op1)
-{
- long res, s1, flags, resh;
- s1 = op1;
- resh = op0h;
- res = op0;
- flags = 0;
- asm ("push %5\n\t"
- "popf\n\t"
- stringify(OP) "q %3\n\t"
- "pushf\n\t"
- "pop %1\n\t"
- : "=a" (res), "=g" (flags), "=d" (resh)
- : "q" (s1), "0" (res), "1" (flags), "2" (resh));
- printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
- stringify(OP) "q", op0h, op0, s1, resh, res, flags & CC_MASK);
-}
-#endif
-
-#undef OP
diff --git a/tools/ioemu/tests/test-i386-shift.h b/tools/ioemu/tests/test-i386-shift.h
deleted file mode 100644
index c1ed489f11..0000000000
--- a/tools/ioemu/tests/test-i386-shift.h
+++ /dev/null
@@ -1,187 +0,0 @@
-
-#define exec_op glue(exec_, OP)
-#define exec_opq glue(glue(exec_, OP), q)
-#define exec_opl glue(glue(exec_, OP), l)
-#define exec_opw glue(glue(exec_, OP), w)
-#define exec_opb glue(glue(exec_, OP), b)
-
-#ifndef OP_SHIFTD
-
-#ifdef OP_NOBYTE
-#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
- asm ("push %4\n\t"\
- "popf\n\t"\
- stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
- "pushf\n\t"\
- "pop %1\n\t"\
- : "=g" (res), "=g" (flags)\
- : "r" (s1), "0" (res), "1" (flags));
-#else
-#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
- asm ("push %4\n\t"\
- "popf\n\t"\
- stringify(OP) size " %%cl, %" rsize "0\n\t" \
- "pushf\n\t"\
- "pop %1\n\t"\
- : "=q" (res), "=g" (flags)\
- : "c" (s1), "0" (res), "1" (flags));
-#endif
-
-#if defined(__x86_64__)
-void exec_opq(long s2, long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECSHIFT("q", "", res, s1, s2, flags);
- /* overflow is undefined if count != 1 */
- if (s1 != 1)
- flags &= ~CC_O;
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
- stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK);
-}
-#endif
-
-void exec_opl(long s2, long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECSHIFT("l", "k", res, s1, s2, flags);
- /* overflow is undefined if count != 1 */
- if (s1 != 1)
- flags &= ~CC_O;
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
- stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
-}
-
-void exec_opw(long s2, long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECSHIFT("w", "w", res, s1, s2, flags);
- /* overflow is undefined if count != 1 */
- if (s1 != 1)
- flags &= ~CC_O;
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
- stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
-}
-
-#else
-#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
- asm ("push %4\n\t"\
- "popf\n\t"\
- stringify(OP) size " %%cl, %" rsize "5, %" rsize "0\n\t" \
- "pushf\n\t"\
- "pop %1\n\t"\
- : "=g" (res), "=g" (flags)\
- : "c" (s1), "0" (res), "1" (flags), "r" (s2));
-
-#if defined(__x86_64__)
-void exec_opq(long s2, long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECSHIFT("q", "", res, s1, s2, flags);
- /* overflow is undefined if count != 1 */
- if (s1 != 1)
- flags &= ~CC_O;
- printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
- stringify(OP) "q", s0, s2, s1, res, iflags, flags & CC_MASK);
-}
-#endif
-
-void exec_opl(long s2, long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECSHIFT("l", "k", res, s1, s2, flags);
- /* overflow is undefined if count != 1 */
- if (s1 != 1)
- flags &= ~CC_O;
- printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
- stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
-}
-
-void exec_opw(long s2, long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECSHIFT("w", "w", res, s1, s2, flags);
- /* overflow is undefined if count != 1 */
- if (s1 != 1)
- flags &= ~CC_O;
- printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
- stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
-}
-
-#endif
-
-#ifndef OP_NOBYTE
-void exec_opb(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECSHIFT("b", "b", res, s1, 0, flags);
- /* overflow is undefined if count != 1 */
- if (s1 != 1)
- flags &= ~CC_O;
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
- stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
-}
-#endif
-
-void exec_op(long s2, long s0, long s1)
-{
- s2 = i2l(s2);
- s0 = i2l(s0);
-#if defined(__x86_64__)
- exec_opq(s2, s0, s1, 0);
-#endif
- exec_opl(s2, s0, s1, 0);
-#ifdef OP_SHIFTD
- if (s1 <= 15)
- exec_opw(s2, s0, s1, 0);
-#else
- exec_opw(s2, s0, s1, 0);
-#endif
-#ifndef OP_NOBYTE
- exec_opb(s0, s1, 0);
-#endif
-#ifdef OP_CC
-#if defined(__x86_64__)
- exec_opq(s2, s0, s1, CC_C);
-#endif
- exec_opl(s2, s0, s1, CC_C);
- exec_opw(s2, s0, s1, CC_C);
- exec_opb(s0, s1, CC_C);
-#endif
-}
-
-void glue(test_, OP)(void)
-{
- int i, n;
-#if defined(__x86_64__)
- n = 64;
-#else
- n = 32;
-#endif
- for(i = 0; i < n; i++)
- exec_op(0x21ad3d34, 0x12345678, i);
- for(i = 0; i < n; i++)
- exec_op(0x813f3421, 0x82345679, i);
-}
-
-void *glue(_test_, OP) __init_call = glue(test_, OP);
-
-#undef OP
-#undef OP_CC
-#undef OP_SHIFTD
-#undef OP_NOBYTE
-#undef EXECSHIFT
-
diff --git a/tools/ioemu/tests/test-i386-vm86.S b/tools/ioemu/tests/test-i386-vm86.S
deleted file mode 100644
index a972f1b81e..0000000000
--- a/tools/ioemu/tests/test-i386-vm86.S
+++ /dev/null
@@ -1,104 +0,0 @@
- .code16
- .globl vm86_code_start
- .globl vm86_code_end
-
-#define GET_OFFSET(x) ((x) - vm86_code_start + 0x100)
-
-vm86_code_start:
- movw $GET_OFFSET(hello_world), %dx
- movb $0x09, %ah
- int $0x21
-
- /* prepare int 0x90 vector */
- xorw %ax, %ax
- movw %ax, %es
- es movw $GET_OFFSET(int90_test), 0x90 * 4
- es movw %cs, 0x90 * 4 + 2
-
- /* launch int 0x90 */
-
- int $0x90
-
- /* test IF support */
- movw $GET_OFFSET(IF_msg), %dx
- movb $0x09, %ah
- int $0x21
-
- pushf
- popw %dx
- movb $0xff, %ah
- int $0x21
-
- cli
- pushf
- popw %dx
- movb $0xff, %ah
- int $0x21
-
- sti
- pushfl
- popl %edx
- movb $0xff, %ah
- int $0x21
-
-#if 0
- movw $GET_OFFSET(IF_msg1), %dx
- movb $0x09, %ah
- int $0x21
-
- pushf
- movw %sp, %bx
- andw $~0x200, (%bx)
- popf
-#else
- cli
-#endif
-
- pushf
- popw %dx
- movb $0xff, %ah
- int $0x21
-
- pushfl
- movw %sp, %bx
- orw $0x200, (%bx)
- popfl
-
- pushfl
- popl %edx
- movb $0xff, %ah
- int $0x21
-
- movb $0x00, %ah
- int $0x21
-
-int90_test:
- pushf
- pop %dx
- movb $0xff, %ah
- int $0x21
-
- movw %sp, %bx
- movw 4(%bx), %dx
- movb $0xff, %ah
- int $0x21
-
- movw $GET_OFFSET(int90_msg), %dx
- movb $0x09, %ah
- int $0x21
- iret
-
-int90_msg:
- .string "INT90 started\n$"
-
-hello_world:
- .string "Hello VM86 world\n$"
-
-IF_msg:
- .string "VM86 IF test\n$"
-
-IF_msg1:
- .string "If you see a diff here, your Linux kernel is buggy, please update to 2.4.20 kernel\n$"
-
-vm86_code_end:
- \ No newline at end of file
diff --git a/tools/ioemu/tests/test-i386.c b/tools/ioemu/tests/test-i386.c
deleted file mode 100644
index 267391575a..0000000000
--- a/tools/ioemu/tests/test-i386.c
+++ /dev/null
@@ -1,2665 +0,0 @@
-/*
- * x86 CPU test
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <math.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <errno.h>
-#include <sys/ucontext.h>
-#include <sys/mman.h>
-
-#if !defined(__x86_64__)
-#define TEST_VM86
-#define TEST_SEGS
-#endif
-//#define LINUX_VM86_IOPL_FIX
-//#define TEST_P4_FLAGS
-#if defined(__x86_64__)
-#define TEST_SSE
-#define TEST_CMOV 1
-#define TEST_FCOMI 1
-#else
-//#define TEST_SSE
-#define TEST_CMOV 0
-#define TEST_FCOMI 0
-#endif
-
-#if defined(__x86_64__)
-#define FMT64X "%016lx"
-#define FMTLX "%016lx"
-#define X86_64_ONLY(x) x
-#else
-#define FMT64X "%016" PRIx64
-#define FMTLX "%08lx"
-#define X86_64_ONLY(x)
-#endif
-
-#ifdef TEST_VM86
-#include <asm/vm86.h>
-#endif
-
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-
-#define CC_C 0x0001
-#define CC_P 0x0004
-#define CC_A 0x0010
-#define CC_Z 0x0040
-#define CC_S 0x0080
-#define CC_O 0x0800
-
-#define __init_call __attribute__ ((unused,__section__ ("initcall")))
-
-#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
-
-#if defined(__x86_64__)
-static inline long i2l(long v)
-{
- return v | ((v ^ 0xabcd) << 32);
-}
-#else
-static inline long i2l(long v)
-{
- return v;
-}
-#endif
-
-#define OP add
-#include "test-i386.h"
-
-#define OP sub
-#include "test-i386.h"
-
-#define OP xor
-#include "test-i386.h"
-
-#define OP and
-#include "test-i386.h"
-
-#define OP or
-#include "test-i386.h"
-
-#define OP cmp
-#include "test-i386.h"
-
-#define OP adc
-#define OP_CC
-#include "test-i386.h"
-
-#define OP sbb
-#define OP_CC
-#include "test-i386.h"
-
-#define OP inc
-#define OP_CC
-#define OP1
-#include "test-i386.h"
-
-#define OP dec
-#define OP_CC
-#define OP1
-#include "test-i386.h"
-
-#define OP neg
-#define OP_CC
-#define OP1
-#include "test-i386.h"
-
-#define OP not
-#define OP_CC
-#define OP1
-#include "test-i386.h"
-
-#undef CC_MASK
-#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
-
-#define OP shl
-#include "test-i386-shift.h"
-
-#define OP shr
-#include "test-i386-shift.h"
-
-#define OP sar
-#include "test-i386-shift.h"
-
-#define OP rol
-#include "test-i386-shift.h"
-
-#define OP ror
-#include "test-i386-shift.h"
-
-#define OP rcr
-#define OP_CC
-#include "test-i386-shift.h"
-
-#define OP rcl
-#define OP_CC
-#include "test-i386-shift.h"
-
-#define OP shld
-#define OP_SHIFTD
-#define OP_NOBYTE
-#include "test-i386-shift.h"
-
-#define OP shrd
-#define OP_SHIFTD
-#define OP_NOBYTE
-#include "test-i386-shift.h"
-
-/* XXX: should be more precise ? */
-#undef CC_MASK
-#define CC_MASK (CC_C)
-
-#define OP bt
-#define OP_NOBYTE
-#include "test-i386-shift.h"
-
-#define OP bts
-#define OP_NOBYTE
-#include "test-i386-shift.h"
-
-#define OP btr
-#define OP_NOBYTE
-#include "test-i386-shift.h"
-
-#define OP btc
-#define OP_NOBYTE
-#include "test-i386-shift.h"
-
-/* lea test (modrm support) */
-#define TEST_LEAQ(STR)\
-{\
- asm("lea " STR ", %0"\
- : "=r" (res)\
- : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
- printf("lea %s = " FMTLX "\n", STR, res);\
-}
-
-#define TEST_LEA(STR)\
-{\
- asm("lea " STR ", %0"\
- : "=r" (res)\
- : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
- printf("lea %s = " FMTLX "\n", STR, res);\
-}
-
-#define TEST_LEA16(STR)\
-{\
- asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
- : "=wq" (res)\
- : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
- printf("lea %s = %08lx\n", STR, res);\
-}
-
-
-void test_lea(void)
-{
- long eax, ebx, ecx, edx, esi, edi, res;
- eax = i2l(0x0001);
- ebx = i2l(0x0002);
- ecx = i2l(0x0004);
- edx = i2l(0x0008);
- esi = i2l(0x0010);
- edi = i2l(0x0020);
-
- TEST_LEA("0x4000");
-
- TEST_LEA("(%%eax)");
- TEST_LEA("(%%ebx)");
- TEST_LEA("(%%ecx)");
- TEST_LEA("(%%edx)");
- TEST_LEA("(%%esi)");
- TEST_LEA("(%%edi)");
-
- TEST_LEA("0x40(%%eax)");
- TEST_LEA("0x40(%%ebx)");
- TEST_LEA("0x40(%%ecx)");
- TEST_LEA("0x40(%%edx)");
- TEST_LEA("0x40(%%esi)");
- TEST_LEA("0x40(%%edi)");
-
- TEST_LEA("0x4000(%%eax)");
- TEST_LEA("0x4000(%%ebx)");
- TEST_LEA("0x4000(%%ecx)");
- TEST_LEA("0x4000(%%edx)");
- TEST_LEA("0x4000(%%esi)");
- TEST_LEA("0x4000(%%edi)");
-
- TEST_LEA("(%%eax, %%ecx)");
- TEST_LEA("(%%ebx, %%edx)");
- TEST_LEA("(%%ecx, %%ecx)");
- TEST_LEA("(%%edx, %%ecx)");
- TEST_LEA("(%%esi, %%ecx)");
- TEST_LEA("(%%edi, %%ecx)");
-
- TEST_LEA("0x40(%%eax, %%ecx)");
- TEST_LEA("0x4000(%%ebx, %%edx)");
-
- TEST_LEA("(%%ecx, %%ecx, 2)");
- TEST_LEA("(%%edx, %%ecx, 4)");
- TEST_LEA("(%%esi, %%ecx, 8)");
-
- TEST_LEA("(,%%eax, 2)");
- TEST_LEA("(,%%ebx, 4)");
- TEST_LEA("(,%%ecx, 8)");
-
- TEST_LEA("0x40(,%%eax, 2)");
- TEST_LEA("0x40(,%%ebx, 4)");
- TEST_LEA("0x40(,%%ecx, 8)");
-
-
- TEST_LEA("-10(%%ecx, %%ecx, 2)");
- TEST_LEA("-10(%%edx, %%ecx, 4)");
- TEST_LEA("-10(%%esi, %%ecx, 8)");
-
- TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
- TEST_LEA("0x4000(%%edx, %%ecx, 4)");
- TEST_LEA("0x4000(%%esi, %%ecx, 8)");
-
-#if defined(__x86_64__)
- TEST_LEAQ("0x4000");
- TEST_LEAQ("0x4000(%%rip)");
-
- TEST_LEAQ("(%%rax)");
- TEST_LEAQ("(%%rbx)");
- TEST_LEAQ("(%%rcx)");
- TEST_LEAQ("(%%rdx)");
- TEST_LEAQ("(%%rsi)");
- TEST_LEAQ("(%%rdi)");
-
- TEST_LEAQ("0x40(%%rax)");
- TEST_LEAQ("0x40(%%rbx)");
- TEST_LEAQ("0x40(%%rcx)");
- TEST_LEAQ("0x40(%%rdx)");
- TEST_LEAQ("0x40(%%rsi)");
- TEST_LEAQ("0x40(%%rdi)");
-
- TEST_LEAQ("0x4000(%%rax)");
- TEST_LEAQ("0x4000(%%rbx)");
- TEST_LEAQ("0x4000(%%rcx)");
- TEST_LEAQ("0x4000(%%rdx)");
- TEST_LEAQ("0x4000(%%rsi)");
- TEST_LEAQ("0x4000(%%rdi)");
-
- TEST_LEAQ("(%%rax, %%rcx)");
- TEST_LEAQ("(%%rbx, %%rdx)");
- TEST_LEAQ("(%%rcx, %%rcx)");
- TEST_LEAQ("(%%rdx, %%rcx)");
- TEST_LEAQ("(%%rsi, %%rcx)");
- TEST_LEAQ("(%%rdi, %%rcx)");
-
- TEST_LEAQ("0x40(%%rax, %%rcx)");
- TEST_LEAQ("0x4000(%%rbx, %%rdx)");
-
- TEST_LEAQ("(%%rcx, %%rcx, 2)");
- TEST_LEAQ("(%%rdx, %%rcx, 4)");
- TEST_LEAQ("(%%rsi, %%rcx, 8)");
-
- TEST_LEAQ("(,%%rax, 2)");
- TEST_LEAQ("(,%%rbx, 4)");
- TEST_LEAQ("(,%%rcx, 8)");
-
- TEST_LEAQ("0x40(,%%rax, 2)");
- TEST_LEAQ("0x40(,%%rbx, 4)");
- TEST_LEAQ("0x40(,%%rcx, 8)");
-
-
- TEST_LEAQ("-10(%%rcx, %%rcx, 2)");
- TEST_LEAQ("-10(%%rdx, %%rcx, 4)");
- TEST_LEAQ("-10(%%rsi, %%rcx, 8)");
-
- TEST_LEAQ("0x4000(%%rcx, %%rcx, 2)");
- TEST_LEAQ("0x4000(%%rdx, %%rcx, 4)");
- TEST_LEAQ("0x4000(%%rsi, %%rcx, 8)");
-#else
- /* limited 16 bit addressing test */
- TEST_LEA16("0x4000");
- TEST_LEA16("(%%bx)");
- TEST_LEA16("(%%si)");
- TEST_LEA16("(%%di)");
- TEST_LEA16("0x40(%%bx)");
- TEST_LEA16("0x40(%%si)");
- TEST_LEA16("0x40(%%di)");
- TEST_LEA16("0x4000(%%bx)");
- TEST_LEA16("0x4000(%%si)");
- TEST_LEA16("(%%bx,%%si)");
- TEST_LEA16("(%%bx,%%di)");
- TEST_LEA16("0x40(%%bx,%%si)");
- TEST_LEA16("0x40(%%bx,%%di)");
- TEST_LEA16("0x4000(%%bx,%%si)");
- TEST_LEA16("0x4000(%%bx,%%di)");
-#endif
-}
-
-#define TEST_JCC(JCC, v1, v2)\
-{\
- int res;\
- asm("movl $1, %0\n\t"\
- "cmpl %2, %1\n\t"\
- "j" JCC " 1f\n\t"\
- "movl $0, %0\n\t"\
- "1:\n\t"\
- : "=r" (res)\
- : "r" (v1), "r" (v2));\
- printf("%-10s %d\n", "j" JCC, res);\
-\
- asm("movl $0, %0\n\t"\
- "cmpl %2, %1\n\t"\
- "set" JCC " %b0\n\t"\
- : "=r" (res)\
- : "r" (v1), "r" (v2));\
- printf("%-10s %d\n", "set" JCC, res);\
- if (TEST_CMOV) {\
- long val = i2l(1);\
- long res = i2l(0x12345678);\
-X86_64_ONLY(\
- asm("cmpl %2, %1\n\t"\
- "cmov" JCC "q %3, %0\n\t"\
- : "=r" (res)\
- : "r" (v1), "r" (v2), "m" (val), "0" (res));\
- printf("%-10s R=" FMTLX "\n", "cmov" JCC "q", res);)\
- asm("cmpl %2, %1\n\t"\
- "cmov" JCC "l %k3, %k0\n\t"\
- : "=r" (res)\
- : "r" (v1), "r" (v2), "m" (val), "0" (res));\
- printf("%-10s R=" FMTLX "\n", "cmov" JCC "l", res);\
- asm("cmpl %2, %1\n\t"\
- "cmov" JCC "w %w3, %w0\n\t"\
- : "=r" (res)\
- : "r" (v1), "r" (v2), "r" (1), "0" (res));\
- printf("%-10s R=" FMTLX "\n", "cmov" JCC "w", res);\
- } \
-}
-
-/* various jump tests */
-void test_jcc(void)
-{
- TEST_JCC("ne", 1, 1);
- TEST_JCC("ne", 1, 0);
-
- TEST_JCC("e", 1, 1);
- TEST_JCC("e", 1, 0);
-
- TEST_JCC("l", 1, 1);
- TEST_JCC("l", 1, 0);
- TEST_JCC("l", 1, -1);
-
- TEST_JCC("le", 1, 1);
- TEST_JCC("le", 1, 0);
- TEST_JCC("le", 1, -1);
-
- TEST_JCC("ge", 1, 1);
- TEST_JCC("ge", 1, 0);
- TEST_JCC("ge", -1, 1);
-
- TEST_JCC("g", 1, 1);
- TEST_JCC("g", 1, 0);
- TEST_JCC("g", 1, -1);
-
- TEST_JCC("b", 1, 1);
- TEST_JCC("b", 1, 0);
- TEST_JCC("b", 1, -1);
-
- TEST_JCC("be", 1, 1);
- TEST_JCC("be", 1, 0);
- TEST_JCC("be", 1, -1);
-
- TEST_JCC("ae", 1, 1);
- TEST_JCC("ae", 1, 0);
- TEST_JCC("ae", 1, -1);
-
- TEST_JCC("a", 1, 1);
- TEST_JCC("a", 1, 0);
- TEST_JCC("a", 1, -1);
-
-
- TEST_JCC("p", 1, 1);
- TEST_JCC("p", 1, 0);
-
- TEST_JCC("np", 1, 1);
- TEST_JCC("np", 1, 0);
-
- TEST_JCC("o", 0x7fffffff, 0);
- TEST_JCC("o", 0x7fffffff, -1);
-
- TEST_JCC("no", 0x7fffffff, 0);
- TEST_JCC("no", 0x7fffffff, -1);
-
- TEST_JCC("s", 0, 1);
- TEST_JCC("s", 0, -1);
- TEST_JCC("s", 0, 0);
-
- TEST_JCC("ns", 0, 1);
- TEST_JCC("ns", 0, -1);
- TEST_JCC("ns", 0, 0);
-}
-
-#undef CC_MASK
-#ifdef TEST_P4_FLAGS
-#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
-#else
-#define CC_MASK (CC_O | CC_C)
-#endif
-
-#define OP mul
-#include "test-i386-muldiv.h"
-
-#define OP imul
-#include "test-i386-muldiv.h"
-
-void test_imulw2(long op0, long op1)
-{
- long res, s1, s0, flags;
- s0 = op0;
- s1 = op1;
- res = s0;
- flags = 0;
- asm volatile ("push %4\n\t"
- "popf\n\t"
- "imulw %w2, %w0\n\t"
- "pushf\n\t"
- "pop %1\n\t"
- : "=q" (res), "=g" (flags)
- : "q" (s1), "0" (res), "1" (flags));
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
- "imulw", s0, s1, res, flags & CC_MASK);
-}
-
-void test_imull2(long op0, long op1)
-{
- long res, s1, s0, flags;
- s0 = op0;
- s1 = op1;
- res = s0;
- flags = 0;
- asm volatile ("push %4\n\t"
- "popf\n\t"
- "imull %k2, %k0\n\t"
- "pushf\n\t"
- "pop %1\n\t"
- : "=q" (res), "=g" (flags)
- : "q" (s1), "0" (res), "1" (flags));
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
- "imull", s0, s1, res, flags & CC_MASK);
-}
-
-#if defined(__x86_64__)
-void test_imulq2(long op0, long op1)
-{
- long res, s1, s0, flags;
- s0 = op0;
- s1 = op1;
- res = s0;
- flags = 0;
- asm volatile ("push %4\n\t"
- "popf\n\t"
- "imulq %2, %0\n\t"
- "pushf\n\t"
- "pop %1\n\t"
- : "=q" (res), "=g" (flags)
- : "q" (s1), "0" (res), "1" (flags));
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
- "imulq", s0, s1, res, flags & CC_MASK);
-}
-#endif
-
-#define TEST_IMUL_IM(size, rsize, op0, op1)\
-{\
- long res, flags, s1;\
- flags = 0;\
- res = 0;\
- s1 = op1;\
- asm volatile ("push %3\n\t"\
- "popf\n\t"\
- "imul" size " $" #op0 ", %" rsize "2, %" rsize "0\n\t" \
- "pushf\n\t"\
- "pop %1\n\t"\
- : "=r" (res), "=g" (flags)\
- : "r" (s1), "1" (flags), "0" (res));\
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",\
- "imul" size " im", (long)op0, (long)op1, res, flags & CC_MASK);\
-}
-
-
-#undef CC_MASK
-#define CC_MASK (0)
-
-#define OP div
-#include "test-i386-muldiv.h"
-
-#define OP idiv
-#include "test-i386-muldiv.h"
-
-void test_mul(void)
-{
- test_imulb(0x1234561d, 4);
- test_imulb(3, -4);
- test_imulb(0x80, 0x80);
- test_imulb(0x10, 0x10);
-
- test_imulw(0, 0x1234001d, 45);
- test_imulw(0, 23, -45);
- test_imulw(0, 0x8000, 0x8000);
- test_imulw(0, 0x100, 0x100);
-
- test_imull(0, 0x1234001d, 45);
- test_imull(0, 23, -45);
- test_imull(0, 0x80000000, 0x80000000);
- test_imull(0, 0x10000, 0x10000);
-
- test_mulb(0x1234561d, 4);
- test_mulb(3, -4);
- test_mulb(0x80, 0x80);
- test_mulb(0x10, 0x10);
-
- test_mulw(0, 0x1234001d, 45);
- test_mulw(0, 23, -45);
- test_mulw(0, 0x8000, 0x8000);
- test_mulw(0, 0x100, 0x100);
-
- test_mull(0, 0x1234001d, 45);
- test_mull(0, 23, -45);
- test_mull(0, 0x80000000, 0x80000000);
- test_mull(0, 0x10000, 0x10000);
-
- test_imulw2(0x1234001d, 45);
- test_imulw2(23, -45);
- test_imulw2(0x8000, 0x8000);
- test_imulw2(0x100, 0x100);
-
- test_imull2(0x1234001d, 45);
- test_imull2(23, -45);
- test_imull2(0x80000000, 0x80000000);
- test_imull2(0x10000, 0x10000);
-
- TEST_IMUL_IM("w", "w", 45, 0x1234);
- TEST_IMUL_IM("w", "w", -45, 23);
- TEST_IMUL_IM("w", "w", 0x8000, 0x80000000);
- TEST_IMUL_IM("w", "w", 0x7fff, 0x1000);
-
- TEST_IMUL_IM("l", "k", 45, 0x1234);
- TEST_IMUL_IM("l", "k", -45, 23);
- TEST_IMUL_IM("l", "k", 0x8000, 0x80000000);
- TEST_IMUL_IM("l", "k", 0x7fff, 0x1000);
-
- test_idivb(0x12341678, 0x127e);
- test_idivb(0x43210123, -5);
- test_idivb(0x12340004, -1);
-
- test_idivw(0, 0x12345678, 12347);
- test_idivw(0, -23223, -45);
- test_idivw(0, 0x12348000, -1);
- test_idivw(0x12343, 0x12345678, 0x81238567);
-
- test_idivl(0, 0x12345678, 12347);
- test_idivl(0, -233223, -45);
- test_idivl(0, 0x80000000, -1);
- test_idivl(0x12343, 0x12345678, 0x81234567);
-
- test_divb(0x12341678, 0x127e);
- test_divb(0x43210123, -5);
- test_divb(0x12340004, -1);
-
- test_divw(0, 0x12345678, 12347);
- test_divw(0, -23223, -45);
- test_divw(0, 0x12348000, -1);
- test_divw(0x12343, 0x12345678, 0x81238567);
-
- test_divl(0, 0x12345678, 12347);
- test_divl(0, -233223, -45);
- test_divl(0, 0x80000000, -1);
- test_divl(0x12343, 0x12345678, 0x81234567);
-
-#if defined(__x86_64__)
- test_imulq(0, 0x1234001d1234001d, 45);
- test_imulq(0, 23, -45);
- test_imulq(0, 0x8000000000000000, 0x8000000000000000);
- test_imulq(0, 0x100000000, 0x100000000);
-
- test_mulq(0, 0x1234001d1234001d, 45);
- test_mulq(0, 23, -45);
- test_mulq(0, 0x8000000000000000, 0x8000000000000000);
- test_mulq(0, 0x100000000, 0x100000000);
-
- test_imulq2(0x1234001d1234001d, 45);
- test_imulq2(23, -45);
- test_imulq2(0x8000000000000000, 0x8000000000000000);
- test_imulq2(0x100000000, 0x100000000);
-
- TEST_IMUL_IM("q", "", 45, 0x12341234);
- TEST_IMUL_IM("q", "", -45, 23);
- TEST_IMUL_IM("q", "", 0x8000, 0x8000000000000000);
- TEST_IMUL_IM("q", "", 0x7fff, 0x10000000);
-
- test_idivq(0, 0x12345678abcdef, 12347);
- test_idivq(0, -233223, -45);
- test_idivq(0, 0x8000000000000000, -1);
- test_idivq(0x12343, 0x12345678, 0x81234567);
-
- test_divq(0, 0x12345678abcdef, 12347);
- test_divq(0, -233223, -45);
- test_divq(0, 0x8000000000000000, -1);
- test_divq(0x12343, 0x12345678, 0x81234567);
-#endif
-}
-
-#define TEST_BSX(op, size, op0)\
-{\
- long res, val, resz;\
- val = op0;\
- asm("xor %1, %1\n"\
- "mov $0x12345678, %0\n"\
- #op " %" size "2, %" size "0 ; setz %b1" \
- : "=r" (res), "=q" (resz)\
- : "g" (val));\
- printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\
-}
-
-void test_bsx(void)
-{
- TEST_BSX(bsrw, "w", 0);
- TEST_BSX(bsrw, "w", 0x12340128);
- TEST_BSX(bsfw, "w", 0);
- TEST_BSX(bsfw, "w", 0x12340128);
- TEST_BSX(bsrl, "k", 0);
- TEST_BSX(bsrl, "k", 0x00340128);
- TEST_BSX(bsfl, "k", 0);
- TEST_BSX(bsfl, "k", 0x00340128);
-#if defined(__x86_64__)
- TEST_BSX(bsrq, "", 0);
- TEST_BSX(bsrq, "", 0x003401281234);
- TEST_BSX(bsfq, "", 0);
- TEST_BSX(bsfq, "", 0x003401281234);
-#endif
-}
-
-/**********************************************/
-
-union float64u {
- double d;
- uint64_t l;
-};
-
-union float64u q_nan = { .l = 0xFFF8000000000000 };
-union float64u s_nan = { .l = 0xFFF0000000000000 };
-
-void test_fops(double a, double b)
-{
- printf("a=%f b=%f a+b=%f\n", a, b, a + b);
- printf("a=%f b=%f a-b=%f\n", a, b, a - b);
- printf("a=%f b=%f a*b=%f\n", a, b, a * b);
- printf("a=%f b=%f a/b=%f\n", a, b, a / b);
- printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
- printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
- printf("a=%f sin(a)=%f\n", a, sin(a));
- printf("a=%f cos(a)=%f\n", a, cos(a));
- printf("a=%f tan(a)=%f\n", a, tan(a));
- printf("a=%f log(a)=%f\n", a, log(a));
- printf("a=%f exp(a)=%f\n", a, exp(a));
- printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
- /* just to test some op combining */
- printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
- printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
- printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
-
-}
-
-void fpu_clear_exceptions(void)
-{
- struct __attribute__((packed)) {
- uint16_t fpuc;
- uint16_t dummy1;
- uint16_t fpus;
- uint16_t dummy2;
- uint16_t fptag;
- uint16_t dummy3;
- uint32_t ignored[4];
- long double fpregs[8];
- } float_env32;
-
- asm volatile ("fnstenv %0\n" : : "m" (float_env32));
- float_env32.fpus &= ~0x7f;
- asm volatile ("fldenv %0\n" : : "m" (float_env32));
-}
-
-/* XXX: display exception bits when supported */
-#define FPUS_EMASK 0x0000
-//#define FPUS_EMASK 0x007f
-
-void test_fcmp(double a, double b)
-{
- long eflags, fpus;
-
- fpu_clear_exceptions();
- asm("fcom %2\n"
- "fstsw %%ax\n"
- : "=a" (fpus)
- : "t" (a), "u" (b));
- printf("fcom(%f %f)=%04lx \n",
- a, b, fpus & (0x4500 | FPUS_EMASK));
- fpu_clear_exceptions();
- asm("fucom %2\n"
- "fstsw %%ax\n"
- : "=a" (fpus)
- : "t" (a), "u" (b));
- printf("fucom(%f %f)=%04lx\n",
- a, b, fpus & (0x4500 | FPUS_EMASK));
- if (TEST_FCOMI) {
- /* test f(u)comi instruction */
- fpu_clear_exceptions();
- asm("fcomi %3, %2\n"
- "fstsw %%ax\n"
- "pushf\n"
- "pop %0\n"
- : "=r" (eflags), "=a" (fpus)
- : "t" (a), "u" (b));
- printf("fcomi(%f %f)=%04lx %02lx\n",
- a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
- fpu_clear_exceptions();
- asm("fucomi %3, %2\n"
- "fstsw %%ax\n"
- "pushf\n"
- "pop %0\n"
- : "=r" (eflags), "=a" (fpus)
- : "t" (a), "u" (b));
- printf("fucomi(%f %f)=%04lx %02lx\n",
- a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
- }
- fpu_clear_exceptions();
- asm volatile("fxam\n"
- "fstsw %%ax\n"
- : "=a" (fpus)
- : "t" (a));
- printf("fxam(%f)=%04lx\n", a, fpus & 0x4700);
- fpu_clear_exceptions();
-}
-
-void test_fcvt(double a)
-{
- float fa;
- long double la;
- int16_t fpuc;
- int i;
- int64_t lla;
- int ia;
- int16_t wa;
- double ra;
-
- fa = a;
- la = a;
- printf("(float)%f = %f\n", a, fa);
- printf("(long double)%f = %Lf\n", a, la);
- printf("a=" FMT64X "\n", *(uint64_t *)&a);
- printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
- *(unsigned short *)((char *)(&la) + 8));
-
- /* test all roundings */
- asm volatile ("fstcw %0" : "=m" (fpuc));
- for(i=0;i<4;i++) {
- asm volatile ("fldcw %0" : : "m" ((fpuc & ~0x0c00) | (i << 10)));
- asm volatile ("fist %0" : "=m" (wa) : "t" (a));
- asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
- asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
- asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
- asm volatile ("fldcw %0" : : "m" (fpuc));
- printf("(short)a = %d\n", wa);
- printf("(int)a = %d\n", ia);
- printf("(int64_t)a = " FMT64X "\n", lla);
- printf("rint(a) = %f\n", ra);
- }
-}
-
-#define TEST(N) \
- asm("fld" #N : "=t" (a)); \
- printf("fld" #N "= %f\n", a);
-
-void test_fconst(void)
-{
- double a;
- TEST(1);
- TEST(l2t);
- TEST(l2e);
- TEST(pi);
- TEST(lg2);
- TEST(ln2);
- TEST(z);
-}
-
-void test_fbcd(double a)
-{
- unsigned short bcd[5];
- double b;
-
- asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
- asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
- printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
- a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
-}
-
-#define TEST_ENV(env, save, restore)\
-{\
- memset((env), 0xaa, sizeof(*(env)));\
- for(i=0;i<5;i++)\
- asm volatile ("fldl %0" : : "m" (dtab[i]));\
- asm volatile (save " %0\n" : : "m" (*(env)));\
- asm volatile (restore " %0\n": : "m" (*(env)));\
- for(i=0;i<5;i++)\
- asm volatile ("fstpl %0" : "=m" (rtab[i]));\
- for(i=0;i<5;i++)\
- printf("res[%d]=%f\n", i, rtab[i]);\
- printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
- (env)->fpuc,\
- (env)->fpus & 0xff00,\
- (env)->fptag);\
-}
-
-void test_fenv(void)
-{
- struct __attribute__((packed)) {
- uint16_t fpuc;
- uint16_t dummy1;
- uint16_t fpus;
- uint16_t dummy2;
- uint16_t fptag;
- uint16_t dummy3;
- uint32_t ignored[4];
- long double fpregs[8];
- } float_env32;
- struct __attribute__((packed)) {
- uint16_t fpuc;
- uint16_t fpus;
- uint16_t fptag;
- uint16_t ignored[4];
- long double fpregs[8];
- } float_env16;
- double dtab[8];
- double rtab[8];
- int i;
-
- for(i=0;i<8;i++)
- dtab[i] = i + 1;
-
- TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
- TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
- TEST_ENV(&float_env32, "fnstenv", "fldenv");
- TEST_ENV(&float_env32, "fnsave", "frstor");
-
- /* test for ffree */
- for(i=0;i<5;i++)
- asm volatile ("fldl %0" : : "m" (dtab[i]));
- asm volatile("ffree %st(2)");
- asm volatile ("fnstenv %0\n" : : "m" (float_env32));
- asm volatile ("fninit");
- printf("fptag=%04x\n", float_env32.fptag);
-}
-
-
-#define TEST_FCMOV(a, b, eflags, CC)\
-{\
- double res;\
- asm("push %3\n"\
- "popf\n"\
- "fcmov" CC " %2, %0\n"\
- : "=t" (res)\
- : "0" (a), "u" (b), "g" (eflags));\
- printf("fcmov%s eflags=0x%04lx-> %f\n", \
- CC, (long)eflags, res);\
-}
-
-void test_fcmov(void)
-{
- double a, b;
- long eflags, i;
-
- a = 1.0;
- b = 2.0;
- for(i = 0; i < 4; i++) {
- eflags = 0;
- if (i & 1)
- eflags |= CC_C;
- if (i & 2)
- eflags |= CC_Z;
- TEST_FCMOV(a, b, eflags, "b");
- TEST_FCMOV(a, b, eflags, "e");
- TEST_FCMOV(a, b, eflags, "be");
- TEST_FCMOV(a, b, eflags, "nb");
- TEST_FCMOV(a, b, eflags, "ne");
- TEST_FCMOV(a, b, eflags, "nbe");
- }
- TEST_FCMOV(a, b, 0, "u");
- TEST_FCMOV(a, b, CC_P, "u");
- TEST_FCMOV(a, b, 0, "nu");
- TEST_FCMOV(a, b, CC_P, "nu");
-}
-
-void test_floats(void)
-{
- test_fops(2, 3);
- test_fops(1.4, -5);
- test_fcmp(2, -1);
- test_fcmp(2, 2);
- test_fcmp(2, 3);
- test_fcmp(2, q_nan.d);
- test_fcmp(q_nan.d, -1);
- test_fcmp(-1.0/0.0, -1);
- test_fcmp(1.0/0.0, -1);
- test_fcvt(0.5);
- test_fcvt(-0.5);
- test_fcvt(1.0/7.0);
- test_fcvt(-1.0/9.0);
- test_fcvt(32768);
- test_fcvt(-1e20);
- test_fcvt(-1.0/0.0);
- test_fcvt(1.0/0.0);
- test_fcvt(q_nan.d);
- test_fconst();
- test_fbcd(1234567890123456);
- test_fbcd(-123451234567890);
- test_fenv();
- if (TEST_CMOV) {
- test_fcmov();
- }
-}
-
-/**********************************************/
-#if !defined(__x86_64__)
-
-#define TEST_BCD(op, op0, cc_in, cc_mask)\
-{\
- int res, flags;\
- res = op0;\
- flags = cc_in;\
- asm ("push %3\n\t"\
- "popf\n\t"\
- #op "\n\t"\
- "pushf\n\t"\
- "pop %1\n\t"\
- : "=a" (res), "=g" (flags)\
- : "0" (res), "1" (flags));\
- printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
- #op, op0, res, cc_in, flags & cc_mask);\
-}
-
-void test_bcd(void)
-{
- TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
-
- TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
- TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
-
- TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
- TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
- TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
- TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
- TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
- TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
- TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
- TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
-
- TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
- TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
- TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
- TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
- TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
- TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
- TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
- TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
-
- TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
- TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
-}
-#endif
-
-#define TEST_XCHG(op, size, opconst)\
-{\
- long op0, op1;\
- op0 = i2l(0x12345678);\
- op1 = i2l(0xfbca7654);\
- asm(#op " %" size "0, %" size "1" \
- : "=q" (op0), opconst (op1) \
- : "0" (op0), "1" (op1));\
- printf("%-10s A=" FMTLX " B=" FMTLX "\n",\
- #op, op0, op1);\
-}
-
-#define TEST_CMPXCHG(op, size, opconst, eax)\
-{\
- long op0, op1, op2;\
- op0 = i2l(0x12345678);\
- op1 = i2l(0xfbca7654);\
- op2 = i2l(eax);\
- asm(#op " %" size "0, %" size "1" \
- : "=q" (op0), opconst (op1) \
- : "0" (op0), "1" (op1), "a" (op2));\
- printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\
- #op, op2, op0, op1);\
-}
-
-void test_xchg(void)
-{
-#if defined(__x86_64__)
- TEST_XCHG(xchgq, "", "=q");
-#endif
- TEST_XCHG(xchgl, "k", "=q");
- TEST_XCHG(xchgw, "w", "=q");
- TEST_XCHG(xchgb, "b", "=q");
-
-#if defined(__x86_64__)
- TEST_XCHG(xchgq, "", "=m");
-#endif
- TEST_XCHG(xchgl, "k", "=m");
- TEST_XCHG(xchgw, "w", "=m");
- TEST_XCHG(xchgb, "b", "=m");
-
-#if defined(__x86_64__)
- TEST_XCHG(xaddq, "", "=q");
-#endif
- TEST_XCHG(xaddl, "k", "=q");
- TEST_XCHG(xaddw, "w", "=q");
- TEST_XCHG(xaddb, "b", "=q");
-
- {
- int res;
- res = 0x12345678;
- asm("xaddl %1, %0" : "=r" (res) : "0" (res));
- printf("xaddl same res=%08x\n", res);
- }
-
-#if defined(__x86_64__)
- TEST_XCHG(xaddq, "", "=m");
-#endif
- TEST_XCHG(xaddl, "k", "=m");
- TEST_XCHG(xaddw, "w", "=m");
- TEST_XCHG(xaddb, "b", "=m");
-
-#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfbca7654);
-#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
-
-#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfffefdfc);
-#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
-
-#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfbca7654);
-#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
- TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
-
-#if defined(__x86_64__)
- TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfffefdfc);
-#endif
- TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
- TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
-
- {
- uint64_t op0, op1, op2;
- long i, eflags;
-
- for(i = 0; i < 2; i++) {
- op0 = 0x123456789abcd;
- if (i == 0)
- op1 = 0xfbca765423456;
- else
- op1 = op0;
- op2 = 0x6532432432434;
- asm("cmpxchg8b %1\n"
- "pushf\n"
- "pop %2\n"
- : "=A" (op0), "=m" (op1), "=g" (eflags)
- : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
- printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n",
- op0, op1, eflags & CC_Z);
- }
- }
-}
-
-#ifdef TEST_SEGS
-/**********************************************/
-/* segmentation tests */
-
-#include <asm/ldt.h>
-#include <linux/unistd.h>
-#include <linux/version.h>
-
-_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
-#define modify_ldt_ldt_s user_desc
-#endif
-
-#define MK_SEL(n) (((n) << 3) | 7)
-
-uint8_t seg_data1[4096];
-uint8_t seg_data2[4096];
-
-#define TEST_LR(op, size, seg, mask)\
-{\
- int res, res2;\
- res = 0x12345678;\
- asm (op " %" size "2, %" size "0\n" \
- "movl $0, %1\n"\
- "jnz 1f\n"\
- "movl $1, %1\n"\
- "1:\n"\
- : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\
- printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
-}
-
-/* NOTE: we use Linux modify_ldt syscall */
-void test_segs(void)
-{
- struct modify_ldt_ldt_s ldt;
- long long ldt_table[3];
- int res, res2;
- char tmp;
- struct {
- uint32_t offset;
- uint16_t seg;
- } __attribute__((packed)) segoff;
-
- ldt.entry_number = 1;
- ldt.base_addr = (unsigned long)&seg_data1;
- ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
- ldt.seg_32bit = 1;
- ldt.contents = MODIFY_LDT_CONTENTS_DATA;
- ldt.read_exec_only = 0;
- ldt.limit_in_pages = 1;
- ldt.seg_not_present = 0;
- ldt.useable = 1;
- modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
- ldt.entry_number = 2;
- ldt.base_addr = (unsigned long)&seg_data2;
- ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
- ldt.seg_32bit = 1;
- ldt.contents = MODIFY_LDT_CONTENTS_DATA;
- ldt.read_exec_only = 0;
- ldt.limit_in_pages = 1;
- ldt.seg_not_present = 0;
- ldt.useable = 1;
- modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
- modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
-#if 0
- {
- int i;
- for(i=0;i<3;i++)
- printf("%d: %016Lx\n", i, ldt_table[i]);
- }
-#endif
- /* do some tests with fs or gs */
- asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
-
- seg_data1[1] = 0xaa;
- seg_data2[1] = 0x55;
-
- asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
- printf("FS[1] = %02x\n", res);
-
- asm volatile ("pushl %%gs\n"
- "movl %1, %%gs\n"
- "gs movzbl 0x1, %0\n"
- "popl %%gs\n"
- : "=r" (res)
- : "r" (MK_SEL(2)));
- printf("GS[1] = %02x\n", res);
-
- /* tests with ds/ss (implicit segment case) */
- tmp = 0xa5;
- asm volatile ("pushl %%ebp\n\t"
- "pushl %%ds\n\t"
- "movl %2, %%ds\n\t"
- "movl %3, %%ebp\n\t"
- "movzbl 0x1, %0\n\t"
- "movzbl (%%ebp), %1\n\t"
- "popl %%ds\n\t"
- "popl %%ebp\n\t"
- : "=r" (res), "=r" (res2)
- : "r" (MK_SEL(1)), "r" (&tmp));
- printf("DS[1] = %02x\n", res);
- printf("SS[tmp] = %02x\n", res2);
-
- segoff.seg = MK_SEL(2);
- segoff.offset = 0xabcdef12;
- asm volatile("lfs %2, %0\n\t"
- "movl %%fs, %1\n\t"
- : "=r" (res), "=g" (res2)
- : "m" (segoff));
- printf("FS:reg = %04x:%08x\n", res2, res);
-
- TEST_LR("larw", "w", MK_SEL(2), 0x0100);
- TEST_LR("larl", "", MK_SEL(2), 0x0100);
- TEST_LR("lslw", "w", MK_SEL(2), 0);
- TEST_LR("lsll", "", MK_SEL(2), 0);
-
- TEST_LR("larw", "w", 0xfff8, 0);
- TEST_LR("larl", "", 0xfff8, 0);
- TEST_LR("lslw", "w", 0xfff8, 0);
- TEST_LR("lsll", "", 0xfff8, 0);
-}
-
-/* 16 bit code test */
-extern char code16_start, code16_end;
-extern char code16_func1;
-extern char code16_func2;
-extern char code16_func3;
-
-void test_code16(void)
-{
- struct modify_ldt_ldt_s ldt;
- int res, res2;
-
- /* build a code segment */
- ldt.entry_number = 1;
- ldt.base_addr = (unsigned long)&code16_start;
- ldt.limit = &code16_end - &code16_start;
- ldt.seg_32bit = 0;
- ldt.contents = MODIFY_LDT_CONTENTS_CODE;
- ldt.read_exec_only = 0;
- ldt.limit_in_pages = 0;
- ldt.seg_not_present = 0;
- ldt.useable = 1;
- modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
- /* call the first function */
- asm volatile ("lcall %1, %2"
- : "=a" (res)
- : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
- printf("func1() = 0x%08x\n", res);
- asm volatile ("lcall %2, %3"
- : "=a" (res), "=c" (res2)
- : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
- printf("func2() = 0x%08x spdec=%d\n", res, res2);
- asm volatile ("lcall %1, %2"
- : "=a" (res)
- : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
- printf("func3() = 0x%08x\n", res);
-}
-#endif
-
-#if defined(__x86_64__)
-asm(".globl func_lret\n"
- "func_lret:\n"
- "movl $0x87654641, %eax\n"
- "lretq\n");
-#else
-asm(".globl func_lret\n"
- "func_lret:\n"
- "movl $0x87654321, %eax\n"
- "lret\n"
-
- ".globl func_iret\n"
- "func_iret:\n"
- "movl $0xabcd4321, %eax\n"
- "iret\n");
-#endif
-
-extern char func_lret;
-extern char func_iret;
-
-void test_misc(void)
-{
- char table[256];
- long res, i;
-
- for(i=0;i<256;i++) table[i] = 256 - i;
- res = 0x12345678;
- asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
- printf("xlat: EAX=" FMTLX "\n", res);
-
-#if defined(__x86_64__)
- {
- static struct __attribute__((packed)) {
- uint32_t offset;
- uint16_t seg;
- } desc;
- long cs_sel;
-
- asm volatile ("mov %%cs, %0" : "=r" (cs_sel));
-
- asm volatile ("push %1\n"
- "call func_lret\n"
- : "=a" (res)
- : "r" (cs_sel) : "memory", "cc");
- printf("func_lret=" FMTLX "\n", res);
-
- /* NOTE: we assume that &func_lret < 4GB */
- desc.offset = (long)&func_lret;
- desc.seg = cs_sel;
-
- asm volatile ("xor %%rax, %%rax\n"
- "rex64 lcall %1\n"
- : "=a" (res)
- : "m" (desc)
- : "memory", "cc");
- printf("func_lret2=" FMTLX "\n", res);
-
- asm volatile ("push %2\n"
- "mov $ 1f, %%rax\n"
- "push %%rax\n"
- "ljmp %1\n"
- "1:\n"
- : "=a" (res)
- : "m" (desc), "b" (cs_sel)
- : "memory", "cc");
- printf("func_lret3=" FMTLX "\n", res);
- }
-#else
- asm volatile ("push %%cs ; call %1"
- : "=a" (res)
- : "m" (func_lret): "memory", "cc");
- printf("func_lret=" FMTLX "\n", res);
-
- asm volatile ("pushf ; push %%cs ; call %1"
- : "=a" (res)
- : "m" (func_iret): "memory", "cc");
- printf("func_iret=" FMTLX "\n", res);
-#endif
-
-#if defined(__x86_64__)
- /* specific popl test */
- asm volatile ("push $12345432 ; push $0x9abcdef ; pop (%%rsp) ; pop %0"
- : "=g" (res));
- printf("popl esp=" FMTLX "\n", res);
-#else
- /* specific popl test */
- asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0"
- : "=g" (res));
- printf("popl esp=" FMTLX "\n", res);
-
- /* specific popw test */
- asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0"
- : "=g" (res));
- printf("popw esp=" FMTLX "\n", res);
-#endif
-}
-
-uint8_t str_buffer[4096];
-
-#define TEST_STRING1(OP, size, DF, REP)\
-{\
- long esi, edi, eax, ecx, eflags;\
-\
- esi = (long)(str_buffer + sizeof(str_buffer) / 2);\
- edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\
- eax = i2l(0x12345678);\
- ecx = 17;\
-\
- asm volatile ("push $0\n\t"\
- "popf\n\t"\
- DF "\n\t"\
- REP #OP size "\n\t"\
- "cld\n\t"\
- "pushf\n\t"\
- "pop %4\n\t"\
- : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\
- : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\
- printf("%-10s ESI=" FMTLX " EDI=" FMTLX " EAX=" FMTLX " ECX=" FMTLX " EFL=%04x\n",\
- REP #OP size, esi, edi, eax, ecx,\
- (int)(eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)));\
-}
-
-#define TEST_STRING(OP, REP)\
- TEST_STRING1(OP, "b", "", REP);\
- TEST_STRING1(OP, "w", "", REP);\
- TEST_STRING1(OP, "l", "", REP);\
- X86_64_ONLY(TEST_STRING1(OP, "q", "", REP));\
- TEST_STRING1(OP, "b", "std", REP);\
- TEST_STRING1(OP, "w", "std", REP);\
- TEST_STRING1(OP, "l", "std", REP);\
- X86_64_ONLY(TEST_STRING1(OP, "q", "std", REP))
-
-void test_string(void)
-{
- int i;
- for(i = 0;i < sizeof(str_buffer); i++)
- str_buffer[i] = i + 0x56;
- TEST_STRING(stos, "");
- TEST_STRING(stos, "rep ");
- TEST_STRING(lods, ""); /* to verify stos */
- TEST_STRING(lods, "rep ");
- TEST_STRING(movs, "");
- TEST_STRING(movs, "rep ");
- TEST_STRING(lods, ""); /* to verify stos */
-
- /* XXX: better tests */
- TEST_STRING(scas, "");
- TEST_STRING(scas, "repz ");
- TEST_STRING(scas, "repnz ");
- TEST_STRING(cmps, "");
- TEST_STRING(cmps, "repz ");
- TEST_STRING(cmps, "repnz ");
-}
-
-#ifdef TEST_VM86
-/* VM86 test */
-
-static inline void set_bit(uint8_t *a, unsigned int bit)
-{
- a[bit / 8] |= (1 << (bit % 8));
-}
-
-static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
-{
- return (uint8_t *)((seg << 4) + (reg & 0xffff));
-}
-
-static inline void pushw(struct vm86_regs *r, int val)
-{
- r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
- *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
-}
-
-#undef __syscall_return
-#define __syscall_return(type, res) \
-do { \
- return (type) (res); \
-} while (0)
-
-_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
-
-extern char vm86_code_start;
-extern char vm86_code_end;
-
-#define VM86_CODE_CS 0x100
-#define VM86_CODE_IP 0x100
-
-void test_vm86(void)
-{
- struct vm86plus_struct ctx;
- struct vm86_regs *r;
- uint8_t *vm86_mem;
- int seg, ret;
-
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
- MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
- if (vm86_mem == MAP_FAILED) {
- printf("ERROR: could not map vm86 memory");
- return;
- }
- memset(&ctx, 0, sizeof(ctx));
-
- /* init basic registers */
- r = &ctx.regs;
- r->eip = VM86_CODE_IP;
- r->esp = 0xfffe;
- seg = VM86_CODE_CS;
- r->cs = seg;
- r->ss = seg;
- r->ds = seg;
- r->es = seg;
- r->fs = seg;
- r->gs = seg;
- r->eflags = VIF_MASK;
-
- /* move code to proper address. We use the same layout as a .com
- dos program. */
- memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
- &vm86_code_start, &vm86_code_end - &vm86_code_start);
-
- /* mark int 0x21 as being emulated */
- set_bit((uint8_t *)&ctx.int_revectored, 0x21);
-
- for(;;) {
- ret = vm86(VM86_ENTER, &ctx);
- switch(VM86_TYPE(ret)) {
- case VM86_INTx:
- {
- int int_num, ah, v;
-
- int_num = VM86_ARG(ret);
- if (int_num != 0x21)
- goto unknown_int;
- ah = (r->eax >> 8) & 0xff;
- switch(ah) {
- case 0x00: /* exit */
- goto the_end;
- case 0x02: /* write char */
- {
- uint8_t c = r->edx;
- putchar(c);
- }
- break;
- case 0x09: /* write string */
- {
- uint8_t c, *ptr;
- ptr = seg_to_linear(r->ds, r->edx);
- for(;;) {
- c = *ptr++;
- if (c == '$')
- break;
- putchar(c);
- }
- r->eax = (r->eax & ~0xff) | '$';
- }
- break;
- case 0xff: /* extension: write eflags number in edx */
- v = (int)r->edx;
-#ifndef LINUX_VM86_IOPL_FIX
- v &= ~0x3000;
-#endif
- printf("%08x\n", v);
- break;
- default:
- unknown_int:
- printf("unsupported int 0x%02x\n", int_num);
- goto the_end;
- }
- }
- break;
- case VM86_SIGNAL:
- /* a signal came, we just ignore that */
- break;
- case VM86_STI:
- break;
- default:
- printf("ERROR: unhandled vm86 return code (0x%x)\n", ret);
- goto the_end;
- }
- }
- the_end:
- printf("VM86 end\n");
- munmap(vm86_mem, 0x110000);
-}
-#endif
-
-/* exception tests */
-#if defined(__i386__) && !defined(REG_EAX)
-#define REG_EAX EAX
-#define REG_EBX EBX
-#define REG_ECX ECX
-#define REG_EDX EDX
-#define REG_ESI ESI
-#define REG_EDI EDI
-#define REG_EBP EBP
-#define REG_ESP ESP
-#define REG_EIP EIP
-#define REG_EFL EFL
-#define REG_TRAPNO TRAPNO
-#define REG_ERR ERR
-#endif
-
-#if defined(__x86_64__)
-#define REG_EIP REG_RIP
-#endif
-
-jmp_buf jmp_env;
-int v1;
-int tab[2];
-
-void sig_handler(int sig, siginfo_t *info, void *puc)
-{
- struct ucontext *uc = puc;
-
- printf("si_signo=%d si_errno=%d si_code=%d",
- info->si_signo, info->si_errno, info->si_code);
- printf(" si_addr=0x%08lx",
- (unsigned long)info->si_addr);
- printf("\n");
-
- printf("trapno=" FMTLX " err=" FMTLX,
- (long)uc->uc_mcontext.gregs[REG_TRAPNO],
- (long)uc->uc_mcontext.gregs[REG_ERR]);
- printf(" EIP=" FMTLX, (long)uc->uc_mcontext.gregs[REG_EIP]);
- printf("\n");
- longjmp(jmp_env, 1);
-}
-
-void test_exceptions(void)
-{
- struct sigaction act;
- volatile int val;
-
- act.sa_sigaction = sig_handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO | SA_NODEFER;
- sigaction(SIGFPE, &act, NULL);
- sigaction(SIGILL, &act, NULL);
- sigaction(SIGSEGV, &act, NULL);
- sigaction(SIGBUS, &act, NULL);
- sigaction(SIGTRAP, &act, NULL);
-
- /* test division by zero reporting */
- printf("DIVZ exception:\n");
- if (setjmp(jmp_env) == 0) {
- /* now divide by zero */
- v1 = 0;
- v1 = 2 / v1;
- }
-
-#if !defined(__x86_64__)
- printf("BOUND exception:\n");
- if (setjmp(jmp_env) == 0) {
- /* bound exception */
- tab[0] = 1;
- tab[1] = 10;
- asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0]));
- }
-#endif
-
-#ifdef TEST_SEGS
- printf("segment exceptions:\n");
- if (setjmp(jmp_env) == 0) {
- /* load an invalid segment */
- asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1));
- }
- if (setjmp(jmp_env) == 0) {
- /* null data segment is valid */
- asm volatile ("movl %0, %%fs" : : "r" (3));
- /* null stack segment */
- asm volatile ("movl %0, %%ss" : : "r" (3));
- }
-
- {
- struct modify_ldt_ldt_s ldt;
- ldt.entry_number = 1;
- ldt.base_addr = (unsigned long)&seg_data1;
- ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
- ldt.seg_32bit = 1;
- ldt.contents = MODIFY_LDT_CONTENTS_DATA;
- ldt.read_exec_only = 0;
- ldt.limit_in_pages = 1;
- ldt.seg_not_present = 1;
- ldt.useable = 1;
- modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
- if (setjmp(jmp_env) == 0) {
- /* segment not present */
- asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
- }
- }
-#endif
-
- /* test SEGV reporting */
- printf("PF exception:\n");
- if (setjmp(jmp_env) == 0) {
- val = 1;
- /* we add a nop to test a weird PC retrieval case */
- asm volatile ("nop");
- /* now store in an invalid address */
- *(char *)0x1234 = 1;
- }
-
- /* test SEGV reporting */
- printf("PF exception:\n");
- if (setjmp(jmp_env) == 0) {
- val = 1;
- /* read from an invalid address */
- v1 = *(char *)0x1234;
- }
-
- /* test illegal instruction reporting */
- printf("UD2 exception:\n");
- if (setjmp(jmp_env) == 0) {
- /* now execute an invalid instruction */
- asm volatile("ud2");
- }
- printf("lock nop exception:\n");
- if (setjmp(jmp_env) == 0) {
- /* now execute an invalid instruction */
- asm volatile("lock nop");
- }
-
- printf("INT exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("int $0xfd");
- }
- if (setjmp(jmp_env) == 0) {
- asm volatile ("int $0x01");
- }
- if (setjmp(jmp_env) == 0) {
- asm volatile (".byte 0xcd, 0x03");
- }
- if (setjmp(jmp_env) == 0) {
- asm volatile ("int $0x04");
- }
- if (setjmp(jmp_env) == 0) {
- asm volatile ("int $0x05");
- }
-
- printf("INT3 exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("int3");
- }
-
- printf("CLI exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("cli");
- }
-
- printf("STI exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("cli");
- }
-
-#if !defined(__x86_64__)
- printf("INTO exception:\n");
- if (setjmp(jmp_env) == 0) {
- /* overflow exception */
- asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
- }
-#endif
-
- printf("OUTB exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
- }
-
- printf("INB exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
- }
-
- printf("REP OUTSB exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
- }
-
- printf("REP INSB exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
- }
-
- printf("HLT exception:\n");
- if (setjmp(jmp_env) == 0) {
- asm volatile ("hlt");
- }
-
- printf("single step exception:\n");
- val = 0;
- if (setjmp(jmp_env) == 0) {
- asm volatile ("pushf\n"
- "orl $0x00100, (%%esp)\n"
- "popf\n"
- "movl $0xabcd, %0\n"
- "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
- }
- printf("val=0x%x\n", val);
-}
-
-#if !defined(__x86_64__)
-/* specific precise single step test */
-void sig_trap_handler(int sig, siginfo_t *info, void *puc)
-{
- struct ucontext *uc = puc;
- printf("EIP=" FMTLX "\n", (long)uc->uc_mcontext.gregs[REG_EIP]);
-}
-
-const uint8_t sstep_buf1[4] = { 1, 2, 3, 4};
-uint8_t sstep_buf2[4];
-
-void test_single_step(void)
-{
- struct sigaction act;
- volatile int val;
- int i;
-
- val = 0;
- act.sa_sigaction = sig_trap_handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
- sigaction(SIGTRAP, &act, NULL);
- asm volatile ("pushf\n"
- "orl $0x00100, (%%esp)\n"
- "popf\n"
- "movl $0xabcd, %0\n"
-
- /* jmp test */
- "movl $3, %%ecx\n"
- "1:\n"
- "addl $1, %0\n"
- "decl %%ecx\n"
- "jnz 1b\n"
-
- /* movsb: the single step should stop at each movsb iteration */
- "movl $sstep_buf1, %%esi\n"
- "movl $sstep_buf2, %%edi\n"
- "movl $0, %%ecx\n"
- "rep movsb\n"
- "movl $3, %%ecx\n"
- "rep movsb\n"
- "movl $1, %%ecx\n"
- "rep movsb\n"
-
- /* cmpsb: the single step should stop at each cmpsb iteration */
- "movl $sstep_buf1, %%esi\n"
- "movl $sstep_buf2, %%edi\n"
- "movl $0, %%ecx\n"
- "rep cmpsb\n"
- "movl $4, %%ecx\n"
- "rep cmpsb\n"
-
- /* getpid() syscall: single step should skip one
- instruction */
- "movl $20, %%eax\n"
- "int $0x80\n"
- "movl $0, %%eax\n"
-
- /* when modifying SS, trace is not done on the next
- instruction */
- "movl %%ss, %%ecx\n"
- "movl %%ecx, %%ss\n"
- "addl $1, %0\n"
- "movl $1, %%eax\n"
- "movl %%ecx, %%ss\n"
- "jmp 1f\n"
- "addl $1, %0\n"
- "1:\n"
- "movl $1, %%eax\n"
- "pushl %%ecx\n"
- "popl %%ss\n"
- "addl $1, %0\n"
- "movl $1, %%eax\n"
-
- "pushf\n"
- "andl $~0x00100, (%%esp)\n"
- "popf\n"
- : "=m" (val)
- :
- : "cc", "memory", "eax", "ecx", "esi", "edi");
- printf("val=%d\n", val);
- for(i = 0; i < 4; i++)
- printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]);
-}
-
-/* self modifying code test */
-uint8_t code[] = {
- 0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */
- 0xc3, /* ret */
-};
-
-asm("smc_code2:\n"
- "movl 4(%esp), %eax\n"
- "movl %eax, smc_patch_addr2 + 1\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "smc_patch_addr2:\n"
- "movl $1, %eax\n"
- "ret\n");
-
-typedef int FuncType(void);
-extern int smc_code2(int);
-void test_self_modifying_code(void)
-{
- int i;
-
- printf("self modifying code:\n");
- printf("func1 = 0x%x\n", ((FuncType *)code)());
- for(i = 2; i <= 4; i++) {
- code[1] = i;
- printf("func%d = 0x%x\n", i, ((FuncType *)code)());
- }
-
- /* more difficult test : the modified code is just after the
- modifying instruction. It is forbidden in Intel specs, but it
- is used by old DOS programs */
- for(i = 2; i <= 4; i++) {
- printf("smc_code2(%d) = %d\n", i, smc_code2(i));
- }
-}
-#endif
-
-long enter_stack[4096];
-
-#if defined(__x86_64__)
-#define RSP "%%rsp"
-#define RBP "%%rbp"
-#else
-#define RSP "%%esp"
-#define RBP "%%ebp"
-#endif
-
-#define TEST_ENTER(size, stack_type, level)\
-{\
- long esp_save, esp_val, ebp_val, ebp_save, i;\
- stack_type *ptr, *stack_end, *stack_ptr;\
- memset(enter_stack, 0, sizeof(enter_stack));\
- stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
- ebp_val = (long)stack_ptr;\
- for(i=1;i<=32;i++)\
- *--stack_ptr = i;\
- esp_val = (long)stack_ptr;\
- asm("mov " RSP ", %[esp_save]\n"\
- "mov " RBP ", %[ebp_save]\n"\
- "mov %[esp_val], " RSP "\n"\
- "mov %[ebp_val], " RBP "\n"\
- "enter" size " $8, $" #level "\n"\
- "mov " RSP ", %[esp_val]\n"\
- "mov " RBP ", %[ebp_val]\n"\
- "mov %[esp_save], " RSP "\n"\
- "mov %[ebp_save], " RBP "\n"\
- : [esp_save] "=r" (esp_save),\
- [ebp_save] "=r" (ebp_save),\
- [esp_val] "=r" (esp_val),\
- [ebp_val] "=r" (ebp_val)\
- : "[esp_val]" (esp_val),\
- "[ebp_val]" (ebp_val));\
- printf("level=%d:\n", level);\
- printf("esp_val=" FMTLX "\n", esp_val - (long)stack_end);\
- printf("ebp_val=" FMTLX "\n", ebp_val - (long)stack_end);\
- for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
- printf(FMTLX "\n", (long)ptr[0]);\
-}
-
-static void test_enter(void)
-{
-#if defined(__x86_64__)
- TEST_ENTER("q", uint64_t, 0);
- TEST_ENTER("q", uint64_t, 1);
- TEST_ENTER("q", uint64_t, 2);
- TEST_ENTER("q", uint64_t, 31);
-#else
- TEST_ENTER("l", uint32_t, 0);
- TEST_ENTER("l", uint32_t, 1);
- TEST_ENTER("l", uint32_t, 2);
- TEST_ENTER("l", uint32_t, 31);
-#endif
-
- TEST_ENTER("w", uint16_t, 0);
- TEST_ENTER("w", uint16_t, 1);
- TEST_ENTER("w", uint16_t, 2);
- TEST_ENTER("w", uint16_t, 31);
-}
-
-#ifdef TEST_SSE
-
-typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
-typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
-
-typedef union {
- double d[2];
- float s[4];
- uint32_t l[4];
- uint64_t q[2];
- __m128 dq;
-} XMMReg;
-
-static uint64_t __attribute__((aligned(16))) test_values[4][2] = {
- { 0x456723c698694873, 0xdc515cff944a58ec },
- { 0x1f297ccd58bad7ab, 0x41f21efba9e3e146 },
- { 0x007c62c2085427f8, 0x231be9e8cde7438d },
- { 0x0f76255a085427f8, 0xc233e9e8c4c9439a },
-};
-
-#define SSE_OP(op)\
-{\
- asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.q[1], a.q[0],\
- b.q[1], b.q[0],\
- r.q[1], r.q[0]);\
-}
-
-#define SSE_OP2(op)\
-{\
- int i;\
- for(i=0;i<2;i++) {\
- a.q[0] = test_values[2*i][0];\
- a.q[1] = test_values[2*i][1];\
- b.q[0] = test_values[2*i+1][0];\
- b.q[1] = test_values[2*i+1][1];\
- SSE_OP(op);\
- }\
-}
-
-#define MMX_OP2(op)\
-{\
- int i;\
- for(i=0;i<2;i++) {\
- a.q[0] = test_values[2*i][0];\
- b.q[0] = test_values[2*i+1][0];\
- asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\
- printf("%-9s: a=" FMT64X " b=" FMT64X " r=" FMT64X "\n",\
- #op,\
- a.q[0],\
- b.q[0],\
- r.q[0]);\
- }\
- SSE_OP2(op);\
-}
-
-#define SHUF_OP(op, ib)\
-{\
- a.q[0] = test_values[0][0];\
- a.q[1] = test_values[0][1];\
- b.q[0] = test_values[1][0];\
- b.q[1] = test_values[1][1];\
- asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.q[1], a.q[0],\
- b.q[1], b.q[0],\
- ib,\
- r.q[1], r.q[0]);\
-}
-
-#define PSHUF_OP(op, ib)\
-{\
- int i;\
- for(i=0;i<2;i++) {\
- a.q[0] = test_values[2*i][0];\
- a.q[1] = test_values[2*i][1];\
- asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.q[1], a.q[0],\
- ib,\
- r.q[1], r.q[0]);\
- }\
-}
-
-#define SHIFT_IM(op, ib)\
-{\
- int i;\
- for(i=0;i<2;i++) {\
- a.q[0] = test_values[2*i][0];\
- a.q[1] = test_values[2*i][1];\
- asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.q[1], a.q[0],\
- ib,\
- r.q[1], r.q[0]);\
- }\
-}
-
-#define SHIFT_OP(op, ib)\
-{\
- int i;\
- SHIFT_IM(op, ib);\
- for(i=0;i<2;i++) {\
- a.q[0] = test_values[2*i][0];\
- a.q[1] = test_values[2*i][1];\
- b.q[0] = ib;\
- b.q[1] = 0;\
- asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.q[1], a.q[0],\
- b.q[1], b.q[0],\
- r.q[1], r.q[0]);\
- }\
-}
-
-#define MOVMSK(op)\
-{\
- int i, reg;\
- for(i=0;i<2;i++) {\
- a.q[0] = test_values[2*i][0];\
- a.q[1] = test_values[2*i][1];\
- asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
- #op,\
- a.q[1], a.q[0],\
- reg);\
- }\
-}
-
-#define SSE_OPS(a) \
-SSE_OP(a ## ps);\
-SSE_OP(a ## ss);
-
-#define SSE_OPD(a) \
-SSE_OP(a ## pd);\
-SSE_OP(a ## sd);
-
-#define SSE_COMI(op, field)\
-{\
- unsigned int eflags;\
- XMMReg a, b;\
- a.field[0] = a1;\
- b.field[0] = b1;\
- asm volatile (#op " %2, %1\n"\
- "pushf\n"\
- "pop %0\n"\
- : "=m" (eflags)\
- : "x" (a.dq), "x" (b.dq));\
- printf("%-9s: a=%f b=%f cc=%04x\n",\
- #op, a1, b1,\
- eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
-}
-
-void test_sse_comi(double a1, double b1)
-{
- SSE_COMI(ucomiss, s);
- SSE_COMI(ucomisd, d);
- SSE_COMI(comiss, s);
- SSE_COMI(comisd, d);
-}
-
-#define CVT_OP_XMM(op)\
-{\
- asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.q[1], a.q[0],\
- r.q[1], r.q[0]);\
-}
-
-/* Force %xmm0 usage to avoid the case where both register index are 0
- to test intruction decoding more extensively */
-#define CVT_OP_XMM2MMX(op)\
-{\
- asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \
- : "%xmm0");\
- printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\
- #op,\
- a.q[1], a.q[0],\
- r.q[0]);\
-}
-
-#define CVT_OP_MMX2XMM(op)\
-{\
- asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\
- printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.q[0],\
- r.q[1], r.q[0]);\
-}
-
-#define CVT_OP_REG2XMM(op)\
-{\
- asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\
- printf("%-9s: a=%08x r=" FMT64X "" FMT64X "\n",\
- #op,\
- a.l[0],\
- r.q[1], r.q[0]);\
-}
-
-#define CVT_OP_XMM2REG(op)\
-{\
- asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\
- printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
- #op,\
- a.q[1], a.q[0],\
- r.l[0]);\
-}
-
-struct fpxstate {
- uint16_t fpuc;
- uint16_t fpus;
- uint16_t fptag;
- uint16_t fop;
- uint32_t fpuip;
- uint16_t cs_sel;
- uint16_t dummy0;
- uint32_t fpudp;
- uint16_t ds_sel;
- uint16_t dummy1;
- uint32_t mxcsr;
- uint32_t mxcsr_mask;
- uint8_t fpregs1[8 * 16];
- uint8_t xmm_regs[8 * 16];
- uint8_t dummy2[224];
-};
-
-static struct fpxstate fpx_state __attribute__((aligned(16)));
-static struct fpxstate fpx_state2 __attribute__((aligned(16)));
-
-void test_fxsave(void)
-{
- struct fpxstate *fp = &fpx_state;
- struct fpxstate *fp2 = &fpx_state2;
- int i, nb_xmm;
- XMMReg a, b;
- a.q[0] = test_values[0][0];
- a.q[1] = test_values[0][1];
- b.q[0] = test_values[1][0];
- b.q[1] = test_values[1][1];
-
- asm("movdqa %2, %%xmm0\n"
- "movdqa %3, %%xmm7\n"
-#if defined(__x86_64__)
- "movdqa %2, %%xmm15\n"
-#endif
- " fld1\n"
- " fldpi\n"
- " fldln2\n"
- " fxsave %0\n"
- " fxrstor %0\n"
- " fxsave %1\n"
- " fninit\n"
- : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
- : "m" (a), "m" (b));
- printf("fpuc=%04x\n", fp->fpuc);
- printf("fpus=%04x\n", fp->fpus);
- printf("fptag=%04x\n", fp->fptag);
- for(i = 0; i < 3; i++) {
- printf("ST%d: " FMT64X " %04x\n",
- i,
- *(uint64_t *)&fp->fpregs1[i * 16],
- *(uint16_t *)&fp->fpregs1[i * 16 + 8]);
- }
- printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80);
-#if defined(__x86_64__)
- nb_xmm = 16;
-#else
- nb_xmm = 8;
-#endif
- for(i = 0; i < nb_xmm; i++) {
- printf("xmm%d: " FMT64X "" FMT64X "\n",
- i,
- *(uint64_t *)&fp->xmm_regs[i * 16],
- *(uint64_t *)&fp->xmm_regs[i * 16 + 8]);
- }
-}
-
-void test_sse(void)
-{
- XMMReg r, a, b;
- int i;
-
- MMX_OP2(punpcklbw);
- MMX_OP2(punpcklwd);
- MMX_OP2(punpckldq);
- MMX_OP2(packsswb);
- MMX_OP2(pcmpgtb);
- MMX_OP2(pcmpgtw);
- MMX_OP2(pcmpgtd);
- MMX_OP2(packuswb);
- MMX_OP2(punpckhbw);
- MMX_OP2(punpckhwd);
- MMX_OP2(punpckhdq);
- MMX_OP2(packssdw);
- MMX_OP2(pcmpeqb);
- MMX_OP2(pcmpeqw);
- MMX_OP2(pcmpeqd);
-
- MMX_OP2(paddq);
- MMX_OP2(pmullw);
- MMX_OP2(psubusb);
- MMX_OP2(psubusw);
- MMX_OP2(pminub);
- MMX_OP2(pand);
- MMX_OP2(paddusb);
- MMX_OP2(paddusw);
- MMX_OP2(pmaxub);
- MMX_OP2(pandn);
-
- MMX_OP2(pmulhuw);
- MMX_OP2(pmulhw);
-
- MMX_OP2(psubsb);
- MMX_OP2(psubsw);
- MMX_OP2(pminsw);
- MMX_OP2(por);
- MMX_OP2(paddsb);
- MMX_OP2(paddsw);
- MMX_OP2(pmaxsw);
- MMX_OP2(pxor);
- MMX_OP2(pmuludq);
- MMX_OP2(pmaddwd);
- MMX_OP2(psadbw);
- MMX_OP2(psubb);
- MMX_OP2(psubw);
- MMX_OP2(psubd);
- MMX_OP2(psubq);
- MMX_OP2(paddb);
- MMX_OP2(paddw);
- MMX_OP2(paddd);
-
- MMX_OP2(pavgb);
- MMX_OP2(pavgw);
-
- asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678));
- printf("%-9s: r=" FMT64X "\n", "pinsrw", r.q[0]);
-
- asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678));
- printf("%-9s: r=" FMT64X "" FMT64X "\n", "pinsrw", r.q[1], r.q[0]);
-
- a.q[0] = test_values[0][0];
- a.q[1] = test_values[0][1];
- asm volatile ("pextrw $1, %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
- printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
-
- asm volatile ("pextrw $5, %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
- printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
-
- asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
- printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
-
- asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
- printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
-
- {
- r.q[0] = -1;
- r.q[1] = -1;
-
- a.q[0] = test_values[0][0];
- a.q[1] = test_values[0][1];
- b.q[0] = test_values[1][0];
- b.q[1] = test_values[1][1];
- asm volatile("maskmovq %1, %0" :
- : "y" (a.q[0]), "y" (b.q[0]), "D" (&r)
- : "memory");
- printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
- "maskmov",
- r.q[0],
- a.q[0],
- b.q[0]);
- asm volatile("maskmovdqu %1, %0" :
- : "x" (a.dq), "x" (b.dq), "D" (&r)
- : "memory");
- printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
- "maskmov",
- r.q[1], r.q[0],
- a.q[1], a.q[0],
- b.q[1], b.q[0]);
- }
-
- asm volatile ("emms");
-
- SSE_OP2(punpcklqdq);
- SSE_OP2(punpckhqdq);
- SSE_OP2(andps);
- SSE_OP2(andpd);
- SSE_OP2(andnps);
- SSE_OP2(andnpd);
- SSE_OP2(orps);
- SSE_OP2(orpd);
- SSE_OP2(xorps);
- SSE_OP2(xorpd);
-
- SSE_OP2(unpcklps);
- SSE_OP2(unpcklpd);
- SSE_OP2(unpckhps);
- SSE_OP2(unpckhpd);
-
- SHUF_OP(shufps, 0x78);
- SHUF_OP(shufpd, 0x02);
-
- PSHUF_OP(pshufd, 0x78);
- PSHUF_OP(pshuflw, 0x78);
- PSHUF_OP(pshufhw, 0x78);
-
- SHIFT_OP(psrlw, 7);
- SHIFT_OP(psrlw, 16);
- SHIFT_OP(psraw, 7);
- SHIFT_OP(psraw, 16);
- SHIFT_OP(psllw, 7);
- SHIFT_OP(psllw, 16);
-
- SHIFT_OP(psrld, 7);
- SHIFT_OP(psrld, 32);
- SHIFT_OP(psrad, 7);
- SHIFT_OP(psrad, 32);
- SHIFT_OP(pslld, 7);
- SHIFT_OP(pslld, 32);
-
- SHIFT_OP(psrlq, 7);
- SHIFT_OP(psrlq, 32);
- SHIFT_OP(psllq, 7);
- SHIFT_OP(psllq, 32);
-
- SHIFT_IM(psrldq, 16);
- SHIFT_IM(psrldq, 7);
- SHIFT_IM(pslldq, 16);
- SHIFT_IM(pslldq, 7);
-
- MOVMSK(movmskps);
- MOVMSK(movmskpd);
-
- /* FPU specific ops */
-
- {
- uint32_t mxcsr;
- asm volatile("stmxcsr %0" : "=m" (mxcsr));
- printf("mxcsr=%08x\n", mxcsr & 0x1f80);
- asm volatile("ldmxcsr %0" : : "m" (mxcsr));
- }
-
- test_sse_comi(2, -1);
- test_sse_comi(2, 2);
- test_sse_comi(2, 3);
- test_sse_comi(2, q_nan.d);
- test_sse_comi(q_nan.d, -1);
-
- for(i = 0; i < 2; i++) {
- a.s[0] = 2.7;
- a.s[1] = 3.4;
- a.s[2] = 4;
- a.s[3] = -6.3;
- b.s[0] = 45.7;
- b.s[1] = 353.4;
- b.s[2] = 4;
- b.s[3] = 56.3;
- if (i == 1) {
- a.s[0] = q_nan.d;
- b.s[3] = q_nan.d;
- }
-
- SSE_OPS(add);
- SSE_OPS(mul);
- SSE_OPS(sub);
- SSE_OPS(min);
- SSE_OPS(div);
- SSE_OPS(max);
- SSE_OPS(sqrt);
- SSE_OPS(cmpeq);
- SSE_OPS(cmplt);
- SSE_OPS(cmple);
- SSE_OPS(cmpunord);
- SSE_OPS(cmpneq);
- SSE_OPS(cmpnlt);
- SSE_OPS(cmpnle);
- SSE_OPS(cmpord);
-
-
- a.d[0] = 2.7;
- a.d[1] = -3.4;
- b.d[0] = 45.7;
- b.d[1] = -53.4;
- if (i == 1) {
- a.d[0] = q_nan.d;
- b.d[1] = q_nan.d;
- }
- SSE_OPD(add);
- SSE_OPD(mul);
- SSE_OPD(sub);
- SSE_OPD(min);
- SSE_OPD(div);
- SSE_OPD(max);
- SSE_OPD(sqrt);
- SSE_OPD(cmpeq);
- SSE_OPD(cmplt);
- SSE_OPD(cmple);
- SSE_OPD(cmpunord);
- SSE_OPD(cmpneq);
- SSE_OPD(cmpnlt);
- SSE_OPD(cmpnle);
- SSE_OPD(cmpord);
- }
-
- /* float to float/int */
- a.s[0] = 2.7;
- a.s[1] = 3.4;
- a.s[2] = 4;
- a.s[3] = -6.3;
- CVT_OP_XMM(cvtps2pd);
- CVT_OP_XMM(cvtss2sd);
- CVT_OP_XMM2MMX(cvtps2pi);
- CVT_OP_XMM2MMX(cvttps2pi);
- CVT_OP_XMM2REG(cvtss2si);
- CVT_OP_XMM2REG(cvttss2si);
- CVT_OP_XMM(cvtps2dq);
- CVT_OP_XMM(cvttps2dq);
-
- a.d[0] = 2.6;
- a.d[1] = -3.4;
- CVT_OP_XMM(cvtpd2ps);
- CVT_OP_XMM(cvtsd2ss);
- CVT_OP_XMM2MMX(cvtpd2pi);
- CVT_OP_XMM2MMX(cvttpd2pi);
- CVT_OP_XMM2REG(cvtsd2si);
- CVT_OP_XMM2REG(cvttsd2si);
- CVT_OP_XMM(cvtpd2dq);
- CVT_OP_XMM(cvttpd2dq);
-
- /* sse/mmx moves */
- CVT_OP_XMM2MMX(movdq2q);
- CVT_OP_MMX2XMM(movq2dq);
-
- /* int to float */
- a.l[0] = -6;
- a.l[1] = 2;
- a.l[2] = 100;
- a.l[3] = -60000;
- CVT_OP_MMX2XMM(cvtpi2ps);
- CVT_OP_MMX2XMM(cvtpi2pd);
- CVT_OP_REG2XMM(cvtsi2ss);
- CVT_OP_REG2XMM(cvtsi2sd);
- CVT_OP_XMM(cvtdq2ps);
- CVT_OP_XMM(cvtdq2pd);
-
- /* XXX: test PNI insns */
-#if 0
- SSE_OP2(movshdup);
-#endif
- asm volatile ("emms");
-}
-
-#endif
-
-#define TEST_CONV_RAX(op)\
-{\
- unsigned long a, r;\
- a = i2l(0x8234a6f8);\
- r = a;\
- asm volatile(#op : "=a" (r) : "0" (r));\
- printf("%-10s A=" FMTLX " R=" FMTLX "\n", #op, a, r);\
-}
-
-#define TEST_CONV_RAX_RDX(op)\
-{\
- unsigned long a, d, r, rh; \
- a = i2l(0x8234a6f8);\
- d = i2l(0x8345a1f2);\
- r = a;\
- rh = d;\
- asm volatile(#op : "=a" (r), "=d" (rh) : "0" (r), "1" (rh)); \
- printf("%-10s A=" FMTLX " R=" FMTLX ":" FMTLX "\n", #op, a, r, rh); \
-}
-
-void test_conv(void)
-{
- TEST_CONV_RAX(cbw);
- TEST_CONV_RAX(cwde);
-#if defined(__x86_64__)
- TEST_CONV_RAX(cdqe);
-#endif
-
- TEST_CONV_RAX_RDX(cwd);
- TEST_CONV_RAX_RDX(cdq);
-#if defined(__x86_64__)
- TEST_CONV_RAX_RDX(cqo);
-#endif
-}
-
-extern void *__start_initcall;
-extern void *__stop_initcall;
-
-
-int main(int argc, char **argv)
-{
- void **ptr;
- void (*func)(void);
-
- ptr = &__start_initcall;
- while (ptr != &__stop_initcall) {
- func = *ptr++;
- func();
- }
- test_bsx();
- test_mul();
- test_jcc();
- test_floats();
-#if !defined(__x86_64__)
- test_bcd();
-#endif
- test_xchg();
- test_string();
- test_misc();
- test_lea();
-#ifdef TEST_SEGS
- test_segs();
- test_code16();
-#endif
-#ifdef TEST_VM86
- test_vm86();
-#endif
- test_exceptions();
-#if !defined(__x86_64__)
- test_self_modifying_code();
- test_single_step();
-#endif
- test_enter();
- test_conv();
-#ifdef TEST_SSE
- test_sse();
- test_fxsave();
-#endif
- return 0;
-}
diff --git a/tools/ioemu/tests/test-i386.h b/tools/ioemu/tests/test-i386.h
deleted file mode 100644
index 75106b8ce2..0000000000
--- a/tools/ioemu/tests/test-i386.h
+++ /dev/null
@@ -1,152 +0,0 @@
-
-#define exec_op glue(exec_, OP)
-#define exec_opq glue(glue(exec_, OP), q)
-#define exec_opl glue(glue(exec_, OP), l)
-#define exec_opw glue(glue(exec_, OP), w)
-#define exec_opb glue(glue(exec_, OP), b)
-
-#define EXECOP2(size, rsize, res, s1, flags) \
- asm ("push %4\n\t"\
- "popf\n\t"\
- stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
- "pushf\n\t"\
- "pop %1\n\t"\
- : "=q" (res), "=g" (flags)\
- : "q" (s1), "0" (res), "1" (flags)); \
- printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \
- stringify(OP) size, s0, s1, res, iflags, flags & CC_MASK);
-
-#define EXECOP1(size, rsize, res, flags) \
- asm ("push %3\n\t"\
- "popf\n\t"\
- stringify(OP) size " %" rsize "0\n\t" \
- "pushf\n\t"\
- "pop %1\n\t"\
- : "=q" (res), "=g" (flags)\
- : "0" (res), "1" (flags)); \
- printf("%-10s A=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \
- stringify(OP) size, s0, res, iflags, flags & CC_MASK);
-
-#ifdef OP1
-#if defined(__x86_64__)
-void exec_opq(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP1("q", "", res, flags);
-}
-#endif
-
-void exec_opl(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP1("l", "k", res, flags);
-}
-
-void exec_opw(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP1("w", "w", res, flags);
-}
-
-void exec_opb(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP1("b", "b", res, flags);
-}
-#else
-#if defined(__x86_64__)
-void exec_opq(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP2("q", "", res, s1, flags);
-}
-#endif
-
-void exec_opl(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP2("l", "k", res, s1, flags);
-}
-
-void exec_opw(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP2("w", "w", res, s1, flags);
-}
-
-void exec_opb(long s0, long s1, long iflags)
-{
- long res, flags;
- res = s0;
- flags = iflags;
- EXECOP2("b", "b", res, s1, flags);
-}
-#endif
-
-void exec_op(long s0, long s1)
-{
- s0 = i2l(s0);
- s1 = i2l(s1);
-#if defined(__x86_64__)
- exec_opq(s0, s1, 0);
-#endif
- exec_opl(s0, s1, 0);
- exec_opw(s0, s1, 0);
- exec_opb(s0, s1, 0);
-#ifdef OP_CC
-#if defined(__x86_64__)
- exec_opq(s0, s1, CC_C);
-#endif
- exec_opl(s0, s1, CC_C);
- exec_opw(s0, s1, CC_C);
- exec_opb(s0, s1, CC_C);
-#endif
-}
-
-void glue(test_, OP)(void)
-{
- exec_op(0x12345678, 0x812FADA);
- exec_op(0x12341, 0x12341);
- exec_op(0x12341, -0x12341);
- exec_op(0xffffffff, 0);
- exec_op(0xffffffff, -1);
- exec_op(0xffffffff, 1);
- exec_op(0xffffffff, 2);
- exec_op(0x7fffffff, 0);
- exec_op(0x7fffffff, 1);
- exec_op(0x7fffffff, -1);
- exec_op(0x80000000, -1);
- exec_op(0x80000000, 1);
- exec_op(0x80000000, -2);
- exec_op(0x12347fff, 0);
- exec_op(0x12347fff, 1);
- exec_op(0x12347fff, -1);
- exec_op(0x12348000, -1);
- exec_op(0x12348000, 1);
- exec_op(0x12348000, -2);
- exec_op(0x12347f7f, 0);
- exec_op(0x12347f7f, 1);
- exec_op(0x12347f7f, -1);
- exec_op(0x12348080, -1);
- exec_op(0x12348080, 1);
- exec_op(0x12348080, -2);
-}
-
-void *glue(_test_, OP) __init_call = glue(test_, OP);
-
-#undef OP
-#undef OP_CC
diff --git a/tools/ioemu/tests/test_path.c b/tools/ioemu/tests/test_path.c
deleted file mode 100644
index a9b52de378..0000000000
--- a/tools/ioemu/tests/test_path.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Test path override code */
-#define _GNU_SOURCE
-#include "../path.c"
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-/* Any log message kills the test. */
-void gemu_log(const char *fmt, ...)
-{
- va_list ap;
-
- fprintf(stderr, "FATAL: ");
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- exit(1);
-}
-
-#define NO_CHANGE(_path) \
- do { \
- if (strcmp(path(_path), _path) != 0) return __LINE__; \
- } while(0)
-
-#define CHANGE_TO(_path, _newpath) \
- do { \
- if (strcmp(path(_path), _newpath) != 0) return __LINE__; \
- } while(0)
-
-static void cleanup(void)
-{
- unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE");
- unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE2");
- unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE3");
- unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE4");
- unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE5");
- rmdir("/tmp/qemu-test_path/DIR1/DIR2");
- rmdir("/tmp/qemu-test_path/DIR1/DIR3");
- rmdir("/tmp/qemu-test_path/DIR1");
- rmdir("/tmp/qemu-test_path");
-}
-
-static unsigned int do_test(void)
-{
- if (mkdir("/tmp/qemu-test_path", 0700) != 0)
- return __LINE__;
-
- if (mkdir("/tmp/qemu-test_path/DIR1", 0700) != 0)
- return __LINE__;
-
- if (mkdir("/tmp/qemu-test_path/DIR1/DIR2", 0700) != 0)
- return __LINE__;
-
- if (mkdir("/tmp/qemu-test_path/DIR1/DIR3", 0700) != 0)
- return __LINE__;
-
- if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE", 0600)) != 0)
- return __LINE__;
-
- if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE2", 0600)) != 0)
- return __LINE__;
-
- if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE3", 0600)) != 0)
- return __LINE__;
-
- if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE4", 0600)) != 0)
- return __LINE__;
-
- if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE5", 0600)) != 0)
- return __LINE__;
-
- init_paths("/tmp/qemu-test_path");
-
- NO_CHANGE("/tmp");
- NO_CHANGE("/tmp/");
- NO_CHANGE("/tmp/qemu-test_path");
- NO_CHANGE("/tmp/qemu-test_path/");
- NO_CHANGE("/tmp/qemu-test_path/D");
- NO_CHANGE("/tmp/qemu-test_path/DI");
- NO_CHANGE("/tmp/qemu-test_path/DIR");
- NO_CHANGE("/tmp/qemu-test_path/DIR1");
- NO_CHANGE("/tmp/qemu-test_path/DIR1/");
-
- NO_CHANGE("/D");
- NO_CHANGE("/DI");
- NO_CHANGE("/DIR");
- NO_CHANGE("/DIR2");
- NO_CHANGE("/DIR1.");
-
- CHANGE_TO("/DIR1", "/tmp/qemu-test_path/DIR1");
- CHANGE_TO("/DIR1/", "/tmp/qemu-test_path/DIR1");
-
- NO_CHANGE("/DIR1/D");
- NO_CHANGE("/DIR1/DI");
- NO_CHANGE("/DIR1/DIR");
- NO_CHANGE("/DIR1/DIR1");
-
- CHANGE_TO("/DIR1/DIR2", "/tmp/qemu-test_path/DIR1/DIR2");
- CHANGE_TO("/DIR1/DIR2/", "/tmp/qemu-test_path/DIR1/DIR2");
-
- CHANGE_TO("/DIR1/DIR3", "/tmp/qemu-test_path/DIR1/DIR3");
- CHANGE_TO("/DIR1/DIR3/", "/tmp/qemu-test_path/DIR1/DIR3");
-
- NO_CHANGE("/DIR1/DIR2/F");
- NO_CHANGE("/DIR1/DIR2/FI");
- NO_CHANGE("/DIR1/DIR2/FIL");
- NO_CHANGE("/DIR1/DIR2/FIL.");
-
- CHANGE_TO("/DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/DIR1/DIR2/FILE2", "/tmp/qemu-test_path/DIR1/DIR2/FILE2");
- CHANGE_TO("/DIR1/DIR2/FILE3", "/tmp/qemu-test_path/DIR1/DIR2/FILE3");
- CHANGE_TO("/DIR1/DIR2/FILE4", "/tmp/qemu-test_path/DIR1/DIR2/FILE4");
- CHANGE_TO("/DIR1/DIR2/FILE5", "/tmp/qemu-test_path/DIR1/DIR2/FILE5");
-
- NO_CHANGE("/DIR1/DIR2/FILE6");
- NO_CHANGE("/DIR1/DIR2/FILE/X");
-
- CHANGE_TO("/DIR1/../DIR1", "/tmp/qemu-test_path/DIR1");
- CHANGE_TO("/DIR1/../DIR1/", "/tmp/qemu-test_path/DIR1");
- CHANGE_TO("/../DIR1", "/tmp/qemu-test_path/DIR1");
- CHANGE_TO("/../DIR1/", "/tmp/qemu-test_path/DIR1");
- CHANGE_TO("/DIR1/DIR2/../DIR2", "/tmp/qemu-test_path/DIR1/DIR2");
- CHANGE_TO("/DIR1/DIR2/../DIR2/../../DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/DIR1/DIR2/../DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
-
- NO_CHANGE("/DIR1/DIR2/../DIR1");
- NO_CHANGE("/DIR1/DIR2/../FILE");
-
- CHANGE_TO("/./DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/././DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/DIR1/./DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/DIR1/././DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/DIR1/DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/DIR1/DIR2/././FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
- CHANGE_TO("/./DIR1/./DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int ret;
-
- ret = do_test();
- cleanup();
- if (ret) {
- fprintf(stderr, "test_path: failed on line %i\n", ret);
- return 1;
- }
- return 0;
-}
-
diff --git a/tools/ioemu/tests/testthread.c b/tools/ioemu/tests/testthread.c
deleted file mode 100644
index 27e4825bc6..0000000000
--- a/tools/ioemu/tests/testthread.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <pthread.h>
-#include <sys/wait.h>
-#include <sched.h>
-
-void *thread1_func(void *arg)
-{
- int i;
- char buf[512];
-
- for(i=0;i<10;i++) {
- snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg);
- write(1, buf, strlen(buf));
- usleep(100 * 1000);
- }
- return NULL;
-}
-
-void *thread2_func(void *arg)
-{
- int i;
- char buf[512];
- for(i=0;i<20;i++) {
- snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg);
- write(1, buf, strlen(buf));
- usleep(150 * 1000);
- }
- return NULL;
-}
-
-void test_pthread(void)
-{
- pthread_t tid1, tid2;
-
- pthread_create(&tid1, NULL, thread1_func, "hello1");
- pthread_create(&tid2, NULL, thread2_func, "hello2");
- pthread_join(tid1, NULL);
- pthread_join(tid2, NULL);
- printf("End of pthread test.\n");
-}
-
-int main(int argc, char **argv)
-{
- test_pthread();
- return 0;
-}
diff --git a/tools/ioemu/texi2pod.pl b/tools/ioemu/texi2pod.pl
deleted file mode 100644
index 176627e9b9..0000000000
--- a/tools/ioemu/texi2pod.pl
+++ /dev/null
@@ -1,428 +0,0 @@
-#! /usr/bin/perl -w
-
-# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
-
-# This file is part of GNU CC.
-
-# GNU CC is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# GNU CC is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with GNU CC; see the file COPYING. If not, write to
-# the Free Software Foundation, 59 Temple Place - Suite 330,
-# Boston MA 02111-1307, USA.
-
-# This does trivial (and I mean _trivial_) conversion of Texinfo
-# markup to Perl POD format. It's intended to be used to extract
-# something suitable for a manpage from a Texinfo document.
-
-$output = 0;
-$skipping = 0;
-%sects = ();
-$section = "";
-@icstack = ();
-@endwstack = ();
-@skstack = ();
-@instack = ();
-$shift = "";
-%defs = ();
-$fnno = 1;
-$inf = "";
-$ibase = "";
-
-while ($_ = shift) {
- if (/^-D(.*)$/) {
- if ($1 ne "") {
- $flag = $1;
- } else {
- $flag = shift;
- }
- $value = "";
- ($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/);
- die "no flag specified for -D\n"
- unless $flag ne "";
- die "flags may only contain letters, digits, hyphens, dashes and underscores\n"
- unless $flag =~ /^[a-zA-Z0-9_-]+$/;
- $defs{$flag} = $value;
- } elsif (/^-/) {
- usage();
- } else {
- $in = $_, next unless defined $in;
- $out = $_, next unless defined $out;
- usage();
- }
-}
-
-if (defined $in) {
- $inf = gensym();
- open($inf, "<$in") or die "opening \"$in\": $!\n";
- $ibase = $1 if $in =~ m|^(.+)/[^/]+$|;
-} else {
- $inf = \*STDIN;
-}
-
-if (defined $out) {
- open(STDOUT, ">$out") or die "opening \"$out\": $!\n";
-}
-
-while(defined $inf) {
-while(<$inf>) {
- # Certain commands are discarded without further processing.
- /^\@(?:
- [a-z]+index # @*index: useful only in complete manual
- |need # @need: useful only in printed manual
- |(?:end\s+)?group # @group .. @end group: ditto
- |page # @page: ditto
- |node # @node: useful only in .info file
- |(?:end\s+)?ifnottex # @ifnottex .. @end ifnottex: use contents
- )\b/x and next;
-
- chomp;
-
- # Look for filename and title markers.
- /^\@setfilename\s+([^.]+)/ and $fn = $1, next;
- /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next;
-
- # Identify a man title but keep only the one we are interested in.
- /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do {
- if (exists $defs{$1}) {
- $fn = $1;
- $tl = postprocess($2);
- }
- next;
- };
-
- # Look for blocks surrounded by @c man begin SECTION ... @c man end.
- # This really oughta be @ifman ... @end ifman and the like, but such
- # would require rev'ing all other Texinfo translators.
- /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do {
- $output = 1 if exists $defs{$2};
- $sect = $1;
- next;
- };
- /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next;
- /^\@c\s+man\s+end/ and do {
- $sects{$sect} = "" unless exists $sects{$sect};
- $sects{$sect} .= postprocess($section);
- $section = "";
- $output = 0;
- next;
- };
-
- # handle variables
- /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do {
- $defs{$1} = $2;
- next;
- };
- /^\@clear\s+([a-zA-Z0-9_-]+)/ and do {
- delete $defs{$1};
- next;
- };
-
- next unless $output;
-
- # Discard comments. (Can't do it above, because then we'd never see
- # @c man lines.)
- /^\@c\b/ and next;
-
- # End-block handler goes up here because it needs to operate even
- # if we are skipping.
- /^\@end\s+([a-z]+)/ and do {
- # Ignore @end foo, where foo is not an operation which may
- # cause us to skip, if we are presently skipping.
- my $ended = $1;
- next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/;
-
- die "\@end $ended without \@$ended at line $.\n" unless defined $endw;
- die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw;
-
- $endw = pop @endwstack;
-
- if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
- $skipping = pop @skstack;
- next;
- } elsif ($ended =~ /^(?:example|smallexample|display)$/) {
- $shift = "";
- $_ = ""; # need a paragraph break
- } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
- $_ = "\n=back\n";
- $ic = pop @icstack;
- } else {
- die "unknown command \@end $ended at line $.\n";
- }
- };
-
- # We must handle commands which can cause skipping even while we
- # are skipping, otherwise we will not process nested conditionals
- # correctly.
- /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do {
- push @endwstack, $endw;
- push @skstack, $skipping;
- $endw = "ifset";
- $skipping = 1 unless exists $defs{$1};
- next;
- };
-
- /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do {
- push @endwstack, $endw;
- push @skstack, $skipping;
- $endw = "ifclear";
- $skipping = 1 if exists $defs{$1};
- next;
- };
-
- /^\@(ignore|menu|iftex)\b/ and do {
- push @endwstack, $endw;
- push @skstack, $skipping;
- $endw = $1;
- $skipping = 1;
- next;
- };
-
- next if $skipping;
-
- # Character entities. First the ones that can be replaced by raw text
- # or discarded outright:
- s/\@copyright\{\}/(c)/g;
- s/\@dots\{\}/.../g;
- s/\@enddots\{\}/..../g;
- s/\@([.!? ])/$1/g;
- s/\@[:-]//g;
- s/\@bullet(?:\{\})?/*/g;
- s/\@TeX\{\}/TeX/g;
- s/\@pounds\{\}/\#/g;
- s/\@minus(?:\{\})?/-/g;
- s/\\,/,/g;
-
- # Now the ones that have to be replaced by special escapes
- # (which will be turned back into text by unmunge())
- s/&/&amp;/g;
- s/\@\{/&lbrace;/g;
- s/\@\}/&rbrace;/g;
- s/\@\@/&at;/g;
-
- # Inside a verbatim block, handle @var specially.
- if ($shift ne "") {
- s/\@var\{([^\}]*)\}/<$1>/g;
- }
-
- # POD doesn't interpret E<> inside a verbatim block.
- if ($shift eq "") {
- s/</&lt;/g;
- s/>/&gt;/g;
- } else {
- s/</&LT;/g;
- s/>/&GT;/g;
- }
-
- # Single line command handlers.
-
- /^\@include\s+(.+)$/ and do {
- push @instack, $inf;
- $inf = gensym();
-
- # Try cwd and $ibase.
- open($inf, "<" . $1)
- or open($inf, "<" . $ibase . "/" . $1)
- or die "cannot open $1 or $ibase/$1: $!\n";
- next;
- };
-
- /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/
- and $_ = "\n=head2 $1\n";
- /^\@subsection\s+(.+)$/
- and $_ = "\n=head3 $1\n";
-
- # Block command handlers:
- /^\@itemize\s+(\@[a-z]+|\*|-)/ and do {
- push @endwstack, $endw;
- push @icstack, $ic;
- $ic = $1;
- $_ = "\n=over 4\n";
- $endw = "itemize";
- };
-
- /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do {
- push @endwstack, $endw;
- push @icstack, $ic;
- if (defined $1) {
- $ic = $1 . ".";
- } else {
- $ic = "1.";
- }
- $_ = "\n=over 4\n";
- $endw = "enumerate";
- };
-
- /^\@([fv]?table)\s+(\@[a-z]+)/ and do {
- push @endwstack, $endw;
- push @icstack, $ic;
- $endw = $1;
- $ic = $2;
- $ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/;
- $ic =~ s/\@(?:code|kbd)/C/;
- $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
- $ic =~ s/\@(?:file)/F/;
- $_ = "\n=over 4\n";
- };
-
- /^\@((?:small)?example|display)/ and do {
- push @endwstack, $endw;
- $endw = $1;
- $shift = "\t";
- $_ = ""; # need a paragraph break
- };
-
- /^\@itemx?\s*(.+)?$/ and do {
- if (defined $1) {
- # Entity escapes prevent munging by the <> processing below.
-# print "$ic\n";
- $_ = "\n=item $ic\&LT;$1\&GT;\n";
- } else {
- $_ = "\n=item $ic\n";
- $ic =~ y/A-Ya-y/B-Zb-z/;
- $ic =~ s/(\d+)/$1 + 1/eg;
- }
- };
-
- $section .= $shift.$_."\n";
-}
-# End of current file.
-close($inf);
-$inf = pop @instack;
-}
-
-die "No filename or title\n" unless defined $fn && defined $tl;
-
-$sects{NAME} = "$fn \- $tl\n";
-$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
-
-for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES
- BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) {
- if(exists $sects{$sect}) {
- $head = $sect;
- $head =~ s/SEEALSO/SEE ALSO/;
- print "=head1 $head\n\n";
- print scalar unmunge ($sects{$sect});
- print "\n";
- }
-}
-
-sub usage
-{
- die "usage: $0 [-D toggle...] [infile [outfile]]\n";
-}
-
-sub postprocess
-{
- local $_ = $_[0];
-
- # @value{foo} is replaced by whatever 'foo' is defined as.
- while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) {
- if (! exists $defs{$2}) {
- print STDERR "Option $2 not defined\n";
- s/\Q$1\E//;
- } else {
- $value = $defs{$2};
- s/\Q$1\E/$value/;
- }
- }
-
- # Formatting commands.
- # Temporary escape for @r.
- s/\@r\{([^\}]*)\}/R<$1>/g;
- s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g;
- s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g;
- s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
- s/\@sc\{([^\}]*)\}/\U$1/g;
- s/\@file\{([^\}]*)\}/F<$1>/g;
- s/\@w\{([^\}]*)\}/S<$1>/g;
- s/\@(?:dmn|math)\{([^\}]*)\}/$1/g;
-
- # Cross references are thrown away, as are @noindent and @refill.
- # (@noindent is impossible in .pod, and @refill is unnecessary.)
- # @* is also impossible in .pod; we discard it and any newline that
- # follows it. Similarly, our macro @gol must be discarded.
-
- s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
- s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
- s/;\s+\@pxref\{(?:[^\}]*)\}//g;
- s/\@noindent\s*//g;
- s/\@refill//g;
- s/\@gol//g;
- s/\@\*\s*\n?//g;
-
- # @uref can take one, two, or three arguments, with different
- # semantics each time. @url and @email are just like @uref with
- # one argument, for our purposes.
- s/\@(?:uref|url|email)\{([^\},]*)\}/&lt;B<$1>&gt;/g;
- s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
- s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
-
- # Turn B<blah I<blah> blah> into B<blah> I<blah> B<blah> to
- # match Texinfo semantics of @emph inside @samp. Also handle @r
- # inside bold.
- s/&LT;/</g;
- s/&GT;/>/g;
- 1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B</g;
- 1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B</g);
- 1 while (s/I<([^<>]*)B<([^>]+)>/I<$1>B<$2>I</g);
- s/[BI]<>//g;
- s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g;
- s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g;
-
- # Extract footnotes. This has to be done after all other
- # processing because otherwise the regexp will choke on formatting
- # inside @footnote.
- while (/\@footnote/g) {
- s/\@footnote\{([^\}]+)\}/[$fnno]/;
- add_footnote($1, $fnno);
- $fnno++;
- }
-
- return $_;
-}
-
-sub unmunge
-{
- # Replace escaped symbols with their equivalents.
- local $_ = $_[0];
-
- s/&lt;/E<lt>/g;
- s/&gt;/E<gt>/g;
- s/&lbrace;/\{/g;
- s/&rbrace;/\}/g;
- s/&at;/\@/g;
- s/&amp;/&/g;
- return $_;
-}
-
-sub add_footnote
-{
- unless (exists $sects{FOOTNOTES}) {
- $sects{FOOTNOTES} = "\n=over 4\n\n";
- }
-
- $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
- $sects{FOOTNOTES} .= $_[0];
- $sects{FOOTNOTES} .= "\n\n";
-}
-
-# stolen from Symbol.pm
-{
- my $genseq = 0;
- sub gensym
- {
- my $name = "GEN" . $genseq++;
- my $ref = \*{$name};
- delete $::{$name};
- return $ref;
- }
-}
diff --git a/tools/ioemu/thunk.c b/tools/ioemu/thunk.c
deleted file mode 100644
index bc9bd28819..0000000000
--- a/tools/ioemu/thunk.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Generic thunking code to convert data between host and target CPU
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "qemu.h"
-#include "thunk.h"
-
-//#define DEBUG
-
-#define MAX_STRUCTS 128
-
-/* XXX: make it dynamic */
-StructEntry struct_entries[MAX_STRUCTS];
-
-static inline const argtype *thunk_type_next(const argtype *type_ptr)
-{
- int type;
-
- type = *type_ptr++;
- switch(type) {
- case TYPE_CHAR:
- case TYPE_SHORT:
- case TYPE_INT:
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- return type_ptr;
- case TYPE_PTR:
- return thunk_type_next(type_ptr);
- case TYPE_ARRAY:
- return thunk_type_next(type_ptr + 1);
- case TYPE_STRUCT:
- return type_ptr + 1;
- default:
- return NULL;
- }
-}
-
-void thunk_register_struct(int id, const char *name, const argtype *types)
-{
- const argtype *type_ptr;
- StructEntry *se;
- int nb_fields, offset, max_align, align, size, i, j;
-
- se = struct_entries + id;
-
- /* first we count the number of fields */
- type_ptr = types;
- nb_fields = 0;
- while (*type_ptr != TYPE_NULL) {
- type_ptr = thunk_type_next(type_ptr);
- nb_fields++;
- }
- se->field_types = types;
- se->nb_fields = nb_fields;
- se->name = name;
-#ifdef DEBUG
- printf("struct %s: id=%d nb_fields=%d\n",
- se->name, id, se->nb_fields);
-#endif
- /* now we can alloc the data */
-
- for(i = 0;i < 2; i++) {
- offset = 0;
- max_align = 1;
- se->field_offsets[i] = malloc(nb_fields * sizeof(int));
- type_ptr = se->field_types;
- for(j = 0;j < nb_fields; j++) {
- size = thunk_type_size(type_ptr, i);
- align = thunk_type_align(type_ptr, i);
- offset = (offset + align - 1) & ~(align - 1);
- se->field_offsets[i][j] = offset;
- offset += size;
- if (align > max_align)
- max_align = align;
- type_ptr = thunk_type_next(type_ptr);
- }
- offset = (offset + max_align - 1) & ~(max_align - 1);
- se->size[i] = offset;
- se->align[i] = max_align;
-#ifdef DEBUG
- printf("%s: size=%d align=%d\n",
- i == THUNK_HOST ? "host" : "target", offset, max_align);
-#endif
- }
-}
-
-void thunk_register_struct_direct(int id, const char *name, StructEntry *se1)
-{
- StructEntry *se;
- se = struct_entries + id;
- *se = *se1;
- se->name = name;
-}
-
-
-/* now we can define the main conversion functions */
-const argtype *thunk_convert(void *dst, const void *src,
- const argtype *type_ptr, int to_host)
-{
- int type;
-
- type = *type_ptr++;
- switch(type) {
- case TYPE_CHAR:
- *(uint8_t *)dst = *(uint8_t *)src;
- break;
- case TYPE_SHORT:
- *(uint16_t *)dst = tswap16(*(uint16_t *)src);
- break;
- case TYPE_INT:
- *(uint32_t *)dst = tswap32(*(uint32_t *)src);
- break;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- *(uint64_t *)dst = tswap64(*(uint64_t *)src);
- break;
-#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- *(uint32_t *)dst = tswap32(*(uint32_t *)src);
- break;
-#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- if (to_host) {
- *(uint64_t *)dst = tswap32(*(uint32_t *)src);
- } else {
- *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
- }
- break;
-#else
-#warning unsupported conversion
-#endif
- case TYPE_ARRAY:
- {
- int array_length, i, dst_size, src_size;
- const uint8_t *s;
- uint8_t *d;
-
- array_length = *type_ptr++;
- dst_size = thunk_type_size(type_ptr, to_host);
- src_size = thunk_type_size(type_ptr, 1 - to_host);
- d = dst;
- s = src;
- for(i = 0;i < array_length; i++) {
- thunk_convert(d, s, type_ptr, to_host);
- d += dst_size;
- s += src_size;
- }
- type_ptr = thunk_type_next(type_ptr);
- }
- break;
- case TYPE_STRUCT:
- {
- int i;
- const StructEntry *se;
- const uint8_t *s;
- uint8_t *d;
- const argtype *field_types;
- const int *dst_offsets, *src_offsets;
-
- se = struct_entries + *type_ptr++;
- if (se->convert[0] != NULL) {
- /* specific conversion is needed */
- (*se->convert[to_host])(dst, src);
- } else {
- /* standard struct conversion */
- field_types = se->field_types;
- dst_offsets = se->field_offsets[to_host];
- src_offsets = se->field_offsets[1 - to_host];
- d = dst;
- s = src;
- for(i = 0;i < se->nb_fields; i++) {
- field_types = thunk_convert(d + dst_offsets[i],
- s + src_offsets[i],
- field_types, to_host);
- }
- }
- }
- break;
- default:
- fprintf(stderr, "Invalid type 0x%x\n", type);
- break;
- }
- return type_ptr;
-}
-
-/* from em86 */
-
-/* Utility function: Table-driven functions to translate bitmasks
- * between X86 and Alpha formats...
- */
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
- bitmask_transtbl * trans_tbl)
-{
- bitmask_transtbl * btp;
- unsigned int alpha_mask = 0;
-
- for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
- if((x86_mask & btp->x86_mask) == btp->x86_bits) {
- alpha_mask |= btp->alpha_bits;
- }
- }
- return(alpha_mask);
-}
-
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
- bitmask_transtbl * trans_tbl)
-{
- bitmask_transtbl * btp;
- unsigned int x86_mask = 0;
-
- for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
- if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) {
- x86_mask |= btp->x86_bits;
- }
- }
- return(x86_mask);
-}
diff --git a/tools/ioemu/thunk.h b/tools/ioemu/thunk.h
deleted file mode 100644
index 42fd96f3a3..0000000000
--- a/tools/ioemu/thunk.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Generic thunking code to convert data between host and target CPU
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef THUNK_H
-#define THUNK_H
-
-#include <inttypes.h>
-#include "cpu.h"
-
-/* types enums definitions */
-
-typedef enum argtype {
- TYPE_NULL,
- TYPE_CHAR,
- TYPE_SHORT,
- TYPE_INT,
- TYPE_LONG,
- TYPE_ULONG,
- TYPE_PTRVOID, /* pointer on unknown data */
- TYPE_LONGLONG,
- TYPE_ULONGLONG,
- TYPE_PTR,
- TYPE_ARRAY,
- TYPE_STRUCT,
-} argtype;
-
-#define MK_PTR(type) TYPE_PTR, type
-#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
-#define MK_STRUCT(id) TYPE_STRUCT, id
-
-#define THUNK_TARGET 0
-#define THUNK_HOST 1
-
-typedef struct {
- /* standard struct handling */
- const argtype *field_types;
- int nb_fields;
- int *field_offsets[2];
- /* special handling */
- void (*convert[2])(void *dst, const void *src);
- int size[2];
- int align[2];
- const char *name;
-} StructEntry;
-
-/* Translation table for bitmasks... */
-typedef struct bitmask_transtbl {
- unsigned int x86_mask;
- unsigned int x86_bits;
- unsigned int alpha_mask;
- unsigned int alpha_bits;
-} bitmask_transtbl;
-
-void thunk_register_struct(int id, const char *name, const argtype *types);
-void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
-const argtype *thunk_convert(void *dst, const void *src,
- const argtype *type_ptr, int to_host);
-#ifndef NO_THUNK_TYPE_SIZE
-
-extern StructEntry struct_entries[];
-
-static inline int thunk_type_size(const argtype *type_ptr, int is_host)
-{
- int type, size;
- const StructEntry *se;
-
- type = *type_ptr;
- switch(type) {
- case TYPE_CHAR:
- return 1;
- case TYPE_SHORT:
- return 2;
- case TYPE_INT:
- return 4;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- return 8;
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- case TYPE_PTR:
- if (is_host) {
- return HOST_LONG_SIZE;
- } else {
- return TARGET_LONG_SIZE;
- }
- break;
- case TYPE_ARRAY:
- size = type_ptr[1];
- return size * thunk_type_size(type_ptr + 2, is_host);
- case TYPE_STRUCT:
- se = struct_entries + type_ptr[1];
- return se->size[is_host];
- default:
- return -1;
- }
-}
-
-static inline int thunk_type_align(const argtype *type_ptr, int is_host)
-{
- int type;
- const StructEntry *se;
-
- type = *type_ptr;
- switch(type) {
- case TYPE_CHAR:
- return 1;
- case TYPE_SHORT:
- return 2;
- case TYPE_INT:
- return 4;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- return 8;
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- case TYPE_PTR:
- if (is_host) {
- return HOST_LONG_SIZE;
- } else {
- return TARGET_LONG_SIZE;
- }
- break;
- case TYPE_ARRAY:
- return thunk_type_align(type_ptr + 2, is_host);
- case TYPE_STRUCT:
- se = struct_entries + type_ptr[1];
- return se->align[is_host];
- default:
- return -1;
- }
-}
-
-#endif /* NO_THUNK_TYPE_SIZE */
-
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
- bitmask_transtbl * trans_tbl);
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
- bitmask_transtbl * trans_tbl);
-
-#endif
diff --git a/tools/ioemu/translate-all.c b/tools/ioemu/translate-all.c
deleted file mode 100644
index 43365478bd..0000000000
--- a/tools/ioemu/translate-all.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Host code generation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-
-#define NO_CPU_IO_DEFS
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-
-extern int dyngen_code(uint8_t *gen_code_buf,
- uint16_t *label_offsets, uint16_t *jmp_offsets,
- const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels);
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
- NB_OPS,
-};
-
-uint16_t gen_opc_buf[OPC_BUF_SIZE];
-uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
-long gen_labels[OPC_BUF_SIZE];
-int nb_gen_labels;
-
-target_ulong gen_opc_pc[OPC_BUF_SIZE];
-uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-#if defined(TARGET_I386)
-uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
-#elif defined(TARGET_SPARC)
-target_ulong gen_opc_npc[OPC_BUF_SIZE];
-target_ulong gen_opc_jump_pc[2];
-#elif defined(TARGET_MIPS)
-uint32_t gen_opc_hflags[OPC_BUF_SIZE];
-#endif
-
-int code_copy_enabled = 1;
-
-#ifdef DEBUG_DISAS
-static const char *op_str[] = {
-#define DEF(s, n, copy_size) #s,
-#include "opc.h"
-#undef DEF
-};
-
-static uint8_t op_nb_args[] = {
-#define DEF(s, n, copy_size) n,
-#include "opc.h"
-#undef DEF
-};
-
-static const unsigned short opc_copy_size[] = {
-#define DEF(s, n, copy_size) copy_size,
-#include "opc.h"
-#undef DEF
-};
-
-void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf)
-{
- const uint16_t *opc_ptr;
- const uint32_t *opparam_ptr;
- int c, n, i;
-
- opc_ptr = opc_buf;
- opparam_ptr = opparam_buf;
- for(;;) {
- c = *opc_ptr++;
- n = op_nb_args[c];
- fprintf(logfile, "0x%04x: %s",
- (int)(opc_ptr - opc_buf - 1), op_str[c]);
- for(i = 0; i < n; i++) {
- fprintf(logfile, " 0x%x", opparam_ptr[i]);
- }
- fprintf(logfile, "\n");
- if (c == INDEX_op_end)
- break;
- opparam_ptr += n;
- }
-}
-
-#endif
-
-/* compute label info */
-static void dyngen_labels(long *gen_labels, int nb_gen_labels,
- uint8_t *gen_code_buf, const uint16_t *opc_buf)
-{
- uint8_t *gen_code_ptr;
- int c, i;
- unsigned long gen_code_addr[OPC_BUF_SIZE];
-
- if (nb_gen_labels == 0)
- return;
- /* compute the address of each op code */
-
- gen_code_ptr = gen_code_buf;
- i = 0;
- for(;;) {
- c = opc_buf[i];
- gen_code_addr[i] =(unsigned long)gen_code_ptr;
- if (c == INDEX_op_end)
- break;
- gen_code_ptr += opc_copy_size[c];
- i++;
- }
-
- /* compute the address of each label */
- for(i = 0; i < nb_gen_labels; i++) {
- gen_labels[i] = gen_code_addr[gen_labels[i]];
- }
-}
-
-/* return non zero if the very first instruction is invalid so that
- the virtual CPU can trigger an exception.
-
- '*gen_code_size_ptr' contains the size of the generated code (host
- code).
-*/
-int cpu_gen_code(CPUState *env, TranslationBlock *tb,
- int max_code_size, int *gen_code_size_ptr)
-{
- uint8_t *gen_code_buf;
- int gen_code_size;
-
-#ifdef USE_CODE_COPY
- if (code_copy_enabled &&
- cpu_gen_code_copy(env, tb, max_code_size, &gen_code_size) == 0) {
- /* nothing more to do */
- } else
-#endif
- {
- if (gen_intermediate_code(env, tb) < 0)
- return -1;
-
- /* generate machine code */
- tb->tb_next_offset[0] = 0xffff;
- tb->tb_next_offset[1] = 0xffff;
- gen_code_buf = tb->tc_ptr;
-#ifdef USE_DIRECT_JUMP
- /* the following two entries are optional (only used for string ops) */
- tb->tb_jmp_offset[2] = 0xffff;
- tb->tb_jmp_offset[3] = 0xffff;
-#endif
- dyngen_labels(gen_labels, nb_gen_labels, gen_code_buf, gen_opc_buf);
-
- gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset,
-#ifdef USE_DIRECT_JUMP
- tb->tb_jmp_offset,
-#else
- NULL,
-#endif
- gen_opc_buf, gen_opparam_buf, gen_labels);
- }
- *gen_code_size_ptr = gen_code_size;
-#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_OUT_ASM) {
- fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
- disas(logfile, tb->tc_ptr, *gen_code_size_ptr);
- fprintf(logfile, "\n");
- fflush(logfile);
- }
-#endif
- return 0;
-}
-
-/* The cpu state corresponding to 'searched_pc' is restored.
- */
-int cpu_restore_state(TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc)
-{
- int j, c;
- unsigned long tc_ptr;
- uint16_t *opc_ptr;
-
-#ifdef USE_CODE_COPY
- if (tb->cflags & CF_CODE_COPY) {
- return cpu_restore_state_copy(tb, env, searched_pc, puc);
- }
-#endif
- if (gen_intermediate_code_pc(env, tb) < 0)
- return -1;
-
- /* find opc index corresponding to search_pc */
- tc_ptr = (unsigned long)tb->tc_ptr;
- if (searched_pc < tc_ptr)
- return -1;
- j = 0;
- opc_ptr = gen_opc_buf;
- for(;;) {
- c = *opc_ptr;
- if (c == INDEX_op_end)
- return -1;
- tc_ptr += opc_copy_size[c];
- if (searched_pc < tc_ptr)
- break;
- opc_ptr++;
- }
- j = opc_ptr - gen_opc_buf;
- /* now find start of instruction before */
- while (gen_opc_instr_start[j] == 0)
- j--;
-#if defined(TARGET_I386)
- {
- int cc_op;
-#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_OP) {
- int i;
- fprintf(logfile, "RESTORE:\n");
- for(i=0;i<=j; i++) {
- if (gen_opc_instr_start[i]) {
- fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
- }
- }
- fprintf(logfile, "spc=0x%08lx j=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
- searched_pc, j, gen_opc_pc[j] - tb->cs_base,
- (uint32_t)tb->cs_base);
- }
-#endif
- env->eip = gen_opc_pc[j] - tb->cs_base;
- cc_op = gen_opc_cc_op[j];
- if (cc_op != CC_OP_DYNAMIC)
- env->cc_op = cc_op;
- }
-#elif defined(TARGET_ARM)
- env->regs[15] = gen_opc_pc[j];
-#elif defined(TARGET_SPARC)
- {
- target_ulong npc;
- env->pc = gen_opc_pc[j];
- npc = gen_opc_npc[j];
- if (npc == 1) {
- /* dynamic NPC: already stored */
- } else if (npc == 2) {
- target_ulong t2 = (target_ulong)puc;
- /* jump PC: use T2 and the jump targets of the translation */
- if (t2)
- env->npc = gen_opc_jump_pc[0];
- else
- env->npc = gen_opc_jump_pc[1];
- } else {
- env->npc = npc;
- }
- }
-#elif defined(TARGET_PPC)
- {
- int type;
- /* for PPC, we need to look at the micro operation to get the
- access type */
- env->nip = gen_opc_pc[j];
- switch(c) {
-#if defined(CONFIG_USER_ONLY)
-#define CASE3(op)\
- case INDEX_op_ ## op ## _raw
-#else
-#define CASE3(op)\
- case INDEX_op_ ## op ## _user:\
- case INDEX_op_ ## op ## _kernel
-#endif
-
- CASE3(stfd):
- CASE3(stfs):
- CASE3(lfd):
- CASE3(lfs):
- type = ACCESS_FLOAT;
- break;
- CASE3(lwarx):
- type = ACCESS_RES;
- break;
- CASE3(stwcx):
- type = ACCESS_RES;
- break;
- CASE3(eciwx):
- CASE3(ecowx):
- type = ACCESS_EXT;
- break;
- default:
- type = ACCESS_INT;
- break;
- }
- env->access_type = type;
- }
-#elif defined(TARGET_M68K)
- env->pc = gen_opc_pc[j];
-#elif defined(TARGET_MIPS)
- env->PC = gen_opc_pc[j];
- env->hflags &= ~MIPS_HFLAG_BMASK;
- env->hflags |= gen_opc_hflags[j];
-#endif
- return 0;
-}
diff --git a/tools/ioemu/translate-op.c b/tools/ioemu/translate-op.c
deleted file mode 100644
index fddac70c4a..0000000000
--- a/tools/ioemu/translate-op.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Host code generation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
- NB_OPS,
-};
-
-#include "dyngen.h"
-#include "op.h"
-
diff --git a/tools/ioemu/usb-linux.c b/tools/ioemu/usb-linux.c
deleted file mode 100644
index b757066ae6..0000000000
--- a/tools/ioemu/usb-linux.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Linux host USB redirector
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#if defined(__linux__)
-#include <dirent.h>
-#include <sys/ioctl.h>
-/* Some versions of usbdevice_fs.h need __user to be defined for them. */
-/* This may (harmlessly) conflict with a definition in linux/compiler.h. */
-#define __user
-#include <linux/usbdevice_fs.h>
-#include <linux/version.h>
-
-/* We redefine it to avoid version problems */
-struct usb_ctrltransfer {
- uint8_t bRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
- uint32_t timeout;
- void *data;
-};
-
-typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed);
-static int usb_host_find_device(int *pbus_num, int *paddr,
- char *product_name, int product_name_size,
- const char *devname);
-
-//#define DEBUG
-
-#define USBDEVFS_PATH "/proc/bus/usb"
-#define PRODUCT_NAME_SZ 32
-
-typedef struct USBHostDevice {
- USBDevice dev;
- int fd;
-} USBHostDevice;
-
-static void usb_host_handle_reset(USBDevice *dev)
-{
-#if 0
- USBHostDevice *s = (USBHostDevice *)dev;
- /* USBDEVFS_RESET, but not the first time as it has already be
- done by the host OS */
- ioctl(s->fd, USBDEVFS_RESET);
-#endif
-}
-
-static void usb_host_handle_destroy(USBDevice *dev)
-{
- USBHostDevice *s = (USBHostDevice *)dev;
-
- if (s->fd >= 0)
- close(s->fd);
- qemu_free(s);
-}
-
-static int usb_host_handle_control(USBDevice *dev,
- int request,
- int value,
- int index,
- int length,
- uint8_t *data)
-{
- USBHostDevice *s = (USBHostDevice *)dev;
- struct usb_ctrltransfer ct;
- int ret;
-
- if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
- /* specific SET_ADDRESS support */
- dev->addr = value;
- return 0;
- } else {
- ct.bRequestType = request >> 8;
- ct.bRequest = request;
- ct.wValue = value;
- ct.wIndex = index;
- ct.wLength = length;
- ct.timeout = 50;
- ct.data = data;
- ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
- if (ret < 0) {
- switch(errno) {
- case ETIMEDOUT:
- return USB_RET_NAK;
- default:
- return USB_RET_STALL;
- }
- } else {
- return ret;
- }
- }
-}
-
-static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
-{
- USBHostDevice *s = (USBHostDevice *)dev;
- struct usbdevfs_bulktransfer bt;
- int ret;
- uint8_t devep = p->devep;
-
- /* XXX: optimize and handle all data types by looking at the
- config descriptor */
- if (p->pid == USB_TOKEN_IN)
- devep |= 0x80;
- bt.ep = devep;
- bt.len = p->len;
- bt.timeout = 50;
- bt.data = p->data;
- ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
- if (ret < 0) {
- switch(errno) {
- case ETIMEDOUT:
- return USB_RET_NAK;
- case EPIPE:
- default:
-#ifdef DEBUG
- printf("handle_data: errno=%d\n", errno);
-#endif
- return USB_RET_STALL;
- }
- } else {
- return ret;
- }
-}
-
-/* XXX: exclude high speed devices or implement EHCI */
-USBDevice *usb_host_device_open(const char *devname)
-{
- int fd, interface, ret, i;
- USBHostDevice *dev;
- struct usbdevfs_connectinfo ci;
- uint8_t descr[1024];
- char buf[1024];
- int descr_len, dev_descr_len, config_descr_len, nb_interfaces;
- int bus_num, addr;
- char product_name[PRODUCT_NAME_SZ];
-
- if (usb_host_find_device(&bus_num, &addr,
- product_name, sizeof(product_name),
- devname) < 0)
- return NULL;
-
- snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
- bus_num, addr);
- fd = open(buf, O_RDWR);
- if (fd < 0) {
- perror(buf);
- return NULL;
- }
-
- /* read the config description */
- descr_len = read(fd, descr, sizeof(descr));
- if (descr_len <= 0) {
- perror("read descr");
- goto fail;
- }
-
- i = 0;
- dev_descr_len = descr[0];
- if (dev_descr_len > descr_len)
- goto fail;
- i += dev_descr_len;
- config_descr_len = descr[i];
- if (i + config_descr_len > descr_len)
- goto fail;
- nb_interfaces = descr[i + 4];
- if (nb_interfaces != 1) {
- /* NOTE: currently we grab only one interface */
- fprintf(stderr, "usb_host: only one interface supported\n");
- goto fail;
- }
-
-#ifdef USBDEVFS_DISCONNECT
- /* earlier Linux 2.4 do not support that */
- {
- struct usbdevfs_ioctl ctrl;
- ctrl.ioctl_code = USBDEVFS_DISCONNECT;
- ctrl.ifno = 0;
- ret = ioctl(fd, USBDEVFS_IOCTL, &ctrl);
- if (ret < 0 && errno != ENODATA) {
- perror("USBDEVFS_DISCONNECT");
- goto fail;
- }
- }
-#endif
-
- /* XXX: only grab if all interfaces are free */
- interface = 0;
- ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
- if (ret < 0) {
- if (errno == EBUSY) {
- fprintf(stderr, "usb_host: device already grabbed\n");
- } else {
- perror("USBDEVFS_CLAIMINTERFACE");
- }
- fail:
- close(fd);
- return NULL;
- }
-
- ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
- if (ret < 0) {
- perror("USBDEVFS_CONNECTINFO");
- goto fail;
- }
-
-#ifdef DEBUG
- printf("host USB device %d.%d grabbed\n", bus_num, addr);
-#endif
-
- dev = qemu_mallocz(sizeof(USBHostDevice));
- if (!dev)
- goto fail;
- dev->fd = fd;
- if (ci.slow)
- dev->dev.speed = USB_SPEED_LOW;
- else
- dev->dev.speed = USB_SPEED_HIGH;
- dev->dev.handle_packet = usb_generic_handle_packet;
-
- dev->dev.handle_reset = usb_host_handle_reset;
- dev->dev.handle_control = usb_host_handle_control;
- dev->dev.handle_data = usb_host_handle_data;
- dev->dev.handle_destroy = usb_host_handle_destroy;
-
- if (product_name[0] == '\0')
- snprintf(dev->dev.devname, sizeof(dev->dev.devname),
- "host:%s", devname);
- else
- pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
- product_name);
-
- return (USBDevice *)dev;
-}
-
-static int get_tag_value(char *buf, int buf_size,
- const char *str, const char *tag,
- const char *stopchars)
-{
- const char *p;
- char *q;
- p = strstr(str, tag);
- if (!p)
- return -1;
- p += strlen(tag);
- while (isspace((uint8_t)*p))
- p++;
- q = buf;
- while (*p != '\0' && !strchr(stopchars, *p)) {
- if ((q - buf) < (buf_size - 1))
- *q++ = *p;
- p++;
- }
- *q = '\0';
- return q - buf;
-}
-
-static int usb_host_scan(void *opaque, USBScanFunc *func)
-{
- FILE *f;
- char line[1024];
- char buf[1024];
- int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
- int ret;
- char product_name[512];
-
- f = fopen(USBDEVFS_PATH "/devices", "r");
- if (!f) {
- term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
- return 0;
- }
- device_count = 0;
- bus_num = addr = speed = class_id = product_id = vendor_id = 0;
- ret = 0;
- for(;;) {
- if (fgets(line, sizeof(line), f) == NULL)
- break;
- if (strlen(line) > 0)
- line[strlen(line) - 1] = '\0';
- if (line[0] == 'T' && line[1] == ':') {
- if (device_count && (vendor_id || product_id)) {
- /* New device. Add the previously discovered device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
- if (ret)
- goto the_end;
- }
- if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
- goto fail;
- bus_num = atoi(buf);
- if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
- goto fail;
- addr = atoi(buf);
- if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
- goto fail;
- if (!strcmp(buf, "480"))
- speed = USB_SPEED_HIGH;
- else if (!strcmp(buf, "1.5"))
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- product_name[0] = '\0';
- class_id = 0xff;
- device_count++;
- product_id = 0;
- vendor_id = 0;
- } else if (line[0] == 'P' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
- goto fail;
- vendor_id = strtoul(buf, NULL, 16);
- if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
- goto fail;
- product_id = strtoul(buf, NULL, 16);
- } else if (line[0] == 'S' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
- goto fail;
- pstrcpy(product_name, sizeof(product_name), buf);
- } else if (line[0] == 'D' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
- goto fail;
- class_id = strtoul(buf, NULL, 16);
- }
- fail: ;
- }
- if (device_count && (vendor_id || product_id)) {
- /* Add the last device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
- }
- the_end:
- fclose(f);
- return ret;
-}
-
-typedef struct FindDeviceState {
- int vendor_id;
- int product_id;
- int bus_num;
- int addr;
- char product_name[PRODUCT_NAME_SZ];
-} FindDeviceState;
-
-static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed)
-{
- FindDeviceState *s = opaque;
- if ((vendor_id == s->vendor_id &&
- product_id == s->product_id) ||
- (bus_num == s->bus_num &&
- addr == s->addr)) {
- pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
- s->bus_num = bus_num;
- s->addr = addr;
- return 1;
- } else {
- return 0;
- }
-}
-
-/* the syntax is :
- 'bus.addr' (decimal numbers) or
- 'vendor_id:product_id' (hexa numbers) */
-static int usb_host_find_device(int *pbus_num, int *paddr,
- char *product_name, int product_name_size,
- const char *devname)
-{
- const char *p;
- int ret;
- FindDeviceState fs;
-
- p = strchr(devname, '.');
- if (p) {
- *pbus_num = strtoul(devname, NULL, 0);
- *paddr = strtoul(p + 1, NULL, 0);
- fs.bus_num = *pbus_num;
- fs.addr = *paddr;
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret)
- pstrcpy(product_name, product_name_size, fs.product_name);
- return 0;
- }
- p = strchr(devname, ':');
- if (p) {
- fs.vendor_id = strtoul(devname, NULL, 16);
- fs.product_id = strtoul(p + 1, NULL, 16);
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret) {
- *pbus_num = fs.bus_num;
- *paddr = fs.addr;
- pstrcpy(product_name, product_name_size, fs.product_name);
- return 0;
- }
- }
- return -1;
-}
-
-/**********************/
-/* USB host device info */
-
-struct usb_class_info {
- int class;
- const char *class_name;
-};
-
-static const struct usb_class_info usb_class_info[] = {
- { USB_CLASS_AUDIO, "Audio"},
- { USB_CLASS_COMM, "Communication"},
- { USB_CLASS_HID, "HID"},
- { USB_CLASS_HUB, "Hub" },
- { USB_CLASS_PHYSICAL, "Physical" },
- { USB_CLASS_PRINTER, "Printer" },
- { USB_CLASS_MASS_STORAGE, "Storage" },
- { USB_CLASS_CDC_DATA, "Data" },
- { USB_CLASS_APP_SPEC, "Application Specific" },
- { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
- { USB_CLASS_STILL_IMAGE, "Still Image" },
- { USB_CLASS_CSCID, "Smart Card" },
- { USB_CLASS_CONTENT_SEC, "Content Security" },
- { -1, NULL }
-};
-
-static const char *usb_class_str(uint8_t class)
-{
- const struct usb_class_info *p;
- for(p = usb_class_info; p->class != -1; p++) {
- if (p->class == class)
- break;
- }
- return p->class_name;
-}
-
-void usb_info_device(int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- const char *class_str, *speed_str;
-
- switch(speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
-
- term_printf(" Device %d.%d, speed %s Mb/s\n",
- bus_num, addr, speed_str);
- class_str = usb_class_str(class_id);
- if (class_str)
- term_printf(" %s:", class_str);
- else
- term_printf(" Class %02x:", class_id);
- term_printf(" USB device %04x:%04x", vendor_id, product_id);
- if (product_name[0] != '\0')
- term_printf(", %s", product_name);
- term_printf("\n");
-}
-
-static int usb_host_info_device(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
- product_name, speed);
- return 0;
-}
-
-void usb_host_info(void)
-{
- usb_host_scan(NULL, usb_host_info_device);
-}
-
-#else
-
-void usb_host_info(void)
-{
- term_printf("USB host devices not supported\n");
-}
-
-/* XXX: modify configure to compile the right host driver */
-USBDevice *usb_host_device_open(const char *devname)
-{
- return NULL;
-}
-
-#endif
diff --git a/tools/ioemu/vgafont.h b/tools/ioemu/vgafont.h
deleted file mode 100644
index bb75796be5..0000000000
--- a/tools/ioemu/vgafont.h
+++ /dev/null
@@ -1,4611 +0,0 @@
-static uint8_t vgafont16[256 * 16] = {
-
- /* 0 0x00 '^@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 1 0x01 '^A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x81, /* 10000001 */
- 0xa5, /* 10100101 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 2 0x02 '^B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xdb, /* 11011011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 3 0x03 '^C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 4 0x04 '^D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 5 0x05 '^E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 6 0x06 '^F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 7 0x07 '^G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 8 0x08 '^H' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xe7, /* 11100111 */
- 0xc3, /* 11000011 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 9 0x09 '^I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x42, /* 01000010 */
- 0x42, /* 01000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 10 0x0a '^J' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0x99, /* 10011001 */
- 0xbd, /* 10111101 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0xc3, /* 11000011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 11 0x0b '^K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x1a, /* 00011010 */
- 0x32, /* 00110010 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 12 0x0c '^L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 13 0x0d '^M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x33, /* 00110011 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x70, /* 01110000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 14 0x0e '^N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x67, /* 01100111 */
- 0xe7, /* 11100111 */
- 0xe6, /* 11100110 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 15 0x0f '^O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xdb, /* 11011011 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0x3c, /* 00111100 */
- 0xdb, /* 11011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 16 0x10 '^P' */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0xf0, /* 11110000 */
- 0xf8, /* 11111000 */
- 0xfe, /* 11111110 */
- 0xf8, /* 11111000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 17 0x11 '^Q' */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0e, /* 00001110 */
- 0x1e, /* 00011110 */
- 0x3e, /* 00111110 */
- 0xfe, /* 11111110 */
- 0x3e, /* 00111110 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 18 0x12 '^R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 19 0x13 '^S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 20 0x14 '^T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7b, /* 01111011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 21 0x15 '^U' */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 22 0x16 '^V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 23 0x17 '^W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 24 0x18 '^X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 25 0x19 '^Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 26 0x1a '^Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 27 0x1b '^[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xfe, /* 11111110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 28 0x1c '^\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 29 0x1d '^]' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x28, /* 00101000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x28, /* 00101000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 30 0x1e '^^' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 31 0x1f '^_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 32 0x20 ' ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 33 0x21 '!' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 34 0x22 '"' */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x24, /* 00100100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 35 0x23 '#' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 36 0x24 '$' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x86, /* 10000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 37 0x25 '%' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 38 0x26 '&' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 39 0x27 ''' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 40 0x28 '(' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 41 0x29 ')' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 42 0x2a '*' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0xff, /* 11111111 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 43 0x2b '+' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 44 0x2c ',' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 45 0x2d '-' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 46 0x2e '.' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 47 0x2f '/' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 48 0x30 '0' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 49 0x31 '1' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x38, /* 00111000 */
- 0x78, /* 01111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 50 0x32 '2' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 51 0x33 '3' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x3c, /* 00111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 52 0x34 '4' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x1c, /* 00011100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 53 0x35 '5' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 54 0x36 '6' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 55 0x37 '7' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 56 0x38 '8' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 57 0x39 '9' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 58 0x3a ':' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 59 0x3b ';' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 60 0x3c '<' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 61 0x3d '=' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 62 0x3e '>' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 63 0x3f '?' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 64 0x40 '@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xdc, /* 11011100 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 65 0x41 'A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 66 0x42 'B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 67 0x43 'C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 68 0x44 'D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 69 0x45 'E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 70 0x46 'F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 71 0x47 'G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xde, /* 11011110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x66, /* 01100110 */
- 0x3a, /* 00111010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 72 0x48 'H' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 73 0x49 'I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 74 0x4a 'J' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 75 0x4b 'K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe6, /* 11100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 76 0x4c 'L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 77 0x4d 'M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xee, /* 11101110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 78 0x4e 'N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 79 0x4f 'O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 80 0x50 'P' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 81 0x51 'Q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xde, /* 11011110 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 82 0x52 'R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 83 0x53 'S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 84 0x54 'T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x5a, /* 01011010 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 85 0x55 'U' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 86 0x56 'V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 87 0x57 'W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0xee, /* 11101110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 88 0x58 'X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 89 0x59 'Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 90 0x5a 'Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 91 0x5b '[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 92 0x5c '\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0x70, /* 01110000 */
- 0x38, /* 00111000 */
- 0x1c, /* 00011100 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 93 0x5d ']' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 94 0x5e '^' */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 95 0x5f '_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 96 0x60 '`' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 97 0x61 'a' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 98 0x62 'b' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 99 0x63 'c' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 100 0x64 'd' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 101 0x65 'e' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 102 0x66 'f' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x36, /* 00110110 */
- 0x32, /* 00110010 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 103 0x67 'g' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 104 0x68 'h' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x6c, /* 01101100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 105 0x69 'i' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 106 0x6a 'j' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
-
- /* 107 0x6b 'k' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 108 0x6c 'l' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 109 0x6d 'm' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 110 0x6e 'n' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 111 0x6f 'o' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 112 0x70 'p' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
-
- /* 113 0x71 'q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
-
- /* 114 0x72 'r' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 115 0x73 's' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 116 0x74 't' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0xfc, /* 11111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x36, /* 00110110 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 117 0x75 'u' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 118 0x76 'v' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 119 0x77 'w' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 120 0x78 'x' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 121 0x79 'y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
-
- /* 122 0x7a 'z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 123 0x7b '{' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 124 0x7c '|' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 125 0x7d '}' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 126 0x7e '~' */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 127 0x7f '' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 128 0x80 '€' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 129 0x81 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 130 0x82 '‚' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 131 0x83 'ƒ' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 132 0x84 '„' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 133 0x85 'Â…' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 134 0x86 '†' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 135 0x87 '‡' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 136 0x88 'ˆ' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 137 0x89 '‰' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 138 0x8a 'Š' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 139 0x8b '‹' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 140 0x8c 'Œ' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 141 0x8d 'Â' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 142 0x8e 'ÂŽ' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 143 0x8f 'Â' */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 144 0x90 'Â' */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 145 0x91 '‘' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x6e, /* 01101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 146 0x92 'Â’' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3e, /* 00111110 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xce, /* 11001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 147 0x93 '“' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 148 0x94 '”' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 149 0x95 '•' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 150 0x96 '–' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 151 0x97 '—' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 152 0x98 '˜' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 153 0x99 '™' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 154 0x9a 'š' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 155 0x9b '›' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 156 0x9c 'œ' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x64, /* 01100100 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xe6, /* 11100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 157 0x9d 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 158 0x9e 'ž' */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xf8, /* 11111000 */
- 0xc4, /* 11000100 */
- 0xcc, /* 11001100 */
- 0xde, /* 11011110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 159 0x9f 'Ÿ' */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 160 0xa0 ' ' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 161 0xa1 '¡' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 162 0xa2 '¢' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 163 0xa3 '£' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 164 0xa4 '¤' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 165 0xa5 'Â¥' */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 166 0xa6 '¦' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 167 0xa7 '§' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 168 0xa8 '¨' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 169 0xa9 '©' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 170 0xaa 'ª' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 171 0xab '«' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xdc, /* 11011100 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 172 0xac '¬' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x66, /* 01100110 */
- 0xce, /* 11001110 */
- 0x9a, /* 10011010 */
- 0x3f, /* 00111111 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 173 0xad '­' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 174 0xae '®' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 175 0xaf '¯' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 176 0xb0 '°' */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
-
- /* 177 0xb1 '±' */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
-
- /* 178 0xb2 '²' */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
-
- /* 179 0xb3 '³' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 180 0xb4 '´' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 181 0xb5 'µ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 182 0xb6 '¶' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 183 0xb7 '·' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 184 0xb8 '¸' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 185 0xb9 '¹' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 186 0xba 'º' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 187 0xbb '»' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 188 0xbc '¼' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 189 0xbd '½' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 190 0xbe '¾' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 191 0xbf '¿' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 192 0xc0 'À' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 193 0xc1 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 194 0xc2 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 195 0xc3 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 196 0xc4 'Ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 197 0xc5 'Ã…' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 198 0xc6 'Æ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 199 0xc7 'Ç' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 200 0xc8 'È' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 201 0xc9 'É' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 202 0xca 'Ê' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 203 0xcb 'Ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 204 0xcc 'Ì' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 205 0xcd 'Ã' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 206 0xce 'ÃŽ' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 207 0xcf 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 208 0xd0 'Ã' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 209 0xd1 'Ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 210 0xd2 'Ã’' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 211 0xd3 'Ó' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 212 0xd4 'Ô' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 213 0xd5 'Õ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 214 0xd6 'Ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 215 0xd7 '×' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 216 0xd8 'Ø' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 217 0xd9 'Ù' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 218 0xda 'Ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 219 0xdb 'Û' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 220 0xdc 'Ü' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 221 0xdd 'Ã' */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
-
- /* 222 0xde 'Þ' */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
-
- /* 223 0xdf 'ß' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 224 0xe0 'à' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 225 0xe1 'á' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xd8, /* 11011000 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 226 0xe2 'â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 227 0xe3 'ã' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 228 0xe4 'ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 229 0xe5 'Ã¥' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 230 0xe6 'æ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
-
- /* 231 0xe7 'ç' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 232 0xe8 'è' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 233 0xe9 'é' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 234 0xea 'ê' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xee, /* 11101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 235 0xeb 'ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x3e, /* 00111110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 236 0xec 'ì' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 237 0xed 'í' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x03, /* 00000011 */
- 0x06, /* 00000110 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xf3, /* 11110011 */
- 0x7e, /* 01111110 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 238 0xee 'î' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 239 0xef 'ï' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 240 0xf0 'ð' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 241 0xf1 'ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 242 0xf2 'ò' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 243 0xf3 'ó' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 244 0xf4 'ô' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 245 0xf5 'õ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 246 0xf6 'ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 247 0xf7 '÷' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 248 0xf8 'ø' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 249 0xf9 'ù' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 250 0xfa 'ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 251 0xfb 'û' */
- 0x00, /* 00000000 */
- 0x0f, /* 00001111 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xec, /* 11101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3c, /* 00111100 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 252 0xfc 'ü' */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 253 0xfd 'ý' */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x32, /* 00110010 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 254 0xfe 'þ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 255 0xff 'ÿ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
-};
diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c
deleted file mode 100644
index fc40a4c243..0000000000
--- a/tools/ioemu/vl.c
+++ /dev/null
@@ -1,7995 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2007 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <zlib.h>
-
-#ifndef _WIN32
-#include <sys/times.h>
-#include <sys/wait.h>
-#include <termios.h>
-#ifndef CONFIG_STUBDOM
-#include <sys/poll.h>
-#endif
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#ifndef CONFIG_STUBDOM
-#include <net/if.h>
-#endif
-#if defined(__NetBSD__)
-#include <net/if_tap.h>
-#endif
-#if defined(__linux__) || defined(__Linux__)
-#include <linux/if_tun.h>
-#endif
-#ifndef CONFIG_STUBDOM
-#include <arpa/inet.h>
-#include <dirent.h>
-#endif
-#include <netdb.h>
-#ifndef CONFIG_STUBDOM
-#ifdef _BSD
-#include <sys/stat.h>
-#ifndef _BSD
-#include <libutil.h>
-#else
-#include <util.h>
-#endif
-#else
-#ifndef __sun__
-#include <pty.h>
-#include <linux/rtc.h>
-#include <linux/ppdev.h>
-#endif
-#endif
-#if defined(__sun__)
-#include <stropts.h>
-#endif
-#endif
-#endif
-
-#if defined(CONFIG_SLIRP)
-#include "libslirp.h"
-#endif
-
-#ifdef _WIN32
-#include <sys/timeb.h>
-#include <windows.h>
-#define getopt_long_only getopt_long
-#define memalign(align, size) malloc(size)
-#define NO_DAEMONIZE 1
-#endif
-
-#include "qemu_socket.h"
-
-#ifdef CONFIG_SDL
-#ifdef __APPLE__
-#include <SDL/SDL.h>
-#endif
-#endif /* CONFIG_SDL */
-
-#ifdef CONFIG_COCOA
-#undef main
-#define main qemu_main
-#endif /* CONFIG_COCOA */
-
-#include "disas.h"
-
-#include "exec-all.h"
-
-#define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
-#ifdef _BSD
-#define DEFAULT_BRIDGE "bridge0"
-#else
-#define DEFAULT_BRIDGE "xenbr0"
-#endif
-#ifdef __sun__
-#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
-#else
-#define SMBD_COMMAND "/usr/sbin/smbd"
-#endif
-
-//#define DEBUG_UNUSED_IOPORT
-//#define DEBUG_IOPORT
-
-#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
-
-#ifdef TARGET_PPC
-#define DEFAULT_RAM_SIZE 144
-#else
-#define DEFAULT_RAM_SIZE 128
-#endif
-
-/* Max number of USB devices that can be specified on the commandline. */
-#define MAX_USB_CMDLINE 8
-
-/* XXX: use a two level table to limit memory usage */
-#define MAX_IOPORTS 65536
-
-/* Max number of PCI emulation */
-#define MAX_PCI_EMULATION 32
-
-const char *bios_dir = CONFIG_QEMU_SHAREDIR;
-void *ioport_opaque[MAX_IOPORTS];
-IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
-IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
-/* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
- to store the VM snapshots */
-BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS + 1], *fd_table[MAX_FD];
-/* point to the block driver where the snapshots are managed */
-BlockDriverState *bs_snapshots;
-int vga_ram_size;
-int bios_size;
-static DisplayState display_state;
-int nographic;
-int vncviewer;
-int vncunused;
-const char* keyboard_layout = NULL;
-int64_t ticks_per_sec;
-char *boot_device = NULL;
-uint64_t ram_size;
-int pit_min_timer_count = 0;
-int nb_nics;
-NICInfo nd_table[MAX_NICS];
-QEMUTimer *gui_timer;
-int vm_running;
-int rtc_utc = 1;
-int cirrus_vga_enabled = 1;
-#ifdef TARGET_SPARC
-int graphic_width = 1024;
-int graphic_height = 768;
-#else
-int graphic_width = 800;
-int graphic_height = 600;
-#endif
-int graphic_depth = 15;
-int full_screen = 0;
-#ifdef CONFIG_OPENGL
-int opengl_enabled = 1;
-#else
-int opengl_enabled = 0;
-#endif
-int no_quit = 0;
-CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-#ifdef TARGET_I386
-int win2k_install_hack = 0;
-#endif
-int usb_enabled = 0;
-static VLANState *first_vlan;
-int smp_cpus = 1;
-const char *vnc_display;
-#if defined(TARGET_SPARC)
-#define MAX_CPUS 16
-#elif defined(TARGET_I386)
-#define MAX_CPUS 255
-#else
-#define MAX_CPUS 1
-#endif
-int acpi_enabled = 0;
-int fd_bootchk = 1;
-int no_reboot = 0;
-#ifndef NO_DAEMONIZE
-int daemonize = 0;
-#endif
-const char *option_rom[MAX_OPTION_ROMS];
-int nb_option_roms;
-int semihosting_enabled = 0;
-int autostart = 1;
-
-extern int vcpus;
-
-int xc_handle;
-
-char domain_name[64] = "Xen-no-name";
-extern int domid;
-
-PCI_EMULATION_INFO *PciEmulationInfoHead = NULL;
-
-/***********************************************************/
-/* x86 ISA bus support */
-
-target_phys_addr_t isa_mem_base = 0;
-PicState2 *isa_pic;
-
-uint32_t default_ioport_readb(void *opaque, uint32_t address)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "inb: port=0x%04x\n", address);
-#endif
- return 0xff;
-}
-
-void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
-#endif
-}
-
-/* default is to make two byte accesses */
-uint32_t default_ioport_readw(void *opaque, uint32_t address)
-{
- uint32_t data;
- IOPortReadFunc *func = ioport_read_table[0][address];
- if (!func)
- func = default_ioport_readb;
- data = func(ioport_opaque[address], address);
- address = (address + 1) & (MAX_IOPORTS - 1);
- func = ioport_read_table[0][address];
- if (!func)
- func = default_ioport_readb;
- data |= func(ioport_opaque[address], address) << 8;
- return data;
-}
-
-void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
-{
- IOPortWriteFunc *func = ioport_write_table[0][address];
- if (!func)
- func = default_ioport_writeb;
- func(ioport_opaque[address], address, data & 0xff);
- address = (address + 1) & (MAX_IOPORTS - 1);
- func = ioport_write_table[0][address];
- if (!func)
- func = default_ioport_writeb;
- func(ioport_opaque[address], address, (data >> 8) & 0xff);
-}
-
-uint32_t default_ioport_readl(void *opaque, uint32_t address)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "inl: port=0x%04x\n", address);
-#endif
- return 0xffffffff;
-}
-
-void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
-#endif
-}
-
-void init_ioports(void)
-{
-}
-
-/* size is the word size in byte */
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque)
-{
- int i, bsize;
-
- if (size == 1) {
- bsize = 0;
- } else if (size == 2) {
- bsize = 1;
- } else if (size == 4) {
- bsize = 2;
- } else {
- hw_error("register_ioport_read: invalid size");
- return -1;
- }
- for(i = start; i < start + length; i += size) {
- ioport_read_table[bsize][i] = func;
- if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
- hw_error("register_ioport_write: invalid opaque");
- ioport_opaque[i] = opaque;
- }
- return 0;
-}
-
-/* size is the word size in byte */
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque)
-{
- int i, bsize;
-
- if (size == 1) {
- bsize = 0;
- } else if (size == 2) {
- bsize = 1;
- } else if (size == 4) {
- bsize = 2;
- } else {
- hw_error("register_ioport_write: invalid size");
- return -1;
- }
- for(i = start; i < start + length; i += size) {
- ioport_write_table[bsize][i] = func;
- if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
- hw_error("register_ioport_write: invalid opaque");
- ioport_opaque[i] = opaque;
- }
- return 0;
-}
-
-void isa_unassign_ioport(int start, int length)
-{
- int i;
-
- for(i = start; i < start + length; i++) {
- ioport_read_table[0][i] = default_ioport_readb;
- ioport_read_table[1][i] = default_ioport_readw;
- ioport_read_table[2][i] = default_ioport_readl;
-
- ioport_write_table[0][i] = default_ioport_writeb;
- ioport_write_table[1][i] = default_ioport_writew;
- ioport_write_table[2][i] = default_ioport_writel;
- }
-}
-
-/***********************************************************/
-
-void cpu_outb(CPUState *env, int addr, int val)
-{
- IOPortWriteFunc *func = ioport_write_table[0][addr];
- if (!func)
- func = default_ioport_writeb;
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outb: %04x %02x\n", addr, val);
-#endif
- func(ioport_opaque[addr], addr, val);
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-void cpu_outw(CPUState *env, int addr, int val)
-{
- IOPortWriteFunc *func = ioport_write_table[1][addr];
- if (!func)
- func = default_ioport_writew;
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outw: %04x %04x\n", addr, val);
-#endif
- func(ioport_opaque[addr], addr, val);
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-void cpu_outl(CPUState *env, int addr, int val)
-{
- IOPortWriteFunc *func = ioport_write_table[2][addr];
- if (!func)
- func = default_ioport_writel;
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outl: %04x %08x\n", addr, val);
-#endif
- func(ioport_opaque[addr], addr, val);
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-int cpu_inb(CPUState *env, int addr)
-{
- int val;
- IOPortReadFunc *func = ioport_read_table[0][addr];
- if (!func)
- func = default_ioport_readb;
- val = func(ioport_opaque[addr], addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inb : %04x %02x\n", addr, val);
-#endif
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
- return val;
-}
-
-int cpu_inw(CPUState *env, int addr)
-{
- int val;
- IOPortReadFunc *func = ioport_read_table[1][addr];
- if (!func)
- func = default_ioport_readw;
- val = func(ioport_opaque[addr], addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inw : %04x %04x\n", addr, val);
-#endif
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
- return val;
-}
-
-int cpu_inl(CPUState *env, int addr)
-{
- int val;
- IOPortReadFunc *func = ioport_read_table[2][addr];
- if (!func)
- func = default_ioport_readl;
- val = func(ioport_opaque[addr], addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inl : %04x %08x\n", addr, val);
-#endif
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
- return val;
-}
-
-/***********************************************************/
-void hw_error(const char *fmt, ...)
-{
- va_list ap;
-#ifndef CONFIG_DM
- CPUState *env;
-#endif /* !CONFIG_DM */
-
- va_start(ap, fmt);
- fprintf(stderr, "qemu: hardware error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
-#ifndef CONFIG_DM
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- fprintf(stderr, "CPU #%d:\n", env->cpu_index);
-#ifdef TARGET_I386
- cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
-#else
- cpu_dump_state(env, stderr, fprintf, 0);
-#endif
- }
-#endif /* !CONFIG_DM */
- va_end(ap);
- abort();
-}
-
-/***********************************************************/
-/* keyboard/mouse */
-
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
-static QEMUPutMouseEntry *qemu_put_mouse_event_head;
-static QEMUPutMouseEntry *qemu_put_mouse_event_current;
-
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
-{
- qemu_put_kbd_event_opaque = opaque;
- qemu_put_kbd_event = func;
-}
-
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
- const char *name)
-{
- QEMUPutMouseEntry *s, *cursor;
-
- s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
- if (!s)
- return NULL;
-
- s->qemu_put_mouse_event = func;
- s->qemu_put_mouse_event_opaque = opaque;
- s->qemu_put_mouse_event_absolute = absolute;
- s->qemu_put_mouse_event_name = qemu_strdup(name);
- s->next = NULL;
-
- if (!qemu_put_mouse_event_head) {
- qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
- return s;
- }
-
- cursor = qemu_put_mouse_event_head;
- while (cursor->next != NULL)
- cursor = cursor->next;
-
- cursor->next = s;
- qemu_put_mouse_event_current = s;
-
- return s;
-}
-
-void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
-{
- QEMUPutMouseEntry *prev = NULL, *cursor;
-
- if (!qemu_put_mouse_event_head || entry == NULL)
- return;
-
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL && cursor != entry) {
- prev = cursor;
- cursor = cursor->next;
- }
-
- if (cursor == NULL) // does not exist or list empty
- return;
- else if (prev == NULL) { // entry is head
- qemu_put_mouse_event_head = cursor->next;
- if (qemu_put_mouse_event_current == entry)
- qemu_put_mouse_event_current = cursor->next;
- qemu_free(entry->qemu_put_mouse_event_name);
- qemu_free(entry);
- return;
- }
-
- prev->next = entry->next;
-
- if (qemu_put_mouse_event_current == entry)
- qemu_put_mouse_event_current = prev;
-
- qemu_free(entry->qemu_put_mouse_event_name);
- qemu_free(entry);
-}
-
-void kbd_put_keycode(int keycode)
-{
- if (qemu_put_kbd_event) {
- qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
- }
-}
-
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
-{
- QEMUPutMouseEvent *mouse_event;
- void *mouse_event_opaque;
-
- if (!qemu_put_mouse_event_current) {
- return;
- }
-
- mouse_event =
- qemu_put_mouse_event_current->qemu_put_mouse_event;
- mouse_event_opaque =
- qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
-
- if (mouse_event) {
- mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state);
- }
-}
-
-int kbd_mouse_is_absolute(void)
-{
- if (!qemu_put_mouse_event_current)
- return 0;
-
- return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
-}
-
-void do_info_mice(void)
-{
- QEMUPutMouseEntry *cursor;
- int index = 0;
-
- if (!qemu_put_mouse_event_head) {
- term_printf("No mouse devices connected\n");
- return;
- }
-
- term_printf("Mouse devices available:\n");
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL) {
- term_printf("%c Mouse #%d: %s\n",
- (cursor == qemu_put_mouse_event_current ? '*' : ' '),
- index, cursor->qemu_put_mouse_event_name);
- index++;
- cursor = cursor->next;
- }
-}
-
-void do_mouse_set(int index)
-{
- QEMUPutMouseEntry *cursor;
- int i = 0;
-
- if (!qemu_put_mouse_event_head) {
- term_printf("No mouse devices connected\n");
- return;
- }
-
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL && index != i) {
- i++;
- cursor = cursor->next;
- }
-
- if (cursor != NULL)
- qemu_put_mouse_event_current = cursor;
- else
- term_printf("Mouse at given index not found\n");
-}
-
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
- union {
- uint64_t ll;
- struct {
-#ifdef WORDS_BIGENDIAN
- uint32_t high, low;
-#else
- uint32_t low, high;
-#endif
- } l;
- } u, res;
- uint64_t rl, rh;
-
- u.ll = a;
- rl = (uint64_t)u.l.low * (uint64_t)b;
- rh = (uint64_t)u.l.high * (uint64_t)b;
- rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
- return res.ll;
-}
-
-/***********************************************************/
-/* real time host monotonic timer */
-
-#define QEMU_TIMER_BASE 1000000000LL
-
-#ifdef WIN32
-
-static int64_t clock_freq;
-
-static void init_get_clock(void)
-{
- LARGE_INTEGER freq;
- int ret;
- ret = QueryPerformanceFrequency(&freq);
- if (ret == 0) {
- fprintf(stderr, "Could not calibrate ticks\n");
- exit(1);
- }
- clock_freq = freq.QuadPart;
-}
-
-static int64_t get_clock(void)
-{
- LARGE_INTEGER ti;
- QueryPerformanceCounter(&ti);
- return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
-}
-
-#else
-
-static int use_rt_clock;
-
-static void init_get_clock(void)
-{
- use_rt_clock = 0;
-#if defined(__linux__)
- {
- struct timespec ts;
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
- use_rt_clock = 1;
- }
- }
-#endif
-}
-
-static int64_t get_clock(void)
-{
-#if defined(__linux__)
- if (use_rt_clock) {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return ts.tv_sec * 1000000000LL + ts.tv_nsec;
- } else
-#endif
- {
- /* XXX: using gettimeofday leads to problems if the date
- changes, so it should be avoided. */
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
- }
-}
-
-#endif
-
-/***********************************************************/
-/* guest cycle counter */
-
-static int64_t cpu_ticks_prev;
-static int64_t cpu_ticks_offset;
-static int64_t cpu_clock_offset;
-static int cpu_ticks_enabled;
-
-/* return the host CPU cycle counter and handle stop/restart */
-int64_t cpu_get_ticks(void)
-{
- if (!cpu_ticks_enabled) {
- return cpu_ticks_offset;
- } else {
- int64_t ticks;
- ticks = cpu_get_real_ticks();
- if (cpu_ticks_prev > ticks) {
- /* Note: non increasing ticks may happen if the host uses
- software suspend */
- cpu_ticks_offset += cpu_ticks_prev - ticks;
- }
- cpu_ticks_prev = ticks;
- return ticks + cpu_ticks_offset;
- }
-}
-
-/* return the host CPU monotonic timer and handle stop/restart */
-static int64_t cpu_get_clock(void)
-{
- int64_t ti;
- if (!cpu_ticks_enabled) {
- return cpu_clock_offset;
- } else {
- ti = get_clock();
- return ti + cpu_clock_offset;
- }
-}
-
-/* enable cpu_get_ticks() */
-void cpu_enable_ticks(void)
-{
- if (!cpu_ticks_enabled) {
- cpu_ticks_offset -= cpu_get_real_ticks();
- cpu_clock_offset -= get_clock();
- cpu_ticks_enabled = 1;
- }
-}
-
-/* disable cpu_get_ticks() : the clock is stopped. You must not call
- cpu_get_ticks() after that. */
-void cpu_disable_ticks(void)
-{
- if (cpu_ticks_enabled) {
- cpu_ticks_offset = cpu_get_ticks();
- cpu_clock_offset = cpu_get_clock();
- cpu_ticks_enabled = 0;
- }
-}
-
-/***********************************************************/
-/* timers */
-
-#define QEMU_TIMER_REALTIME 0
-#define QEMU_TIMER_VIRTUAL 1
-
-struct QEMUClock {
- int type;
- /* XXX: add frequency */
-};
-
-struct QEMUTimer {
- QEMUClock *clock;
- int64_t expire_time;
- QEMUTimerCB *cb;
- void *opaque;
- struct QEMUTimer *next;
-};
-
-QEMUClock *rt_clock;
-QEMUClock *vm_clock;
-
-static QEMUTimer *active_timers[2];
-#ifdef _WIN32
-static MMRESULT timerID;
-static HANDLE host_alarm = NULL;
-static unsigned int period = 1;
-#endif
-
-QEMUClock *qemu_new_clock(int type)
-{
- QEMUClock *clock;
- clock = qemu_mallocz(sizeof(QEMUClock));
- if (!clock)
- return NULL;
- clock->type = type;
- return clock;
-}
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
-{
- QEMUTimer *ts;
-
- ts = qemu_mallocz(sizeof(QEMUTimer));
- ts->clock = clock;
- ts->cb = cb;
- ts->opaque = opaque;
- return ts;
-}
-
-void qemu_free_timer(QEMUTimer *ts)
-{
- qemu_free(ts);
-}
-
-/* stop a timer, but do not dealloc it */
-void qemu_del_timer(QEMUTimer *ts)
-{
- QEMUTimer **pt, *t;
-
- /* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &active_timers[ts->clock->type];
- for(;;) {
- t = *pt;
- if (!t)
- break;
- if (t == ts) {
- *pt = t->next;
- break;
- }
- pt = &t->next;
- }
-}
-
-void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time)
-{
- if (ts->expire_time > expire_time || !qemu_timer_pending(ts))
- qemu_mod_timer(ts, expire_time);
-}
-
-/* modify the current timer so that it will be fired when current_time
- >= expire_time. The corresponding callback will be called. */
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
-{
- QEMUTimer **pt, *t;
-
- qemu_del_timer(ts);
-
- /* add the timer in the sorted list */
- /* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &active_timers[ts->clock->type];
- for(;;) {
- t = *pt;
- if (!t)
- break;
- if (t->expire_time > expire_time)
- break;
- pt = &t->next;
- }
- ts->expire_time = expire_time;
- ts->next = *pt;
- *pt = ts;
-}
-
-int qemu_timer_pending(QEMUTimer *ts)
-{
- QEMUTimer *t;
- for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
- if (t == ts)
- return 1;
- }
- return 0;
-}
-
-static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
-{
- if (!timer_head)
- return 0;
- return (timer_head->expire_time <= current_time);
-}
-
-static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
-{
- QEMUTimer *ts;
-
- for(;;) {
- ts = *ptimer_head;
- if (!ts || ts->expire_time > current_time)
- break;
- /* remove timer from the list before calling the callback */
- *ptimer_head = ts->next;
- ts->next = NULL;
-
- /* run the callback (the timer list can be modified) */
- ts->cb(ts->opaque);
- }
-}
-
-int64_t qemu_get_clock(QEMUClock *clock)
-{
- switch(clock->type) {
- case QEMU_TIMER_REALTIME:
- return get_clock() / 1000000;
- default:
- case QEMU_TIMER_VIRTUAL:
- return cpu_get_clock();
- }
-}
-
-static void init_timers(void)
-{
- init_get_clock();
- ticks_per_sec = QEMU_TIMER_BASE;
- rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
- vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
-}
-
-/* save a timer */
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
-{
- uint64_t expire_time;
-
- if (qemu_timer_pending(ts)) {
- expire_time = ts->expire_time;
- } else {
- expire_time = -1;
- }
- qemu_put_be64(f, expire_time);
-}
-
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
-{
- uint64_t expire_time;
-
- expire_time = qemu_get_be64(f);
- if (expire_time != -1) {
- qemu_mod_timer(ts, expire_time);
- } else {
- qemu_del_timer(ts);
- }
-}
-
-#ifdef CONFIG_DM
-static void timer_save(QEMUFile *f, void *opaque)
-{
- /* need timer for save/restoe qemu_timer in usb_uhci */
- if (cpu_ticks_enabled) {
- hw_error("cannot save state if virtual timers are running");
- }
- qemu_put_be64s(f, &cpu_clock_offset);
-}
-
-static int timer_load(QEMUFile *f, void *opaque, int version_id)
-{
- if (version_id != 1 && version_id != 2)
- return -EINVAL;
- if (cpu_ticks_enabled) {
- return -EINVAL;
- }
-
- qemu_get_be64s(f, &cpu_clock_offset);
- return 0;
-}
-#else /* !CONFIG_DM */
-static void timer_save(QEMUFile *f, void *opaque)
-{
- if (cpu_ticks_enabled) {
- hw_error("cannot save state if virtual timers are running");
- }
- qemu_put_be64s(f, &cpu_ticks_offset);
- qemu_put_be64s(f, &ticks_per_sec);
- qemu_put_be64s(f, &cpu_clock_offset);
-}
-
-static int timer_load(QEMUFile *f, void *opaque, int version_id)
-{
- if (version_id != 1 && version_id != 2)
- return -EINVAL;
- if (cpu_ticks_enabled) {
- return -EINVAL;
- }
- qemu_get_be64s(f, &cpu_ticks_offset);
- qemu_get_be64s(f, &ticks_per_sec);
- if (version_id == 2) {
- qemu_get_be64s(f, &cpu_clock_offset);
- }
- return 0;
-}
-
-#ifdef _WIN32
-void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
- DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
-#else
-static void host_alarm_handler(int host_signum)
-#endif
-{
-#if 0
-#define DISP_FREQ 1000
- {
- static int64_t delta_min = INT64_MAX;
- static int64_t delta_max, delta_cum, last_clock, delta, ti;
- static int count;
- ti = qemu_get_clock(vm_clock);
- if (last_clock != 0) {
- delta = ti - last_clock;
- if (delta < delta_min)
- delta_min = delta;
- if (delta > delta_max)
- delta_max = delta;
- delta_cum += delta;
- if (++count == DISP_FREQ) {
- printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
- muldiv64(delta_min, 1000000, ticks_per_sec),
- muldiv64(delta_max, 1000000, ticks_per_sec),
- muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
- (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
- count = 0;
- delta_min = INT64_MAX;
- delta_max = 0;
- delta_cum = 0;
- }
- }
- last_clock = ti;
- }
-#endif
- if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
- qemu_get_clock(vm_clock)) ||
- qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
- qemu_get_clock(rt_clock))) {
-#ifdef _WIN32
- SetEvent(host_alarm);
-#endif
- CPUState *env = cpu_single_env;
- if (env) {
- /* stop the currently executing cpu because a timer occured */
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_cpu_interrupt(env);
- }
-#endif
- }
- }
-}
-
-#ifndef _WIN32
-
-#if defined(__linux__)
-
-#define RTC_FREQ 1024
-
-static int rtc_fd;
-
-static int start_rtc_timer(void)
-{
- rtc_fd = open("/dev/rtc", O_RDONLY);
- if (rtc_fd < 0)
- return -1;
- if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
- fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
- "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
- "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
- goto fail;
- }
- if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
- fail:
- close(rtc_fd);
- return -1;
- }
- pit_min_timer_count = PIT_FREQ / RTC_FREQ;
- return 0;
-}
-
-#else
-
-static int start_rtc_timer(void)
-{
- return -1;
-}
-
-#endif /* !defined(__linux__) */
-
-#endif /* !defined(_WIN32) */
-
-#endif /* !CONFIG_DM */
-
-static void init_timer_alarm(void)
-{
-#ifdef _WIN32
- {
- int count=0;
- TIMECAPS tc;
-
- ZeroMemory(&tc, sizeof(TIMECAPS));
- timeGetDevCaps(&tc, sizeof(TIMECAPS));
- if (period < tc.wPeriodMin)
- period = tc.wPeriodMin;
- timeBeginPeriod(period);
- timerID = timeSetEvent(1, // interval (ms)
- period, // resolution
- host_alarm_handler, // function
- (DWORD)&count, // user parameter
- TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- if( !timerID ) {
- perror("failed timer alarm");
- exit(1);
- }
- host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!host_alarm) {
- perror("failed CreateEvent");
- exit(1);
- }
- qemu_add_wait_object(host_alarm, NULL, NULL);
- }
- pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
-#else
- {
-#ifndef CONFIG_DM
- struct sigaction act;
- struct itimerval itv;
-#endif
-
-#ifndef CONFIG_DM
- /* timer signal */
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
- act.sa_flags |= SA_ONSTACK;
-#endif
- act.sa_handler = host_alarm_handler;
- sigaction(SIGALRM, &act, NULL);
-
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 999; /* for i386 kernel 2.6 to get 1 ms */
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 10 * 1000;
- setitimer(ITIMER_REAL, &itv, NULL);
- /* we probe the tick duration of the kernel to inform the user if
- the emulated kernel requested a too high timer frequency */
- getitimer(ITIMER_REAL, &itv);
-
-#if defined(__linux__)
- /* XXX: force /dev/rtc usage because even 2.6 kernels may not
- have timers with 1 ms resolution. The correct solution will
- be to use the POSIX real time timers available in recent
- 2.6 kernels */
- if (itv.it_interval.tv_usec > 1000 || 1) {
- /* try to use /dev/rtc to have a faster timer */
- if (start_rtc_timer() < 0)
- goto use_itimer;
- /* disable itimer */
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 0;
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 0;
- setitimer(ITIMER_REAL, &itv, NULL);
-
- /* use the RTC */
- sigaction(SIGIO, &act, NULL);
- fcntl(rtc_fd, F_SETFL, O_ASYNC);
- fcntl(rtc_fd, F_SETOWN, getpid());
- } else
-#endif /* defined(__linux__) */
- {
- use_itimer:
- pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
- PIT_FREQ) / 1000000;
- }
-#endif /* CONFIG_DM */
- }
-#endif
-}
-
-void quit_timers(void)
-{
-#ifdef _WIN32
- timeKillEvent(timerID);
- timeEndPeriod(period);
- if (host_alarm) {
- CloseHandle(host_alarm);
- host_alarm = NULL;
- }
-#endif
-}
-
-/***********************************************************/
-/* character device */
-
-static void qemu_chr_event(CharDriverState *s, int event)
-{
- if (!s->chr_event)
- return;
- s->chr_event(s->handler_opaque, event);
-}
-
-static void qemu_chr_reset_bh(void *opaque)
-{
- CharDriverState *s = opaque;
- qemu_chr_event(s, CHR_EVENT_RESET);
- qemu_bh_delete(s->bh);
- s->bh = NULL;
-}
-
-void qemu_chr_reset(CharDriverState *s)
-{
- if (s->bh == NULL) {
- s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
- qemu_bh_schedule(s->bh);
- }
-}
-
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
-{
- return s->chr_write(s, buf, len);
-}
-
-int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
-{
- if (!s->chr_ioctl)
- return -ENOTSUP;
- return s->chr_ioctl(s, cmd, arg);
-}
-
-int qemu_chr_can_read(CharDriverState *s)
-{
- if (!s->chr_can_read)
- return 0;
- return s->chr_can_read(s->handler_opaque);
-}
-
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
-{
- s->chr_read(s->handler_opaque, buf, len);
-}
-
-
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
-{
- char buf[4096];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- qemu_chr_write(s, buf, strlen(buf));
- va_end(ap);
-}
-
-void qemu_chr_send_event(CharDriverState *s, int event)
-{
- if (s->chr_send_event)
- s->chr_send_event(s, event);
-}
-
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque)
-{
- s->chr_can_read = fd_can_read;
- s->chr_read = fd_read;
- s->chr_event = fd_event;
- s->handler_opaque = opaque;
- if (s->chr_update_read_handler)
- s->chr_update_read_handler(s);
-}
-
-static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- return len;
-}
-
-static CharDriverState *qemu_chr_open_null(void)
-{
- CharDriverState *chr;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- chr->chr_write = null_chr_write;
- return chr;
-}
-
-#ifdef _WIN32
-
-static void socket_cleanup(void)
-{
- WSACleanup();
-}
-
-static int socket_init(void)
-{
- WSADATA Data;
- int ret, err;
-
- ret = WSAStartup(MAKEWORD(2,2), &Data);
- if (ret != 0) {
- err = WSAGetLastError();
- fprintf(stderr, "WSAStartup: %d\n", err);
- return -1;
- }
- atexit(socket_cleanup);
- return 0;
-}
-
-static int send_all(int fd, const uint8_t *buf, int len1)
-{
- int ret, len;
-
- len = len1;
- while (len > 0) {
- ret = send(fd, buf, len, 0);
- if (ret < 0) {
- int errno;
- errno = WSAGetLastError();
- if (errno != WSAEWOULDBLOCK) {
- return -1;
- }
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- return len1 - len;
-}
-
-void socket_set_nonblock(int fd)
-{
- unsigned long opt = 1;
- ioctlsocket(fd, FIONBIO, &opt);
-}
-
-#else
-
-static int unix_write(int fd, const uint8_t *buf, int len1)
-{
- int ret, sel_ret, len;
- int max_fd;
- fd_set writefds;
- struct timeval timeout;
-
- max_fd = fd;
-
- len = len1;
- while (len > 0) {
- FD_ZERO(&writefds);
- FD_SET(fd, &writefds);
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- sel_ret = select(max_fd + 1, NULL, &writefds, 0, &timeout);
- if (sel_ret <= 0) {
- /* Timeout or select error */
- return -1;
- } else {
- ret = write(fd, buf, len);
- if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN)
- return -1;
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- }
- return len1 - len;
-}
-
-static inline int send_all(int fd, const uint8_t *buf, int len1)
-{
- return unix_write(fd, buf, len1);
-}
-
-void socket_set_nonblock(int fd)
-{
- fcntl(fd, F_SETFL, O_NONBLOCK);
-}
-#endif /* !_WIN32 */
-
-#ifndef _WIN32
-
-typedef struct {
- int fd_in, fd_out;
- int max_size;
-} FDCharDriver;
-
-#define STDIO_MAX_CLIENTS 2
-
-static int stdio_nb_clients;
-static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
-
-static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- FDCharDriver *s = chr->opaque;
- return unix_write(s->fd_out, buf, len);
-}
-
-static int fd_chr_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- FDCharDriver *s = chr->opaque;
-
- s->max_size = qemu_chr_can_read(chr);
- return s->max_size;
-}
-
-static void fd_chr_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- FDCharDriver *s = chr->opaque;
- int size, len;
- uint8_t buf[1024];
-
- len = sizeof(buf);
- if (len > s->max_size)
- len = s->max_size;
- if (len == 0)
- return;
- size = read(s->fd_in, buf, len);
- if (size == 0) {
- /* FD has been closed. Remove it from the active list. */
- qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
- return;
- }
- if (size > 0) {
- qemu_chr_read(chr, buf, size);
- }
-}
-
-static void fd_chr_update_read_handler(CharDriverState *chr)
-{
- FDCharDriver *s = chr->opaque;
-
- if (s->fd_in >= 0) {
- if (nographic && s->fd_in == 0) {
- } else {
- qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
- fd_chr_read, NULL, chr);
- }
- }
-}
-
-/* open a character device to a unix fd */
-static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
-{
- CharDriverState *chr;
- FDCharDriver *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(FDCharDriver));
- if (!s) {
- free(chr);
- return NULL;
- }
- s->fd_in = fd_in;
- s->fd_out = fd_out;
- chr->opaque = s;
- chr->chr_write = fd_chr_write;
- chr->chr_update_read_handler = fd_chr_update_read_handler;
-
- qemu_chr_reset(chr);
-
- return chr;
-}
-
-static CharDriverState *qemu_chr_open_file_out(const char *file_out)
-{
- int fd_out;
-
- fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666);
- if (fd_out < 0)
- return NULL;
- return qemu_chr_open_fd(-1, fd_out);
-}
-
-#ifndef CONFIG_STUBDOM
-static CharDriverState *qemu_chr_open_pipe(const char *filename)
-{
- int fd_in, fd_out;
- char filename_in[256], filename_out[256];
-
- snprintf(filename_in, 256, "%s.in", filename);
- snprintf(filename_out, 256, "%s.out", filename);
- fd_in = open(filename_in, O_RDWR | O_BINARY);
- fd_out = open(filename_out, O_RDWR | O_BINARY);
- if (fd_in < 0 || fd_out < 0) {
- if (fd_in >= 0)
- close(fd_in);
- if (fd_out >= 0)
- close(fd_out);
- fd_in = fd_out = open(filename, O_RDWR | O_BINARY);
- if (fd_in < 0)
- return NULL;
- }
- return qemu_chr_open_fd(fd_in, fd_out);
-}
-
-
-/* for STDIO, we handle the case where several clients use it
- (nographic mode) */
-
-#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
-
-#define TERM_FIFO_MAX_SIZE 1
-
-static int term_got_escape, client_index;
-static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
-static int term_fifo_size;
-static int term_timestamps;
-static int64_t term_timestamps_start;
-
-void term_print_help(void)
-{
- printf("\n"
- "C-a h print this help\n"
- "C-a x exit emulator\n"
- "C-a s save disk data back to file (if -snapshot)\n"
- "C-a b send break (magic sysrq)\n"
- "C-a t toggle console timestamps\n"
- "C-a c switch between console and monitor\n"
- "C-a C-a send C-a\n"
- );
-}
-
-/* called when a char is received */
-static void stdio_received_byte(int ch)
-{
- if (term_got_escape) {
- term_got_escape = 0;
- switch(ch) {
- case 'h':
- term_print_help();
- break;
- case 'x':
- exit(0);
- break;
- case 's':
- {
- int i;
- for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (bs_table[i])
- bdrv_commit(bs_table[i]);
- }
- }
- break;
- case 'b':
- if (client_index < stdio_nb_clients) {
- CharDriverState *chr;
- FDCharDriver *s;
-
- chr = stdio_clients[client_index];
- s = chr->opaque;
- qemu_chr_event(chr, CHR_EVENT_BREAK);
- }
- break;
- case 'c':
- client_index++;
- if (client_index >= stdio_nb_clients)
- client_index = 0;
- if (client_index == 0) {
- /* send a new line in the monitor to get the prompt */
- ch = '\r';
- goto send_char;
- }
- break;
- case 't':
- term_timestamps = !term_timestamps;
- term_timestamps_start = -1;
- break;
- case TERM_ESCAPE:
- goto send_char;
- }
- } else if (ch == TERM_ESCAPE) {
- term_got_escape = 1;
- } else {
- send_char:
- if (client_index < stdio_nb_clients) {
- uint8_t buf[1];
- CharDriverState *chr;
-
- chr = stdio_clients[client_index];
- if (qemu_chr_can_read(chr) > 0) {
- buf[0] = ch;
- qemu_chr_read(chr, buf, 1);
- } else if (term_fifo_size == 0) {
- term_fifo[term_fifo_size++] = ch;
- }
- }
- }
-}
-
-static int stdio_read_poll(void *opaque)
-{
- CharDriverState *chr;
-
- if (client_index < stdio_nb_clients) {
- chr = stdio_clients[client_index];
- /* try to flush the queue if needed */
- if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
- qemu_chr_read(chr, term_fifo, 1);
- term_fifo_size = 0;
- }
- /* see if we can absorb more chars */
- if (term_fifo_size == 0)
- return 1;
- else
- return 0;
- } else {
- return 1;
- }
-}
-
-static void stdio_read(void *opaque)
-{
- int size;
- uint8_t buf[1];
-
- size = read(0, buf, 1);
- if (size == 0) {
- /* stdin has been closed. Remove it from the active list. */
- qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
- return;
- }
- if (size > 0)
- stdio_received_byte(buf[0]);
-}
-
-static int stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- FDCharDriver *s = chr->opaque;
- if (!term_timestamps) {
- return unix_write(s->fd_out, buf, len);
- } else {
- int i;
- char buf1[64];
-
- for(i = 0; i < len; i++) {
- unix_write(s->fd_out, buf + i, 1);
- if (buf[i] == '\n') {
- int64_t ti;
- int secs;
-
- ti = get_clock();
- if (term_timestamps_start == -1)
- term_timestamps_start = ti;
- ti -= term_timestamps_start;
- secs = ti / 1000000000;
- snprintf(buf1, sizeof(buf1),
- "[%02d:%02d:%02d.%03d] ",
- secs / 3600,
- (secs / 60) % 60,
- secs % 60,
- (int)((ti / 1000000) % 1000));
- unix_write(s->fd_out, buf1, strlen(buf1));
- }
- }
- return len;
- }
-}
-
-/* init terminal so that we can grab keys */
-static struct termios oldtty;
-static int old_fd0_flags;
-
-static void term_exit(void)
-{
- tcsetattr (0, TCSANOW, &oldtty);
- fcntl(0, F_SETFL, old_fd0_flags);
-}
-
-static void term_init(void)
-{
- struct termios tty;
-
- tcgetattr (0, &tty);
- oldtty = tty;
- old_fd0_flags = fcntl(0, F_GETFL);
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
- /* if graphical mode, we allow Ctrl-C handling */
- if (nographic)
- tty.c_lflag &= ~ISIG;
- tty.c_cflag &= ~(CSIZE|PARENB);
- tty.c_cflag |= CS8;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VTIME] = 0;
-
- tcsetattr (0, TCSANOW, &tty);
-
- atexit(term_exit);
-
- fcntl(0, F_SETFL, O_NONBLOCK);
-}
-
-static CharDriverState *qemu_chr_open_stdio(void)
-{
- CharDriverState *chr;
-
- if (nographic) {
- if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
- return NULL;
- chr = qemu_chr_open_fd(0, 1);
- chr->chr_write = stdio_write;
- if (stdio_nb_clients == 0)
- qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, NULL);
- client_index = stdio_nb_clients;
- } else {
- if (stdio_nb_clients != 0)
- return NULL;
- chr = qemu_chr_open_fd(0, 1);
- }
- stdio_clients[stdio_nb_clients++] = chr;
- if (stdio_nb_clients == 1) {
- /* set the terminal in raw mode */
- term_init();
- }
- return chr;
-}
-#endif
-
-/*
- * Create a store entry for a device (e.g., monitor, serial/parallel lines).
- * The entry is <domain-path><storeString>/tty and the value is the name
- * of the pty associated with the device.
- */
-static int store_dev_info(char *devName, int domid,
- CharDriverState *cState, char *storeString)
-{
-#ifdef CONFIG_STUBDOM
- fprintf(logfile, "can't store dev %s name for domid %d in %s from a stub domain\n", devName, domid, storeString);
- return ENOSYS;
-#else
- int xc_handle;
- struct xs_handle *xs;
- char *path;
- char *newpath;
- FDCharDriver *s;
- char *pts;
-
- /* Check for valid arguments (at least, prevent segfaults). */
- if ((devName == NULL) || (cState == NULL) || (storeString == NULL)) {
- fprintf(logfile, "%s - invalid arguments\n", __FUNCTION__);
- return EINVAL;
- }
-
- /*
- * Only continue if we're talking to a pty
- * Actually, the following code works for any CharDriverState using
- * FDCharDriver, but we really only care about pty's here
- */
- if (strcmp(devName, "pty"))
- return 0;
-
- s = cState->opaque;
- if (s == NULL) {
- fprintf(logfile, "%s - unable to retrieve fd for '%s'/'%s'\n",
- __FUNCTION__, storeString, devName);
- return EBADF;
- }
-
- pts = ptsname(s->fd_in);
- if (pts == NULL) {
- fprintf(logfile, "%s - unable to determine ptsname '%s'/'%s', "
- "error %d (%s)\n",
- __FUNCTION__, storeString, devName, errno, strerror(errno));
- return errno;
- }
-
- /* We now have everything we need to set the xenstore entry. */
- xs = xs_daemon_open();
- if (xs == NULL) {
- fprintf(logfile, "Could not contact XenStore\n");
- return -1;
- }
-
- xc_handle = xc_interface_open();
- if (xc_handle == -1) {
- fprintf(logfile, "xc_interface_open() error\n");
- return -1;
- }
-
- path = xs_get_domain_path(xs, domid);
- if (path == NULL) {
- fprintf(logfile, "xs_get_domain_path() error\n");
- return -1;
- }
- newpath = realloc(path, (strlen(path) + strlen(storeString) +
- strlen("/tty") + 1));
- if (newpath == NULL) {
- free(path); /* realloc errors leave old block */
- fprintf(logfile, "realloc error\n");
- return -1;
- }
- path = newpath;
-
- strcat(path, storeString);
- strcat(path, "/tty");
- if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
- fprintf(logfile, "xs_write for '%s' fail", storeString);
- return -1;
- }
-
- free(path);
- xs_daemon_close(xs);
- close(xc_handle);
-
- return 0;
-#endif
-}
-
-#ifndef CONFIG_STUBDOM
-#ifdef __sun__
-/* Once Solaris has openpty(), this is going to be removed. */
-int openpty(int *amaster, int *aslave, char *name,
- struct termios *termp, struct winsize *winp)
-{
- const char *slave;
- int mfd = -1, sfd = -1;
-
- *amaster = *aslave = -1;
-
- mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
- if (mfd < 0)
- goto err;
-
- if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
- goto err;
-
- if ((slave = ptsname(mfd)) == NULL)
- goto err;
-
- if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
- goto err;
-
- if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
- (termp != NULL && tcgetattr(sfd, termp) < 0))
- goto err;
-
- if (amaster)
- *amaster = mfd;
- if (aslave)
- *aslave = sfd;
- if (winp)
- ioctl(sfd, TIOCSWINSZ, winp);
-
- return 0;
-
-err:
- if (sfd != -1)
- close(sfd);
- close(mfd);
- return -1;
-}
-
-void cfmakeraw (struct termios *termios_p)
-{
- termios_p->c_iflag &=
- ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
- termios_p->c_oflag &= ~OPOST;
- termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- termios_p->c_cflag &= ~(CSIZE|PARENB);
- termios_p->c_cflag |= CS8;
-
- termios_p->c_cc[VMIN] = 0;
- termios_p->c_cc[VTIME] = 0;
-}
-
-#endif
-
-#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun__)
-static CharDriverState *qemu_chr_open_pty(void)
-{
- struct termios tty;
- int master_fd, slave_fd;
-
- /* Not satisfying */
- if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
- return NULL;
- }
-
- /* Set raw attributes on the pty. */
- cfmakeraw(&tty);
- tcsetattr(slave_fd, TCSAFLUSH, &tty);
-
- fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-
- return qemu_chr_open_fd(master_fd, master_fd);
-}
-
-static void tty_serial_init(int fd, int speed,
- int parity, int data_bits, int stop_bits)
-{
- struct termios tty;
- speed_t spd;
-
-#if 0
- printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
- speed, parity, data_bits, stop_bits);
-#endif
- tcgetattr (fd, &tty);
-
- switch(speed) {
- case 50:
- spd = B50;
- break;
- case 75:
- spd = B75;
- break;
- case 300:
- spd = B300;
- break;
- case 600:
- spd = B600;
- break;
- case 1200:
- spd = B1200;
- break;
- case 2400:
- spd = B2400;
- break;
- case 4800:
- spd = B4800;
- break;
- case 9600:
- spd = B9600;
- break;
- case 19200:
- spd = B19200;
- break;
- case 38400:
- spd = B38400;
- break;
- case 57600:
- spd = B57600;
- break;
- default:
- case 115200:
- spd = B115200;
- break;
- }
-
- cfsetispeed(&tty, spd);
- cfsetospeed(&tty, spd);
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
- tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
- switch(data_bits) {
- default:
- case 8:
- tty.c_cflag |= CS8;
- break;
- case 7:
- tty.c_cflag |= CS7;
- break;
- case 6:
- tty.c_cflag |= CS6;
- break;
- case 5:
- tty.c_cflag |= CS5;
- break;
- }
- switch(parity) {
- default:
- case 'N':
- break;
- case 'E':
- tty.c_cflag |= PARENB;
- break;
- case 'O':
- tty.c_cflag |= PARENB | PARODD;
- break;
- }
- if (stop_bits == 2)
- tty.c_cflag |= CSTOPB;
-
- tcsetattr (fd, TCSANOW, &tty);
-}
-
-static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
-{
- FDCharDriver *s = chr->opaque;
-
- switch(cmd) {
- case CHR_IOCTL_SERIAL_SET_PARAMS:
- {
- QEMUSerialSetParams *ssp = arg;
- tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
- ssp->data_bits, ssp->stop_bits);
- }
- break;
- case CHR_IOCTL_SERIAL_SET_BREAK:
- {
- int enable = *(int *)arg;
- if (enable)
- tcsendbreak(s->fd_in, 1);
- }
- break;
- case CHR_IOCTL_SERIAL_GET_TIOCM:
- {
- ioctl(s->fd_in, TIOCMGET, arg);
- }
- break;
- case CHR_IOCTL_SERIAL_SET_TIOCM:
- {
- ioctl(s->fd_in, TIOCMSET, arg);
- }
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-static CharDriverState *qemu_chr_open_tty(const char *filename)
-{
- CharDriverState *chr;
- int fd;
-
- fd = open(filename, O_RDWR | O_NONBLOCK);
- if (fd < 0)
- return NULL;
- fcntl(fd, F_SETFL, O_NONBLOCK);
- tty_serial_init(fd, 115200, 'N', 8, 1);
- chr = qemu_chr_open_fd(fd, fd);
- if (!chr)
- return NULL;
- chr->chr_ioctl = tty_serial_ioctl;
- qemu_chr_reset(chr);
- return chr;
-}
-
-#if defined(__linux__)
-static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
-{
- int fd = (int)chr->opaque;
- uint8_t b;
-
- switch(cmd) {
- case CHR_IOCTL_PP_READ_DATA:
- if (ioctl(fd, PPRDATA, &b) < 0)
- return -ENOTSUP;
- *(uint8_t *)arg = b;
- break;
- case CHR_IOCTL_PP_WRITE_DATA:
- b = *(uint8_t *)arg;
- if (ioctl(fd, PPWDATA, &b) < 0)
- return -ENOTSUP;
- break;
- case CHR_IOCTL_PP_READ_CONTROL:
- if (ioctl(fd, PPRCONTROL, &b) < 0)
- return -ENOTSUP;
- *(uint8_t *)arg = b;
- break;
- case CHR_IOCTL_PP_WRITE_CONTROL:
- b = *(uint8_t *)arg;
- if (ioctl(fd, PPWCONTROL, &b) < 0)
- return -ENOTSUP;
- break;
- case CHR_IOCTL_PP_READ_STATUS:
- if (ioctl(fd, PPRSTATUS, &b) < 0)
- return -ENOTSUP;
- *(uint8_t *)arg = b;
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-static CharDriverState *qemu_chr_open_pp(const char *filename)
-{
- CharDriverState *chr;
- int fd;
-
- fd = open(filename, O_RDWR);
- if (fd < 0)
- return NULL;
-
- if (ioctl(fd, PPCLAIM) < 0) {
- close(fd);
- return NULL;
- }
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr) {
- close(fd);
- return NULL;
- }
- chr->opaque = (void *)fd;
- chr->chr_write = null_chr_write;
- chr->chr_ioctl = pp_ioctl;
-
- qemu_chr_reset(chr);
-
- return chr;
-}
-#endif /* __linux__ */
-
-#else
-static CharDriverState *qemu_chr_open_pty(void)
-{
- return NULL;
-}
-#endif /* __linux__ || __NetBSD__ || __OpenBSD__ || __sun__ */
-
-#endif /* !defined(_WIN32) */
-
-#ifdef _WIN32
-typedef struct {
- CharDriverState *chr;
- int max_size;
- HANDLE hcom, hrecv, hsend;
- OVERLAPPED orecv, osend;
- BOOL fpipe;
- DWORD len;
-} WinCharState;
-
-#define NSENDBUF 2048
-#define NRECVBUF 2048
-#define MAXCONNECT 1
-#define NTIMEOUT 5000
-
-static int win_chr_poll(void *opaque);
-static int win_chr_pipe_poll(void *opaque);
-
-static void win_chr_close2(WinCharState *s)
-{
- if (s->hsend) {
- CloseHandle(s->hsend);
- s->hsend = NULL;
- }
- if (s->hrecv) {
- CloseHandle(s->hrecv);
- s->hrecv = NULL;
- }
- if (s->hcom) {
- CloseHandle(s->hcom);
- s->hcom = NULL;
- }
- if (s->fpipe)
- qemu_del_polling_cb(win_chr_pipe_poll, s);
- else
- qemu_del_polling_cb(win_chr_poll, s);
-}
-
-static void win_chr_close(CharDriverState *chr)
-{
- WinCharState *s = chr->opaque;
- win_chr_close2(s);
-}
-
-static int win_chr_init(WinCharState *s, CharDriverState *chr, const char *filename)
-{
- COMMCONFIG comcfg;
- COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
- COMSTAT comstat;
- DWORD size;
- DWORD err;
-
- s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hsend) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
- s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hrecv) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
-
- s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
- if (s->hcom == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
- s->hcom = NULL;
- goto fail;
- }
-
- if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
- fprintf(stderr, "Failed SetupComm\n");
- goto fail;
- }
-
- ZeroMemory(&comcfg, sizeof(COMMCONFIG));
- size = sizeof(COMMCONFIG);
- GetDefaultCommConfig(filename, &comcfg, &size);
- comcfg.dcb.DCBlength = sizeof(DCB);
- CommConfigDialog(filename, NULL, &comcfg);
-
- if (!SetCommState(s->hcom, &comcfg.dcb)) {
- fprintf(stderr, "Failed SetCommState\n");
- goto fail;
- }
-
- if (!SetCommMask(s->hcom, EV_ERR)) {
- fprintf(stderr, "Failed SetCommMask\n");
- goto fail;
- }
-
- cto.ReadIntervalTimeout = MAXDWORD;
- if (!SetCommTimeouts(s->hcom, &cto)) {
- fprintf(stderr, "Failed SetCommTimeouts\n");
- goto fail;
- }
-
- if (!ClearCommError(s->hcom, &err, &comstat)) {
- fprintf(stderr, "Failed ClearCommError\n");
- goto fail;
- }
- s->chr = chr;
- qemu_add_polling_cb(win_chr_poll, s);
- return 0;
-
- fail:
- win_chr_close2(s);
- return -1;
-}
-
-static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
-{
- WinCharState *s = chr->opaque;
- DWORD len, ret, size, err;
-
- len = len1;
- ZeroMemory(&s->osend, sizeof(s->osend));
- s->osend.hEvent = s->hsend;
- while (len > 0) {
- if (s->hsend)
- ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
- else
- ret = WriteFile(s->hcom, buf, len, &size, NULL);
- if (!ret) {
- err = GetLastError();
- if (err == ERROR_IO_PENDING) {
- ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
- if (ret) {
- buf += size;
- len -= size;
- } else {
- break;
- }
- } else {
- break;
- }
- } else {
- buf += size;
- len -= size;
- }
- }
- return len1 - len;
-}
-
-static int win_chr_read_poll(WinCharState *s)
-{
- s->max_size = qemu_chr_can_read(s->chr);
- return s->max_size;
-}
-
-static void win_chr_readfile(WinCharState *s)
-{
- int ret, err;
- uint8_t buf[1024];
- DWORD size;
-
- ZeroMemory(&s->orecv, sizeof(s->orecv));
- s->orecv.hEvent = s->hrecv;
- ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
- if (!ret) {
- err = GetLastError();
- if (err == ERROR_IO_PENDING) {
- ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
- }
- }
-
- if (size > 0) {
- qemu_chr_read(s->chr, buf, size);
- }
-}
-
-static void win_chr_read(WinCharState *s)
-{
- if (s->len > s->max_size)
- s->len = s->max_size;
- if (s->len == 0)
- return;
-
- win_chr_readfile(s);
-}
-
-static int win_chr_poll(void *opaque)
-{
- WinCharState *s = opaque;
- COMSTAT status;
- DWORD comerr;
-
- ClearCommError(s->hcom, &comerr, &status);
- if (status.cbInQue > 0) {
- s->len = status.cbInQue;
- win_chr_read_poll(s);
- win_chr_read(s);
- return 1;
- }
- return 0;
-}
-
-static CharDriverState *qemu_chr_open_win(const char *filename)
-{
- CharDriverState *chr;
- WinCharState *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(WinCharState));
- if (!s) {
- free(chr);
- return NULL;
- }
- chr->opaque = s;
- chr->chr_write = win_chr_write;
- chr->chr_close = win_chr_close;
-
- if (win_chr_init(s, chr, filename) < 0) {
- free(s);
- free(chr);
- return NULL;
- }
- qemu_chr_reset(chr);
- return chr;
-}
-
-static int win_chr_pipe_poll(void *opaque)
-{
- WinCharState *s = opaque;
- DWORD size;
-
- PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
- if (size > 0) {
- s->len = size;
- win_chr_read_poll(s);
- win_chr_read(s);
- return 1;
- }
- return 0;
-}
-
-static int win_chr_pipe_init(WinCharState *s, const char *filename)
-{
- OVERLAPPED ov;
- int ret;
- DWORD size;
- char openname[256];
-
- s->fpipe = TRUE;
-
- s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hsend) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
- s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hrecv) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
-
- snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
- s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
- PIPE_WAIT,
- MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
- if (s->hcom == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
- s->hcom = NULL;
- goto fail;
- }
-
- ZeroMemory(&ov, sizeof(ov));
- ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- ret = ConnectNamedPipe(s->hcom, &ov);
- if (ret) {
- fprintf(stderr, "Failed ConnectNamedPipe\n");
- goto fail;
- }
-
- ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
- if (!ret) {
- fprintf(stderr, "Failed GetOverlappedResult\n");
- if (ov.hEvent) {
- CloseHandle(ov.hEvent);
- ov.hEvent = NULL;
- }
- goto fail;
- }
-
- if (ov.hEvent) {
- CloseHandle(ov.hEvent);
- ov.hEvent = NULL;
- }
- qemu_add_polling_cb(win_chr_pipe_poll, s);
- return 0;
-
- fail:
- win_chr_close2(s);
- return -1;
-}
-
-
-static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
-{
- CharDriverState *chr;
- WinCharState *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(WinCharState));
- if (!s) {
- free(chr);
- return NULL;
- }
- chr->opaque = s;
- chr->chr_write = win_chr_write;
- chr->chr_close = win_chr_close;
-
- if (win_chr_pipe_init(s, filename) < 0) {
- free(s);
- free(chr);
- return NULL;
- }
- qemu_chr_reset(chr);
- return chr;
-}
-
-static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
-{
- CharDriverState *chr;
- WinCharState *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(WinCharState));
- if (!s) {
- free(chr);
- return NULL;
- }
- s->hcom = fd_out;
- chr->opaque = s;
- chr->chr_write = win_chr_write;
- qemu_chr_reset(chr);
- return chr;
-}
-
-static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
-{
- HANDLE fd_out;
-
- fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (fd_out == INVALID_HANDLE_VALUE)
- return NULL;
-
- return qemu_chr_open_win_file(fd_out);
-}
-#endif
-#endif
-
-/***********************************************************/
-/* UDP Net console */
-
-typedef struct {
- int fd;
- struct sockaddr_in daddr;
- char buf[1024];
- int bufcnt;
- int bufptr;
- int max_size;
-} NetCharDriver;
-
-static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- NetCharDriver *s = chr->opaque;
-
- return sendto(s->fd, buf, len, 0,
- (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
-}
-
-static int udp_chr_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- NetCharDriver *s = chr->opaque;
-
- s->max_size = qemu_chr_can_read(chr);
-
- /* If there were any stray characters in the queue process them
- * first
- */
- while (s->max_size > 0 && s->bufptr < s->bufcnt) {
- qemu_chr_read(chr, &s->buf[s->bufptr], 1);
- s->bufptr++;
- s->max_size = qemu_chr_can_read(chr);
- }
- return s->max_size;
-}
-
-static void udp_chr_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- NetCharDriver *s = chr->opaque;
-
- if (s->max_size == 0)
- return;
- s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
- s->bufptr = s->bufcnt;
- if (s->bufcnt <= 0)
- return;
-
- s->bufptr = 0;
- while (s->max_size > 0 && s->bufptr < s->bufcnt) {
- qemu_chr_read(chr, &s->buf[s->bufptr], 1);
- s->bufptr++;
- s->max_size = qemu_chr_can_read(chr);
- }
-}
-
-static void udp_chr_update_read_handler(CharDriverState *chr)
-{
- NetCharDriver *s = chr->opaque;
-
- if (s->fd >= 0) {
- qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
- udp_chr_read, NULL, chr);
- }
-}
-
-int parse_host_port(struct sockaddr_in *saddr, const char *str);
-#ifndef NO_UNIX_SOCKETS
-static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
-#endif
-int parse_host_src_port(struct sockaddr_in *haddr,
- struct sockaddr_in *saddr,
- const char *str);
-
-static CharDriverState *qemu_chr_open_udp(const char *def)
-{
- CharDriverState *chr = NULL;
- NetCharDriver *s = NULL;
- int fd = -1;
- struct sockaddr_in saddr;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- goto return_err;
- s = qemu_mallocz(sizeof(NetCharDriver));
- if (!s)
- goto return_err;
-
- fd = socket(PF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- perror("socket(PF_INET, SOCK_DGRAM)");
- goto return_err;
- }
-
- if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
- printf("Could not parse: %s\n", def);
- goto return_err;
- }
-
- if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
- {
- perror("bind");
- goto return_err;
- }
-
- s->fd = fd;
- s->bufcnt = 0;
- s->bufptr = 0;
- chr->opaque = s;
- chr->chr_write = udp_chr_write;
- chr->chr_update_read_handler = udp_chr_update_read_handler;
- return chr;
-
-return_err:
- if (chr)
- free(chr);
- if (s)
- free(s);
- if (fd >= 0)
- closesocket(fd);
- return NULL;
-}
-
-/***********************************************************/
-/* TCP Net console */
-
-typedef struct {
- int fd, listen_fd;
- int connected;
- int max_size;
- int do_telnetopt;
- int do_nodelay;
- int is_unix;
-} TCPCharDriver;
-
-static void tcp_chr_accept(void *opaque);
-
-static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- TCPCharDriver *s = chr->opaque;
- if (s->connected) {
- return send_all(s->fd, buf, len);
- } else {
- /* XXX: indicate an error ? */
- return len;
- }
-}
-
-static int tcp_chr_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
- if (!s->connected)
- return 0;
- s->max_size = qemu_chr_can_read(chr);
- return s->max_size;
-}
-
-#define IAC 255
-#define IAC_BREAK 243
-static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
- TCPCharDriver *s,
- char *buf, int *size)
-{
- /* Handle any telnet client's basic IAC options to satisfy char by
- * char mode with no echo. All IAC options will be removed from
- * the buf and the do_telnetopt variable will be used to track the
- * state of the width of the IAC information.
- *
- * IAC commands come in sets of 3 bytes with the exception of the
- * "IAC BREAK" command and the double IAC.
- */
-
- int i;
- int j = 0;
-
- for (i = 0; i < *size; i++) {
- if (s->do_telnetopt > 1) {
- if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
- /* Double IAC means send an IAC */
- if (j != i)
- buf[j] = buf[i];
- j++;
- s->do_telnetopt = 1;
- } else {
- if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
- /* Handle IAC break commands by sending a serial break */
- qemu_chr_event(chr, CHR_EVENT_BREAK);
- s->do_telnetopt++;
- }
- s->do_telnetopt++;
- }
- if (s->do_telnetopt >= 4) {
- s->do_telnetopt = 1;
- }
- } else {
- if ((unsigned char)buf[i] == IAC) {
- s->do_telnetopt = 2;
- } else {
- if (j != i)
- buf[j] = buf[i];
- j++;
- }
- }
- }
- *size = j;
-}
-
-static void tcp_chr_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
- uint8_t buf[1024];
- int len, size;
-
- if (!s->connected || s->max_size <= 0)
- return;
- len = sizeof(buf);
- if (len > s->max_size)
- len = s->max_size;
- size = recv(s->fd, buf, len, 0);
- if (size == 0) {
- /* connection closed */
- s->connected = 0;
- if (s->listen_fd >= 0) {
- qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
- }
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
- closesocket(s->fd);
- s->fd = -1;
- } else if (size > 0) {
- if (s->do_telnetopt)
- tcp_chr_process_IAC_bytes(chr, s, buf, &size);
- if (size > 0)
- qemu_chr_read(chr, buf, size);
- }
-}
-
-static void tcp_chr_connect(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
-
- s->connected = 1;
- qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
- tcp_chr_read, NULL, chr);
- qemu_chr_reset(chr);
-}
-
-#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
-static void tcp_chr_telnet_init(int fd)
-{
- char buf[3];
- /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
- IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
- send(fd, (char *)buf, 3, 0);
- IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
- send(fd, (char *)buf, 3, 0);
- IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
- send(fd, (char *)buf, 3, 0);
- IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
- send(fd, (char *)buf, 3, 0);
-}
-
-static void socket_set_nodelay(int fd)
-{
- int val = 1;
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
-}
-
-static void tcp_chr_accept(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
- struct sockaddr_in saddr;
-#ifndef NO_UNIX_SOCKETS
- struct sockaddr_un uaddr;
-#endif
- struct sockaddr *addr;
- socklen_t len;
- int fd;
-
- for(;;) {
-#ifndef NO_UNIX_SOCKETS
- if (s->is_unix) {
- len = sizeof(uaddr);
- addr = (struct sockaddr *)&uaddr;
- } else
-#endif
- {
- len = sizeof(saddr);
- addr = (struct sockaddr *)&saddr;
- }
- fd = accept(s->listen_fd, addr, &len);
- if (fd < 0 && errno != EINTR) {
- return;
- } else if (fd >= 0) {
- if (s->do_telnetopt)
- tcp_chr_telnet_init(fd);
- break;
- }
- }
- socket_set_nonblock(fd);
- if (s->do_nodelay)
- socket_set_nodelay(fd);
- s->fd = fd;
- qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
- tcp_chr_connect(chr);
-}
-
-static void tcp_chr_close(CharDriverState *chr)
-{
- TCPCharDriver *s = chr->opaque;
- if (s->fd >= 0)
- closesocket(s->fd);
- if (s->listen_fd >= 0)
- closesocket(s->listen_fd);
- qemu_free(s);
-}
-
-static CharDriverState *qemu_chr_open_tcp(const char *host_str,
- int is_telnet,
- int is_unix)
-{
- CharDriverState *chr = NULL;
- TCPCharDriver *s = NULL;
- int fd = -1, ret, err, val;
- int is_listen = 0;
- int is_waitconnect = 1;
- int do_nodelay = 0;
- const char *ptr;
- struct sockaddr_in saddr;
-#ifndef NO_UNIX_SOCKETS
- struct sockaddr_un uaddr;
-#endif
- struct sockaddr *addr;
- socklen_t addrlen;
-
-#ifndef NO_UNIX_SOCKETS
- if (is_unix) {
- addr = (struct sockaddr *)&uaddr;
- addrlen = sizeof(uaddr);
- if (parse_unix_path(&uaddr, host_str) < 0)
- goto fail;
- } else
-#endif
- {
- addr = (struct sockaddr *)&saddr;
- addrlen = sizeof(saddr);
- if (parse_host_port(&saddr, host_str) < 0)
- goto fail;
- }
-
- ptr = host_str;
- while((ptr = strchr(ptr,','))) {
- ptr++;
- if (!strncmp(ptr,"server",6)) {
- is_listen = 1;
- } else if (!strncmp(ptr,"nowait",6)) {
- is_waitconnect = 0;
- } else if (!strncmp(ptr,"nodelay",6)) {
- do_nodelay = 1;
- } else {
- printf("Unknown option: %s\n", ptr);
- goto fail;
- }
- }
- if (!is_listen)
- is_waitconnect = 0;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- goto fail;
- s = qemu_mallocz(sizeof(TCPCharDriver));
- if (!s)
- goto fail;
-
-#ifndef NO_UNIX_SOCKETS
- if (is_unix)
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- else
-#endif
- fd = socket(PF_INET, SOCK_STREAM, 0);
-
- if (fd < 0)
- goto fail;
-
- if (!is_waitconnect)
- socket_set_nonblock(fd);
-
- s->connected = 0;
- s->fd = -1;
- s->listen_fd = -1;
- s->is_unix = is_unix;
- s->do_nodelay = do_nodelay && !is_unix;
-
- chr->opaque = s;
- chr->chr_write = tcp_chr_write;
- chr->chr_close = tcp_chr_close;
-
- if (is_listen) {
- /* allow fast reuse */
-#ifndef NO_UNIX_SOCKETS
- if (is_unix) {
- char path[109];
- strncpy(path, uaddr.sun_path, 108);
- path[108] = 0;
- unlink(path);
- } else
-#endif
- {
- val = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
- }
-
- ret = bind(fd, addr, addrlen);
- if (ret < 0)
- goto fail;
-
- ret = listen(fd, 0);
- if (ret < 0)
- goto fail;
-
- s->listen_fd = fd;
- qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
- if (is_telnet)
- s->do_telnetopt = 1;
- } else {
- for(;;) {
- ret = connect(fd, addr, addrlen);
- if (ret < 0) {
- err = socket_error();
- if (err == EINTR || err == EWOULDBLOCK) {
- } else if (err == EINPROGRESS) {
- break;
- } else {
- goto fail;
- }
- } else {
- s->connected = 1;
- break;
- }
- }
- s->fd = fd;
- socket_set_nodelay(fd);
- if (s->connected)
- tcp_chr_connect(chr);
- else
- qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
- }
-
- if (is_listen && is_waitconnect) {
- printf("QEMU waiting for connection on: %s\n", host_str);
- tcp_chr_accept(chr);
- socket_set_nonblock(s->listen_fd);
- }
-
- return chr;
- fail:
- if (fd >= 0)
- closesocket(fd);
- qemu_free(s);
- qemu_free(chr);
- return NULL;
-}
-
-CharDriverState *qemu_chr_open(const char *filename)
-{
- const char *p;
-
- if (!strcmp(filename, "vc")) {
- return text_console_init(&display_state);
- } else if (!strcmp(filename, "null")) {
- return qemu_chr_open_null();
- } else
- if (strstart(filename, "tcp:", &p)) {
- return qemu_chr_open_tcp(p, 0, 0);
- } else
- if (strstart(filename, "telnet:", &p)) {
- return qemu_chr_open_tcp(p, 1, 0);
- } else
- if (strstart(filename, "udp:", &p)) {
- return qemu_chr_open_udp(p);
- } else
-#ifndef _WIN32
- if (strstart(filename, "unix:", &p)) {
- return qemu_chr_open_tcp(p, 0, 1);
- } else if (strstart(filename, "file:", &p)) {
- return qemu_chr_open_file_out(p);
-#ifndef CONFIG_STUBDOM
- } else if (strstart(filename, "pipe:", &p)) {
- return qemu_chr_open_pipe(p);
- } else if (!strcmp(filename, "pty")) {
- return qemu_chr_open_pty();
- } else if (!strcmp(filename, "stdio")) {
- return qemu_chr_open_stdio();
-#endif
- } else
-#endif
-#if defined(__linux__)
- if (strstart(filename, "/dev/parport", NULL)) {
- return qemu_chr_open_pp(filename);
- } else
- if (strstart(filename, "/dev/", NULL)) {
- return qemu_chr_open_tty(filename);
- } else
-#endif
-#ifdef _WIN32
- if (strstart(filename, "COM", NULL)) {
- return qemu_chr_open_win(filename);
- } else
- if (strstart(filename, "pipe:", &p)) {
- return qemu_chr_open_win_pipe(p);
- } else
- if (strstart(filename, "file:", &p)) {
- return qemu_chr_open_win_file_out(p);
- }
-#endif
- {
- return NULL;
- }
-}
-
-void qemu_chr_close(CharDriverState *chr)
-{
- if (chr->chr_close)
- chr->chr_close(chr);
-}
-
-/***********************************************************/
-/* network device redirectors */
-
-void hex_dump(FILE *f, const uint8_t *buf, int size)
-{
- int len, i, j, c;
-
- for(i=0;i<size;i+=16) {
- len = size - i;
- if (len > 16)
- len = 16;
- fprintf(f, "%08x ", i);
- for(j=0;j<16;j++) {
- if (j < len)
- fprintf(f, " %02x", buf[i+j]);
- else
- fprintf(f, " ");
- }
- fprintf(f, " ");
- for(j=0;j<len;j++) {
- c = buf[i+j];
- if (c < ' ' || c > '~')
- c = '.';
- fprintf(f, "%c", c);
- }
- fprintf(f, "\n");
- }
-}
-
-static int parse_macaddr(uint8_t *macaddr, const char *p)
-{
- int i;
- for(i = 0; i < 6; i++) {
- macaddr[i] = strtol(p, (char **)&p, 16);
- if (i == 5) {
- if (*p != '\0')
- return -1;
- } else {
- if (*p != ':')
- return -1;
- p++;
- }
- }
- return 0;
-}
-
-static int get_str_sep(char *buf, size_t buf_size, const char **pp, int sep)
-{
- const char *p, *p1;
- int len;
- p = *pp;
- p1 = strchr(p, sep);
- if (!p1)
- return -1;
- len = p1 - p;
- p1++;
- if (buf_size > 0) {
- if (len > buf_size - 1)
- len = buf_size - 1;
- memcpy(buf, p, len);
- buf[len] = '\0';
- }
- *pp = p1;
- return 0;
-}
-
-int parse_host_src_port(struct sockaddr_in *haddr,
- struct sockaddr_in *saddr,
- const char *input_str)
-{
- char *str = strdup(input_str);
- char *host_str = str;
- char *src_str;
- char *ptr;
-
- /*
- * Chop off any extra arguments at the end of the string which
- * would start with a comma, then fill in the src port information
- * if it was provided else use the "any address" and "any port".
- */
- if ((ptr = strchr(str,',')))
- *ptr = '\0';
-
- if ((src_str = strchr(input_str,'@'))) {
- *src_str = '\0';
- src_str++;
- }
-
- if (parse_host_port(haddr, host_str) < 0)
- goto fail;
-
- if (!src_str || *src_str == '\0')
- src_str = ":0";
-
- if (parse_host_port(saddr, src_str) < 0)
- goto fail;
-
- free(str);
- return(0);
-
-fail:
- free(str);
- return -1;
-}
-
-int parse_host_port(struct sockaddr_in *saddr, const char *str)
-{
- char buf[512];
- struct hostent *he;
- const char *p, *r;
- int port;
-
- p = str;
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- return -1;
- saddr->sin_family = AF_INET;
- if (buf[0] == '\0') {
- saddr->sin_addr.s_addr = 0;
- } else {
- if (isdigit((uint8_t)buf[0])) {
- if (!inet_aton(buf, &saddr->sin_addr))
- return -1;
- } else {
- if ((he = gethostbyname(buf)) == NULL)
- return - 1;
- saddr->sin_addr = *(struct in_addr *)he->h_addr;
- }
- }
- port = strtol(p, (char **)&r, 0);
- if (r == p)
- return -1;
- saddr->sin_port = htons(port);
- return 0;
-}
-
-#ifndef NO_UNIX_SOCKETS
-static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
-{
- const char *p;
- int len;
-
- len = MIN(108, strlen(str));
- p = strchr(str, ',');
- if (p)
- len = MIN(len, p - str);
-
- memset(uaddr, 0, sizeof(*uaddr));
-
- uaddr->sun_family = AF_UNIX;
- memcpy(uaddr->sun_path, str, len);
-
- return 0;
-}
-#endif
-
-/* find or alloc a new VLAN */
-VLANState *qemu_find_vlan(int id)
-{
- VLANState **pvlan, *vlan;
- for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
- if (vlan->id == id)
- return vlan;
- }
- vlan = qemu_mallocz(sizeof(VLANState));
- if (!vlan)
- return NULL;
- vlan->id = id;
- vlan->next = NULL;
- pvlan = &first_vlan;
- while (*pvlan != NULL)
- pvlan = &(*pvlan)->next;
- *pvlan = vlan;
- return vlan;
-}
-
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque)
-{
- VLANClientState *vc, **pvc;
- vc = qemu_mallocz(sizeof(VLANClientState));
- if (!vc)
- return NULL;
- vc->fd_read = fd_read;
- vc->fd_can_read = fd_can_read;
- vc->opaque = opaque;
- vc->vlan = vlan;
-
- vc->next = NULL;
- pvc = &vlan->first_client;
- while (*pvc != NULL)
- pvc = &(*pvc)->next;
- *pvc = vc;
- return vc;
-}
-
-int qemu_can_send_packet(VLANClientState *vc1)
-{
- VLANState *vlan = vc1->vlan;
- VLANClientState *vc;
-
- for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
- if (vc != vc1) {
- if (vc->fd_can_read && !vc->fd_can_read(vc->opaque))
- return 0;
- }
- }
- return 1;
-}
-
-void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
-{
- VLANState *vlan = vc1->vlan;
- VLANClientState *vc;
-
-#if 0
- printf("vlan %d send:\n", vlan->id);
- hex_dump(stdout, buf, size);
-#endif
- for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
- if (vc != vc1) {
- vc->fd_read(vc->opaque, buf, size);
- }
- }
-}
-
-#if defined(CONFIG_SLIRP)
-
-/* slirp network adapter */
-
-static int slirp_inited;
-static VLANClientState *slirp_vc;
-
-int slirp_can_output(void)
-{
- return !slirp_vc || qemu_can_send_packet(slirp_vc);
-}
-
-void slirp_output(const uint8_t *pkt, int pkt_len)
-{
-#if 0
- printf("slirp output:\n");
- hex_dump(stdout, pkt, pkt_len);
-#endif
- if (!slirp_vc)
- return;
- qemu_send_packet(slirp_vc, pkt, pkt_len);
-}
-
-static void slirp_receive(void *opaque, const uint8_t *buf, int size)
-{
-#if 0
- printf("slirp input:\n");
- hex_dump(stdout, buf, size);
-#endif
- slirp_input(buf, size);
-}
-
-static int net_slirp_init(VLANState *vlan)
-{
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
- slirp_vc = qemu_new_vlan_client(vlan,
- slirp_receive, NULL, NULL);
- snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
- return 0;
-}
-
-static void net_slirp_redir(const char *redir_str)
-{
- int is_udp;
- char buf[256], *r;
- const char *p;
- struct in_addr guest_addr;
- int host_port, guest_port;
-
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
-
- p = redir_str;
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- if (!strcmp(buf, "tcp")) {
- is_udp = 0;
- } else if (!strcmp(buf, "udp")) {
- is_udp = 1;
- } else {
- goto fail;
- }
-
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- host_port = strtol(buf, &r, 0);
- if (r == buf)
- goto fail;
-
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- if (buf[0] == '\0') {
- pstrcpy(buf, sizeof(buf), "10.0.2.15");
- }
- if (!inet_aton(buf, &guest_addr))
- goto fail;
-
- guest_port = strtol(p, &r, 0);
- if (r == p)
- goto fail;
-
- if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
- fprintf(stderr, "qemu: could not set up redirection\n");
- exit(1);
- }
- return;
- fail:
- fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
- exit(1);
-}
-
-#ifndef _WIN32
-
-char smb_dir[1024];
-
-static void smb_exit(void)
-{
- DIR *d;
- struct dirent *de;
- char filename[1024];
-
- /* erase all the files in the directory */
- d = opendir(smb_dir);
- for(;;) {
- de = readdir(d);
- if (!de)
- break;
- if (strcmp(de->d_name, ".") != 0 &&
- strcmp(de->d_name, "..") != 0) {
- snprintf(filename, sizeof(filename), "%s/%s",
- smb_dir, de->d_name);
- unlink(filename);
- }
- }
- closedir(d);
- rmdir(smb_dir);
-}
-
-/* automatic user mode samba server configuration */
-void net_slirp_smb(const char *exported_dir)
-{
- char smb_conf[1024];
- char smb_cmdline[1024];
- FILE *f;
-
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
-
- /* XXX: better tmp dir construction */
- snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%ld", (long)getpid());
- if (mkdir(smb_dir, 0700) < 0) {
- fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
- exit(1);
- }
- snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
-
- f = fopen(smb_conf, "w");
- if (!f) {
- fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
- exit(1);
- }
- fprintf(f,
- "[global]\n"
- "private dir=%s\n"
- "smb ports=0\n"
- "socket address=127.0.0.1\n"
- "pid directory=%s\n"
- "lock directory=%s\n"
- "log file=%s/log.smbd\n"
- "smb passwd file=%s/smbpasswd\n"
- "security = share\n"
- "[qemu]\n"
- "path=%s\n"
- "read only=no\n"
- "guest ok=yes\n",
- smb_dir,
- smb_dir,
- smb_dir,
- smb_dir,
- smb_dir,
- exported_dir
- );
- fclose(f);
- atexit(smb_exit);
-
- snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
- SMBD_COMMAND, smb_conf);
-
- slirp_add_exec(0, smb_cmdline, 4, 139);
-}
-
-#endif /* !defined(_WIN32) */
-
-#endif /* CONFIG_SLIRP */
-
-#if !defined(_WIN32)
-
-typedef struct TAPState {
- VLANClientState *vc;
- int fd;
-} TAPState;
-
-static void tap_receive(void *opaque, const uint8_t *buf, int size)
-{
- TAPState *s = opaque;
- int ret;
- for(;;) {
- ret = write(s->fd, buf, size);
- if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
- } else {
- break;
- }
- }
-}
-
-static void tap_send(void *opaque)
-{
- TAPState *s = opaque;
- uint8_t buf[4096];
- int size;
-
- size = read(s->fd, buf, sizeof(buf));
- if (size > 0) {
- qemu_send_packet(s->vc, buf, size);
- }
-}
-
-/* fd support */
-
-static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
-{
- TAPState *s;
-
- s = qemu_mallocz(sizeof(TAPState));
- if (!s)
- return NULL;
- s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
- qemu_set_fd_handler(s->fd, tap_send, NULL, s);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
- return s;
-}
-
-#ifdef CONFIG_STUBDOM
-#include <netfront.h>
-static int tap_open(char *ifname, int ifname_size)
-{
- char nodename[64];
- static int num = 1; // 0 is for our own TCP/IP networking
- snprintf(nodename, sizeof(nodename), "device/vif/%d", num++);
- return netfront_tap_open(nodename);
-}
-#elif defined(_BSD)
-static int tap_open(char *ifname, int ifname_size)
-{
- int fd;
-#ifndef TAPGIFNAME
- char *dev;
- struct stat s;
-#endif
- struct ifreq ifr;
-
- fd = open("/dev/tap", O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation %s\n", strerror(errno));
- return -1;
- }
-
-#ifdef TAPGIFNAME
- if (ioctl (fd, TAPGIFNAME, (void*)&ifr) < 0) {
- fprintf(stderr, "warning: could not open get tap name: %s\n",
- strerror(errno));
- return -1;
- }
- pstrcpy(ifname, ifname_size, ifr.ifr_name);
-#else
- fstat(fd, &s);
- dev = devname(s.st_rdev, S_IFCHR);
- pstrcpy(ifname, ifname_size, dev);
-#endif
-
- fcntl(fd, F_SETFL, O_NONBLOCK);
- return fd;
-}
-#elif defined(__sun__)
-static int tap_open(char *ifname, int ifname_size)
-{
- fprintf(stderr, "warning: tap_open not yet implemented\n");
- return -1;
-}
-#else
-static int tap_open(char *ifname, int ifname_size)
-{
- struct ifreq ifr;
- int fd, ret, retries = 0;
-
- fd = open("/dev/net/tun", O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
- return -1;
- }
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- if (ifname[0] != '\0')
- pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
- else
- pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
- do {
- ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
- } while ((ret != 0) && (retries++ < 3));
- if (ret != 0) {
- fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
- close(fd);
- return -1;
- }
- pstrcpy(ifname, ifname_size, ifr.ifr_name);
- fcntl(fd, F_SETFL, O_NONBLOCK);
- return fd;
-}
-#endif
-
-static int net_tap_init(VLANState *vlan, const char *ifname1,
- const char *setup_script, const char *bridge)
-{
- TAPState *s;
- int pid, status, fd;
- char *args[4];
- char **parg;
- char ifname[128];
-
- memset(ifname, 0, sizeof(ifname));
-
- if (ifname1 != NULL)
- pstrcpy(ifname, sizeof(ifname), ifname1);
- else
- ifname[0] = '\0';
- fd = tap_open(ifname, sizeof(ifname));
- if (fd < 0)
- return -1;
-
-#ifndef CONFIG_STUBDOM
- if (!setup_script || !strcmp(setup_script, "no"))
- setup_script = "";
- if (setup_script[0] != '\0') {
- /* try to launch network init script */
- pid = fork();
- if (pid >= 0) {
- if (pid == 0) {
- int open_max = sysconf(_SC_OPEN_MAX), i;
- for (i = 0; i < open_max; i++)
- if (i != STDIN_FILENO &&
- i != STDOUT_FILENO &&
- i != STDERR_FILENO &&
- i != fd)
- close(i);
-
- parg = args;
- *parg++ = (char *)setup_script;
- *parg++ = ifname;
- *parg++ = (char *)bridge;
- *parg++ = NULL;
- execv(setup_script, args);
- _exit(1);
- }
- while (waitpid(pid, &status, 0) != pid);
- if (!WIFEXITED(status) ||
- WEXITSTATUS(status) != 0) {
- fprintf(stderr, "%s: could not launch network script\n",
- setup_script);
- return -1;
- }
- }
- }
-#endif
- s = net_tap_fd_init(vlan, fd);
- if (!s)
- return -1;
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "tap: ifname=%s setup_script=%s", ifname, setup_script);
- return 0;
-}
-
-#endif /* !_WIN32 */
-
-/* network connection */
-typedef struct NetSocketState {
- VLANClientState *vc;
- int fd;
- int state; /* 0 = getting length, 1 = getting data */
- int index;
- int packet_len;
- uint8_t buf[4096];
- struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
-} NetSocketState;
-
-typedef struct NetSocketListenState {
- VLANState *vlan;
- int fd;
-} NetSocketListenState;
-
-/* XXX: we consider we can send the whole packet without blocking */
-static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
-{
- NetSocketState *s = opaque;
- uint32_t len;
- len = htonl(size);
-
- send_all(s->fd, (const uint8_t *)&len, sizeof(len));
- send_all(s->fd, buf, size);
-}
-
-static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
-{
- NetSocketState *s = opaque;
- sendto(s->fd, buf, size, 0,
- (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
-}
-
-static void net_socket_send(void *opaque)
-{
- NetSocketState *s = opaque;
- int l, size, err;
- uint8_t buf1[4096];
- const uint8_t *buf;
-
- size = recv(s->fd, buf1, sizeof(buf1), 0);
- if (size < 0) {
- err = socket_error();
- if (err != EWOULDBLOCK)
- goto eoc;
- } else if (size == 0) {
- /* end of connection */
- eoc:
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
- closesocket(s->fd);
- return;
- }
- buf = buf1;
- while (size > 0) {
- /* reassemble a packet from the network */
- switch(s->state) {
- case 0:
- l = 4 - s->index;
- if (l > size)
- l = size;
- memcpy(s->buf + s->index, buf, l);
- buf += l;
- size -= l;
- s->index += l;
- if (s->index == 4) {
- /* got length */
- s->packet_len = ntohl(*(uint32_t *)s->buf);
- s->index = 0;
- s->state = 1;
- }
- break;
- case 1:
- l = s->packet_len - s->index;
- if (l > size)
- l = size;
- memcpy(s->buf + s->index, buf, l);
- s->index += l;
- buf += l;
- size -= l;
- if (s->index >= s->packet_len) {
- qemu_send_packet(s->vc, s->buf, s->packet_len);
- s->index = 0;
- s->state = 0;
- }
- break;
- }
- }
-}
-
-static void net_socket_send_dgram(void *opaque)
-{
- NetSocketState *s = opaque;
- int size;
-
- size = recv(s->fd, s->buf, sizeof(s->buf), 0);
- if (size < 0)
- return;
- if (size == 0) {
- /* end of connection */
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
- return;
- }
- qemu_send_packet(s->vc, s->buf, size);
-}
-
-static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
-{
- struct ip_mreq imr;
- int fd;
- int val, ret;
- if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
- fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
- inet_ntoa(mcastaddr->sin_addr),
- (int)ntohl(mcastaddr->sin_addr.s_addr));
- return -1;
-
- }
- fd = socket(PF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- perror("socket(PF_INET, SOCK_DGRAM)");
- return -1;
- }
-
- val = 1;
- ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (const char *)&val, sizeof(char));
- if (ret < 0) {
- perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
- goto fail;
- }
-
- ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
- if (ret < 0) {
- perror("bind");
- goto fail;
- }
-
- /* Add host to multicast group */
- imr.imr_multiaddr = mcastaddr->sin_addr;
- imr.imr_interface.s_addr = htonl(INADDR_ANY);
-
- ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (const char *)&imr, sizeof(struct ip_mreq));
- if (ret < 0) {
- perror("setsockopt(IP_ADD_MEMBERSHIP)");
- goto fail;
- }
-
- /* Force mcast msgs to loopback (eg. several QEMUs in same host */
- val = 1;
- ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
- (const char *)&val, sizeof(val));
- if (ret < 0) {
- perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
- goto fail;
- }
-
- socket_set_nonblock(fd);
- return fd;
-fail:
- if (fd >= 0)
- closesocket(fd);
- return -1;
-}
-
-static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
- int is_connected)
-{
- struct sockaddr_in saddr;
- int newfd;
- socklen_t saddr_len;
- NetSocketState *s;
-
- /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
- * Because this may be "shared" socket from a "master" process, datagrams would be recv()
- * by ONLY ONE process: we must "clone" this dgram socket --jjo
- */
-
- if (is_connected) {
- if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
- /* must be bound */
- if (saddr.sin_addr.s_addr==0) {
- fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
- fd);
- return NULL;
- }
- /* clone dgram socket */
- newfd = net_socket_mcast_create(&saddr);
- if (newfd < 0) {
- /* error already reported by net_socket_mcast_create() */
- close(fd);
- return NULL;
- }
- /* clone newfd to fd, close newfd */
- dup2(newfd, fd);
- close(newfd);
-
- } else {
- fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
- fd, strerror(errno));
- return NULL;
- }
- }
-
- s = qemu_mallocz(sizeof(NetSocketState));
- if (!s)
- return NULL;
- s->fd = fd;
-
- s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
- qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
-
- /* mcast: save bound address as dst */
- if (is_connected) s->dgram_dst=saddr;
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: fd=%d (%s mcast=%s:%d)",
- fd, is_connected? "cloned" : "",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
- return s;
-}
-
-static void net_socket_connect(void *opaque)
-{
- NetSocketState *s = opaque;
- qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
-}
-
-static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
- int is_connected)
-{
- NetSocketState *s;
- s = qemu_mallocz(sizeof(NetSocketState));
- if (!s)
- return NULL;
- s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan,
- net_socket_receive, NULL, s);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: fd=%d", fd);
- if (is_connected) {
- net_socket_connect(s);
- } else {
- qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
- }
- return s;
-}
-
-static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
- int is_connected)
-{
- int so_type=-1, optlen=sizeof(so_type);
-
- if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, &optlen)< 0) {
- fprintf(stderr, "qemu: error: setsockopt(SO_TYPE) for fd=%d failed\n", fd);
- return NULL;
- }
- switch(so_type) {
- case SOCK_DGRAM:
- return net_socket_fd_init_dgram(vlan, fd, is_connected);
- case SOCK_STREAM:
- return net_socket_fd_init_stream(vlan, fd, is_connected);
- default:
- /* who knows ... this could be a eg. a pty, do warn and continue as stream */
- fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
- return net_socket_fd_init_stream(vlan, fd, is_connected);
- }
- return NULL;
-}
-
-static void net_socket_accept(void *opaque)
-{
- NetSocketListenState *s = opaque;
- NetSocketState *s1;
- struct sockaddr_in saddr;
- socklen_t len;
- int fd;
-
- for(;;) {
- len = sizeof(saddr);
- fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
- if (fd < 0 && errno != EINTR) {
- return;
- } else if (fd >= 0) {
- break;
- }
- }
- s1 = net_socket_fd_init(s->vlan, fd, 1);
- if (!s1) {
- closesocket(fd);
- } else {
- snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
- "socket: connection from %s:%d",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
- }
-}
-
-static int net_socket_listen_init(VLANState *vlan, const char *host_str)
-{
- NetSocketListenState *s;
- int fd, val, ret;
- struct sockaddr_in saddr;
-
- if (parse_host_port(&saddr, host_str) < 0)
- return -1;
-
- s = qemu_mallocz(sizeof(NetSocketListenState));
- if (!s)
- return -1;
-
- fd = socket(PF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- perror("socket");
- return -1;
- }
- socket_set_nonblock(fd);
-
- /* allow fast reuse */
- val = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
-
- ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
- if (ret < 0) {
- perror("bind");
- return -1;
- }
- ret = listen(fd, 0);
- if (ret < 0) {
- perror("listen");
- return -1;
- }
- s->vlan = vlan;
- s->fd = fd;
- qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
- return 0;
-}
-
-static int net_socket_connect_init(VLANState *vlan, const char *host_str)
-{
- NetSocketState *s;
- int fd, connected, ret, err;
- struct sockaddr_in saddr;
-
- if (parse_host_port(&saddr, host_str) < 0)
- return -1;
-
- fd = socket(PF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- perror("socket");
- return -1;
- }
- socket_set_nonblock(fd);
-
- connected = 0;
- for(;;) {
- ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
- if (ret < 0) {
- err = socket_error();
- if (err == EINTR || err == EWOULDBLOCK) {
- } else if (err == EINPROGRESS) {
- break;
- } else {
- perror("connect");
- closesocket(fd);
- return -1;
- }
- } else {
- connected = 1;
- break;
- }
- }
- s = net_socket_fd_init(vlan, fd, connected);
- if (!s)
- return -1;
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: connect to %s:%d",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
- return 0;
-}
-
-static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
-{
- NetSocketState *s;
- int fd;
- struct sockaddr_in saddr;
-
- if (parse_host_port(&saddr, host_str) < 0)
- return -1;
-
-
- fd = net_socket_mcast_create(&saddr);
- if (fd < 0)
- return -1;
-
- s = net_socket_fd_init(vlan, fd, 0);
- if (!s)
- return -1;
-
- s->dgram_dst = saddr;
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: mcast=%s:%d",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
- return 0;
-
-}
-
-static int get_param_value(char *buf, size_t buf_size,
- const char *tag, const char *str)
-{
- const char *p;
- char *q;
- char option[128];
-
- p = str;
- for(;;) {
- q = option;
- while (*p != '\0' && *p != '=') {
- if ((q - option) < sizeof(option) - 1)
- *q++ = *p;
- p++;
- }
- *q = '\0';
- if (*p != '=')
- break;
- p++;
- if (!strcmp(tag, option)) {
- q = buf;
- while (*p != '\0' && *p != ',') {
- if ((q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- *q = '\0';
- return q - buf;
- } else {
- while (*p != '\0' && *p != ',') {
- p++;
- }
- }
- if (*p != ',')
- break;
- p++;
- }
- return 0;
-}
-
-static int net_client_init(const char *str)
-{
- const char *p;
- char *q;
- char device[64];
- char buf[1024];
- int vlan_id, ret;
- VLANState *vlan;
-
- p = str;
- q = device;
- while (*p != '\0' && *p != ',') {
- if ((q - device) < sizeof(device) - 1)
- *q++ = *p;
- p++;
- }
- *q = '\0';
- if (*p == ',')
- p++;
- vlan_id = 0;
- if (get_param_value(buf, sizeof(buf), "vlan", p)) {
- vlan_id = strtol(buf, NULL, 0);
- }
- vlan = qemu_find_vlan(vlan_id);
- if (!vlan) {
- fprintf(stderr, "Could not create vlan %d\n", vlan_id);
- return -1;
- }
- if (!strcmp(device, "nic")) {
- NICInfo *nd;
- uint8_t *macaddr;
-
- if (nb_nics < MAX_NICS) {
- nd = &nd_table[nb_nics];
- macaddr = nd->macaddr;
- macaddr[0] = 0x52;
- macaddr[1] = 0x54;
- macaddr[2] = 0x00;
- macaddr[3] = 0x12;
- macaddr[4] = 0x34;
- macaddr[5] = 0x56 + nb_nics;
-
- if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
- if (parse_macaddr(macaddr, buf) < 0) {
- fprintf(stderr, "invalid syntax for ethernet address\n");
- return -1;
- }
- }
- if (get_param_value(buf, sizeof(buf), "model", p)) {
- nd->model = strdup(buf);
- }
- nd->vlan = vlan;
- nb_nics++;
- } else {
- fprintf(stderr, "Too Many NICs\n");
- }
- ret = 0;
- } else
- if (!strcmp(device, "none")) {
- /* does nothing. It is needed to signal that no network cards
- are wanted */
- ret = 0;
- } else
-#ifdef CONFIG_SLIRP
- if (!strcmp(device, "user")) {
- if (get_param_value(buf, sizeof(buf), "hostname", p)) {
- pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
- }
- ret = net_slirp_init(vlan);
- } else
-#endif
-#ifdef _WIN32
- if (!strcmp(device, "tap")) {
- char ifname[64];
- if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
- fprintf(stderr, "tap: no interface name\n");
- return -1;
- }
- ret = tap_win32_init(vlan, ifname);
- } else
-#else
- if (!strcmp(device, "tap")) {
- char ifname[64];
- char setup_script[1024];
- char bridge[16];
- int fd;
-
- memset(ifname, 0, sizeof(ifname));
- memset(setup_script, 0, sizeof(setup_script));
-
- if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
- fd = strtol(buf, NULL, 0);
- ret = -1;
- if (net_tap_fd_init(vlan, fd))
- ret = 0;
- } else {
- if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
- ifname[0] = '\0';
- }
- if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
- pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
- }
- if (get_param_value(bridge, sizeof(bridge), "bridge", p) == 0) {
- pstrcpy(bridge, sizeof(bridge), DEFAULT_BRIDGE);
- }
- ret = net_tap_init(vlan, ifname, setup_script, bridge);
- }
- } else
-#endif
- if (!strcmp(device, "socket")) {
- if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
- int fd;
- fd = strtol(buf, NULL, 0);
- ret = -1;
- if (net_socket_fd_init(vlan, fd, 1))
- ret = 0;
- } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
- ret = net_socket_listen_init(vlan, buf);
- } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
- ret = net_socket_connect_init(vlan, buf);
- } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
- ret = net_socket_mcast_init(vlan, buf);
- } else {
- fprintf(stderr, "Unknown socket options: %s\n", p);
- return -1;
- }
- } else
- {
- fprintf(stderr, "Unknown network device: %s\n", device);
- return -1;
- }
- if (ret < 0) {
- fprintf(stderr, "Could not initialize device '%s'\n", device);
- }
-
- return ret;
-}
-
-void do_info_network(void)
-{
- VLANState *vlan;
- VLANClientState *vc;
-
- for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
- term_printf("VLAN %d devices:\n", vlan->id);
- for(vc = vlan->first_client; vc != NULL; vc = vc->next)
- term_printf(" %s\n", vc->info_str);
- }
-}
-
-/***********************************************************/
-/* USB devices */
-
-static USBPort *used_usb_ports;
-static USBPort *free_usb_ports;
-
-/* ??? Maybe change this to register a hub to keep track of the topology. */
-void qemu_register_usb_port(USBPort *port, void *opaque, int index,
- usb_attachfn attach)
-{
- port->opaque = opaque;
- port->index = index;
- port->attach = attach;
- port->next = free_usb_ports;
- free_usb_ports = port;
-}
-
-static int usb_device_add(const char *devname)
-{
- const char *p;
- USBDevice *dev;
- USBPort *port;
- char usb_name[256] = "USB ";
-
- if (!free_usb_ports)
- return -1;
-
- if (strstart(devname, "host:", &p)) {
- dev = usb_host_device_open(p);
- } else if (!strcmp(devname, "mouse")) {
- dev = usb_mouse_init();
- } else if (!strcmp(devname, "tablet")) {
- dev = usb_tablet_init();
- } else if (strstart(devname, "disk:", &p)) {
- dev = usb_msd_init(p, &bdrv_raw);
- } else if (strstart(devname, "disk-qcow:", &p)) {
- dev = usb_msd_init(p, 0);
- } else {
- return -1;
- }
- if (!dev)
- return -1;
-
- /* Find a USB port to add the device to. */
- port = free_usb_ports;
- if (!port->next) {
- USBDevice *hub;
-
- /* Create a new hub and chain it on. */
- free_usb_ports = NULL;
- port->next = used_usb_ports;
- used_usb_ports = port;
-
- hub = usb_hub_init(VM_USB_HUB_SIZE);
- usb_attach(port, hub);
- port = free_usb_ports;
- }
-
- free_usb_ports = port->next;
- port->next = used_usb_ports;
- used_usb_ports = port;
-
- pstrcpy(usb_name + strlen(usb_name),
- sizeof(usb_name) - strlen(usb_name),
- devname);
- register_savevm(usb_name, 0, 1, generic_usb_save, generic_usb_load, dev);
-
- usb_attach(port, dev);
- return 0;
-}
-
-static int usb_device_del(const char *devname)
-{
- USBPort *port;
- USBPort **lastp;
- USBDevice *dev;
- int bus_num, addr;
- const char *p;
-
- if (!used_usb_ports)
- return -1;
-
- p = strchr(devname, '.');
- if (!p)
- return -1;
- bus_num = strtoul(devname, NULL, 0);
- addr = strtoul(p + 1, NULL, 0);
- if (bus_num != 0)
- return -1;
-
- lastp = &used_usb_ports;
- port = used_usb_ports;
- while (port && port->dev->addr != addr) {
- lastp = &port->next;
- port = port->next;
- }
-
- if (!port)
- return -1;
-
- dev = port->dev;
- *lastp = port->next;
- usb_attach(port, NULL);
- dev->handle_destroy(dev);
- port->next = free_usb_ports;
- free_usb_ports = port;
- return 0;
-}
-
-void do_usb_add(const char *devname)
-{
- int ret;
- ret = usb_device_add(devname);
- if (ret < 0)
- term_printf("Could not add USB device '%s'\n", devname);
-}
-
-void do_usb_del(const char *devname)
-{
- int ret;
- ret = usb_device_del(devname);
- if (ret < 0)
- term_printf("Could not remove USB device '%s'\n", devname);
-}
-
-void usb_info(void)
-{
- USBDevice *dev;
- USBPort *port;
- const char *speed_str;
-
- if (!usb_enabled) {
- term_printf("USB support not enabled\n");
- return;
- }
-
- for (port = used_usb_ports; port; port = port->next) {
- dev = port->dev;
- if (!dev)
- continue;
- switch(dev->speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
- term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
- 0, dev->addr, speed_str, dev->devname);
- }
-}
-
-void do_pci_del(char *devname)
-{
-#ifdef CONFIG_PASSTHROUGH
- int pci_slot = bdf_to_slot(devname);
- acpi_php_del(pci_slot);
-#endif
-}
-
-void do_pci_add(char *devname)
-{
-#ifdef CONFIG_PASSTHROUGH
- int pci_slot = insert_to_pci_slot(devname);
- acpi_php_add(pci_slot);
-#endif
-}
-
-static int pci_emulation_add(char *config_text)
-{
- PCI_EMULATION_INFO *new;
- if ((new = qemu_mallocz(sizeof(PCI_EMULATION_INFO))) == NULL) {
- return -1;
- }
- parse_pci_emulation_info(config_text, new);
- new->next = PciEmulationInfoHead;
- PciEmulationInfoHead = new;
- return 0;
-}
-
-/***********************************************************/
-/* pid file */
-
-static char *pid_filename;
-
-/* Remove PID file. Called on normal exit */
-
-static void remove_pidfile(void)
-{
- unlink (pid_filename);
-}
-
-static void create_pidfile(const char *filename)
-{
- struct stat pidstat;
- FILE *f;
-
- /* Try to write our PID to the named file */
- if (stat(filename, &pidstat) < 0) {
- if (errno == ENOENT) {
- if ((f = fopen (filename, "w")) == NULL) {
- perror("Opening pidfile");
- exit(1);
- }
- fprintf(f, "%ld\n", (long)getpid());
- fclose(f);
- pid_filename = qemu_strdup(filename);
- if (!pid_filename) {
- fprintf(stderr, "Could not save PID filename");
- exit(1);
- }
- atexit(remove_pidfile);
- }
- } else {
- fprintf(stderr, "%s already exists. Remove it and try again.\n",
- filename);
- exit(1);
- }
-}
-
-/***********************************************************/
-/* dumb display */
-
-static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
-{
-}
-
-static void dumb_resize(DisplayState *ds, int w, int h, int linesize)
-{
-}
-
-static void dumb_refresh(DisplayState *ds)
-{
- vga_hw_update();
-}
-
-void dumb_display_init(DisplayState *ds)
-{
- ds->data = NULL;
- ds->linesize = 0;
- ds->depth = 0;
- ds->dpy_update = dumb_update;
- ds->dpy_resize = dumb_resize;
- ds->dpy_refresh = dumb_refresh;
- ds->gui_timer_interval = 500;
- ds->idle = 1;
-}
-
-/***********************************************************/
-/* I/O handling */
-
-#define MAX_IO_HANDLERS 64
-
-typedef struct IOHandlerRecord {
- int fd;
- IOCanRWHandler *fd_read_poll;
- IOHandler *fd_read;
- IOHandler *fd_write;
- int deleted;
- void *opaque;
- /* temporary data */
- struct pollfd *ufd;
- struct IOHandlerRecord *next;
-} IOHandlerRecord;
-
-static IOHandlerRecord *first_io_handler;
-
-/* XXX: fd_read_poll should be suppressed, but an API change is
- necessary in the character devices to suppress fd_can_read(). */
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
-{
- IOHandlerRecord **pioh, *ioh;
-
- if (!fd_read && !fd_write) {
- pioh = &first_io_handler;
- for(;;) {
- ioh = *pioh;
- if (ioh == NULL)
- break;
- if (ioh->fd == fd) {
- ioh->deleted = 1;
- break;
- }
- pioh = &ioh->next;
- }
- } else {
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (ioh->fd == fd)
- goto found;
- }
- ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- if (!ioh)
- return -1;
- ioh->next = first_io_handler;
- first_io_handler = ioh;
- found:
- ioh->fd = fd;
- ioh->fd_read_poll = fd_read_poll;
- ioh->fd_read = fd_read;
- ioh->fd_write = fd_write;
- ioh->opaque = opaque;
- ioh->deleted = 0;
- }
- return 0;
-}
-
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
-{
- return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
-}
-
-/***********************************************************/
-/* Polling handling */
-
-typedef struct PollingEntry {
- PollingFunc *func;
- void *opaque;
- struct PollingEntry *next;
-} PollingEntry;
-
-static PollingEntry *first_polling_entry;
-
-int qemu_add_polling_cb(PollingFunc *func, void *opaque)
-{
- PollingEntry **ppe, *pe;
- pe = qemu_mallocz(sizeof(PollingEntry));
- if (!pe)
- return -1;
- pe->func = func;
- pe->opaque = opaque;
- for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
- *ppe = pe;
- return 0;
-}
-
-void qemu_del_polling_cb(PollingFunc *func, void *opaque)
-{
- PollingEntry **ppe, *pe;
- for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
- pe = *ppe;
- if (pe->func == func && pe->opaque == opaque) {
- *ppe = pe->next;
- qemu_free(pe);
- break;
- }
- }
-}
-
-#ifdef _WIN32
-/***********************************************************/
-/* Wait objects support */
-typedef struct WaitObjects {
- int num;
- HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
- WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
- void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
-} WaitObjects;
-
-static WaitObjects wait_objects = {0};
-
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
-{
- WaitObjects *w = &wait_objects;
-
- if (w->num >= MAXIMUM_WAIT_OBJECTS)
- return -1;
- w->events[w->num] = handle;
- w->func[w->num] = func;
- w->opaque[w->num] = opaque;
- w->num++;
- return 0;
-}
-
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
-{
- int i, found;
- WaitObjects *w = &wait_objects;
-
- found = 0;
- for (i = 0; i < w->num; i++) {
- if (w->events[i] == handle)
- found = 1;
- if (found) {
- w->events[i] = w->events[i + 1];
- w->func[i] = w->func[i + 1];
- w->opaque[i] = w->opaque[i + 1];
- }
- }
- if (found)
- w->num--;
-}
-#endif
-
-/***********************************************************/
-/* savevm/loadvm support */
-
-#define IO_BUF_SIZE 32768
-
-struct QEMUFile {
- FILE *outfile;
- BlockDriverState *bs;
- int is_file;
- int is_writable;
- int64_t base_offset;
- int64_t buf_offset; /* start of buffer when writing, end of buffer
- when reading */
- int buf_index;
- int buf_size; /* 0 when writing */
- uint8_t buf[IO_BUF_SIZE];
-};
-
-QEMUFile *qemu_fopen(const char *filename, const char *mode)
-{
- QEMUFile *f;
-
- f = qemu_mallocz(sizeof(QEMUFile));
- if (!f)
- return NULL;
- if (!strcmp(mode, "wb")) {
- f->is_writable = 1;
- } else if (!strcmp(mode, "rb")) {
- f->is_writable = 0;
- } else {
- goto fail;
- }
- f->outfile = fopen(filename, mode);
- if (!f->outfile)
- goto fail;
- f->is_file = 1;
- return f;
- fail:
- if (f->outfile)
- fclose(f->outfile);
- qemu_free(f);
- return NULL;
-}
-
-QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
-{
- QEMUFile *f;
-
- f = qemu_mallocz(sizeof(QEMUFile));
- if (!f)
- return NULL;
- f->is_file = 0;
- f->bs = bs;
- f->is_writable = is_writable;
- f->base_offset = offset;
- return f;
-}
-
-void qemu_fflush(QEMUFile *f)
-{
- if (!f->is_writable)
- return;
- if (f->buf_index > 0) {
- if (f->is_file) {
- fseek(f->outfile, f->buf_offset, SEEK_SET);
- fwrite(f->buf, 1, f->buf_index, f->outfile);
- } else {
- bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
- f->buf, f->buf_index);
- }
- f->buf_offset += f->buf_index;
- f->buf_index = 0;
- }
-}
-
-static void qemu_fill_buffer(QEMUFile *f)
-{
- int len;
-
- if (f->is_writable)
- return;
- if (f->is_file) {
- fseek(f->outfile, f->buf_offset, SEEK_SET);
- len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
- if (len < 0)
- len = 0;
- } else {
- len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
- f->buf, IO_BUF_SIZE);
- if (len < 0)
- len = 0;
- }
- f->buf_index = 0;
- f->buf_size = len;
- f->buf_offset += len;
-}
-
-void qemu_fclose(QEMUFile *f)
-{
- if (f->is_writable)
- qemu_fflush(f);
- if (f->is_file) {
- fclose(f->outfile);
- }
- qemu_free(f);
-}
-
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
-{
- int l;
- while (size > 0) {
- l = IO_BUF_SIZE - f->buf_index;
- if (l > size)
- l = size;
- memcpy(f->buf + f->buf_index, buf, l);
- f->buf_index += l;
- buf += l;
- size -= l;
- if (f->buf_index >= IO_BUF_SIZE)
- qemu_fflush(f);
- }
-}
-
-void qemu_put_byte(QEMUFile *f, int v)
-{
- f->buf[f->buf_index++] = v;
- if (f->buf_index >= IO_BUF_SIZE)
- qemu_fflush(f);
-}
-
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
-{
- int size, l;
-
- size = size1;
- while (size > 0) {
- l = f->buf_size - f->buf_index;
- if (l == 0) {
- qemu_fill_buffer(f);
- l = f->buf_size - f->buf_index;
- if (l == 0)
- break;
- }
- if (l > size)
- l = size;
- memcpy(buf, f->buf + f->buf_index, l);
- f->buf_index += l;
- buf += l;
- size -= l;
- }
- return size1 - size;
-}
-
-int qemu_get_byte(QEMUFile *f)
-{
- if (f->buf_index >= f->buf_size) {
- qemu_fill_buffer(f);
- if (f->buf_index >= f->buf_size)
- return 0;
- }
- return f->buf[f->buf_index++];
-}
-
-int64_t qemu_ftell(QEMUFile *f)
-{
- return f->buf_offset - f->buf_size + f->buf_index;
-}
-
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
-{
- if (whence == SEEK_SET) {
- /* nothing to do */
- } else if (whence == SEEK_CUR) {
- pos += qemu_ftell(f);
- } else {
- /* SEEK_END not supported */
- return -1;
- }
- if (f->is_writable) {
- qemu_fflush(f);
- f->buf_offset = pos;
- } else {
- f->buf_offset = pos;
- f->buf_index = 0;
- f->buf_size = 0;
- }
- return pos;
-}
-
-void qemu_put_be16(QEMUFile *f, unsigned int v)
-{
- qemu_put_byte(f, v >> 8);
- qemu_put_byte(f, v);
-}
-
-void qemu_put_be32(QEMUFile *f, unsigned int v)
-{
- qemu_put_byte(f, v >> 24);
- qemu_put_byte(f, v >> 16);
- qemu_put_byte(f, v >> 8);
- qemu_put_byte(f, v);
-}
-
-void qemu_put_be64(QEMUFile *f, uint64_t v)
-{
- qemu_put_be32(f, v >> 32);
- qemu_put_be32(f, v);
-}
-
-unsigned int qemu_get_be16(QEMUFile *f)
-{
- unsigned int v;
- v = qemu_get_byte(f) << 8;
- v |= qemu_get_byte(f);
- return v;
-}
-
-unsigned int qemu_get_be32(QEMUFile *f)
-{
- unsigned int v;
- v = qemu_get_byte(f) << 24;
- v |= qemu_get_byte(f) << 16;
- v |= qemu_get_byte(f) << 8;
- v |= qemu_get_byte(f);
- return v;
-}
-
-uint64_t qemu_get_be64(QEMUFile *f)
-{
- uint64_t v;
- v = (uint64_t)qemu_get_be32(f) << 32;
- v |= qemu_get_be32(f);
- return v;
-}
-
-typedef struct SaveStateEntry {
- char idstr[256];
- int instance_id;
- int version_id;
- SaveStateHandler *save_state;
- LoadStateHandler *load_state;
- void *opaque;
- struct SaveStateEntry *next;
-} SaveStateEntry;
-
-static SaveStateEntry *first_se;
-
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque)
-{
- SaveStateEntry *se, **pse;
-
- se = qemu_malloc(sizeof(SaveStateEntry));
- if (!se)
- return -1;
- pstrcpy(se->idstr, sizeof(se->idstr), idstr);
- se->instance_id = instance_id;
- se->version_id = version_id;
- se->save_state = save_state;
- se->load_state = load_state;
- se->opaque = opaque;
- se->next = NULL;
-
- /* add at the end of list */
- pse = &first_se;
- while (*pse != NULL)
- pse = &(*pse)->next;
- *pse = se;
- return 0;
-}
-
-#define QEMU_VM_FILE_MAGIC 0x5145564d
-#define QEMU_VM_FILE_VERSION 0x00000002
-
-int qemu_savevm_state(QEMUFile *f)
-{
- SaveStateEntry *se;
- int len, ret;
- int64_t cur_pos, len_pos, total_len_pos;
-
- qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
- qemu_put_be32(f, QEMU_VM_FILE_VERSION);
- total_len_pos = qemu_ftell(f);
- qemu_put_be64(f, 0); /* total size */
-
- for(se = first_se; se != NULL; se = se->next) {
- /* ID string */
- len = strlen(se->idstr);
- qemu_put_byte(f, len);
- qemu_put_buffer(f, se->idstr, len);
-
- qemu_put_be32(f, se->instance_id);
- qemu_put_be32(f, se->version_id);
-
- /* record size: filled later */
- len_pos = qemu_ftell(f);
- qemu_put_be32(f, 0);
-
- se->save_state(f, se->opaque);
-
- /* fill record size */
- cur_pos = qemu_ftell(f);
- len = cur_pos - len_pos - 4;
- qemu_fseek(f, len_pos, SEEK_SET);
- qemu_put_be32(f, len);
- qemu_fseek(f, cur_pos, SEEK_SET);
- }
- cur_pos = qemu_ftell(f);
- qemu_fseek(f, total_len_pos, SEEK_SET);
- qemu_put_be64(f, cur_pos - total_len_pos - 8);
- qemu_fseek(f, cur_pos, SEEK_SET);
-
- ret = 0;
- return ret;
-}
-
-static SaveStateEntry *find_se(const char *idstr, int instance_id)
-{
- SaveStateEntry *se;
-
- for(se = first_se; se != NULL; se = se->next) {
- if (!strcmp(se->idstr, idstr) &&
- instance_id == se->instance_id)
- return se;
- }
- return NULL;
-}
-
-int qemu_loadvm_state(QEMUFile *f)
-{
- SaveStateEntry *se;
- int len, ret, instance_id, record_len, version_id;
- int64_t total_len, end_pos, cur_pos;
- unsigned int v;
- char idstr[256];
-
- v = qemu_get_be32(f);
- if (v != QEMU_VM_FILE_MAGIC)
- goto fail;
- v = qemu_get_be32(f);
- if (v != QEMU_VM_FILE_VERSION) {
- fail:
- ret = -1;
- goto the_end;
- }
- total_len = qemu_get_be64(f);
- end_pos = total_len + qemu_ftell(f);
- for(;;) {
- if (qemu_ftell(f) >= end_pos)
- break;
- len = qemu_get_byte(f);
- qemu_get_buffer(f, idstr, len);
- idstr[len] = '\0';
- instance_id = qemu_get_be32(f);
- version_id = qemu_get_be32(f);
- record_len = qemu_get_be32(f);
-#if 0
- printf("idstr=%s instance=0x%x version=%d len=%d\n",
- idstr, instance_id, version_id, record_len);
-#endif
- cur_pos = qemu_ftell(f);
- se = find_se(idstr, instance_id);
- if (!se) {
- fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
- instance_id, idstr);
- } else {
- ret = se->load_state(f, se->opaque, version_id);
- if (ret < 0) {
- fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
- instance_id, idstr);
- }
- }
- /* always seek to exact end of record */
- qemu_fseek(f, cur_pos + record_len, SEEK_SET);
- }
- ret = 0;
- the_end:
- return ret;
-}
-
-/* device can contain snapshots */
-static int bdrv_can_snapshot(BlockDriverState *bs)
-{
- return (bs &&
- !bdrv_is_removable(bs) &&
- !bdrv_is_read_only(bs));
-}
-
-/* device must be snapshots in order to have a reliable snapshot */
-static int bdrv_has_snapshot(BlockDriverState *bs)
-{
- return (bs &&
- !bdrv_is_removable(bs) &&
- !bdrv_is_read_only(bs));
-}
-
-static BlockDriverState *get_bs_snapshots(void)
-{
- BlockDriverState *bs;
- int i;
-
- if (bs_snapshots)
- return bs_snapshots;
- for(i = 0; i <= MAX_DISKS; i++) {
- bs = bs_table[i];
- if (bdrv_can_snapshot(bs))
- goto ok;
- }
- return NULL;
- ok:
- bs_snapshots = bs;
- return bs;
-}
-
-static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
- const char *name)
-{
- QEMUSnapshotInfo *sn_tab, *sn;
- int nb_sns, i, ret;
-
- ret = -ENOENT;
- nb_sns = bdrv_snapshot_list(bs, &sn_tab);
- if (nb_sns < 0)
- return ret;
- for(i = 0; i < nb_sns; i++) {
- sn = &sn_tab[i];
- if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
- *sn_info = *sn;
- ret = 0;
- break;
- }
- }
- qemu_free(sn_tab);
- return ret;
-}
-
-#ifdef CONFIG_DM
-/* We use simpler state save/load functions for Xen */
-void do_savevm(const char *name)
-{
- QEMUFile *f;
- int saved_vm_running, ret;
-
- f = qemu_fopen(name, "wb");
-
- /* ??? Should this occur after vm_stop? */
- qemu_aio_flush();
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- if (!f) {
- fprintf(logfile, "Failed to open savevm file '%s'\n", name);
- goto the_end;
- }
-
- ret = qemu_savevm_state(f);
- qemu_fclose(f);
-
- if (ret < 0)
- fprintf(logfile, "Error %d while writing VM to savevm file '%s'\n",
- ret, name);
-
- the_end:
- if (saved_vm_running)
- vm_start();
-
- return;
-}
-void do_loadvm(const char *name)
-{
- QEMUFile *f;
- int saved_vm_running, ret;
-
- /* Flush all IO requests so they don't interfere with the new state. */
- qemu_aio_flush();
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- /* restore the VM state */
- f = qemu_fopen(name, "rb");
- if (!f) {
- fprintf(logfile, "Could not open VM state file\n");
- goto the_end;
- }
-
- ret = qemu_loadvm_state(f);
- qemu_fclose(f);
- if (ret < 0) {
- fprintf(logfile, "Error %d while loading savevm file '%s'\n",
- ret, name);
- goto the_end;
- }
-
-#if 0
- /* del tmp file */
- if (unlink(name) == -1)
- fprintf(stderr, "delete tmp qemu state file failed.\n");
-#endif
-
-
- the_end:
- if (saved_vm_running)
- vm_start();
-}
-#else
-void do_savevm(const char *name)
-{
- BlockDriverState *bs, *bs1;
- QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
- int must_delete, ret, i;
- BlockDriverInfo bdi1, *bdi = &bdi1;
- QEMUFile *f;
- int saved_vm_running;
-#ifdef _WIN32
- struct _timeb tb;
-#else
- struct timeval tv;
-#endif
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No block device can accept snapshots\n");
- return;
- }
-
- /* ??? Should this occur after vm_stop? */
- qemu_aio_flush();
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- must_delete = 0;
- if (name) {
- ret = bdrv_snapshot_find(bs, old_sn, name);
- if (ret >= 0) {
- must_delete = 1;
- }
- }
- memset(sn, 0, sizeof(*sn));
- if (must_delete) {
- pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
- pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
- } else {
- if (name)
- pstrcpy(sn->name, sizeof(sn->name), name);
- }
-
- /* fill auxiliary fields */
-#ifdef _WIN32
- _ftime(&tb);
- sn->date_sec = tb.time;
- sn->date_nsec = tb.millitm * 1000000;
-#else
- gettimeofday(&tv, NULL);
- sn->date_sec = tv.tv_sec;
- sn->date_nsec = tv.tv_usec * 1000;
-#endif
- sn->vm_clock_nsec = qemu_get_clock(vm_clock);
-
- if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
- term_printf("Device %s does not support VM state snapshots\n",
- bdrv_get_device_name(bs));
- goto the_end;
- }
-
- /* save the VM state */
- f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
- if (!f) {
- term_printf("Could not open VM state file\n");
- goto the_end;
- }
- ret = qemu_savevm_state(f);
- sn->vm_state_size = qemu_ftell(f);
- qemu_fclose(f);
- if (ret < 0) {
- term_printf("Error %d while writing VM\n", ret);
- goto the_end;
- }
-
- /* create the snapshots */
-
- for(i = 0; i < MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- if (must_delete) {
- ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
- if (ret < 0) {
- term_printf("Error while deleting snapshot on '%s'\n",
- bdrv_get_device_name(bs1));
- }
- }
- ret = bdrv_snapshot_create(bs1, sn);
- if (ret < 0) {
- term_printf("Error while creating snapshot on '%s'\n",
- bdrv_get_device_name(bs1));
- }
- }
- }
-
- the_end:
- if (saved_vm_running)
- vm_start();
-}
-
-void do_loadvm(const char *name)
-{
- BlockDriverState *bs, *bs1;
- BlockDriverInfo bdi1, *bdi = &bdi1;
- QEMUFile *f;
- int i, ret;
- int saved_vm_running;
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No block device supports snapshots\n");
- return;
- }
-
- /* Flush all IO requests so they don't interfere with the new state. */
- qemu_aio_flush();
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- for(i = 0; i <= MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- ret = bdrv_snapshot_goto(bs1, name);
- if (ret < 0) {
- if (bs != bs1)
- term_printf("Warning: ");
- switch(ret) {
- case -ENOTSUP:
- term_printf("Snapshots not supported on device '%s'\n",
- bdrv_get_device_name(bs1));
- break;
- case -ENOENT:
- term_printf("Could not find snapshot '%s' on device '%s'\n",
- name, bdrv_get_device_name(bs1));
- break;
- default:
- term_printf("Error %d while activating snapshot on '%s'\n",
- ret, bdrv_get_device_name(bs1));
- break;
- }
- /* fatal on snapshot block device */
- if (bs == bs1)
- goto the_end;
- }
- }
- }
-
- if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
- term_printf("Device %s does not support VM state snapshots\n",
- bdrv_get_device_name(bs));
- return;
- }
-
- /* restore the VM state */
- f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
- if (!f) {
- term_printf("Could not open VM state file\n");
- goto the_end;
- }
- ret = qemu_loadvm_state(f);
- qemu_fclose(f);
- if (ret < 0) {
- term_printf("Error %d while loading VM state\n", ret);
- }
-
- /* del tmp file */
- if (unlink(name) == -1)
- fprintf(stderr, "delete tmp qemu state file failed.\n");
-
- the_end:
- if (saved_vm_running)
- vm_start();
-}
-#endif
-
-void do_delvm(const char *name)
-{
- BlockDriverState *bs, *bs1;
- int i, ret;
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No block device supports snapshots\n");
- return;
- }
-
- for(i = 0; i <= MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- ret = bdrv_snapshot_delete(bs1, name);
- if (ret < 0) {
- if (ret == -ENOTSUP)
- term_printf("Snapshots not supported on device '%s'\n",
- bdrv_get_device_name(bs1));
- else
- term_printf("Error %d while deleting snapshot on '%s'\n",
- ret, bdrv_get_device_name(bs1));
- }
- }
- }
-}
-
-void do_info_snapshots(void)
-{
- BlockDriverState *bs, *bs1;
- QEMUSnapshotInfo *sn_tab, *sn;
- int nb_sns, i;
- char buf[256];
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No available block device supports snapshots\n");
- return;
- }
- term_printf("Snapshot devices:");
- for(i = 0; i <= MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- if (bs == bs1)
- term_printf(" %s", bdrv_get_device_name(bs1));
- }
- }
- term_printf("\n");
-
- nb_sns = bdrv_snapshot_list(bs, &sn_tab);
- if (nb_sns < 0) {
- term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
- return;
- }
- term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
- term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
- for(i = 0; i < nb_sns; i++) {
- sn = &sn_tab[i];
- term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
- }
- qemu_free(sn_tab);
-}
-
-#ifndef CONFIG_DM
-/***********************************************************/
-/* cpu save/restore */
-
-#if defined(TARGET_I386)
-
-static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
-{
- qemu_put_be32(f, dt->selector);
- qemu_put_betl(f, dt->base);
- qemu_put_be32(f, dt->limit);
- qemu_put_be32(f, dt->flags);
-}
-
-static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
-{
- dt->selector = qemu_get_be32(f);
- dt->base = qemu_get_betl(f);
- dt->limit = qemu_get_be32(f);
- dt->flags = qemu_get_be32(f);
-}
-
-void cpu_save(QEMUFile *f, void *opaque)
-{
- CPUState *env = opaque;
- uint16_t fptag, fpus, fpuc, fpregs_format;
- uint32_t hflags;
- int i;
-
- for(i = 0; i < CPU_NB_REGS; i++)
- qemu_put_betls(f, &env->regs[i]);
- qemu_put_betls(f, &env->eip);
- qemu_put_betls(f, &env->eflags);
- hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
- qemu_put_be32s(f, &hflags);
-
- /* FPU */
- fpuc = env->fpuc;
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for(i = 0; i < 8; i++) {
- fptag |= ((!env->fptags[i]) << i);
- }
-
- qemu_put_be16s(f, &fpuc);
- qemu_put_be16s(f, &fpus);
- qemu_put_be16s(f, &fptag);
-
-#ifdef USE_X86LDOUBLE
- fpregs_format = 0;
-#else
- fpregs_format = 1;
-#endif
- qemu_put_be16s(f, &fpregs_format);
-
- for(i = 0; i < 8; i++) {
-#ifdef USE_X86LDOUBLE
- {
- uint64_t mant;
- uint16_t exp;
- /* we save the real CPU data (in case of MMX usage only 'mant'
- contains the MMX register */
- cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
- qemu_put_be64(f, mant);
- qemu_put_be16(f, exp);
- }
-#else
- /* if we use doubles for float emulation, we save the doubles to
- avoid losing information in case of MMX usage. It can give
- problems if the image is restored on a CPU where long
- doubles are used instead. */
- qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
-#endif
- }
-
- for(i = 0; i < 6; i++)
- cpu_put_seg(f, &env->segs[i]);
- cpu_put_seg(f, &env->ldt);
- cpu_put_seg(f, &env->tr);
- cpu_put_seg(f, &env->gdt);
- cpu_put_seg(f, &env->idt);
-
- qemu_put_be32s(f, &env->sysenter_cs);
- qemu_put_be32s(f, &env->sysenter_esp);
- qemu_put_be32s(f, &env->sysenter_eip);
-
- qemu_put_betls(f, &env->cr[0]);
- qemu_put_betls(f, &env->cr[2]);
- qemu_put_betls(f, &env->cr[3]);
- qemu_put_betls(f, &env->cr[4]);
-
- for(i = 0; i < 8; i++)
- qemu_put_betls(f, &env->dr[i]);
-
- /* MMU */
- qemu_put_be32s(f, &env->a20_mask);
-
- /* XMM */
- qemu_put_be32s(f, &env->mxcsr);
- for(i = 0; i < CPU_NB_REGS; i++) {
- qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
- qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
- }
-
-#ifdef TARGET_X86_64
- qemu_put_be64s(f, &env->efer);
- qemu_put_be64s(f, &env->star);
- qemu_put_be64s(f, &env->lstar);
- qemu_put_be64s(f, &env->cstar);
- qemu_put_be64s(f, &env->fmask);
- qemu_put_be64s(f, &env->kernelgsbase);
-#endif
- qemu_put_be32s(f, &env->smbase);
-}
-
-#ifdef USE_X86LDOUBLE
-/* XXX: add that in a FPU generic layer */
-union x86_longdouble {
- uint64_t mant;
- uint16_t exp;
-};
-
-#define MANTD1(fp) (fp & ((1LL << 52) - 1))
-#define EXPBIAS1 1023
-#define EXPD1(fp) ((fp >> 52) & 0x7FF)
-#define SIGND1(fp) ((fp >> 32) & 0x80000000)
-
-static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
-{
- int e;
- /* mantissa */
- p->mant = (MANTD1(temp) << 11) | (1LL << 63);
- /* exponent + sign */
- e = EXPD1(temp) - EXPBIAS1 + 16383;
- e |= SIGND1(temp) >> 16;
- p->exp = e;
-}
-#endif
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- CPUState *env = opaque;
- int i, guess_mmx;
- uint32_t hflags;
- uint16_t fpus, fpuc, fptag, fpregs_format;
-
- if (version_id != 3 && version_id != 4)
- return -EINVAL;
- for(i = 0; i < CPU_NB_REGS; i++)
- qemu_get_betls(f, &env->regs[i]);
- qemu_get_betls(f, &env->eip);
- qemu_get_betls(f, &env->eflags);
- qemu_get_be32s(f, &hflags);
-
- qemu_get_be16s(f, &fpuc);
- qemu_get_be16s(f, &fpus);
- qemu_get_be16s(f, &fptag);
- qemu_get_be16s(f, &fpregs_format);
-
- /* NOTE: we cannot always restore the FPU state if the image come
- from a host with a different 'USE_X86LDOUBLE' define. We guess
- if we are in an MMX state to restore correctly in that case. */
- guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
- for(i = 0; i < 8; i++) {
- uint64_t mant;
- uint16_t exp;
-
- switch(fpregs_format) {
- case 0:
- mant = qemu_get_be64(f);
- exp = qemu_get_be16(f);
-#ifdef USE_X86LDOUBLE
- env->fpregs[i].d = cpu_set_fp80(mant, exp);
-#else
- /* difficult case */
- if (guess_mmx)
- env->fpregs[i].mmx.MMX_Q(0) = mant;
- else
- env->fpregs[i].d = cpu_set_fp80(mant, exp);
-#endif
- break;
- case 1:
- mant = qemu_get_be64(f);
-#ifdef USE_X86LDOUBLE
- {
- union x86_longdouble *p;
- /* difficult case */
- p = (void *)&env->fpregs[i];
- if (guess_mmx) {
- p->mant = mant;
- p->exp = 0xffff;
- } else {
- fp64_to_fp80(p, mant);
- }
- }
-#else
- env->fpregs[i].mmx.MMX_Q(0) = mant;
-#endif
- break;
- default:
- return -EINVAL;
- }
- }
-
- env->fpuc = fpuc;
- /* XXX: restore FPU round state */
- env->fpstt = (fpus >> 11) & 7;
- env->fpus = fpus & ~0x3800;
- fptag ^= 0xff;
- for(i = 0; i < 8; i++) {
- env->fptags[i] = (fptag >> i) & 1;
- }
-
- for(i = 0; i < 6; i++)
- cpu_get_seg(f, &env->segs[i]);
- cpu_get_seg(f, &env->ldt);
- cpu_get_seg(f, &env->tr);
- cpu_get_seg(f, &env->gdt);
- cpu_get_seg(f, &env->idt);
-
- qemu_get_be32s(f, &env->sysenter_cs);
- qemu_get_be32s(f, &env->sysenter_esp);
- qemu_get_be32s(f, &env->sysenter_eip);
-
- qemu_get_betls(f, &env->cr[0]);
- qemu_get_betls(f, &env->cr[2]);
- qemu_get_betls(f, &env->cr[3]);
- qemu_get_betls(f, &env->cr[4]);
-
- for(i = 0; i < 8; i++)
- qemu_get_betls(f, &env->dr[i]);
-
- /* MMU */
- qemu_get_be32s(f, &env->a20_mask);
-
- qemu_get_be32s(f, &env->mxcsr);
- for(i = 0; i < CPU_NB_REGS; i++) {
- qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
- qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
- }
-
-#ifdef TARGET_X86_64
- qemu_get_be64s(f, &env->efer);
- qemu_get_be64s(f, &env->star);
- qemu_get_be64s(f, &env->lstar);
- qemu_get_be64s(f, &env->cstar);
- qemu_get_be64s(f, &env->fmask);
- qemu_get_be64s(f, &env->kernelgsbase);
-#endif
- if (version_id >= 4)
- qemu_get_be32s(f, &env->smbase);
-
- /* XXX: compute hflags from scratch, except for CPL and IIF */
- env->hflags = hflags;
- tlb_flush(env, 1);
- return 0;
-}
-
-#elif defined(TARGET_PPC)
-void cpu_save(QEMUFile *f, void *opaque)
-{
-}
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- return 0;
-}
-
-#elif defined(TARGET_MIPS)
-void cpu_save(QEMUFile *f, void *opaque)
-{
-}
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- return 0;
-}
-
-#elif defined(TARGET_SPARC)
-void cpu_save(QEMUFile *f, void *opaque)
-{
- CPUState *env = opaque;
- int i;
- uint32_t tmp;
-
- for(i = 0; i < 8; i++)
- qemu_put_betls(f, &env->gregs[i]);
- for(i = 0; i < NWINDOWS * 16; i++)
- qemu_put_betls(f, &env->regbase[i]);
-
- /* FPU */
- for(i = 0; i < TARGET_FPREGS; i++) {
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = env->fpr[i];
- qemu_put_be32(f, u.i);
- }
-
- qemu_put_betls(f, &env->pc);
- qemu_put_betls(f, &env->npc);
- qemu_put_betls(f, &env->y);
- tmp = GET_PSR(env);
- qemu_put_be32(f, tmp);
- qemu_put_betls(f, &env->fsr);
- qemu_put_betls(f, &env->tbr);
-#ifndef TARGET_SPARC64
- qemu_put_be32s(f, &env->wim);
- /* MMU */
- for(i = 0; i < 16; i++)
- qemu_put_be32s(f, &env->mmuregs[i]);
-#endif
-}
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- CPUState *env = opaque;
- int i;
- uint32_t tmp;
-
- for(i = 0; i < 8; i++)
- qemu_get_betls(f, &env->gregs[i]);
- for(i = 0; i < NWINDOWS * 16; i++)
- qemu_get_betls(f, &env->regbase[i]);
-
- /* FPU */
- for(i = 0; i < TARGET_FPREGS; i++) {
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = qemu_get_be32(f);
- env->fpr[i] = u.f;
- }
-
- qemu_get_betls(f, &env->pc);
- qemu_get_betls(f, &env->npc);
- qemu_get_betls(f, &env->y);
- tmp = qemu_get_be32(f);
- env->cwp = 0; /* needed to ensure that the wrapping registers are
- correctly updated */
- PUT_PSR(env, tmp);
- qemu_get_betls(f, &env->fsr);
- qemu_get_betls(f, &env->tbr);
-#ifndef TARGET_SPARC64
- qemu_get_be32s(f, &env->wim);
- /* MMU */
- for(i = 0; i < 16; i++)
- qemu_get_be32s(f, &env->mmuregs[i]);
-#endif
- tlb_flush(env, 1);
- return 0;
-}
-
-#elif defined(TARGET_ARM)
-
-/* ??? Need to implement these. */
-void cpu_save(QEMUFile *f, void *opaque)
-{
-}
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- return 0;
-}
-
-#else
-
-#warning No CPU save/restore functions
-
-#endif
-
-/***********************************************************/
-/* ram save/restore */
-
-static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
-{
- int v;
-
- v = qemu_get_byte(f);
- switch(v) {
- case 0:
- if (qemu_get_buffer(f, buf, len) != len)
- return -EIO;
- break;
- case 1:
- v = qemu_get_byte(f);
- memset(buf, v, len);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int ram_load_v1(QEMUFile *f, void *opaque)
-{
- int i, ret;
-
- if (qemu_get_be32(f) != phys_ram_size)
- return -EINVAL;
- for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
- ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-#define BDRV_HASH_BLOCK_SIZE 1024
-#define IOBUF_SIZE 4096
-#define RAM_CBLOCK_MAGIC 0xfabe
-
-typedef struct RamCompressState {
- z_stream zstream;
- QEMUFile *f;
- uint8_t buf[IOBUF_SIZE];
-} RamCompressState;
-
-static int ram_compress_open(RamCompressState *s, QEMUFile *f)
-{
- int ret;
- memset(s, 0, sizeof(*s));
- s->f = f;
- ret = deflateInit2(&s->zstream, 1,
- Z_DEFLATED, 15,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != Z_OK)
- return -1;
- s->zstream.avail_out = IOBUF_SIZE;
- s->zstream.next_out = s->buf;
- return 0;
-}
-
-static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
-{
- qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
- qemu_put_be16(s->f, len);
- qemu_put_buffer(s->f, buf, len);
-}
-
-static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
-{
- int ret;
-
- s->zstream.avail_in = len;
- s->zstream.next_in = (uint8_t *)buf;
- while (s->zstream.avail_in > 0) {
- ret = deflate(&s->zstream, Z_NO_FLUSH);
- if (ret != Z_OK)
- return -1;
- if (s->zstream.avail_out == 0) {
- ram_put_cblock(s, s->buf, IOBUF_SIZE);
- s->zstream.avail_out = IOBUF_SIZE;
- s->zstream.next_out = s->buf;
- }
- }
- return 0;
-}
-
-static void ram_compress_close(RamCompressState *s)
-{
- int len, ret;
-
- /* compress last bytes */
- for(;;) {
- ret = deflate(&s->zstream, Z_FINISH);
- if (ret == Z_OK || ret == Z_STREAM_END) {
- len = IOBUF_SIZE - s->zstream.avail_out;
- if (len > 0) {
- ram_put_cblock(s, s->buf, len);
- }
- s->zstream.avail_out = IOBUF_SIZE;
- s->zstream.next_out = s->buf;
- if (ret == Z_STREAM_END)
- break;
- } else {
- goto fail;
- }
- }
-fail:
- deflateEnd(&s->zstream);
-}
-
-typedef struct RamDecompressState {
- z_stream zstream;
- QEMUFile *f;
- uint8_t buf[IOBUF_SIZE];
-} RamDecompressState;
-
-static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
-{
- int ret;
- memset(s, 0, sizeof(*s));
- s->f = f;
- ret = inflateInit(&s->zstream);
- if (ret != Z_OK)
- return -1;
- return 0;
-}
-
-static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
-{
- int ret, clen;
-
- s->zstream.avail_out = len;
- s->zstream.next_out = buf;
- while (s->zstream.avail_out > 0) {
- if (s->zstream.avail_in == 0) {
- if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
- return -1;
- clen = qemu_get_be16(s->f);
- if (clen > IOBUF_SIZE)
- return -1;
- qemu_get_buffer(s->f, s->buf, clen);
- s->zstream.avail_in = clen;
- s->zstream.next_in = s->buf;
- }
- ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END) {
- return -1;
- }
- }
- return 0;
-}
-
-static void ram_decompress_close(RamDecompressState *s)
-{
- inflateEnd(&s->zstream);
-}
-
-static void ram_save(QEMUFile *f, void *opaque)
-{
- int i;
- RamCompressState s1, *s = &s1;
- uint8_t buf[10];
-
- qemu_put_be32(f, phys_ram_size);
- if (ram_compress_open(s, f) < 0)
- return;
- for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
-#if 0
- if (tight_savevm_enabled) {
- int64_t sector_num;
- int j;
-
- /* find if the memory block is available on a virtual
- block device */
- sector_num = -1;
- for(j = 0; j < MAX_DISKS; j++) {
- if (bs_table[j]) {
- sector_num = bdrv_hash_find(bs_table[j],
- phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
- if (sector_num >= 0)
- break;
- }
- }
- if (j == MAX_DISKS)
- goto normal_compress;
- buf[0] = 1;
- buf[1] = j;
- cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
- ram_compress_buf(s, buf, 10);
- } else
-#endif
- {
- // normal_compress:
- buf[0] = 0;
- ram_compress_buf(s, buf, 1);
- ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
- }
- }
- ram_compress_close(s);
-}
-
-static int ram_load(QEMUFile *f, void *opaque, int version_id)
-{
- RamDecompressState s1, *s = &s1;
- uint8_t buf[10];
- int i;
-
- if (version_id == 1)
- return ram_load_v1(f, opaque);
- if (version_id != 2)
- return -EINVAL;
- if (qemu_get_be32(f) != phys_ram_size)
- return -EINVAL;
- if (ram_decompress_open(s, f) < 0)
- return -EINVAL;
- for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
- if (ram_decompress_buf(s, buf, 1) < 0) {
- fprintf(stderr, "Error while reading ram block header\n");
- goto error;
- }
- if (buf[0] == 0) {
- if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
- fprintf(stderr, "Error while reading ram block address=0x%08x", i);
- goto error;
- }
- } else
-#if 0
- if (buf[0] == 1) {
- int bs_index;
- int64_t sector_num;
-
- ram_decompress_buf(s, buf + 1, 9);
- bs_index = buf[1];
- sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
- if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) {
- fprintf(stderr, "Invalid block device index %d\n", bs_index);
- goto error;
- }
- if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i,
- BDRV_HASH_BLOCK_SIZE / 512) < 0) {
- fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
- bs_index, sector_num);
- goto error;
- }
- } else
-#endif
- {
- error:
- printf("Error block header\n");
- return -EINVAL;
- }
- }
- ram_decompress_close(s);
- return 0;
-}
-#else /* CONFIG_DM */
-void cpu_save(QEMUFile *f, void *opaque)
-{
-}
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- return 0;
-}
-
-static void ram_save(QEMUFile *f, void *opaque)
-{
-}
-
-static int ram_load(QEMUFile *f, void *opaque, int version_id)
-{
- return 0;
-}
-#endif /* CONFIG_DM */
-
-/***********************************************************/
-/* bottom halves (can be seen as timers which expire ASAP) */
-
-struct QEMUBH {
- QEMUBHFunc *cb;
- void *opaque;
- int scheduled;
- QEMUBH *next;
-};
-
-static QEMUBH *first_bh = NULL;
-
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
-{
- QEMUBH *bh;
- bh = qemu_mallocz(sizeof(QEMUBH));
- if (!bh)
- return NULL;
- bh->cb = cb;
- bh->opaque = opaque;
- return bh;
-}
-
-int qemu_bh_poll(void)
-{
- QEMUBH *bh, **pbh;
- int ret;
-
- ret = 0;
- for(;;) {
- pbh = &first_bh;
- bh = *pbh;
- if (!bh)
- break;
- ret = 1;
- *pbh = bh->next;
- bh->scheduled = 0;
- bh->cb(bh->opaque);
- }
- return ret;
-}
-
-void qemu_bh_schedule(QEMUBH *bh)
-{
- CPUState *env = cpu_single_env;
- if (bh->scheduled)
- return;
- bh->scheduled = 1;
- bh->next = first_bh;
- first_bh = bh;
-
- /* stop the currently executing CPU to execute the BH ASAP */
- if (env) {
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
- }
-}
-
-void qemu_bh_cancel(QEMUBH *bh)
-{
- QEMUBH **pbh;
- if (bh->scheduled) {
- pbh = &first_bh;
- while (*pbh != bh)
- pbh = &(*pbh)->next;
- *pbh = bh->next;
- bh->scheduled = 0;
- }
-}
-
-void qemu_bh_delete(QEMUBH *bh)
-{
- qemu_bh_cancel(bh);
- qemu_free(bh);
-}
-
-/***********************************************************/
-/* machine registration */
-
-QEMUMachine *first_machine = NULL;
-
-int qemu_register_machine(QEMUMachine *m)
-{
- QEMUMachine **pm;
- pm = &first_machine;
- while (*pm != NULL)
- pm = &(*pm)->next;
- m->next = NULL;
- *pm = m;
- return 0;
-}
-
-QEMUMachine *find_machine(const char *name)
-{
- QEMUMachine *m;
-
- for(m = first_machine; m != NULL; m = m->next) {
- if (!strcmp(m->name, name))
- return m;
- }
- return NULL;
-}
-
-/***********************************************************/
-/* main execution loop */
-
-void gui_update(void *opaque)
-{
- display_state.dpy_refresh(&display_state);
- qemu_mod_timer(gui_timer,
- (display_state.gui_timer_interval ?
- display_state.gui_timer_interval :
- GUI_REFRESH_INTERVAL)
- + qemu_get_clock(rt_clock));
-}
-
-struct vm_change_state_entry {
- VMChangeStateHandler *cb;
- void *opaque;
- LIST_ENTRY (vm_change_state_entry) entries;
-};
-
-static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
- void *opaque)
-{
- VMChangeStateEntry *e;
-
- e = qemu_mallocz(sizeof (*e));
- if (!e)
- return NULL;
-
- e->cb = cb;
- e->opaque = opaque;
- LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
- return e;
-}
-
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
-{
- LIST_REMOVE (e, entries);
- qemu_free (e);
-}
-
-static void vm_state_notify(int running)
-{
- VMChangeStateEntry *e;
-
- for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
- e->cb(e->opaque, running);
- }
-}
-
-/* XXX: support several handlers */
-static VMStopHandler *vm_stop_cb;
-static void *vm_stop_opaque;
-
-int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
-{
- vm_stop_cb = cb;
- vm_stop_opaque = opaque;
- return 0;
-}
-
-void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
-{
- vm_stop_cb = NULL;
-}
-
-void vm_start(void)
-{
- if (!vm_running) {
- cpu_enable_ticks();
- vm_running = 1;
- vm_state_notify(1);
- }
-}
-
-void vm_stop(int reason)
-{
- if (vm_running) {
- cpu_disable_ticks();
- vm_running = 0;
- if (reason != 0) {
- if (vm_stop_cb) {
- vm_stop_cb(vm_stop_opaque, reason);
- }
- }
- vm_state_notify(0);
- }
-}
-
-/* reset/shutdown handler */
-
-typedef struct QEMUResetEntry {
- QEMUResetHandler *func;
- void *opaque;
- struct QEMUResetEntry *next;
-} QEMUResetEntry;
-
-static QEMUResetEntry *first_reset_entry;
-int reset_requested;
-int shutdown_requested;
-int suspend_requested;
-static int powerdown_requested;
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque)
-{
- QEMUResetEntry **pre, *re;
-
- pre = &first_reset_entry;
- while (*pre != NULL)
- pre = &(*pre)->next;
- re = qemu_mallocz(sizeof(QEMUResetEntry));
- re->func = func;
- re->opaque = opaque;
- re->next = NULL;
- *pre = re;
-}
-
-void qemu_system_reset(void)
-{
- QEMUResetEntry *re;
-
- /* reset all devices */
- for(re = first_reset_entry; re != NULL; re = re->next) {
- re->func(re->opaque);
- }
-}
-
-void qemu_system_reset_request(void)
-{
- if (no_reboot) {
- shutdown_requested = 1;
- } else {
- reset_requested = 1;
- }
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-void qemu_system_shutdown_request(void)
-{
- shutdown_requested = 1;
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-void qemu_system_powerdown_request(void)
-{
- powerdown_requested = 1;
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-void main_loop_wait(int timeout)
-{
- IOHandlerRecord *ioh;
- fd_set rfds, wfds, xfds;
- int ret, nfds;
- struct timeval tv;
- PollingEntry *pe;
-
-
- /* XXX: need to suppress polling by better using win32 events */
- ret = 0;
- for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
- ret |= pe->func(pe->opaque);
- }
-#ifdef _WIN32
- if (ret == 0 && timeout > 0) {
- int err;
- WaitObjects *w = &wait_objects;
-
- ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
- if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
- if (w->func[ret - WAIT_OBJECT_0])
- w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
- } else if (ret == WAIT_TIMEOUT) {
- } else {
- err = GetLastError();
- fprintf(stderr, "Wait error %d %d\n", ret, err);
- }
- }
-#endif
- /* poll any events */
- /* XXX: separate device handlers from system ones */
- nfds = -1;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&xfds);
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (ioh->deleted)
- continue;
- if (ioh->fd_read &&
- (!ioh->fd_read_poll ||
- ioh->fd_read_poll(ioh->opaque) != 0)) {
- FD_SET(ioh->fd, &rfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- if (ioh->fd_write) {
- FD_SET(ioh->fd, &wfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- }
-
- tv.tv_sec = 0;
-#ifdef _WIN32
- tv.tv_usec = 0;
-#else
- tv.tv_usec = timeout * 1000;
-#endif
-#if defined(CONFIG_SLIRP)
- if (slirp_inited) {
- slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
- }
-#endif
- ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
- if (ret > 0) {
- IOHandlerRecord **pioh;
-
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
- ioh->fd_read(ioh->opaque);
- }
- if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
- ioh->fd_write(ioh->opaque);
- }
- }
-
- /* remove deleted IO handlers */
- pioh = &first_io_handler;
- while (*pioh) {
- ioh = *pioh;
- if (ioh->deleted) {
- *pioh = ioh->next;
- qemu_free(ioh);
- } else
- pioh = &ioh->next;
- }
- }
-#if defined(CONFIG_SLIRP)
- if (slirp_inited) {
- if (ret < 0) {
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&xfds);
- }
- slirp_select_poll(&rfds, &wfds, &xfds);
- }
-#endif
- qemu_aio_poll();
- qemu_bh_poll();
-
- if (vm_running) {
- qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
- qemu_get_clock(vm_clock));
- /* run dma transfers, if any */
- DMA_run();
- }
-
- /* real time timers */
- qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
- qemu_get_clock(rt_clock));
-}
-
-#ifndef CONFIG_DM
-static CPUState *cur_cpu;
-
-int main_loop(void)
-{
- int ret, timeout;
-#ifdef CONFIG_PROFILER
- int64_t ti;
-#endif
- CPUState *env;
-
- cur_cpu = first_cpu;
- for(;;) {
- if (vm_running) {
-
- env = cur_cpu;
- for(;;) {
- /* get next cpu */
- env = env->next_cpu;
- if (!env)
- env = first_cpu;
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
- ret = cpu_exec(env);
-#ifdef CONFIG_PROFILER
- qemu_time += profile_getclock() - ti;
-#endif
- if (ret != EXCP_HALTED)
- break;
- /* all CPUs are halted ? */
- if (env == cur_cpu) {
- ret = EXCP_HLT;
- break;
- }
- }
- cur_cpu = env;
-
- if (shutdown_requested) {
- ret = EXCP_INTERRUPT;
- break;
- }
- if (reset_requested) {
- reset_requested = 0;
- qemu_system_reset();
- ret = EXCP_INTERRUPT;
- }
- if (powerdown_requested) {
- powerdown_requested = 0;
- qemu_system_powerdown();
- ret = EXCP_INTERRUPT;
- }
- if (ret == EXCP_DEBUG) {
- vm_stop(EXCP_DEBUG);
- }
- /* if hlt instruction, we wait until the next IRQ */
- /* XXX: use timeout computed from timers */
- if (ret == EXCP_HLT)
- timeout = 10;
- else
- timeout = 0;
- } else {
- timeout = 10;
- }
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
- main_loop_wait(timeout);
-#ifdef CONFIG_PROFILER
- dev_time += profile_getclock() - ti;
-#endif
- }
- cpu_disable_ticks();
- return ret;
-}
-#endif /* !CONFIG_DM */
-
-void help(void)
-{
- printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
- "usage: %s [options] [disk_image]\n"
- "\n"
- "'disk_image' is a raw hard image image for IDE hard disk 0\n"
- "\n"
- "Standard options:\n"
- "-M machine select emulated machine (-M ? for list)\n"
- "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
-#ifndef CONFIG_DM
- "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
- "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
- "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
-#endif /* !CONFIG_DM */
- "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
- "-snapshot write to temporary files instead of disk image files\n"
-#ifdef CONFIG_SDL
- "-no-quit disable SDL window close capability\n"
-#endif
-#ifdef CONFIG_OPENGL
- "-disable-opengl disable OpenGL rendering, using SDL"
-#endif
-#ifdef TARGET_I386
- "-no-fd-bootchk disable boot signature checking for floppy disks\n"
-#endif
- "-m megs set virtual RAM size to megs MB [default=%d]\n"
- "-smp n set the number of CPUs to 'n' [default=1]\n"
- "-nographic disable graphical output and redirect serial I/Os to console\n"
- "-vcpus set CPU number of guest platform\n"
-#ifndef _WIN32
- "-k language use keyboard layout (for example \"fr\" for French)\n"
-#endif
-#ifdef HAS_AUDIO
- "-audio-help print list of audio drivers and their options\n"
- "-soundhw c1,... enable audio support\n"
- " and only specified sound cards (comma separated list)\n"
- " use -soundhw ? to get the list of supported cards\n"
- " use -soundhw all to enable all of them\n"
-#endif
- "-localtime set the real time clock to local time [default=utc]\n"
- "-full-screen start in full screen\n"
-#ifdef TARGET_I386
- "-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n"
-#endif
- "-usb enable the USB driver (will be the default soon)\n"
- "-usbdevice name add the host or guest USB device 'name'\n"
-#if defined(TARGET_PPC) || defined(TARGET_SPARC)
- "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
-#endif
- "\n"
- "Network options:\n"
- "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
- " create a new Network Interface Card and connect it to VLAN 'n'\n"
-#ifdef CONFIG_SLIRP
- "-net user[,vlan=n][,hostname=host]\n"
- " connect the user mode network stack to VLAN 'n' and send\n"
- " hostname 'host' to DHCP clients\n"
-#endif
-#ifdef _WIN32
- "-net tap[,vlan=n],ifname=name\n"
- " connect the host TAP network interface to VLAN 'n'\n"
-#else
- "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,bridge=br]\n"
- " connect the host TAP network interface to VLAN 'n' and use\n"
- " the network script 'file' (default=%s);\n"
- " use 'script=no' to disable script execution;\n"
- " use 'fd=h' to connect to an already opened TAP interface\n"
-#endif
- "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
- " connect the vlan 'n' to another VLAN using a socket connection\n"
- "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
- " connect the vlan 'n' to multicast maddr and port\n"
- "-net none use it alone to have zero network devices; if no -net option\n"
- " is provided, the default is '-net nic -net user'\n"
- "\n"
-#ifdef CONFIG_SLIRP
- "-tftp prefix allow tftp access to files starting with prefix [-net user]\n"
-#ifndef _WIN32
- "-smb dir allow SMB access to files in 'dir' [-net user]\n"
-#endif
- "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
- " redirect TCP or UDP connections from host to guest [-net user]\n"
-#endif
- "\n"
- "Linux boot specific:\n"
- "-kernel bzImage use 'bzImage' as kernel image\n"
- "-append cmdline use 'cmdline' as kernel command line\n"
- "-initrd file use 'file' as initial ram disk\n"
- "\n"
- "Debug/Expert options:\n"
- "-monitor dev redirect the monitor to char device 'dev'\n"
- "-serial dev redirect the serial port to char device 'dev'\n"
- "-parallel dev redirect the parallel port to char device 'dev'\n"
- "-pidfile file Write PID to 'file'\n"
- "-S freeze CPU at startup (use 'c' to start execution)\n"
- "-s wait gdb connection to port %d\n"
- "-p port change gdb connection port\n"
- "-l item1,... output log to %s (use -d ? for a list of log items)\n"
- "-d domain domain that we're serving\n"
- "-domain-name domain name that we're serving\n"
- "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
- " translation (t=none or lba) (usually qemu can guess them)\n"
- "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
-#ifdef USE_KQEMU
- "-kernel-kqemu enable KQEMU full virtualization (default is user mode only)\n"
- "-no-kqemu disable KQEMU kernel module usage\n"
-#endif
-#ifdef USE_CODE_COPY
- "-no-code-copy disable code copy acceleration\n"
-#endif
-#ifdef TARGET_I386
- "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
- " (default is CL-GD5446 PCI VGA)\n"
- "-no-acpi disable ACPI\n"
-#endif
- "-no-reboot exit instead of rebooting\n"
- "-loadvm file start right away with a saved state (loadvm in monitor)\n"
- "-vnc display start a VNC server on display\n"
- "-vncviewer start a vncviewer process for this domain\n"
- "-vncunused bind the VNC server to an unused port\n"
-#ifndef NO_DAEMONIZE
- "-daemonize daemonize QEMU after initializing\n"
-#endif
- "-option-rom rom load a file, rom, into the option ROM space\n"
- "-acpi disable or enable ACPI of HVM domain \n"
- "-pciemulation name:vendorid:deviceid:command:status:revision:classcode:headertype:subvendorid:subsystemid:interruputline:interruputpin\n"
- "\n"
- "During emulation, the following keys are useful:\n"
- "ctrl-alt-f toggle full screen\n"
- "ctrl-alt-n switch to virtual console 'n'\n"
- "ctrl-alt toggle mouse and keyboard grab\n"
- "\n"
- "When using -nographic, press 'ctrl-a h' to get some help.\n"
- ,
- "qemu",
- DEFAULT_RAM_SIZE,
-#ifndef _WIN32
- DEFAULT_NETWORK_SCRIPT,
-#endif
- DEFAULT_GDBSTUB_PORT,
- "/tmp/qemu.log");
- exit(1);
-}
-
-#define HAS_ARG 0x0001
-
-enum {
- QEMU_OPTION_h,
-
- QEMU_OPTION_M,
- QEMU_OPTION_fda,
- QEMU_OPTION_fdb,
-#ifndef CONFIG_DM
- QEMU_OPTION_hda,
- QEMU_OPTION_hdb,
- QEMU_OPTION_hdc,
- QEMU_OPTION_hdd,
- QEMU_OPTION_cdrom,
-#endif /* !CONFIG_DM */
- QEMU_OPTION_boot,
- QEMU_OPTION_snapshot,
-#ifdef TARGET_I386
- QEMU_OPTION_no_fd_bootchk,
-#endif
- QEMU_OPTION_m,
- QEMU_OPTION_nographic,
-#ifdef HAS_AUDIO
- QEMU_OPTION_audio_help,
- QEMU_OPTION_soundhw,
-#endif
-
- QEMU_OPTION_net,
- QEMU_OPTION_tftp,
- QEMU_OPTION_smb,
- QEMU_OPTION_redir,
-
- QEMU_OPTION_kernel,
- QEMU_OPTION_append,
- QEMU_OPTION_initrd,
-
- QEMU_OPTION_S,
- QEMU_OPTION_s,
- QEMU_OPTION_p,
- QEMU_OPTION_l,
- QEMU_OPTION_hdachs,
- QEMU_OPTION_L,
-#ifdef USE_CODE_COPY
- QEMU_OPTION_no_code_copy,
-#endif
- QEMU_OPTION_k,
- QEMU_OPTION_localtime,
- QEMU_OPTION_cirrusvga,
- QEMU_OPTION_g,
- QEMU_OPTION_std_vga,
- QEMU_OPTION_monitor,
- QEMU_OPTION_domainname,
- QEMU_OPTION_serial,
- QEMU_OPTION_parallel,
- QEMU_OPTION_loadvm,
- QEMU_OPTION_full_screen,
- QEMU_OPTION_no_quit,
- QEMU_OPTION_disable_opengl,
- QEMU_OPTION_pidfile,
- QEMU_OPTION_no_kqemu,
- QEMU_OPTION_kernel_kqemu,
- QEMU_OPTION_win2k_hack,
- QEMU_OPTION_usb,
- QEMU_OPTION_usbdevice,
- QEMU_OPTION_smp,
- QEMU_OPTION_vnc,
- QEMU_OPTION_no_acpi,
- QEMU_OPTION_no_reboot,
-#ifndef NO_DAEMONIZE
- QEMU_OPTION_daemonize,
-#endif
- QEMU_OPTION_option_rom,
- QEMU_OPTION_semihosting
- ,
- QEMU_OPTION_d,
- QEMU_OPTION_vcpus,
- QEMU_OPTION_acpi,
- QEMU_OPTION_vncviewer,
- QEMU_OPTION_vncunused,
- QEMU_OPTION_pci,
- QEMU_OPTION_pci_emulation,
-};
-
-typedef struct QEMUOption {
- const char *name;
- int flags;
- int index;
-} QEMUOption;
-
-const QEMUOption qemu_options[] = {
- { "h", 0, QEMU_OPTION_h },
- { "help", 0, QEMU_OPTION_h },
-
- { "M", HAS_ARG, QEMU_OPTION_M },
- { "fda", HAS_ARG, QEMU_OPTION_fda },
- { "fdb", HAS_ARG, QEMU_OPTION_fdb },
-#ifndef CONFIG_DM
- { "hda", HAS_ARG, QEMU_OPTION_hda },
- { "hdb", HAS_ARG, QEMU_OPTION_hdb },
- { "hdc", HAS_ARG, QEMU_OPTION_hdc },
- { "hdd", HAS_ARG, QEMU_OPTION_hdd },
- { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
-#endif /* !CONFIG_DM */
- { "boot", HAS_ARG, QEMU_OPTION_boot },
- { "snapshot", 0, QEMU_OPTION_snapshot },
-#ifdef TARGET_I386
- { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
-#endif
- { "m", HAS_ARG, QEMU_OPTION_m },
- { "nographic", 0, QEMU_OPTION_nographic },
- { "k", HAS_ARG, QEMU_OPTION_k },
-#ifdef HAS_AUDIO
- { "audio-help", 0, QEMU_OPTION_audio_help },
- { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
-#endif
-
- { "net", HAS_ARG, QEMU_OPTION_net},
-#ifdef CONFIG_SLIRP
- { "tftp", HAS_ARG, QEMU_OPTION_tftp },
-#ifndef _WIN32
- { "smb", HAS_ARG, QEMU_OPTION_smb },
-#endif
- { "redir", HAS_ARG, QEMU_OPTION_redir },
-#endif
-
- { "kernel", HAS_ARG, QEMU_OPTION_kernel },
- { "append", HAS_ARG, QEMU_OPTION_append },
- { "initrd", HAS_ARG, QEMU_OPTION_initrd },
-
- { "S", 0, QEMU_OPTION_S },
- { "s", 0, QEMU_OPTION_s },
- { "p", HAS_ARG, QEMU_OPTION_p },
- { "l", HAS_ARG, QEMU_OPTION_l },
- { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
- { "L", HAS_ARG, QEMU_OPTION_L },
-#ifdef USE_CODE_COPY
- { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
-#endif
-#ifdef USE_KQEMU
- { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
- { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
-#endif
-#if defined(TARGET_PPC) || defined(TARGET_SPARC)
- { "g", 1, QEMU_OPTION_g },
-#endif
- { "localtime", 0, QEMU_OPTION_localtime },
- { "std-vga", 0, QEMU_OPTION_std_vga },
- { "monitor", 1, QEMU_OPTION_monitor },
- { "domain-name", 1, QEMU_OPTION_domainname },
- { "serial", 1, QEMU_OPTION_serial },
- { "parallel", 1, QEMU_OPTION_parallel },
- { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
- { "full-screen", 0, QEMU_OPTION_full_screen },
-#ifdef CONFIG_SDL
- { "no-quit", 0, QEMU_OPTION_no_quit },
-#endif
- { "disable-opengl", 0, QEMU_OPTION_disable_opengl },
- { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
- { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
- { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
- { "smp", HAS_ARG, QEMU_OPTION_smp },
- { "vnc", HAS_ARG, QEMU_OPTION_vnc },
- { "vncviewer", 0, QEMU_OPTION_vncviewer },
- { "vncunused", 0, QEMU_OPTION_vncunused },
-
- /* temporary options */
- { "usb", 0, QEMU_OPTION_usb },
- { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
- { "no-acpi", 0, QEMU_OPTION_no_acpi },
- { "no-reboot", 0, QEMU_OPTION_no_reboot },
-#ifndef NO_DAEMONIZE
- { "daemonize", 0, QEMU_OPTION_daemonize },
-#endif
- { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
-#if defined(TARGET_ARM)
- { "semihosting", 0, QEMU_OPTION_semihosting },
-#endif
-
- { "d", HAS_ARG, QEMU_OPTION_d },
- { "vcpus", 1, QEMU_OPTION_vcpus },
- { "acpi", 0, QEMU_OPTION_acpi },
- { "pci", HAS_ARG, QEMU_OPTION_pci},
- { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
- { NULL },
-};
-
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
-
-/* this stack is only used during signal handling */
-#define SIGNAL_STACK_SIZE 32768
-
-static uint8_t *signal_stack;
-
-#endif
-
-/* password input */
-
-static BlockDriverState *get_bdrv(int index)
-{
- BlockDriverState *bs;
-
- if (index < 4) {
- bs = bs_table[index];
- } else if (index < 6) {
- bs = fd_table[index - 4];
- } else {
- bs = NULL;
- }
- return bs;
-}
-
-static void read_passwords(void)
-{
- BlockDriverState *bs;
- int i, j;
- char password[256];
-
- for(i = 0; i < 6; i++) {
- bs = get_bdrv(i);
- if (bs && bdrv_is_encrypted(bs)) {
- term_printf("%s is encrypted.\n", bdrv_get_device_name(bs));
- for(j = 0; j < 3; j++) {
- monitor_readline("Password: ",
- 1, password, sizeof(password));
- if (bdrv_set_key(bs, password) == 0)
- break;
- term_printf("invalid password\n");
- }
- }
- }
-}
-
-/* XXX: currently we cannot use simultaneously different CPUs */
-void register_machines(void)
-{
-#if defined(TARGET_I386)
-#ifndef CONFIG_DM
- qemu_register_machine(&pc_machine);
- qemu_register_machine(&isapc_machine);
-#else
- qemu_register_machine(&xenfv_machine);
- qemu_register_machine(&xenpv_machine);
-#endif
-#elif defined(TARGET_PPC)
- qemu_register_machine(&heathrow_machine);
- qemu_register_machine(&core99_machine);
- qemu_register_machine(&prep_machine);
-#elif defined(TARGET_MIPS)
- qemu_register_machine(&mips_machine);
- qemu_register_machine(&mips_malta_machine);
-#elif defined(TARGET_SPARC)
-#ifdef TARGET_SPARC64
- qemu_register_machine(&sun4u_machine);
-#else
- qemu_register_machine(&sun4m_machine);
-#endif
-#elif defined(TARGET_ARM)
- qemu_register_machine(&integratorcp926_machine);
- qemu_register_machine(&integratorcp1026_machine);
- qemu_register_machine(&versatilepb_machine);
- qemu_register_machine(&versatileab_machine);
- qemu_register_machine(&realview_machine);
-#elif defined(TARGET_SH4)
- qemu_register_machine(&shix_machine);
-#else
-#error unsupported CPU
-#endif
-}
-
-#ifdef HAS_AUDIO
-struct soundhw soundhw[] = {
-#ifndef CONFIG_DM
-#ifdef TARGET_I386
- {
- "pcspk",
- "PC speaker",
- 0,
- 1,
- { .init_isa = pcspk_audio_init }
- },
-#endif
-#endif /* !CONFIG_DM */
- {
- "sb16",
- "Creative Sound Blaster 16",
- 0,
- 1,
- { .init_isa = SB16_init }
- },
-
-#ifdef CONFIG_ADLIB
- {
- "adlib",
-#ifdef HAS_YMF262
- "Yamaha YMF262 (OPL3)",
-#else
- "Yamaha YM3812 (OPL2)",
-#endif
- 0,
- 1,
- { .init_isa = Adlib_init }
- },
-#endif
-
-#ifdef CONFIG_GUS
- {
- "gus",
- "Gravis Ultrasound GF1",
- 0,
- 1,
- { .init_isa = GUS_init }
- },
-#endif
-
- {
- "es1370",
- "ENSONIQ AudioPCI ES1370",
- 0,
- 0,
- { .init_pci = es1370_init }
- },
-
- { NULL, NULL, 0, 0, { NULL } }
-};
-
-static void select_soundhw (const char *optarg)
-{
- struct soundhw *c;
-
- if (*optarg == '?') {
- show_valid_cards:
-
- printf ("Valid sound card names (comma separated):\n");
- for (c = soundhw; c->name; ++c) {
- printf ("%-11s %s\n", c->name, c->descr);
- }
- printf ("\n-soundhw all will enable all of the above\n");
- exit (*optarg != '?');
- }
- else {
- size_t l;
- const char *p;
- char *e;
- int bad_card = 0;
-
- if (!strcmp (optarg, "all")) {
- for (c = soundhw; c->name; ++c) {
- c->enabled = 1;
- }
- return;
- }
-
- p = optarg;
- while (*p) {
- e = strchr (p, ',');
- l = !e ? strlen (p) : (size_t) (e - p);
-
- for (c = soundhw; c->name; ++c) {
- if (!strncmp (c->name, p, l)) {
- c->enabled = 1;
- break;
- }
- }
-
- if (!c->name) {
- if (l > 80) {
- fprintf (stderr,
- "Unknown sound card name (too big to show)\n");
- }
- else {
- fprintf (stderr, "Unknown sound card name `%.*s'\n",
- (int) l, p);
- }
- bad_card = 1;
- }
- p += l + (e != NULL);
- }
-
- if (bad_card)
- goto show_valid_cards;
- }
-}
-#endif
-
-#ifdef _WIN32
-static BOOL WINAPI qemu_ctrl_handler(DWORD type)
-{
- exit(STATUS_CONTROL_C_EXIT);
- return TRUE;
-}
-#endif
-
-#define MAX_NET_CLIENTS 32
-
-#include <xg_private.h>
-
-
-int main(int argc, char **argv)
-{
-#ifdef CONFIG_GDBSTUB
- int use_gdbstub, gdbstub_port;
-#endif
- int i;
-#ifndef CONFIG_DM
- int cdrom_index;
-#endif /* !CONFIG_DM */
- int snapshot, linux_boot;
- const char *initrd_filename;
-#ifndef CONFIG_DM
- const char *hd_filename[MAX_DISKS + MAX_SCSI_DISKS];
-#endif /* !CONFIG_DM */
- const char *fd_filename[MAX_FD];
- const char *kernel_filename, *kernel_cmdline;
- DisplayState *ds = &display_state;
- int cyls, heads, secs, translation;
- char net_clients[MAX_NET_CLIENTS][256];
- int nb_net_clients;
- int optind;
- const char *r, *optarg;
- CharDriverState *monitor_hd;
- char monitor_device[128];
- char serial_devices[MAX_SERIAL_PORTS][128];
- int serial_device_index;
- char parallel_devices[MAX_PARALLEL_PORTS][128];
- int parallel_device_index;
- const char *loadvm = NULL;
- QEMUMachine *machine;
- char usb_devices[MAX_USB_CMDLINE][128];
- int usb_devices_index;
- int fds[2];
-#ifndef CONFIG_STUBDOM
- struct rlimit rl;
-#endif
- sigset_t set;
- char qemu_dm_logfilename[128];
- const char *direct_pci = direct_pci_str;
- int nb_pci_emulation = 0;
- char pci_emulation_config_text[MAX_PCI_EMULATION][256];
-
-#if !defined(__sun__) && !defined(CONFIG_STUBDOM)
- /* Maximise rlimits. Needed where default constraints are tight (*BSD). */
- if (getrlimit(RLIMIT_STACK, &rl) != 0) {
- perror("getrlimit(RLIMIT_STACK)");
- exit(1);
- }
- rl.rlim_cur = rl.rlim_max;
- if (setrlimit(RLIMIT_STACK, &rl) != 0)
- perror("setrlimit(RLIMIT_STACK)");
- if (getrlimit(RLIMIT_DATA, &rl) != 0) {
- perror("getrlimit(RLIMIT_DATA)");
- exit(1);
- }
- rl.rlim_cur = rl.rlim_max;
- if (setrlimit(RLIMIT_DATA, &rl) != 0)
- perror("setrlimit(RLIMIT_DATA)");
- rl.rlim_cur = RLIM_INFINITY;
- rl.rlim_max = RLIM_INFINITY;
- if (setrlimit(RLIMIT_RSS, &rl) != 0)
- perror("setrlimit(RLIMIT_RSS)");
- rl.rlim_cur = RLIM_INFINITY;
- rl.rlim_max = RLIM_INFINITY;
- if (setrlimit(RLIMIT_MEMLOCK, &rl) != 0)
- perror("setrlimit(RLIMIT_MEMLOCK)");
-#endif
-
-#ifndef CONFIG_STUBDOM
- /* Ensure that SIGUSR2 is blocked by default when a new thread is created,
- then only the threads that use the signal unblock it -- this fixes a
- race condition in Qcow support where the AIO signal is misdelivered. */
- {
- extern const int aio_sig_num;
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, aio_sig_num);
- sigprocmask(SIG_BLOCK, &set, NULL);
- }
-#endif
-
- LIST_INIT (&vm_change_state_head);
-#ifndef CONFIG_STUBDOM
-#ifndef _WIN32
- {
- struct sigaction act;
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &act, NULL);
- }
-#else
- SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
- /* Note: cpu_interrupt() is currently not SMP safe, so we force
- QEMU to run on a single CPU */
- {
- HANDLE h;
- DWORD mask, smask;
- int i;
- h = GetCurrentProcess();
- if (GetProcessAffinityMask(h, &mask, &smask)) {
- for(i = 0; i < 32; i++) {
- if (mask & (1 << i))
- break;
- }
- if (i != 32) {
- mask = 1 << i;
- SetProcessAffinityMask(h, mask);
- }
- }
- }
-#endif
-#endif
-
- register_machines();
- machine = first_machine;
- initrd_filename = NULL;
- for(i = 0; i < MAX_FD; i++)
- fd_filename[i] = NULL;
-#ifndef CONFIG_DM
- for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
- hd_filename[i] = NULL;
-#endif /* !CONFIG_DM */
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
- vga_ram_size = VGA_RAM_SIZE;
- bios_size = BIOS_SIZE;
-#ifdef CONFIG_GDBSTUB
- use_gdbstub = 0;
- gdbstub_port = DEFAULT_GDBSTUB_PORT;
-#endif
- snapshot = 0;
- nographic = 0;
- vncviewer = 0;
- vncunused = 0;
- kernel_filename = NULL;
- kernel_cmdline = "";
-#ifndef CONFIG_DM
-#ifdef TARGET_PPC
- cdrom_index = 1;
-#else
- cdrom_index = 2;
-#endif
-#endif /* !CONFIG_DM */
- cyls = heads = secs = 0;
- translation = BIOS_ATA_TRANSLATION_AUTO;
- pstrcpy(monitor_device, sizeof(monitor_device), "null");
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++)
- serial_devices[i][0] = '\0';
- serial_device_index = 0;
-
- pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
- for(i = 1; i < MAX_PARALLEL_PORTS; i++)
- parallel_devices[i][0] = '\0';
- parallel_device_index = 0;
-
- usb_devices_index = 0;
-
- nb_net_clients = 0;
-
- nb_nics = 0;
- /* default mac address of the first network interface */
-
- /* Init logs to stderr to start with */
- cpu_set_log(0);
-
- optind = 1;
- for(;;) {
- if (optind >= argc)
- break;
- r = argv[optind];
- if (r[0] != '-') {
-#ifndef CONFIG_DM
- hd_filename[0] = argv[optind++];
-#else
- help();
-#endif /* !CONFIG_DM */
- } else {
- const QEMUOption *popt;
-
- optind++;
- /* Treat --foo the same as -foo. */
- if (r[1] == '-')
- r++;
- popt = qemu_options;
- for(;;) {
- if (!popt->name) {
- fprintf(stderr, "%s: invalid option -- '%s'\n",
- argv[0], r);
- exit(1);
- }
- if (!strcmp(popt->name, r + 1))
- break;
- popt++;
- }
- if (popt->flags & HAS_ARG) {
- if (optind >= argc) {
- fprintf(stderr, "%s: option '%s' requires an argument\n",
- argv[0], r);
- exit(1);
- }
- optarg = argv[optind++];
- } else {
- optarg = NULL;
- }
-
- switch(popt->index) {
- case QEMU_OPTION_M:
- machine = find_machine(optarg);
- if (!machine) {
- QEMUMachine *m;
- printf("Supported machines are:\n");
- for(m = first_machine; m != NULL; m = m->next) {
- printf("%-10s %s%s\n",
- m->name, m->desc,
- m == first_machine ? " (default)" : "");
- }
- exit(1);
- }
- break;
- case QEMU_OPTION_initrd:
- initrd_filename = optarg;
- break;
-#ifndef CONFIG_DM
- case QEMU_OPTION_hda:
- case QEMU_OPTION_hdb:
- case QEMU_OPTION_hdc:
- case QEMU_OPTION_hdd:
- {
- int hd_index;
- hd_index = popt->index - QEMU_OPTION_hda;
- hd_filename[hd_index] = optarg;
- if (hd_index == cdrom_index)
- cdrom_index = -1;
- }
- break;
-#endif /* !CONFIG_DM */
- case QEMU_OPTION_snapshot:
- snapshot = 1;
- break;
- case QEMU_OPTION_hdachs:
- {
- const char *p;
- p = optarg;
- cyls = strtol(p, (char **)&p, 0);
- if (cyls < 1 || cyls > 16383)
- goto chs_fail;
- if (*p != ',')
- goto chs_fail;
- p++;
- heads = strtol(p, (char **)&p, 0);
- if (heads < 1 || heads > 16)
- goto chs_fail;
- if (*p != ',')
- goto chs_fail;
- p++;
- secs = strtol(p, (char **)&p, 0);
- if (secs < 1 || secs > 63)
- goto chs_fail;
- if (*p == ',') {
- p++;
- if (!strcmp(p, "none"))
- translation = BIOS_ATA_TRANSLATION_NONE;
- else if (!strcmp(p, "lba"))
- translation = BIOS_ATA_TRANSLATION_LBA;
- else if (!strcmp(p, "auto"))
- translation = BIOS_ATA_TRANSLATION_AUTO;
- else
- goto chs_fail;
- } else if (*p != '\0') {
- chs_fail:
- fprintf(stderr, "qemu: invalid physical CHS format\n");
- exit(1);
- }
- }
- break;
- case QEMU_OPTION_nographic:
- if(!strcmp(monitor_device, "vc"))
- pstrcpy(monitor_device, sizeof(monitor_device), "null");
- if(!strcmp(serial_devices[0], "vc"))
- pstrcpy(serial_devices[0], sizeof(serial_devices[0]),
- "null");
- nographic = 1;
- break;
- case QEMU_OPTION_kernel:
- kernel_filename = optarg;
- break;
- case QEMU_OPTION_append:
- kernel_cmdline = optarg;
- break;
-#ifndef CONFIG_DM
- case QEMU_OPTION_cdrom:
- if (cdrom_index >= 0) {
- hd_filename[cdrom_index] = optarg;
- }
- break;
-#endif /* !CONFIG_DM */
- case QEMU_OPTION_boot:
- boot_device = strdup(optarg);
- if (strspn(boot_device, "a"
-#if defined(TARGET_SPARC) || defined(TARGET_I386)
- // Network boot
- "n"
-#endif
- "cd") != strlen(boot_device)) {
- fprintf(stderr, "qemu: invalid boot device in '%s'\n", boot_device);
- exit(1);
- }
- break;
- case QEMU_OPTION_fda:
- fd_filename[0] = optarg;
- break;
- case QEMU_OPTION_fdb:
- fd_filename[1] = optarg;
- break;
-#ifdef TARGET_I386
- case QEMU_OPTION_no_fd_bootchk:
- fd_bootchk = 0;
- break;
-#endif
-#ifdef USE_CODE_COPY
- case QEMU_OPTION_no_code_copy:
- code_copy_enabled = 0;
- break;
-#endif
- case QEMU_OPTION_net:
- if (nb_net_clients >= MAX_NET_CLIENTS) {
- fprintf(stderr, "qemu: too many network clients\n");
- exit(1);
- }
- pstrcpy(net_clients[nb_net_clients],
- sizeof(net_clients[0]),
- optarg);
- nb_net_clients++;
- break;
-#ifdef CONFIG_SLIRP
- case QEMU_OPTION_tftp:
- tftp_prefix = optarg;
- break;
-#ifndef _WIN32
- case QEMU_OPTION_smb:
- net_slirp_smb(optarg);
- break;
-#endif
- case QEMU_OPTION_redir:
- net_slirp_redir(optarg);
- break;
-#endif
-#ifdef HAS_AUDIO
- case QEMU_OPTION_audio_help:
- AUD_help ();
- exit (0);
- break;
- case QEMU_OPTION_soundhw:
- select_soundhw (optarg);
- break;
-#endif
- case QEMU_OPTION_h:
- help();
- break;
- case QEMU_OPTION_m:
- ram_size = atol(optarg) * 1024 * 1024;
- ram_size = (uint64_t)atol(optarg) * 1024 * 1024;
- if (ram_size <= 0)
- help();
-#ifndef CONFIG_DM
- if (ram_size > PHYS_RAM_MAX_SIZE) {
- fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
- PHYS_RAM_MAX_SIZE / (1024 * 1024));
- exit(1);
- }
-#endif /* !CONFIG_DM */
- break;
- case QEMU_OPTION_l:
- {
- int mask;
- CPULogItem *item;
-
- mask = cpu_str_to_log_mask(optarg);
- if (!mask) {
- printf("Log items (comma separated):\n");
- for(item = cpu_log_items; item->mask != 0; item++) {
- printf("%-10s %s\n", item->name, item->help);
- }
- exit(1);
- }
- cpu_set_log(mask);
- }
- break;
-#ifdef CONFIG_GDBSTUB
- case QEMU_OPTION_s:
- use_gdbstub = 1;
- break;
- case QEMU_OPTION_p:
- gdbstub_port = atoi(optarg);
- break;
-#endif
- case QEMU_OPTION_L:
- bios_dir = optarg;
- break;
- case QEMU_OPTION_S:
- autostart = 0;
- break;
- case QEMU_OPTION_k:
- keyboard_layout = optarg;
- break;
- case QEMU_OPTION_localtime:
- rtc_utc = 0;
- break;
- case QEMU_OPTION_cirrusvga:
- cirrus_vga_enabled = 1;
- break;
- case QEMU_OPTION_std_vga:
- cirrus_vga_enabled = 0;
- break;
- case QEMU_OPTION_g:
- {
- const char *p;
- int w, h, depth;
- p = optarg;
- w = strtol(p, (char **)&p, 10);
- if (w <= 0) {
- graphic_error:
- fprintf(stderr, "qemu: invalid resolution or depth\n");
- exit(1);
- }
- if (*p != 'x')
- goto graphic_error;
- p++;
- h = strtol(p, (char **)&p, 10);
- if (h <= 0)
- goto graphic_error;
- if (*p == 'x') {
- p++;
- depth = strtol(p, (char **)&p, 10);
- if (depth != 8 && depth != 15 && depth != 16 &&
- depth != 24 && depth != 32)
- goto graphic_error;
- } else if (*p == '\0') {
- depth = graphic_depth;
- } else {
- goto graphic_error;
- }
-
- graphic_width = w;
- graphic_height = h;
- graphic_depth = depth;
- }
- break;
- case QEMU_OPTION_monitor:
- pstrcpy(monitor_device, sizeof(monitor_device), optarg);
- break;
- case QEMU_OPTION_serial:
- if (serial_device_index >= MAX_SERIAL_PORTS) {
- fprintf(stderr, "qemu: too many serial ports\n");
- exit(1);
- }
- pstrcpy(serial_devices[serial_device_index],
- sizeof(serial_devices[0]), optarg);
- serial_device_index++;
- break;
- case QEMU_OPTION_parallel:
- if (parallel_device_index >= MAX_PARALLEL_PORTS) {
- fprintf(stderr, "qemu: too many parallel ports\n");
- exit(1);
- }
- pstrcpy(parallel_devices[parallel_device_index],
- sizeof(parallel_devices[0]), optarg);
- parallel_device_index++;
- break;
- case QEMU_OPTION_loadvm:
- loadvm = optarg;
- break;
- case QEMU_OPTION_full_screen:
- full_screen = 1;
- break;
-#ifdef CONFIG_SDL
- case QEMU_OPTION_no_quit:
- no_quit = 1;
- break;
-#endif
- case QEMU_OPTION_disable_opengl:
- opengl_enabled = 0;
- break;
- case QEMU_OPTION_pidfile:
- create_pidfile(optarg);
- break;
-#ifdef TARGET_I386
- case QEMU_OPTION_win2k_hack:
- win2k_install_hack = 1;
- break;
-#endif
-#ifdef USE_KQEMU
- case QEMU_OPTION_no_kqemu:
- kqemu_allowed = 0;
- break;
- case QEMU_OPTION_kernel_kqemu:
- kqemu_allowed = 2;
- break;
-#endif
- case QEMU_OPTION_usb:
- usb_enabled = 1;
- break;
- case QEMU_OPTION_usbdevice:
- usb_enabled = 1;
- if (usb_devices_index >= MAX_USB_CMDLINE) {
- fprintf(stderr, "Too many USB devices\n");
- exit(1);
- }
- pstrcpy(usb_devices[usb_devices_index],
- sizeof(usb_devices[usb_devices_index]),
- optarg);
- usb_devices_index++;
- break;
- case QEMU_OPTION_smp:
- smp_cpus = atoi(optarg);
- if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
- fprintf(stderr, "Invalid number of CPUs\n");
- exit(1);
- }
- break;
- case QEMU_OPTION_vnc:
- vnc_display = optarg;
- break;
- case QEMU_OPTION_no_acpi:
- acpi_enabled = 0;
- break;
- case QEMU_OPTION_no_reboot:
- no_reboot = 1;
- break;
-#ifndef NO_DAEMONIZE
- case QEMU_OPTION_daemonize:
- daemonize = 1;
- break;
-#endif
- case QEMU_OPTION_option_rom:
- if (nb_option_roms >= MAX_OPTION_ROMS) {
- fprintf(stderr, "Too many option ROMs\n");
- exit(1);
- }
- option_rom[nb_option_roms] = optarg;
- nb_option_roms++;
- break;
- case QEMU_OPTION_semihosting:
- semihosting_enabled = 1;
- break;
- case QEMU_OPTION_domainname:
- snprintf(domain_name, sizeof(domain_name),
- "Xen-%s", optarg);
- break;
- case QEMU_OPTION_d:
- domid = atoi(optarg);
- fprintf(logfile, "domid: %d\n", domid);
- break;
- case QEMU_OPTION_vcpus:
- vcpus = atoi(optarg);
- fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
- break;
- case QEMU_OPTION_acpi:
- acpi_enabled = 1;
- break;
- case QEMU_OPTION_vncviewer:
- vncviewer++;
- break;
- case QEMU_OPTION_vncunused:
- vncunused++;
- break;
- case QEMU_OPTION_pci_emulation:
- if (nb_pci_emulation >= MAX_PCI_EMULATION) {
- fprintf(stderr, "Too many PCI emulations\n");
- exit(1);
- }
- pstrcpy(pci_emulation_config_text[nb_pci_emulation],
- sizeof(pci_emulation_config_text[0]),
- optarg);
- nb_pci_emulation++;
- break;
- }
- }
- }
-
- cpu_set_log(0);
-
-#ifndef NO_DAEMONIZE
- if (daemonize && !nographic && vnc_display == NULL && vncunused == 0) {
- fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
- daemonize = 0;
- }
-
- if (daemonize) {
- pid_t pid;
-
- if (pipe(fds) == -1)
- exit(1);
-
- pid = fork();
- if (pid > 0) {
- uint8_t status;
- ssize_t len;
-
- close(fds[1]);
-
- again:
- len = read(fds[0], &status, 1);
- if (len == -1 && (errno == EINTR))
- goto again;
-
- if (len != 1 || status != 0)
- exit(1);
- else
- exit(0);
- } else if (pid < 0)
- exit(1);
-
- setsid();
-
- pid = fork();
- if (pid > 0)
- exit(0);
- else if (pid < 0)
- exit(1);
-
- umask(027);
- chdir("/");
-
- signal(SIGTSTP, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
- signal(SIGTTIN, SIG_IGN);
- }
-#endif
-
-#ifdef CONFIG_DM
- bdrv_init();
- xc_handle = xc_interface_open();
-#ifdef CONFIG_STUBDOM
- {
- char *domid_s, *msg;
- if ((msg = xenbus_read(XBT_NIL, "domid", &domid_s)))
- fprintf(stderr,"Can not read our own domid: %s\n", msg);
- else
- xenstore_parse_domain_config(atoi(domid_s));
- }
-#else /* CONFIG_STUBDOM */
- xenstore_parse_domain_config(domid);
-#endif /* CONFIG_STUBDOM */
-#endif /* CONFIG_DM */
-
-#ifdef USE_KQEMU
- if (smp_cpus > 1)
- kqemu_allowed = 0;
-#endif
- linux_boot = (kernel_filename != NULL);
-
-#ifndef CONFIG_DM
- if (!linux_boot &&
- hd_filename[0] == '\0' &&
- (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
- fd_filename[0] == '\0')
- help();
-
- /* boot to floppy or the default cd if no hard disk defined yet */
- if (hd_filename[0] == '\0' && boot_device == 'c') {
- if (fd_filename[0] != '\0')
- boot_device = 'a';
- else
- boot_device = 'd';
- }
-#endif /* !CONFIG_DM */
-
- setvbuf(stdout, NULL, _IOLBF, 0);
-
- init_timers();
- init_timer_alarm();
- qemu_aio_init();
-
-#ifdef _WIN32
- socket_init();
-#endif
-
-#ifndef CONFIG_DM
- /* init network clients */
- if (nb_net_clients == 0) {
- /* if no clients, we use a default config */
- pstrcpy(net_clients[0], sizeof(net_clients[0]),
- "nic");
- pstrcpy(net_clients[1], sizeof(net_clients[0]),
- "user");
- nb_net_clients = 2;
- }
-#endif /* !CONFIG_DM */
-
- for(i = 0;i < nb_net_clients; i++) {
- if (net_client_init(net_clients[i]) < 0)
- exit(1);
- }
-
-#ifndef CONFIG_DM
-#ifdef TARGET_I386
- if (boot_device == 'n') {
- for (i = 0; i < nb_nics; i++) {
- const char *model = nd_table[i].model;
- char buf[1024];
- if (model == NULL)
- model = "ne2k_pci";
- snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
- if (get_image_size(buf) > 0) {
- option_rom[nb_option_roms] = strdup(buf);
- nb_option_roms++;
- break;
- }
- }
- if (i == nb_nics) {
- fprintf(stderr, "No valid PXE rom found for network device\n");
- exit(1);
- }
- boot_device = 'c'; /* to prevent confusion by the BIOS */
- }
-#endif
-#endif /* !CONFIG_DM */
-
-#if defined (__ia64__)
- if (ram_size > MMIO_START)
- ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
-#endif
-
- /* init the memory */
- phys_ram_size = ram_size + vga_ram_size + bios_size;
-
-#ifndef CONFIG_DM
- for (i = 0; i < nb_option_roms; i++) {
- int ret = get_image_size(option_rom[i]);
- if (ret == -1) {
- fprintf(stderr, "Could not load option rom '%s'\n", option_rom[i]);
- exit(1);
- }
- phys_ram_size += ret;
- }
-
- phys_ram_base = qemu_vmalloc(phys_ram_size);
- if (!phys_ram_base) {
- fprintf(stderr, "Could not allocate physical memory\n");
- exit(1);
- }
-
- /* we always create the cdrom drive, even if no disk is there */
- bdrv_init();
- if (cdrom_index >= 0) {
- bs_table[cdrom_index] = bdrv_new("cdrom");
- bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
- }
-
- /* open the virtual block devices */
- for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (hd_filename[i]) {
- if (!bs_table[i]) {
- char buf[64];
- snprintf(buf, sizeof(buf), "hd%c", i + 'a');
- bs_table[i] = bdrv_new(buf);
- }
- if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
- fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
- hd_filename[i]);
- exit(1);
- }
- if (i == 0 && cyls != 0) {
- bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
- bdrv_set_translation_hint(bs_table[i], translation);
- }
- }
- }
-#endif /* !CONFIG_DM */
-
- /* we always create at least one floppy disk */
- fd_table[0] = bdrv_new("fda");
- bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
-
- for(i = 0; i < MAX_FD; i++) {
- if (fd_filename[i]) {
- if (!fd_table[i]) {
- char buf[64];
- snprintf(buf, sizeof(buf), "fd%c", i + 'a');
- fd_table[i] = bdrv_new(buf);
- bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
- }
- if (fd_filename[i] != '\0') {
- if (bdrv_open2(fd_table[i], fd_filename[i],
- snapshot ? BDRV_O_SNAPSHOT : 0,
- &bdrv_raw) < 0) {
- fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
- fd_filename[i]);
- exit(1);
- }
- }
- }
- }
-
- register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
- register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
-
- init_ioports();
-
- /* terminal init */
-#ifdef CONFIG_STUBDOM
- if (xenfb_pv_display_init(ds) == 0) {
- } else
-#endif
- if (nographic) {
- dumb_display_init(ds);
- } else if (vnc_display != NULL || vncunused != 0) {
- int vnc_display_port;
- char password[20];
- vnc_display_init(ds);
- xenstore_read_vncpasswd(domid, password, sizeof(password));
- vnc_display_password(ds, password);
- if ((vnc_display_port = vnc_display_open(ds, vnc_display, vncunused)) < 0)
- exit (0);
-#ifndef CONFIG_STUBDOM
- if (vncviewer)
- vnc_start_viewer(vnc_display_port);
-#endif
- xenstore_write_vncport(vnc_display_port);
- } else {
-#if defined(CONFIG_SDL)
- sdl_display_init(ds, full_screen, opengl_enabled);
-#elif defined(CONFIG_COCOA)
- cocoa_display_init(ds, full_screen);
-#else
- dumb_display_init(ds);
-#endif
- }
-
- monitor_hd = qemu_chr_open(monitor_device);
- if (!monitor_hd) {
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
- }
- store_dev_info(monitor_device, domid, monitor_hd, "/monitor");
- monitor_init(monitor_hd, !nographic);
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- const char *devname = serial_devices[i];
- if (devname[0] != '\0' && strcmp(devname, "none")) {
- char buf[16];
- serial_hds[i] = qemu_chr_open(devname);
- if (!serial_hds[i]) {
- fprintf(stderr, "qemu: could not open serial device '%s'\n",
- devname);
- exit(1);
- }
- snprintf(buf, sizeof(buf), "/serial/%d", i);
- store_dev_info(serial_devices[i], domid, serial_hds[i], buf);
- if (i == 0) /* serial 0 is also called the console */
- store_dev_info(serial_devices[i], domid,
- serial_hds[i], "/console");
- if (!strcmp(devname, "vc"))
- qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
- }
- }
-
- for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
- const char *devname = parallel_devices[i];
- if (devname[0] != '\0' && strcmp(devname, "none")) {
- char buf[16];
- parallel_hds[i] = qemu_chr_open(devname);
- if (!parallel_hds[i]) {
- fprintf(stderr, "qemu: could not open parallel device '%s'\n",
- devname);
- exit(1);
- }
- snprintf(buf, sizeof(buf), "/parallel/%d", i);
- store_dev_info(parallel_devices[i], domid, parallel_hds[i], buf);
- if (!strcmp(devname, "vc"))
- qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
- }
- }
-
- for (i = 0; i < nb_pci_emulation; i++) {
- if(pci_emulation_add(pci_emulation_config_text[i]) < 0) {
- fprintf(stderr, "Warning: could not add PCI device %s\n",
- pci_emulation_config_text[i]);
- }
- }
-
- qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL);
-
- machine->init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename,
- direct_pci);
- free(boot_device);
-
- /* init USB devices */
- if (usb_enabled) {
- for(i = 0; i < usb_devices_index; i++) {
- if (usb_device_add(usb_devices[i]) < 0) {
- fprintf(stderr, "Warning: could not add USB device %s\n",
- usb_devices[i]);
- }
- }
- }
-
- if (vnc_display == NULL && vncunused == 0) {
- gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
- qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
- }
-
-#ifdef CONFIG_GDBSTUB
- if (use_gdbstub) {
- /* XXX: use standard host:port notation and modify options
- accordingly. */
- if (gdbserver_start_port(gdbstub_port) < 0) {
- fprintf(stderr, "qemu: could not open gdbstub device on port '%d'\n",
- gdbstub_port);
- exit(1);
- }
- } else
-#endif
- if (loadvm)
- do_loadvm(loadvm);
-
- {
- /* XXX: simplify init */
- read_passwords();
- if (autostart) {
- vm_start();
- }
- }
-
-#ifndef NO_DAEMONIZE
- if (daemonize) {
- uint8_t status = 0;
- ssize_t len;
- int fd;
-
- again1:
- len = write(fds[1], &status, 1);
- if (len == -1 && (errno == EINTR))
- goto again1;
-
- if (len != 1)
- exit(1);
-
- fd = open("/dev/null", O_RDWR);
- if (fd == -1)
- exit(1);
-
- dup2(fd, 0);
- dup2(fd, 1);
- dup2(fd, 2);
-
- close(fd);
- }
-#endif
-
-#ifndef CONFIG_STUBDOM
- /* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */
- signal(SIGHUP, SIG_DFL);
- sigemptyset(&set);
- sigaddset(&set, SIGTERM);
- sigaddset(&set, SIGHUP);
- if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
- fprintf(stderr, "Failed to unblock SIGTERM and SIGHUP\n");
-#endif
-
- main_loop();
- quit_timers();
- return 0;
-}
diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h
deleted file mode 100644
index 04a5f7b77a..0000000000
--- a/tools/ioemu/vl.h
+++ /dev/null
@@ -1,1589 +0,0 @@
-/*
- * QEMU System Emulator header
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef VL_H
-#define VL_H
-
-/* we put basic includes here to avoid repeating them in device drivers */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <time.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include "xenctrl.h"
-#include "xs.h"
-
-#ifndef O_LARGEFILE
-#define O_LARGEFILE 0
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#ifndef ENOMEDIUM
-#define ENOMEDIUM ENODEV
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#define fsync _commit
-#define lseek _lseeki64
-#define ENOTSUP 4096
-extern int qemu_ftruncate64(int, int64_t);
-#define ftruncate qemu_ftruncate64
-
-
-static inline char *realpath(const char *path, char *resolved_path)
-{
- _fullpath(resolved_path, path, _MAX_PATH);
- return resolved_path;
-}
-
-#define PRId64 "I64d"
-#define PRIx64 "I64x"
-#define PRIu64 "I64u"
-#define PRIo64 "I64o"
-#endif
-
-#ifdef QEMU_TOOL
-
-/* we use QEMU_TOOL in the command line tools which do not depend on
- the target CPU type */
-#include "config-host.h"
-#include <setjmp.h>
-#include "osdep.h"
-#include "bswap.h"
-
-#else
-
-#include "audio/audio.h"
-#include "cpu.h"
-
-#endif /* !defined(QEMU_TOOL) */
-
-#ifndef glue
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-#endif
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-/* cutils.c */
-void pstrcpy(char *buf, size_t buf_size, const char *str);
-char *pstrcat(char *buf, size_t buf_size, const char *s);
-int strstart(const char *str, const char *val, const char **ptr);
-int stristart(const char *str, const char *val, const char **ptr);
-
-/* vl.c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
-void hw_error(const char *fmt, ...);
-
-extern const char *bios_dir;
-
-extern int vm_running;
-
-typedef struct vm_change_state_entry VMChangeStateEntry;
-typedef void VMChangeStateHandler(void *opaque, int running);
-typedef void VMStopHandler(void *opaque, int reason);
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
- void *opaque);
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
-
-int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque);
-void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque);
-
-void vm_start(void);
-void vm_stop(int reason);
-
-typedef void QEMUResetHandler(void *opaque);
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque);
-void qemu_system_reset_request(void);
-void qemu_system_reset(void);
-void qemu_system_shutdown_request(void);
-void qemu_system_powerdown_request(void);
-#if !defined(TARGET_SPARC)
-// Please implement a power failure function to signal the OS
-#define qemu_system_powerdown() do{}while(0)
-#else
-void qemu_system_powerdown(void);
-#endif
-
-extern int reset_requested;
-
-void main_loop_wait(int timeout);
-
-int unset_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages,
- unsigned int address_bits, unsigned long *extent_start);
-int set_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages,
- unsigned int address_bits, unsigned long *extent_start);
-
-extern FILE *logfile;
-
-
-#if (defined(__i386__) || defined(__x86_64__)) && !defined(QEMU_TOOL)
-#define MAPCACHE
-uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
-void qemu_invalidate_map_cache(void);
-#else
-#define qemu_invalidate_map_cache() ((void)0)
-#endif
-
-#define mapcache_lock() ((void)0)
-#define mapcache_unlock() ((void)0)
-
-extern int xc_handle;
-extern int domid;
-
-extern uint64_t ram_size;
-extern int bios_size;
-extern int rtc_utc;
-extern int cirrus_vga_enabled;
-extern int graphic_width;
-extern int graphic_height;
-extern int graphic_depth;
-extern const char *keyboard_layout;
-extern int kqemu_allowed;
-extern int win2k_install_hack;
-extern int usb_enabled;
-extern int acpi_enabled;
-extern int smp_cpus;
-extern int no_quit;
-extern int semihosting_enabled;
-extern int autostart;
-
-#define MAX_OPTION_ROMS 16
-extern const char *option_rom[MAX_OPTION_ROMS];
-extern int nb_option_roms;
-
-/* XXX: make it dynamic */
-#if defined (TARGET_PPC) || defined (TARGET_SPARC64)
-#define BIOS_SIZE ((512 + 32) * 1024)
-#elif defined(TARGET_MIPS)
-#define BIOS_SIZE (4 * 1024 * 1024)
-#else
-#define BIOS_SIZE ((256 + 64) * 1024)
-#endif
-
-/* keyboard/mouse support */
-
-#define MOUSE_EVENT_LBUTTON 0x01
-#define MOUSE_EVENT_RBUTTON 0x02
-#define MOUSE_EVENT_MBUTTON 0x04
-
-typedef void QEMUPutKBDEvent(void *opaque, int keycode);
-typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
-
-typedef struct QEMUPutMouseEntry {
- QEMUPutMouseEvent *qemu_put_mouse_event;
- void *qemu_put_mouse_event_opaque;
- int qemu_put_mouse_event_absolute;
- char *qemu_put_mouse_event_name;
-
- /* used internally by qemu for handling mice */
- struct QEMUPutMouseEntry *next;
-} QEMUPutMouseEntry;
-
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
- const char *name);
-void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
-
-void kbd_put_keycode(int keycode);
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
-int kbd_mouse_is_absolute(void);
-
-void do_info_mice(void);
-void do_mouse_set(int index);
-
-/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
- constants) */
-#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
-#define QEMU_KEY_BACKSPACE 0x007f
-#define QEMU_KEY_UP QEMU_KEY_ESC1('A')
-#define QEMU_KEY_DOWN QEMU_KEY_ESC1('B')
-#define QEMU_KEY_RIGHT QEMU_KEY_ESC1('C')
-#define QEMU_KEY_LEFT QEMU_KEY_ESC1('D')
-#define QEMU_KEY_HOME QEMU_KEY_ESC1(1)
-#define QEMU_KEY_END QEMU_KEY_ESC1(4)
-#define QEMU_KEY_PAGEUP QEMU_KEY_ESC1(5)
-#define QEMU_KEY_PAGEDOWN QEMU_KEY_ESC1(6)
-#define QEMU_KEY_DELETE QEMU_KEY_ESC1(3)
-
-#define QEMU_KEY_CTRL_UP 0xe400
-#define QEMU_KEY_CTRL_DOWN 0xe401
-#define QEMU_KEY_CTRL_LEFT 0xe402
-#define QEMU_KEY_CTRL_RIGHT 0xe403
-#define QEMU_KEY_CTRL_HOME 0xe404
-#define QEMU_KEY_CTRL_END 0xe405
-#define QEMU_KEY_CTRL_PAGEUP 0xe406
-#define QEMU_KEY_CTRL_PAGEDOWN 0xe407
-
-void kbd_put_keysym(int keysym);
-
-/* async I/O support */
-
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanRWHandler(void *opaque);
-typedef void IOHandler(void *opaque);
-
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-
-/* Polling handling */
-
-/* return TRUE if no sleep should be done afterwards */
-typedef int PollingFunc(void *opaque);
-
-int qemu_add_polling_cb(PollingFunc *func, void *opaque);
-void qemu_del_polling_cb(PollingFunc *func, void *opaque);
-
-#ifdef _WIN32
-/* Wait objects handling */
-typedef void WaitObjectFunc(void *opaque);
-
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-#endif
-
-typedef struct QEMUBH QEMUBH;
-
-/* character device */
-
-#define CHR_EVENT_BREAK 0 /* serial break char */
-#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
-#define CHR_EVENT_RESET 2 /* new connection established */
-
-
-#define CHR_IOCTL_SERIAL_SET_PARAMS 1
-typedef struct {
- int speed;
- int parity;
- int data_bits;
- int stop_bits;
-} QEMUSerialSetParams;
-
-#define CHR_IOCTL_SERIAL_SET_BREAK 2
-
-#define CHR_IOCTL_PP_READ_DATA 3
-#define CHR_IOCTL_PP_WRITE_DATA 4
-#define CHR_IOCTL_PP_READ_CONTROL 5
-#define CHR_IOCTL_PP_WRITE_CONTROL 6
-#define CHR_IOCTL_PP_READ_STATUS 7
-
-
-#define CHR_IOCTL_SERIAL_SET_TIOCM 8
-#define CHR_IOCTL_SERIAL_GET_TIOCM 9
-
-typedef void IOEventHandler(void *opaque, int event);
-
-typedef struct CharDriverState {
- int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
- void (*chr_update_read_handler)(struct CharDriverState *s);
- int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
- IOEventHandler *chr_event;
- IOCanRWHandler *chr_can_read;
- IOReadHandler *chr_read;
- void *handler_opaque;
- void (*chr_send_event)(struct CharDriverState *chr, int event);
- void (*chr_close)(struct CharDriverState *chr);
- void *opaque;
- QEMUBH *bh;
-} CharDriverState;
-
-CharDriverState *qemu_chr_open(const char *filename);
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
-void qemu_chr_send_event(CharDriverState *s, int event);
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque);
-int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
-void qemu_chr_reset(CharDriverState *s);
-int qemu_chr_can_read(CharDriverState *s);
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
-
-/* consoles */
-
-typedef struct DisplayState DisplayState;
-typedef struct TextConsole TextConsole;
-
-typedef void (*vga_hw_update_ptr)(void *);
-typedef void (*vga_hw_invalidate_ptr)(void *);
-typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
-
-TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
- vga_hw_invalidate_ptr invalidate,
- vga_hw_screen_dump_ptr screen_dump,
- void *opaque);
-void vga_hw_update(void);
-void vga_hw_invalidate(void);
-void vga_hw_screen_dump(const char *filename);
-
-int is_graphic_console(void);
-CharDriverState *text_console_init(DisplayState *ds);
-void console_select(unsigned int index);
-void set_color_table(DisplayState *ds);
-
-/* serial ports */
-
-#define MAX_SERIAL_PORTS 4
-
-extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-
-/* parallel ports */
-
-#define MAX_PARALLEL_PORTS 3
-
-extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-
-/* VLANs support */
-
-typedef struct VLANClientState VLANClientState;
-
-struct VLANClientState {
- IOReadHandler *fd_read;
- /* Packets may still be sent if this returns zero. It's used to
- rate-limit the slirp code. */
- IOCanRWHandler *fd_can_read;
- void *opaque;
- struct VLANClientState *next;
- struct VLANState *vlan;
- char info_str[256];
-};
-
-typedef struct VLANState {
- int id;
- VLANClientState *first_client;
- struct VLANState *next;
-} VLANState;
-
-VLANState *qemu_find_vlan(int id);
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque);
-int qemu_can_send_packet(VLANClientState *vc);
-void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
-void qemu_handler_true(void *opaque);
-
-void do_info_network(void);
-
-/* TAP win32 */
-int tap_win32_init(VLANState *vlan, const char *ifname);
-
-/* NIC info */
-
-#define MAX_NICS 8
-
-typedef struct NICInfo {
- uint8_t macaddr[6];
- const char *model;
- VLANState *vlan;
-} NICInfo;
-
-extern int nb_nics;
-extern NICInfo nd_table[MAX_NICS];
-
-/* timers */
-
-typedef struct QEMUClock QEMUClock;
-typedef struct QEMUTimer QEMUTimer;
-typedef void QEMUTimerCB(void *opaque);
-
-/* The real time clock should be used only for stuff which does not
- change the virtual machine state, as it is run even if the virtual
- machine is stopped. The real time clock has a frequency of 1000
- Hz. */
-extern QEMUClock *rt_clock;
-
-/* The virtual clock is only run during the emulation. It is stopped
- when the virtual machine is stopped. Virtual timers use a high
- precision clock, usually cpu cycles (use ticks_per_sec). */
-extern QEMUClock *vm_clock;
-
-int64_t qemu_get_clock(QEMUClock *clock);
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
-void qemu_free_timer(QEMUTimer *ts);
-void qemu_del_timer(QEMUTimer *ts);
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time);
-int qemu_timer_pending(QEMUTimer *ts);
-
-extern int64_t ticks_per_sec;
-extern int pit_min_timer_count;
-
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
-
-/* VM Load/Save */
-
-typedef struct QEMUFile QEMUFile;
-
-QEMUFile *qemu_fopen(const char *filename, const char *mode);
-void qemu_fflush(QEMUFile *f);
-void qemu_fclose(QEMUFile *f);
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
-void qemu_put_byte(QEMUFile *f, int v);
-void qemu_put_be16(QEMUFile *f, unsigned int v);
-void qemu_put_be32(QEMUFile *f, unsigned int v);
-void qemu_put_be64(QEMUFile *f, uint64_t v);
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
-int qemu_get_byte(QEMUFile *f);
-unsigned int qemu_get_be16(QEMUFile *f);
-unsigned int qemu_get_be32(QEMUFile *f);
-uint64_t qemu_get_be64(QEMUFile *f);
-
-static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
-{
- qemu_put_be64(f, *pv);
-}
-
-static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
-{
- qemu_put_be32(f, *pv);
-}
-
-static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
-{
- qemu_put_be16(f, *pv);
-}
-
-static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
-{
- qemu_put_byte(f, *pv);
-}
-
-static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
-{
- *pv = qemu_get_be64(f);
-}
-
-static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
-{
- *pv = qemu_get_be32(f);
-}
-
-static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
-{
- *pv = qemu_get_be16(f);
-}
-
-static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
-{
- *pv = qemu_get_byte(f);
-}
-
-#if TARGET_LONG_BITS == 64
-#define qemu_put_betl qemu_put_be64
-#define qemu_get_betl qemu_get_be64
-#define qemu_put_betls qemu_put_be64s
-#define qemu_get_betls qemu_get_be64s
-#else
-#define qemu_put_betl qemu_put_be32
-#define qemu_get_betl qemu_get_be32
-#define qemu_put_betls qemu_put_be32s
-#define qemu_get_betls qemu_get_be32s
-#endif
-
-int64_t qemu_ftell(QEMUFile *f);
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
-
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque);
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
-
-void cpu_save(QEMUFile *f, void *opaque);
-int cpu_load(QEMUFile *f, void *opaque, int version_id);
-
-void do_savevm(const char *name);
-void do_loadvm(const char *name);
-void do_delvm(const char *name);
-void do_info_snapshots(void);
-
-/* bottom halves */
-typedef void QEMUBHFunc(void *opaque);
-
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
-void qemu_bh_schedule(QEMUBH *bh);
-void qemu_bh_cancel(QEMUBH *bh);
-void qemu_bh_delete(QEMUBH *bh);
-int qemu_bh_poll(void);
-
-/* block.c */
-typedef struct BlockDriverState BlockDriverState;
-typedef struct BlockDriver BlockDriver;
-
-extern BlockDriver bdrv_raw;
-extern BlockDriver bdrv_host_device;
-#ifdef CONFIG_STUBDOM
-extern BlockDriver bdrv_vbd;
-#endif
-extern BlockDriver bdrv_cow;
-extern BlockDriver bdrv_qcow;
-extern BlockDriver bdrv_vmdk;
-extern BlockDriver bdrv_cloop;
-extern BlockDriver bdrv_dmg;
-extern BlockDriver bdrv_bochs;
-extern BlockDriver bdrv_vpc;
-extern BlockDriver bdrv_vvfat;
-extern BlockDriver bdrv_qcow2;
-
-typedef struct BlockDriverInfo {
- /* in bytes, 0 if irrelevant */
- int cluster_size;
- /* offset at which the VM state can be saved (0 if not possible) */
- int64_t vm_state_offset;
-} BlockDriverInfo;
-
-typedef struct QEMUSnapshotInfo {
- char id_str[128]; /* unique snapshot id */
- /* the following fields are informative. They are not needed for
- the consistency of the snapshot */
- char name[256]; /* user choosen name */
- uint32_t vm_state_size; /* VM state info size */
- uint32_t date_sec; /* UTC date of the snapshot */
- uint32_t date_nsec;
- uint64_t vm_clock_nsec; /* VM clock relative to boot */
-} QEMUSnapshotInfo;
-
-#define BDRV_O_RDONLY 0x0000
-#define BDRV_O_RDWR 0x0002
-#define BDRV_O_ACCESS 0x0003
-#define BDRV_O_CREAT 0x0004 /* create an empty file */
-#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */
-#define BDRV_O_FILE 0x0010 /* open as a raw file (do not try to
- use a disk image format on top of
- it (default for
- bdrv_file_open()) */
-#define BDRV_O_EXTENDABLE 0x0080 /* allow writes out of original size range;
- only effective for some drivers */
-
-void bdrv_init(void);
-BlockDriver *bdrv_find_format(const char *format_name);
-int bdrv_create(BlockDriver *drv,
- const char *filename, int64_t size_in_sectors,
- const char *backing_file, int flags);
-BlockDriverState *bdrv_new(const char *device_name);
-void bdrv_delete(BlockDriverState *bs);
-int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
-int bdrv_open(BlockDriverState *bs, const char *filename, int flags);
-int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
- BlockDriver *drv);
-void bdrv_close(BlockDriverState *bs);
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
- void *buf, int count);
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
- const void *buf, int count);
-int bdrv_truncate(BlockDriverState *bs, int64_t offset);
-int64_t bdrv_getlength(BlockDriverState *bs);
-void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
-int bdrv_commit(BlockDriverState *bs);
-void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
-/* async block I/O */
-typedef struct BlockDriverAIOCB BlockDriverAIOCB;
-typedef void BlockDriverCompletionFunc(void *opaque, int ret);
-
-BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-void bdrv_aio_cancel(BlockDriverAIOCB *acb);
-BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque);
-
-void qemu_aio_init(void);
-void qemu_aio_poll(void);
-void qemu_aio_flush(void);
-void qemu_aio_wait_start(void);
-void qemu_aio_wait(void);
-void qemu_aio_wait_end(void);
-
-/* Ensure contents are flushed to disk. */
-int bdrv_flush(BlockDriverState *bs);
-
-#define BDRV_TYPE_HD 0
-#define BDRV_TYPE_CDROM 1
-#define BDRV_TYPE_FLOPPY 2
-#define BIOS_ATA_TRANSLATION_AUTO 0
-#define BIOS_ATA_TRANSLATION_NONE 1
-#define BIOS_ATA_TRANSLATION_LBA 2
-#define BIOS_ATA_TRANSLATION_LARGE 3
-#define BIOS_ATA_TRANSLATION_RECHS 4
-
-void bdrv_set_geometry_hint(BlockDriverState *bs,
- int cyls, int heads, int secs);
-void bdrv_set_type_hint(BlockDriverState *bs, int type);
-void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
-void bdrv_get_geometry_hint(BlockDriverState *bs,
- int *pcyls, int *pheads, int *psecs);
-int bdrv_get_type_hint(BlockDriverState *bs);
-int bdrv_get_translation_hint(BlockDriverState *bs);
-int bdrv_is_removable(BlockDriverState *bs);
-int bdrv_is_read_only(BlockDriverState *bs);
-int bdrv_is_inserted(BlockDriverState *bs);
-int bdrv_media_changed(BlockDriverState *bs);
-int bdrv_is_locked(BlockDriverState *bs);
-void bdrv_set_locked(BlockDriverState *bs, int locked);
-void bdrv_eject(BlockDriverState *bs, int eject_flag);
-void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque);
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
-void bdrv_info(void);
-BlockDriverState *bdrv_find(const char *name);
-void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
-int bdrv_is_encrypted(BlockDriverState *bs);
-int bdrv_set_key(BlockDriverState *bs, const char *key);
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque);
-const char *bdrv_get_device_name(BlockDriverState *bs);
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
-
-void bdrv_get_backing_filename(BlockDriverState *bs,
- char *filename, int filename_size);
-int bdrv_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info);
-int bdrv_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id);
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
-int bdrv_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info);
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
-
-char *get_human_readable_size(char *buf, int buf_size, int64_t size);
-int path_is_absolute(const char *path);
-void path_combine(char *dest, int dest_size,
- const char *base_path,
- const char *filename);
-
-#ifndef QEMU_TOOL
-
-typedef void QEMUMachineInitFunc(uint64_t ram_size, int vga_ram_size,
- char *boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, const char *direct_pci);
-
-typedef struct QEMUMachine {
- const char *name;
- const char *desc;
- QEMUMachineInitFunc *init;
- struct QEMUMachine *next;
-} QEMUMachine;
-
-int qemu_register_machine(QEMUMachine *m);
-
-typedef void SetIRQFunc(void *opaque, int irq_num, int level);
-typedef void IRQRequestFunc(void *opaque, int level);
-
-/* ISA bus */
-
-extern target_phys_addr_t isa_mem_base;
-
-typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
-typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
-
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque);
-void isa_unassign_ioport(int start, int length);
-
-void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
-
-/* PCI bus */
-
-extern target_phys_addr_t pci_mem_base;
-
-typedef struct PCIBus PCIBus;
-typedef struct PCIDevice PCIDevice;
-
-typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
- uint32_t address, uint32_t data, int len);
-typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
- uint32_t address, int len);
-typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type);
-
-#define PCI_ADDRESS_SPACE_MEM 0x00
-#define PCI_ADDRESS_SPACE_IO 0x01
-#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
-
-typedef struct PCIIORegion {
- uint32_t addr; /* current PCI mapping address. -1 means not mapped */
- uint32_t size;
- uint8_t type;
- PCIMapIORegionFunc *map_func;
-} PCIIORegion;
-
-#define PCI_ROM_SLOT 6
-#define PCI_NUM_REGIONS 7
-
-#define PCI_DEVICES_MAX 64
-
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
-#define PCI_CLASS_DEVICE 0x0a /* Device class */
-#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
-#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
-#define PCI_MIN_GNT 0x3e /* 8 bits */
-#define PCI_MAX_LAT 0x3f /* 8 bits */
-
-struct PCIDevice {
- /*
- * PCI config space. The 4 extra bytes are a safety buffer for guest
- * word/dword writes that can extend past byte 0xff.
- */
- uint8_t config[256+4];
-
- /* the following fields are read only */
- PCIBus *bus;
- int devfn;
- char name[64];
- PCIIORegion io_regions[PCI_NUM_REGIONS];
-
- /* do not access the following fields */
- PCIConfigReadFunc *config_read;
- PCIConfigWriteFunc *config_write;
-
- /* Current IRQ levels. Used internally by the generic PCI code. */
- int irq_state[4];
-};
-
-extern char direct_pci_str[];
-
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write);
-
-void pci_hide_device(PCIDevice *pci_dev);
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func);
-
-int pt_chk_bar_overlap(PCIBus *bus, int devfn, uint32_t addr, uint32_t size);
-
-void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level);
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len);
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len);
-void pci_device_save(PCIDevice *s, QEMUFile *f);
-int pci_device_load(PCIDevice *s, QEMUFile *f);
-
-typedef void (*pci_set_irq_fn)(void *pic, int irq_num, int level);
-typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *pic, int devfn_min, int nirq);
-
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
-int pci_bus_num(PCIBus *s);
-void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
-
-void pci_info(void);
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
- pci_map_irq_fn map_irq, const char *name);
-
-/* PCI slot 6~7 support ACPI PCI hot plug */
-#define PHP_SLOT_START (6)
-#define PHP_SLOT_END (8)
-#define PHP_SLOT_LEN (PHP_SLOT_END - PHP_SLOT_START)
-#define PHP_TO_PCI_SLOT(x) (x + PHP_SLOT_START)
-#define PCI_TO_PHP_SLOT(x) (x - PHP_SLOT_START)
-#define PHP_DEVFN_START (PHP_SLOT_START << 3)
-#define PHP_DEVFN_END (PHP_SLOT_END << 3)
-
-int insert_to_pci_slot(char*);
-int test_pci_slot(int);
-int bdf_to_slot(char*);
-int power_on_php_slot(int);
-int power_off_php_slot(int);
-
-/* prep_pci.c */
-PCIBus *pci_prep_init(void);
-
-/* grackle_pci.c */
-PCIBus *pci_grackle_init(uint32_t base, void *pic);
-
-/* unin_pci.c */
-PCIBus *pci_pmac_init(void *pic);
-
-/* apb_pci.c */
-PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
- void *pic);
-
-PCIBus *pci_vpb_init(void *pic, int irq, int realview);
-
-/* piix_pci.c */
-PCIBus *i440fx_init(PCIDevice **pi440fx_state);
-void i440fx_set_smm(PCIDevice *d, int val);
-int piix3_init(PCIBus *bus, int devfn);
-void i440fx_init_memory_mappings(PCIDevice *d);
-
-int piix4_init(PCIBus *bus, int devfn);
-
-/* openpic.c */
-typedef struct openpic_t openpic_t;
-void openpic_set_irq(void *opaque, int n_IRQ, int level);
-openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
- CPUState **envp);
-
-/* heathrow_pic.c */
-typedef struct HeathrowPICS HeathrowPICS;
-void heathrow_pic_set_irq(void *opaque, int num, int level);
-HeathrowPICS *heathrow_pic_init(int *pmem_index);
-
-/* gt64xxx.c */
-PCIBus *pci_gt64120_init(void *pic);
-
-#ifdef HAS_AUDIO
-struct soundhw {
- const char *name;
- const char *descr;
- int enabled;
- int isa;
- union {
- int (*init_isa) (AudioState *s);
- int (*init_pci) (PCIBus *bus, AudioState *s);
- } init;
-};
-
-extern struct soundhw soundhw[];
-#endif
-
-/* vga.c */
-
-#define VGA_RAM_SIZE (8192 * 1024)
-
-/* in ms */
-#define GUI_REFRESH_INTERVAL 30
-
-struct DisplayState {
- uint8_t *data;
- int linesize;
- int depth;
- int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
- int width;
- int height;
- void *opaque;
- uint32_t *palette;
- uint64_t gui_timer_interval;
- int idle;
-
- int shared_buf;
-
- void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
- void (*dpy_resize)(struct DisplayState *s, int w, int h);
- void (*dpy_setdata)(DisplayState *s, void *pixels);
- void (*dpy_resize_shared)(DisplayState *s, int w, int h, int depth, int linesize, void *pixels);
- void (*dpy_refresh)(struct DisplayState *s);
- void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, int dst_y, int w, int h);
-};
-
-static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
-{
- s->dpy_update(s, x, y, w, h);
-}
-
-static inline void dpy_resize(DisplayState *s, int w, int h)
-{
- s->dpy_resize(s, w, h);
-}
-
-static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, int linesize, void *pixels)
-{
- s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
-}
-
-static inline void dpy_setdata(DisplayState *s, void *pixels)
-{
- s->dpy_setdata(s, pixels);
-}
-
-
-int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size,
- unsigned long vga_bios_offset, int vga_bios_size);
-
-/* cirrus_vga.c */
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-
-/* sdl.c */
-void sdl_display_init(DisplayState *ds, int full_screen, int opengl_enable);
-
-/* cocoa.m */
-void cocoa_display_init(DisplayState *ds, int full_screen);
-
-/* vnc.c */
-void vnc_display_init(DisplayState *ds);
-void vnc_display_close(DisplayState *ds);
-int vnc_display_open(DisplayState *ds, const char * display, int find_unused);
-int vnc_display_password(DisplayState *ds, const char *password);
-void do_info_vnc(void);
-int vnc_start_viewer(int port);
-
-/* x_keymap.c */
-extern uint8_t _translate_keycode(const int key);
-
-/* ide.c */
-#define MAX_DISKS 4
-#define MAX_SCSI_DISKS 7
-
-extern BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS + 1];
-
-void isa_ide_init(int iobase, int iobase2, int irq,
- BlockDriverState *hd0, BlockDriverState *hd1);
-void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
- int secondary_ide_enabled);
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
-int pmac_ide_init (BlockDriverState **hd_table,
- SetIRQFunc *set_irq, void *irq_opaque, int irq);
-
-/* extboot.c */
-void extboot_init(BlockDriverState *bs, int cmd);
-
-/* cdrom.c */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
-
-/* es1370.c */
-int es1370_init (PCIBus *bus, AudioState *s);
-
-/* sb16.c */
-int SB16_init (AudioState *s);
-
-/* adlib.c */
-int Adlib_init (AudioState *s);
-
-/* gus.c */
-int GUS_init (AudioState *s);
-
-/* dma.c */
-typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
-int DMA_get_channel_mode (int nchan);
-int DMA_read_memory (int nchan, void *buf, int pos, int size);
-int DMA_write_memory (int nchan, void *buf, int pos, int size);
-void DMA_hold_DREQ (int nchan);
-void DMA_release_DREQ (int nchan);
-void DMA_schedule(int nchan);
-void DMA_run (void);
-void DMA_init (int high_page_enable);
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque);
-/* fdc.c */
-#define MAX_FD 2
-extern BlockDriverState *fd_table[MAX_FD];
-
-typedef struct fdctrl_t fdctrl_t;
-
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
- uint32_t io_base,
- BlockDriverState **fds);
-int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
-
-/* ne2000.c */
-
-void isa_ne2000_init(int base, int irq, NICInfo *nd);
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* rtl8139.c */
-
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* pcnet.c */
-
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pcnet_h_reset(void *opaque);
-void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque);
-
-/* e100.c */
-void pci_e100_init(PCIBus *bus, NICInfo *nd);
-
-/* e1000.c */
-void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* pckbd.c */
-
-void kbd_init(void);
-
-/* mc146818rtc.c */
-
-typedef struct RTCState RTCState;
-
-RTCState *rtc_init(int base, int irq);
-void rtc_set_memory(RTCState *s, int addr, int val);
-void rtc_set_date(RTCState *s, const struct tm *tm);
-
-/* serial.c */
-
-typedef struct SerialState SerialState;
-SerialState *serial_init(SetIRQFunc *set_irq, void *opaque,
- int base, int irq, CharDriverState *chr);
-SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque,
- target_ulong base, int it_shift,
- int irq, CharDriverState *chr);
-
-/* parallel.c */
-
-typedef struct ParallelState ParallelState;
-ParallelState *parallel_init(int base, int irq, CharDriverState *chr);
-
-/* i8259.c */
-
-typedef struct PicState2 PicState2;
-extern PicState2 *isa_pic;
-void pic_set_irq(int irq, int level);
-void pic_set_irq_new(void *opaque, int irq, int level);
-PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque);
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
- void *alt_irq_opaque);
-int pic_read_irq(PicState2 *s);
-void pic_update_irq(PicState2 *s);
-uint32_t pic_intack_read(PicState2 *s);
-void pic_info(void);
-void irq_info(void);
-void sp_info(void);
-
-/* APIC */
-typedef struct IOAPICState IOAPICState;
-
-int apic_init(CPUState *env);
-int apic_get_interrupt(CPUState *env);
-IOAPICState *ioapic_init(void);
-void ioapic_set_irq(void *opaque, int vector, int level);
-
-/* i8254.c */
-
-#define PIT_FREQ 1193182
-
-typedef struct PITState PITState;
-
-PITState *pit_init(int base, int irq);
-void pit_set_gate(PITState *pit, int channel, int val);
-int pit_get_gate(PITState *pit, int channel);
-int pit_get_initial_count(PITState *pit, int channel);
-int pit_get_mode(PITState *pit, int channel);
-int pit_get_out(PITState *pit, int channel, int64_t current_time);
-
-/* pcspk.c */
-void pcspk_init(PITState *);
-int pcspk_audio_init(AudioState *);
-
-#include "hw/smbus.h"
-
-/* acpi.c */
-extern int acpi_enabled;
-void piix4_pm_init(PCIBus *bus, int devfn);
-void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
-void acpi_bios_init(void);
-
-/* smbus_eeprom.c */
-SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
-
-/* tpm_tis.c */
-int has_tpm_device(void);
-void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
-
-/* piix4acpi.c */
-extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
-void acpi_php_add(int);
-void acpi_php_del(int);
-
-
-/* pc.c */
-extern QEMUMachine pc_machine;
-extern QEMUMachine isapc_machine;
-#ifdef CONFIG_DM
-extern QEMUMachine xenfv_machine;
-extern QEMUMachine xenpv_machine;
-#endif
-extern int fd_bootchk;
-
-void ioport_set_a20(int enable);
-int ioport_get_a20(void);
-void cmos_set_s3_resume(void);
-
-/* ppc.c */
-extern QEMUMachine prep_machine;
-extern QEMUMachine core99_machine;
-extern QEMUMachine heathrow_machine;
-
-/* mips_r4k.c */
-extern QEMUMachine mips_machine;
-
-/* mips_malta.c */
-extern QEMUMachine mips_malta_machine;
-
-/* mips_int */
-extern void cpu_mips_irq_request(void *opaque, int irq, int level);
-
-/* mips_timer.c */
-extern void cpu_mips_clock_init(CPUState *);
-extern void cpu_mips_irqctrl_init (void);
-
-/* shix.c */
-extern QEMUMachine shix_machine;
-
-#ifdef TARGET_PPC
-ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
-#endif
-void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
-
-extern CPUWriteMemoryFunc *PPC_io_write[];
-extern CPUReadMemoryFunc *PPC_io_read[];
-void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
-
-/* sun4m.c */
-extern QEMUMachine sun4m_machine;
-void pic_set_irq_cpu(int irq, int level, unsigned int cpu);
-
-/* iommu.c */
-void *iommu_init(uint32_t addr);
-void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int is_write);
-static inline void sparc_iommu_memory_read(void *opaque,
- target_phys_addr_t addr,
- uint8_t *buf, int len)
-{
- sparc_iommu_memory_rw(opaque, addr, buf, len, 0);
-}
-
-static inline void sparc_iommu_memory_write(void *opaque,
- target_phys_addr_t addr,
- uint8_t *buf, int len)
-{
- sparc_iommu_memory_rw(opaque, addr, buf, len, 1);
-}
-
-/* tcx.c */
-void tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
- unsigned long vram_offset, int vram_size, int width, int height);
-
-/* slavio_intctl.c */
-void *slavio_intctl_init(void);
-void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env);
-void slavio_pic_info(void *opaque);
-void slavio_irq_info(void *opaque);
-void slavio_pic_set_irq(void *opaque, int irq, int level);
-void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu);
-
-/* loader.c */
-int get_image_size(const char *filename);
-int load_image(const char *filename, uint8_t *addr);
-int load_elf(const char *filename, int64_t virt_to_phys_addend, uint64_t *pentry);
-int load_aout(const char *filename, uint8_t *addr);
-
-/* slavio_timer.c */
-void slavio_timer_init(uint32_t addr, int irq, int mode, unsigned int cpu);
-
-/* slavio_serial.c */
-SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2);
-void slavio_serial_ms_kbd_init(int base, int irq);
-
-/* slavio_misc.c */
-void *slavio_misc_init(uint32_t base, int irq);
-void slavio_set_power_fail(void *opaque, int power_failing);
-
-/* esp.c */
-void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id);
-void *esp_init(BlockDriverState **bd, uint32_t espaddr, void *dma_opaque);
-void esp_reset(void *opaque);
-
-/* sparc32_dma.c */
-void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu,
- void *intctl);
-void ledma_set_irq(void *opaque, int isr);
-void ledma_memory_read(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap);
-void ledma_memory_write(void *opaque, target_phys_addr_t addr,
- uint8_t *buf, int len, int do_bswap);
-void espdma_raise_irq(void *opaque);
-void espdma_clear_irq(void *opaque);
-void espdma_memory_read(void *opaque, uint8_t *buf, int len);
-void espdma_memory_write(void *opaque, uint8_t *buf, int len);
-void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque,
- void *lance_opaque);
-
-/* cs4231.c */
-void cs_init(target_phys_addr_t base, int irq, void *intctl);
-
-/* sun4u.c */
-extern QEMUMachine sun4u_machine;
-
-/* NVRAM helpers */
-#include "hw/m48t59.h"
-
-void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value);
-uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value);
-uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value);
-uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
- const unsigned char *str, uint32_t max);
-int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max);
-void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr,
- uint32_t start, uint32_t count);
-int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
- const unsigned char *arch,
- uint32_t RAM_size, char *boot_device,
- uint32_t kernel_image, uint32_t kernel_size,
- const char *cmdline,
- uint32_t initrd_image, uint32_t initrd_size,
- uint32_t NVRAM_image,
- int width, int height, int depth);
-
-/* adb.c */
-
-#define MAX_ADB_DEVICES 16
-
-#define ADB_MAX_OUT_LEN 16
-
-typedef struct ADBDevice ADBDevice;
-
-/* buf = NULL means polling */
-typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
- const uint8_t *buf, int len);
-typedef int ADBDeviceReset(ADBDevice *d);
-
-struct ADBDevice {
- struct ADBBusState *bus;
- int devaddr;
- int handler;
- ADBDeviceRequest *devreq;
- ADBDeviceReset *devreset;
- void *opaque;
-};
-
-typedef struct ADBBusState {
- ADBDevice devices[MAX_ADB_DEVICES];
- int nb_devices;
- int poll_index;
-} ADBBusState;
-
-int adb_request(ADBBusState *s, uint8_t *buf_out,
- const uint8_t *buf, int len);
-int adb_poll(ADBBusState *s, uint8_t *buf_out);
-
-ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
- ADBDeviceRequest *devreq,
- ADBDeviceReset *devreset,
- void *opaque);
-void adb_kbd_init(ADBBusState *bus);
-void adb_mouse_init(ADBBusState *bus);
-
-/* cuda.c */
-
-extern ADBBusState adb_bus;
-int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
-
-#include "hw/usb.h"
-
-/* usb ports of the VM */
-
-void qemu_register_usb_port(USBPort *port, void *opaque, int index,
- usb_attachfn attach);
-
-#define VM_USB_HUB_SIZE 8
-
-void do_usb_add(const char *devname);
-void do_usb_del(const char *devname);
-void usb_info(void);
-
-void do_pci_add(char *devname);
-void do_pci_del(char *devname);
-
-/* scsi-disk.c */
-enum scsi_reason {
- SCSI_REASON_DONE, /* Command complete. */
- SCSI_REASON_DATA /* Transfer complete, more data required. */
-};
-
-typedef struct SCSIDevice SCSIDevice;
-typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag,
- uint32_t arg);
-
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
- int tcq,
- scsi_completionfn completion,
- void *opaque);
-void scsi_disk_destroy(SCSIDevice *s);
-
-int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun);
-/* SCSI data transfers are asynchrnonous. However, unlike the block IO
- layer the completion routine may be called directly by
- scsi_{read,write}_data. */
-void scsi_read_data(SCSIDevice *s, uint32_t tag);
-int scsi_write_data(SCSIDevice *s, uint32_t tag);
-void scsi_cancel_io(SCSIDevice *s, uint32_t tag);
-uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag);
-
-/* lsi53c895a.c */
-void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
-void *lsi_scsi_init(PCIBus *bus, int devfn);
-
-/* integratorcp.c */
-extern QEMUMachine integratorcp926_machine;
-extern QEMUMachine integratorcp1026_machine;
-
-/* versatilepb.c */
-extern QEMUMachine versatilepb_machine;
-extern QEMUMachine versatileab_machine;
-
-/* realview.c */
-extern QEMUMachine realview_machine;
-
-/* ps2.c */
-void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
-void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
-void ps2_write_mouse(void *, int val);
-void ps2_write_keyboard(void *, int val);
-uint32_t ps2_read_data(void *);
-void ps2_queue(void *, int b);
-void ps2_keyboard_set_translation(void *opaque, int mode);
-
-/* smc91c111.c */
-void smc91c111_init(NICInfo *, uint32_t, void *, int);
-
-/* pl110.c */
-void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq, int);
-
-/* pl011.c */
-void pl011_init(uint32_t base, void *pic, int irq, CharDriverState *chr);
-
-/* pl050.c */
-void pl050_init(uint32_t base, void *pic, int irq, int is_mouse);
-
-/* pl080.c */
-void *pl080_init(uint32_t base, void *pic, int irq, int nchannels);
-
-/* pl190.c */
-void *pl190_init(uint32_t base, void *parent, int irq, int fiq);
-
-/* arm-timer.c */
-void sp804_init(uint32_t base, void *pic, int irq);
-void icp_pit_init(uint32_t base, void *pic, int irq);
-
-/* arm_sysctl.c */
-void arm_sysctl_init(uint32_t base, uint32_t sys_id);
-
-/* arm_gic.c */
-void *arm_gic_init(uint32_t base, void *parent, int parent_irq);
-
-/* arm_boot.c */
-
-void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
- const char *kernel_cmdline, const char *initrd_filename,
- int board_id);
-
-/* sh7750.c */
-struct SH7750State;
-
-struct SH7750State *sh7750_init(CPUState * cpu);
-
-typedef struct {
- /* The callback will be triggered if any of the designated lines change */
- uint16_t portamask_trigger;
- uint16_t portbmask_trigger;
- /* Return 0 if no action was taken */
- int (*port_change_cb) (uint16_t porta, uint16_t portb,
- uint16_t * periph_pdtra,
- uint16_t * periph_portdira,
- uint16_t * periph_pdtrb,
- uint16_t * periph_portdirb);
-} sh7750_io_device;
-
-int sh7750_register_io_device(struct SH7750State *s,
- sh7750_io_device * device);
-/* tc58128.c */
-int tc58128_init(struct SH7750State *s, char *zone1, char *zone2);
-
-/* NOR flash devices */
-typedef struct pflash_t pflash_t;
-
-pflash_t *pflash_register (target_ulong base, ram_addr_t off,
- BlockDriverState *bs,
- target_ulong sector_len, int nb_blocs, int width,
- uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3);
-
-#include "gdbstub.h"
-
-#endif /* defined(QEMU_TOOL) */
-
-/* monitor.c */
-void monitor_init(CharDriverState *hd, int show_banner);
-void term_puts(const char *str);
-void term_vprintf(const char *fmt, va_list ap);
-void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
-void term_print_filename(const char *filename);
-void term_flush(void);
-void term_print_help(void);
-void monitor_readline(const char *prompt, int is_password,
- char *buf, int buf_size);
-void do_eject(int force, const char *filename);
-void do_change(const char *device, const char *filename);
-
-/* readline.c */
-typedef void ReadLineFunc(void *opaque, const char *str);
-
-extern int completion_index;
-void add_completion(const char *str);
-void readline_handle_byte(int ch);
-void readline_find_completion(const char *cmdline);
-const char *readline_get_history(unsigned int index);
-void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque);
-
-/* xenstore.c */
-void xenstore_parse_domain_config(int domid);
-int xenstore_fd(void);
-void xenstore_process_event(void *opaque);
-void xenstore_record_dm(char *subpath, char *state);
-void xenstore_record_dm_state(char *state);
-void xenstore_check_new_media_present(int timeout);
-void xenstore_write_vncport(int vnc_display);
-void xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen);
-void xenstore_write_vslots(char *vslots);
-
-int xenstore_domain_has_devtype(struct xs_handle *handle,
- const char *devtype);
-char **xenstore_domain_get_devices(struct xs_handle *handle,
- const char *devtype, unsigned int *num);
-char *xenstore_read_hotplug_status(struct xs_handle *handle,
- const char *devtype, const char *inst);
-char *xenstore_backend_read_variable(struct xs_handle *,
- const char *devtype, const char *inst,
- const char *var);
-int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
- const char *devtype,
- const char *inst,
- const char *token);
-int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
- const char *devtype,
- const char *inst,
- const char *token);
-
-int xenstore_vm_write(int domid, char *key, char *val);
-char *xenstore_vm_read(int domid, char *key, unsigned int *len);
-
-/* xenfb.c */
-int xenfb_pv_display_init(DisplayState *ds);
-int xenfb_pv_display_start(void *vram_start);
-int xenfb_connect_vkbd(const char *path);
-int xenfb_connect_vfb(const char *path);
-
-/* helper2.c */
-extern long time_offset;
-void timeoffset_get(void);
-
-/* xen_platform.c */
-#ifndef QEMU_TOOL
-void pci_xen_platform_init(PCIBus *bus);
-void xen_vga_stolen_vram_addr(uint64_t vram_addr);
-void xen_vga_populate_vram(uint64_t vram_addr);
-void xen_vga_vram_map(uint64_t vram_addr, int copy);
-#endif
-
-/* pci_emulation.c */
-#ifndef QEMU_TOOL
-#include "hw/pci_emulation.h"
-#endif
-
-void kqemu_record_dump(void);
-
-extern char domain_name[];
-
-void destroy_hvm_domain(void);
-
-#ifdef __ia64__
-static inline void xc_domain_shutdown_hook(int xc_handle, uint32_t domid)
-{
- xc_ia64_save_to_nvram(xc_handle, domid);
-}
-
-void handle_buffered_pio(void);
-#else
-#define xc_domain_shutdown_hook(xc_handle, domid) do {} while (0)
-#define handle_buffered_pio() do {} while (0)
-#endif
-
-#endif /* VL_H */
diff --git a/tools/ioemu/vnc.c b/tools/ioemu/vnc.c
deleted file mode 100644
index cd40929f72..0000000000
--- a/tools/ioemu/vnc.c
+++ /dev/null
@@ -1,2868 +0,0 @@
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2006 Christian Limpach <Christian.Limpach@xensource.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "vl.h"
-#include "qemu_socket.h"
-#include <assert.h>
-#ifdef CONFIG_STUBDOM
-#include <netfront.h>
-#endif
-
-/* The refresh interval starts at BASE. If we scan the buffer and
- find no change, we increase by INC, up to MAX. If the mouse moves
- or we get a keypress, the interval is set back to BASE. If we find
- an update, halve the interval.
-
- All times in milliseconds. */
-#define VNC_REFRESH_INTERVAL_BASE 30
-#define VNC_REFRESH_INTERVAL_INC 50
-#define VNC_REFRESH_INTERVAL_MAX 2000
-
-/* Wait at most one second between updates, so that we can detect a
- minimised vncviewer reasonably quickly. */
-#define VNC_MAX_UPDATE_INTERVAL 5000
-
-#include "vnc_keysym.h"
-#include "keymaps.c"
-#include "d3des.h"
-
-#if CONFIG_VNC_TLS
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-#endif /* CONFIG_VNC_TLS */
-
-// #define _VNC_DEBUG 1
-
-#if _VNC_DEBUG
-#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-
-#if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
-/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
-static void vnc_debug_gnutls_log(int level, const char* str) {
- VNC_DEBUG("%d %s", level, str);
-}
-#endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
-#else
-#define VNC_DEBUG(fmt, ...) do { } while (0)
-#endif
-
-
-typedef struct Buffer
-{
- size_t capacity;
- size_t offset;
- uint8_t *buffer;
-} Buffer;
-
-typedef struct VncState VncState;
-
-typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
-
-typedef void VncWritePixels(VncState *vs, void *data, int size);
-
-typedef void VncSendHextileTile(VncState *vs,
- int x, int y, int w, int h,
- void *last_bg,
- void *last_fg,
- int *has_bg, int *has_fg);
-
-#if 0
-#define VNC_MAX_WIDTH 2048
-#define VNC_MAX_HEIGHT 2048
-#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
-#endif
-
-#define VNC_AUTH_CHALLENGE_SIZE 16
-
-enum {
- VNC_AUTH_INVALID = 0,
- VNC_AUTH_NONE = 1,
- VNC_AUTH_VNC = 2,
- VNC_AUTH_RA2 = 5,
- VNC_AUTH_RA2NE = 6,
- VNC_AUTH_TIGHT = 16,
- VNC_AUTH_ULTRA = 17,
- VNC_AUTH_TLS = 18,
- VNC_AUTH_VENCRYPT = 19
-};
-
-#if CONFIG_VNC_TLS
-enum {
- VNC_WIREMODE_CLEAR,
- VNC_WIREMODE_TLS,
-};
-
-enum {
- VNC_AUTH_VENCRYPT_PLAIN = 256,
- VNC_AUTH_VENCRYPT_TLSNONE = 257,
- VNC_AUTH_VENCRYPT_TLSVNC = 258,
- VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
- VNC_AUTH_VENCRYPT_X509NONE = 260,
- VNC_AUTH_VENCRYPT_X509VNC = 261,
- VNC_AUTH_VENCRYPT_X509PLAIN = 262,
-};
-
-#if CONFIG_VNC_TLS
-#define X509_CA_CERT_FILE "ca-cert.pem"
-#define X509_CA_CRL_FILE "ca-crl.pem"
-#define X509_SERVER_KEY_FILE "server-key.pem"
-#define X509_SERVER_CERT_FILE "server-cert.pem"
-#endif
-
-#endif /* CONFIG_VNC_TLS */
-
-#define QUEUE_ALLOC_UNIT 10
-
-typedef struct _QueueItem
-{
- int x, y, w, h;
- int32_t enc;
- struct _QueueItem *next;
-} QueueItem;
-
-typedef struct _Queue
-{
- QueueItem *queue_start;
- int start_count;
- QueueItem *queue_end;
- int end_count;
-} Queue;
-
-struct VncState
-{
- QEMUTimer *timer;
- int timer_interval;
- int64_t last_update_time;
- int lsock;
- int csock;
- DisplayState *ds;
- int width;
- int height;
- uint64_t *dirty_row; /* screen regions which are possibly dirty */
- int dirty_pixel_shift;
- uint64_t *update_row; /* outstanding updates */
- int has_update; /* there's outstanding updates in the
- * visible area */
-
- int update_requested; /* the client requested an update */
-
- uint8_t *old_data;
- int depth; /* internal VNC frame buffer byte per pixel */
- int has_resize;
- int has_hextile;
- int has_pointer_type_change;
- int has_WMVi;
- int absolute;
- int last_x;
- int last_y;
-
- int major;
- int minor;
-
- char *display;
- char *password;
- int auth;
-#if CONFIG_VNC_TLS
- int subauth;
- int x509verify;
-
- char *x509cacert;
- char *x509cacrl;
- char *x509cert;
- char *x509key;
-#endif
- char challenge[VNC_AUTH_CHALLENGE_SIZE];
- int switchbpp;
-
-#if CONFIG_VNC_TLS
- int wiremode;
- gnutls_session_t tls_session;
-#endif
-
- Buffer output;
- Buffer input;
-
- Queue upqueue;
-
- kbd_layout_t *kbd_layout;
- /* current output mode information */
- VncWritePixels *write_pixels;
- VncSendHextileTile *send_hextile_tile;
- int pix_bpp, pix_big_endian;
- int red_shift, red_max, red_shift1, red_max1;
- int green_shift, green_max, green_shift1, green_max1;
- int blue_shift, blue_max, blue_shift1, blue_max1;
-
- VncReadEvent *read_handler;
- size_t read_handler_expect;
-
- int visible_x;
- int visible_y;
- int visible_w;
- int visible_h;
-
- /* input */
- uint8_t modifiers_state[256];
-};
-
-static VncState *vnc_state; /* needed for info vnc */
-
-#define DIRTY_PIXEL_BITS 64
-#define X2DP_DOWN(vs, x) ((x) >> (vs)->dirty_pixel_shift)
-#define X2DP_UP(vs, x) \
- (((x) + (1ULL << (vs)->dirty_pixel_shift) - 1) >> (vs)->dirty_pixel_shift)
-#define DP2X(vs, x) ((x) << (vs)->dirty_pixel_shift)
-
-void do_info_vnc(void)
-{
- if (vnc_state == NULL)
- term_printf("VNC server disabled\n");
- else {
- term_printf("VNC server active on: ");
- term_print_filename(vnc_state->display);
- term_printf("\n");
-
- if (vnc_state->csock == -1)
- term_printf("No client connected\n");
- else
- term_printf("Client connected\n");
- }
-}
-
-/* TODO
- 1) Get the queue working for IO.
- 2) there is some weirdness when using the -S option (the screen is grey
- and not totally invalidated
- 3) resolutions > 1024
-*/
-
-static void vnc_write(VncState *vs, const void *data, size_t len);
-static void vnc_write_u32(VncState *vs, uint32_t value);
-static void vnc_write_s32(VncState *vs, int32_t value);
-static void vnc_write_u16(VncState *vs, uint16_t value);
-static void vnc_write_u8(VncState *vs, uint8_t value);
-static void vnc_flush(VncState *vs);
-static void _vnc_update_client(void *opaque);
-static void vnc_update_client(void *opaque);
-static void vnc_client_read(void *opaque);
-static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
-static void pixel_format_message (VncState *vs);
-static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h, int32_t encoding);
-static void dequeue_framebuffer_update(VncState *vs);
-static int is_empty_queue(VncState *vs);
-static void free_queue(VncState *vs);
-static void vnc_colourdepth(DisplayState *ds, int depth);
-
-#if 0
-static inline void vnc_set_bit(uint32_t *d, int k)
-{
- d[k >> 5] |= 1 << (k & 0x1f);
-}
-
-static inline void vnc_clear_bit(uint32_t *d, int k)
-{
- d[k >> 5] &= ~(1 << (k & 0x1f));
-}
-
-static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
-{
- int j;
-
- j = 0;
- while (n >= 32) {
- d[j++] = -1;
- n -= 32;
- }
- if (n > 0)
- d[j++] = (1 << n) - 1;
- while (j < nb_words)
- d[j++] = 0;
-}
-
-static inline int vnc_get_bit(const uint32_t *d, int k)
-{
- return (d[k >> 5] >> (k & 0x1f)) & 1;
-}
-
-static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
- int nb_words)
-{
- int i;
- for(i = 0; i < nb_words; i++) {
- if ((d1[i] & d2[i]) != 0)
- return 1;
- }
- return 0;
-}
-#endif
-
-static void set_bits_in_row(VncState *vs, uint64_t *row,
- int x, int y, int w, int h)
-{
- int x1, x2;
- uint64_t mask;
-
- if (w == 0)
- return;
-
- x1 = X2DP_DOWN(vs, x);
- x2 = X2DP_UP(vs, x + w);
-
- if (X2DP_UP(vs, w) != DIRTY_PIXEL_BITS)
- mask = ((1ULL << (x2 - x1)) - 1) << x1;
- else
- mask = ~(0ULL);
-
- h += y;
- if (h > vs->ds->height)
- h = vs->ds->height;
- for (; y < h; y++)
- row[y] |= mask;
-}
-
-static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
-{
- VncState *vs = ds->opaque;
-
- set_bits_in_row(vs, vs->dirty_row, x, y, w, h);
-}
-
-static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
- int32_t encoding)
-{
- vnc_write_u16(vs, x);
- vnc_write_u16(vs, y);
- vnc_write_u16(vs, w);
- vnc_write_u16(vs, h);
-
- vnc_write_s32(vs, encoding);
-}
-
-static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
-{
- static int allocated;
- int size_changed;
- VncState *vs = ds->opaque;
- int o;
-
- vnc_colourdepth(ds, depth);
- if (!ds->shared_buf) {
- ds->linesize = w * vs->depth;
- if (allocated)
- ds->data = realloc(ds->data, h * ds->linesize);
- else
- ds->data = malloc(h * ds->linesize);
- allocated = 1;
- } else {
- ds->linesize = linesize;
- if (allocated) {
- free(ds->data);
- allocated = 0;
- }
- }
- vs->old_data = realloc(vs->old_data, h * ds->linesize);
- vs->dirty_row = realloc(vs->dirty_row, h * sizeof(vs->dirty_row[0]));
- vs->update_row = realloc(vs->update_row, h * sizeof(vs->dirty_row[0]));
-
- if (ds->data == NULL || vs->old_data == NULL ||
- vs->dirty_row == NULL || vs->update_row == NULL) {
- fprintf(stderr, "vnc: memory allocation failed\n");
- exit(1);
- }
-
- if (ds->depth != vs->depth * 8) {
- ds->depth = vs->depth * 8;
- set_color_table(ds);
- }
- size_changed = ds->width != w || ds->height != h;
- ds->width = w;
- ds->height = h;
- if (vs->csock != -1 && vs->has_resize && size_changed) {
- vs->width = ds->width;
- vs->height = ds->height;
- if (vs->update_requested) {
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
- vnc_flush(vs);
- vs->update_requested--;
- } else {
- enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
- }
- }
- vs->dirty_pixel_shift = 0;
- for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
- vs->dirty_pixel_shift++;
- framebuffer_set_updated(vs, 0, 0, ds->width, ds->height);
- if (ds->shared_buf) ds->data = pixels;
-}
-
-static void vnc_dpy_resize(DisplayState *ds, int w, int h)
-{
- vnc_dpy_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
-}
-
-/* fastest code */
-static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
-{
- vnc_write(vs, pixels, size);
-}
-
-/* slowest but generic code. */
-static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
-{
- uint8_t r, g, b;
-
- r = ((v >> vs->red_shift1) & vs->red_max1) * (vs->red_max + 1) / (vs->red_max1 + 1);
- g = ((v >> vs->green_shift1) & vs->green_max1) * (vs->green_max + 1) / (vs->green_max1 + 1);
- b = ((v >> vs->blue_shift1) & vs->blue_max1) * (vs->blue_max + 1) / (vs->blue_max1 + 1);
- switch(vs->pix_bpp) {
- case 1:
- buf[0] = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift);
- break;
- case 2:
- {
- uint16_t *p = (uint16_t *) buf;
- *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift);
- if (vs->pix_big_endian) {
- *p = htons(*p);
- }
- }
- break;
- default:
- case 4:
- {
- uint32_t *p = (uint32_t *) buf;
- *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift);
- if (vs->pix_big_endian) {
- *p = htonl(*p);
- }
- break;
- }
- }
-}
-
-static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
-{
- uint8_t buf[4];
-
- if (vs->depth == 4) {
- uint32_t *pixels = pixels1;
- int n, i;
- n = size >> 2;
- for(i = 0; i < n; i++) {
- vnc_convert_pixel(vs, buf, pixels[i]);
- vnc_write(vs, buf, vs->pix_bpp);
- }
- } else if (vs->depth == 2) {
- uint16_t *pixels = pixels1;
- int n, i;
- n = size >> 1;
- for(i = 0; i < n; i++) {
- vnc_convert_pixel(vs, buf, pixels[i]);
- vnc_write(vs, buf, vs->pix_bpp);
- }
- } else if (vs->depth == 1) {
- uint8_t *pixels = pixels1;
- int n, i;
- n = size;
- for(i = 0; i < n; i++) {
- vnc_convert_pixel(vs, buf, pixels[i]);
- vnc_write(vs, buf, vs->pix_bpp);
- }
- } else {
- fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
- }
-}
-
-static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
-{
- int i;
- uint8_t *row;
-
- vnc_framebuffer_update(vs, x, y, w, h, 0);
-
- row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
- for (i = 0; i < h; i++) {
- vs->write_pixels(vs, row, w * vs->depth);
- row += vs->ds->linesize;
- }
-}
-
-static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
-{
- ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
- ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
-}
-
-#define BPP 8
-#include "vnchextile.h"
-#undef BPP
-
-#define BPP 16
-#include "vnchextile.h"
-#undef BPP
-
-#define BPP 32
-#include "vnchextile.h"
-#undef BPP
-
-#define GENERIC
-#define BPP 8
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
-#define BPP 16
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
-#define BPP 32
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
-{
- int i, j;
- int has_fg, has_bg;
- void *last_fg, *last_bg;
-
- vnc_framebuffer_update(vs, x, y, w, h, 5);
-
- last_fg = (void *) malloc(vs->depth);
- last_bg = (void *) malloc(vs->depth);
- has_fg = has_bg = 0;
- for (j = y; j < (y + h); j += 16) {
- for (i = x; i < (x + w); i += 16) {
- vs->send_hextile_tile(vs, i, j,
- MIN(16, x + w - i), MIN(16, y + h - j),
- last_bg, last_fg, &has_bg, &has_fg);
- }
- }
- free(last_fg);
- free(last_bg);
-}
-
-static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
-{
- if (vs->has_hextile)
- send_framebuffer_update_hextile(vs, x, y, w, h);
- else
- send_framebuffer_update_raw(vs, x, y, w, h);
-}
-
-static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
-{
- int src, dst;
- uint8_t *src_row;
- uint8_t *dst_row;
- uint8_t *old_row;
- int y = 0;
- int pitch = ds->linesize;
- VncState *vs = ds->opaque;
- int updating_client = 1;
-
- if (ds->shared_buf) {
- framebuffer_set_updated(vs, dst_x, dst_y, w, h);
- return;
- }
-
- if (!vs->update_requested ||
- src_x < vs->visible_x || src_y < vs->visible_y ||
- dst_x < vs->visible_x || dst_y < vs->visible_y ||
- (src_x + w) > (vs->visible_x + vs->visible_w) ||
- (src_y + h) > (vs->visible_y + vs->visible_h) ||
- (dst_x + w) > (vs->visible_x + vs->visible_w) ||
- (dst_y + h) > (vs->visible_y + vs->visible_h))
- updating_client = 0;
-
- if (updating_client)
- _vnc_update_client(vs);
-
- if (dst_y > src_y) {
- y = h - 1;
- pitch = -pitch;
- }
-
- src = (ds->linesize * (src_y + y) + vs->depth * src_x);
- dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
-
- src_row = ds->data + src;
- dst_row = ds->data + dst;
- old_row = vs->old_data + dst;
-
- for (y = 0; y < h; y++) {
- memmove(old_row, src_row, w * vs->depth);
- memmove(dst_row, src_row, w * vs->depth);
- src_row += pitch;
- dst_row += pitch;
- old_row += pitch;
- }
-
- if (updating_client && vs->csock != -1 && !vs->has_update) {
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
- vnc_write_u16(vs, src_x);
- vnc_write_u16(vs, src_y);
- vnc_flush(vs);
- vs->update_requested--;
- } else
- framebuffer_set_updated(vs, dst_x, dst_y, w, h);
-}
-
-static int find_update_height(VncState *vs, int y, int maxy, int last_x, int x)
-{
- int h;
-
- for (h = 1; y + h < maxy; h++) {
- int tmp_x;
- if (!(vs->update_row[y + h] & (1ULL << last_x)))
- break;
- for (tmp_x = last_x; tmp_x < x; tmp_x++)
- vs->update_row[y + h] &= ~(1ULL << tmp_x);
- }
-
- return h;
-}
-
-static void _vnc_update_client(void *opaque)
-{
- VncState *vs = opaque;
- int64_t now;
- int y;
- uint8_t *row;
- uint8_t *old_row;
- uint64_t width_mask;
- int n_rectangles;
- int saved_offset;
- int maxx, maxy;
- int tile_bytes = vs->depth * DP2X(vs, 1);
-
- if (!vs->update_requested || vs->csock == -1)
- return;
- while (!is_empty_queue(vs) && vs->update_requested) {
- int enc = vs->upqueue.queue_end->enc;
- dequeue_framebuffer_update(vs);
- switch (enc) {
- case 0x574D5669:
- pixel_format_message(vs);
- break;
- default:
- break;
- }
- vs->update_requested--;
- }
- if (!vs->update_requested) return;
-
- now = qemu_get_clock(rt_clock);
-
- if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
- width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
- else
- width_mask = ~(0ULL);
-
- /* Walk through the dirty map and eliminate tiles that really
- aren't dirty */
- row = vs->ds->data;
- old_row = vs->old_data;
-
- for (y = 0; y < vs->ds->height; y++) {
- if (vs->dirty_row[y] & width_mask) {
- int x;
- uint8_t *ptr, *old_ptr;
-
- ptr = row;
- old_ptr = old_row;
-
- for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
- if (vs->dirty_row[y] & (1ULL << x)) {
- if (memcmp(old_ptr, ptr, tile_bytes)) {
- vs->has_update = 1;
- vs->update_row[y] |= (1ULL << x);
- memcpy(old_ptr, ptr, tile_bytes);
- }
- vs->dirty_row[y] &= ~(1ULL << x);
- }
-
- ptr += tile_bytes;
- old_ptr += tile_bytes;
- }
- }
-
- row += vs->ds->linesize;
- old_row += vs->ds->linesize;
- }
-
- if (!vs->has_update || vs->visible_y >= vs->ds->height ||
- vs->visible_x >= vs->ds->width)
- goto backoff;
-
- /* Count rectangles */
- n_rectangles = 0;
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- saved_offset = vs->output.offset;
- vnc_write_u16(vs, 0);
-
- maxy = vs->visible_y + vs->visible_h;
- if (maxy > vs->ds->height)
- maxy = vs->ds->height;
- maxx = vs->visible_x + vs->visible_w;
- if (maxx > vs->ds->width)
- maxx = vs->ds->width;
-
- for (y = vs->visible_y; y < maxy; y++) {
- int x;
- int last_x = -1;
- for (x = X2DP_DOWN(vs, vs->visible_x);
- x < X2DP_UP(vs, maxx); x++) {
- if (vs->update_row[y] & (1ULL << x)) {
- if (last_x == -1)
- last_x = x;
- vs->update_row[y] &= ~(1ULL << x);
- } else {
- if (last_x != -1) {
- int h = find_update_height(vs, y, maxy, last_x, x);
- if (h != 0) {
- send_framebuffer_update(vs, DP2X(vs, last_x), y,
- DP2X(vs, (x - last_x)), h);
- n_rectangles++;
- }
- }
- last_x = -1;
- }
- }
- if (last_x != -1) {
- int h = find_update_height(vs, y, maxy, last_x, x);
- if (h != 0) {
- send_framebuffer_update(vs, DP2X(vs, last_x), y,
- DP2X(vs, (x - last_x)), h);
- n_rectangles++;
- }
- }
- }
- vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
- vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-
- if (n_rectangles == 0) {
- vs->output.offset = saved_offset - 2;
- goto backoff;
- } else
- vs->update_requested--;
-
- vs->has_update = 0;
- vnc_flush(vs);
- vs->last_update_time = now;
- vs->ds->idle = 0;
-
- vs->timer_interval /= 2;
- if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE)
- vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-
- return;
-
- backoff:
- /* No update -> back off a bit */
- vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
- if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
- vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
- if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
- if (!vs->update_requested) {
- vs->ds->idle = 1;
- } else {
- /* Send a null update. If the client is no longer
- interested (e.g. minimised) it'll ignore this, and we
- can stop scanning the buffer until it sends another
- update request. */
- /* It turns out that there's a bug in realvncviewer 4.1.2
- which means that if you send a proper null update (with
- no update rectangles), it gets a bit out of sync and
- never sends any further requests, regardless of whether
- it needs one or not. Fix this by sending a single 1x1
- update rectangle instead. */
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- send_framebuffer_update(vs, 0, 0, 1, 1);
- vnc_flush(vs);
- vs->last_update_time = now;
- vs->update_requested--;
- return;
- }
- }
- }
- qemu_mod_timer(vs->timer, now + vs->timer_interval);
- return;
-}
-
-static void vnc_update_client(void *opaque)
-{
- VncState *vs = opaque;
-
- vs->ds->dpy_refresh(vs->ds);
- _vnc_update_client(vs);
-}
-
-static void vnc_timer_init(VncState *vs)
-{
- if (vs->timer == NULL) {
- vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
- vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- }
-}
-
-static void vnc_dpy_refresh(DisplayState *ds)
-{
- vga_hw_update();
-}
-
-static int vnc_listen_poll(void *opaque)
-{
- VncState *vs = opaque;
- if (vs->csock == -1)
- return 1;
- return 0;
-}
-
-static void buffer_reserve(Buffer *buffer, size_t len)
-{
- if ((buffer->capacity - buffer->offset) < len) {
- buffer->capacity += (len + 1024);
- buffer->buffer = realloc(buffer->buffer, buffer->capacity);
- if (buffer->buffer == NULL) {
- fprintf(stderr, "vnc: out of memory\n");
- exit(1);
- }
- }
-}
-
-static int buffer_empty(Buffer *buffer)
-{
- return buffer->offset == 0;
-}
-
-static uint8_t *buffer_end(Buffer *buffer)
-{
- return buffer->buffer + buffer->offset;
-}
-
-static void buffer_reset(Buffer *buffer)
-{
- buffer->offset = 0;
-}
-
-static void buffer_append(Buffer *buffer, const void *data, size_t len)
-{
- memcpy(buffer->buffer + buffer->offset, data, len);
- buffer->offset += len;
-}
-
-static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h,
- int32_t encoding)
-{
- Queue *q = &vs->upqueue;
- if (q->queue_end != NULL) {
- if (q->queue_end != q->queue_start || q->start_count != q->end_count) {
- if (q->queue_end->next == NULL) {
- q->queue_end->next = (QueueItem *) qemu_mallocz (sizeof(QueueItem) * QUEUE_ALLOC_UNIT);
- q->end_count = QUEUE_ALLOC_UNIT;
- }
- q->queue_end = q->queue_end->next;
- }
- } else {
- q->queue_end = (QueueItem *) qemu_mallocz (sizeof(QueueItem) * QUEUE_ALLOC_UNIT);
- q->queue_start = q->queue_end;
- q->start_count = QUEUE_ALLOC_UNIT;
- q->end_count = QUEUE_ALLOC_UNIT;
- }
- q->end_count--;
-
- q->queue_end->x = x;
- q->queue_end->y = y;
- q->queue_end->w = w;
- q->queue_end->h = h;
- q->queue_end->enc = encoding;
- q->queue_end->next = (q->end_count > 0) ? (q->queue_end + 1) : NULL;
-}
-
-static void dequeue_framebuffer_update(VncState *vs)
-{
- Queue *q = &vs->upqueue;
- if (q->queue_start == NULL ||
- (q->queue_end == q->queue_start && q->start_count == q->end_count))
- return;
-
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, q->queue_start->x, q->queue_start->y,
- q->queue_start->w, q->queue_start->h, q->queue_start->enc);
-
- q->start_count--;
- if (q->queue_end != q->queue_start) {
- if (!q->start_count) {
- QueueItem *i = q->queue_start;
- q->queue_start = q->queue_start->next;
- q->start_count = QUEUE_ALLOC_UNIT;
- free (i - QUEUE_ALLOC_UNIT + 1);
- } else
- q->queue_start = q->queue_start->next;
- } else {
- q->queue_end = q->queue_end - QUEUE_ALLOC_UNIT + q->end_count + 1;
- q->queue_start = q->queue_end;
- q->end_count = QUEUE_ALLOC_UNIT;
- q->start_count = QUEUE_ALLOC_UNIT;
- }
-}
-
-static int is_empty_queue(VncState *vs)
-{
- Queue *q = &vs->upqueue;
- if (q->queue_end == NULL) return 1;
- if (q->queue_end == q->queue_start && q->start_count == q->end_count) return 1;
- return 0;
-}
-
-static void free_queue(VncState *vs)
-{
- Queue *q = &vs->upqueue;
- while (q->queue_start != NULL) {
- QueueItem *i;
- q->queue_start = q->queue_start + q->start_count - 1;
- i = q->queue_start;
- q->queue_start = q->queue_start->next;
- free(i - QUEUE_ALLOC_UNIT + 1);
- q->start_count = QUEUE_ALLOC_UNIT;
- }
- q->queue_end = NULL;
- q->start_count = 0;
- q->end_count = 0;
-}
-
-static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
-{
- if (ret == 0 || ret == -1) {
- if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN))
- return 0;
-
- VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
- qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
- closesocket(vs->csock);
- vs->csock = -1;
- vs->ds->idle = 1;
- buffer_reset(&vs->input);
- buffer_reset(&vs->output);
- free_queue(vs);
- vs->update_requested = 0;
-#if CONFIG_VNC_TLS
- if (vs->tls_session) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- }
- vs->wiremode = VNC_WIREMODE_CLEAR;
-#endif /* CONFIG_VNC_TLS */
- return 0;
- }
- return ret;
-}
-
-static void vnc_client_error(VncState *vs)
-{
- vnc_client_io_error(vs, -1, EINVAL);
-}
-
-static void vnc_client_write(void *opaque)
-{
- long ret;
- VncState *vs = opaque;
-
-#if CONFIG_VNC_TLS
- if (vs->tls_session) {
- ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
- if (ret < 0) {
- if (ret == GNUTLS_E_AGAIN)
- errno = EAGAIN;
- else
- errno = EIO;
- ret = -1;
- }
- } else
-#endif /* CONFIG_VNC_TLS */
- ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
- ret = vnc_client_io_error(vs, ret, socket_error());
- if (!ret)
- return;
-
- memmove(vs->output.buffer, vs->output.buffer + ret,
- vs->output.offset - ret);
- vs->output.offset -= ret;
-
- if (vs->output.offset == 0)
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
-}
-
-static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-{
- vs->read_handler = func;
- vs->read_handler_expect = expecting;
-}
-
-static void vnc_client_read(void *opaque)
-{
- VncState *vs = opaque;
- long ret;
-
- buffer_reserve(&vs->input, 4096);
-
-#if CONFIG_VNC_TLS
- if (vs->tls_session) {
- ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
- if (ret < 0) {
- if (ret == GNUTLS_E_AGAIN)
- errno = EAGAIN;
- else
- errno = EIO;
- ret = -1;
- }
- } else
-#endif /* CONFIG_VNC_TLS */
- ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
- ret = vnc_client_io_error(vs, ret, socket_error());
- if (!ret)
- return;
-
- vs->input.offset += ret;
-
- while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
- size_t len = vs->read_handler_expect;
- int ret;
-
- ret = vs->read_handler(vs, vs->input.buffer, len);
- if (vs->csock == -1)
- return;
-
- if (!ret) {
- memmove(vs->input.buffer, vs->input.buffer + len,
- vs->input.offset - len);
- vs->input.offset -= len;
- } else {
- assert(ret > vs->read_handler_expect);
- vs->read_handler_expect = ret;
- }
- }
-}
-
-static void vnc_write(VncState *vs, const void *data, size_t len)
-{
- buffer_reserve(&vs->output, len);
-
- if (buffer_empty(&vs->output))
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read,
- vnc_client_write, vs);
-
- buffer_append(&vs->output, data, len);
-}
-
-static void vnc_write_s32(VncState *vs, int32_t value)
-{
- vnc_write_u32(vs, *(uint32_t *)&value);
-}
-
-static void vnc_write_u32(VncState *vs, uint32_t value)
-{
- uint8_t buf[4];
-
- buf[0] = (value >> 24) & 0xFF;
- buf[1] = (value >> 16) & 0xFF;
- buf[2] = (value >> 8) & 0xFF;
- buf[3] = value & 0xFF;
-
- vnc_write(vs, buf, 4);
-}
-
-static void vnc_write_u16(VncState *vs, uint16_t value)
-{
- uint8_t buf[2];
-
- buf[0] = (value >> 8) & 0xFF;
- buf[1] = value & 0xFF;
-
- vnc_write(vs, buf, 2);
-}
-
-static void vnc_write_u8(VncState *vs, uint8_t value)
-{
- vnc_write(vs, &value, 1);
-}
-
-static void vnc_flush(VncState *vs)
-{
- if (vs->output.offset)
- vnc_client_write(vs);
-}
-
-static uint8_t read_u8(uint8_t *data, size_t offset)
-{
- return data[offset];
-}
-
-static uint16_t read_u16(uint8_t *data, size_t offset)
-{
- return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
-}
-
-static int32_t read_s32(uint8_t *data, size_t offset)
-{
- return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
- (data[offset + 2] << 8) | data[offset + 3]);
-}
-
-static uint32_t read_u32(uint8_t *data, size_t offset)
-{
- return ((data[offset] << 24) | (data[offset + 1] << 16) |
- (data[offset + 2] << 8) | data[offset + 3]);
-}
-
-#if CONFIG_VNC_TLS
-ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
- const void *data,
- size_t len) {
- struct VncState *vs = (struct VncState *)transport;
- int ret;
-
- retry:
- ret = send(vs->csock, data, len, 0);
- if (ret < 0) {
- if (errno == EINTR)
- goto retry;
- return -1;
- }
- return ret;
-}
-
-
-ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
- void *data,
- size_t len) {
- struct VncState *vs = (struct VncState *)transport;
- int ret;
-
- retry:
- ret = recv(vs->csock, data, len, 0);
- if (ret < 0) {
- if (errno == EINTR)
- goto retry;
- return -1;
- }
- return ret;
-}
-#endif /* CONFIG_VNC_TLS */
-
-static void client_cut_text(VncState *vs, size_t len, char *text)
-{
-}
-
-static void check_pointer_type_change(VncState *vs, int absolute)
-{
- if (vs->has_pointer_type_change && vs->absolute != absolute) {
- if (vs->update_requested) {
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, absolute, 0,
- vs->ds->width, vs->ds->height, -257);
- vnc_flush(vs);
- vs->update_requested--;
- } else {
- enqueue_framebuffer_update(vs, absolute, 0,
- vs->ds->width, vs->ds->height, -257);
- }
- }
- vs->absolute = absolute;
-}
-
-static void pointer_event(VncState *vs, int button_mask, int x, int y)
-{
- int buttons = 0;
- int dz = 0;
-
- if (button_mask & 0x01)
- buttons |= MOUSE_EVENT_LBUTTON;
- if (button_mask & 0x02)
- buttons |= MOUSE_EVENT_MBUTTON;
- if (button_mask & 0x04)
- buttons |= MOUSE_EVENT_RBUTTON;
- if (button_mask & 0x08)
- dz = -1;
- if (button_mask & 0x10)
- dz = 1;
-
- if (vs->absolute) {
- kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
- y * 0x7FFF / (vs->ds->height - 1),
- dz, buttons);
- } else if (vs->has_pointer_type_change) {
- x -= 0x7FFF;
- y -= 0x7FFF;
-
- kbd_mouse_event(x, y, dz, buttons);
- } else {
- if (vs->last_x != -1)
- kbd_mouse_event(x - vs->last_x,
- y - vs->last_y,
- dz, buttons);
- vs->last_x = x;
- vs->last_y = y;
- }
-
- check_pointer_type_change(vs, kbd_mouse_is_absolute());
-}
-
-static void reset_keys(VncState *vs)
-{
- int i;
- for(i = 0; i < 256; i++) {
- if (vs->modifiers_state[i]) {
- if (i & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(i | 0x80);
- vs->modifiers_state[i] = 0;
- }
- }
-}
-
-static void press_key(VncState *vs, int keysym)
-{
- kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
- kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
-}
-
-static void press_key_shift_down(VncState *vs, int down, int keycode)
-{
- if (down)
- kbd_put_keycode(0x2a & 0x7f);
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down)
- kbd_put_keycode(keycode & 0x7f);
- else
- kbd_put_keycode(keycode | 0x80);
-
- if (!down)
- kbd_put_keycode(0x2a | 0x80);
-}
-
-static void press_key_shift_up(VncState *vs, int down, int keycode)
-{
- if (down) {
- if (vs->modifiers_state[0x2a])
- kbd_put_keycode(0x2a | 0x80);
- if (vs->modifiers_state[0x36])
- kbd_put_keycode(0x36 | 0x80);
- }
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down)
- kbd_put_keycode(keycode & 0x7f);
- else
- kbd_put_keycode(keycode | 0x80);
-
- if (!down) {
- if (vs->modifiers_state[0x2a])
- kbd_put_keycode(0x2a & 0x7f);
- if (vs->modifiers_state[0x36])
- kbd_put_keycode(0x36 & 0x7f);
- }
-}
-
-static void do_key_event(VncState *vs, int down, uint32_t sym)
-{
- int keycode;
- int shift_keys = 0;
- int shift = 0;
- int keypad = 0;
-
- if (is_graphic_console()) {
- if (sym >= 'A' && sym <= 'Z') {
- sym = sym - 'A' + 'a';
- shift = 1;
- }
- else {
- shift = keysymIsShift(vs->kbd_layout, sym & 0xFFFF);
- }
- }
- shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36];
-
- keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
- if (keycode == 0) {
- fprintf(stderr, "Key lost : keysym=0x%x(%d)\n", sym, sym);
- return;
- }
-
- /* QEMU console switch */
- switch(keycode) {
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down) {
- vs->modifiers_state[keycode] = 1;
- kbd_put_keycode(keycode & 0x7f);
- }
- else {
- vs->modifiers_state[keycode] = 0;
- kbd_put_keycode(keycode | 0x80);
- }
- return;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
- if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
- /* Reset the modifiers sent to the current console */
- reset_keys(vs);
- console_select(keycode - 0x02);
- return;
- }
- break;
- case 0x45: /* NumLock */
- if (down) {
- kbd_put_keycode(keycode & 0x7f);
- }
- else {
- vs->modifiers_state[keycode] ^= 1;
- kbd_put_keycode(keycode | 0x80);
- }
- return;
- }
-
- keypad = keycodeIsKeypad(vs->kbd_layout, keycode);
- if (keypad) {
- /* If the numlock state needs to change then simulate an additional
- keypress before sending this one. This will happen if the user
- toggles numlock away from the VNC window.
- */
- if (keysymIsNumlock(vs->kbd_layout, sym & 0xFFFF)) {
- if (!vs->modifiers_state[0x45]) {
- vs->modifiers_state[0x45] = 1;
- press_key(vs, 0xff7f);
- }
- } else {
- if (vs->modifiers_state[0x45]) {
- vs->modifiers_state[0x45] = 0;
- press_key(vs, 0xff7f);
- }
- }
- }
-
- if (is_graphic_console()) {
- /* If the shift state needs to change then simulate an additional
- keypress before sending this one. Ignore for non shiftable keys.
- */
- if (shift && !shift_keys) {
- press_key_shift_down(vs, down, keycode);
- return;
- }
- else if (!shift && shift_keys && !keypad &&
- keycodeIsShiftable(vs->kbd_layout, keycode)) {
- press_key_shift_up(vs, down, keycode);
- return;
- }
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down)
- kbd_put_keycode(keycode & 0x7f);
- else
- kbd_put_keycode(keycode | 0x80);
- } else {
- /* QEMU console emulation */
- if (down) {
- switch (keycode) {
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- break;
- case 0xc8:
- kbd_put_keysym(QEMU_KEY_UP);
- break;
- case 0xd0:
- kbd_put_keysym(QEMU_KEY_DOWN);
- break;
- case 0xcb:
- kbd_put_keysym(QEMU_KEY_LEFT);
- break;
- case 0xcd:
- kbd_put_keysym(QEMU_KEY_RIGHT);
- break;
- case 0xd3:
- kbd_put_keysym(QEMU_KEY_DELETE);
- break;
- case 0xc7:
- kbd_put_keysym(QEMU_KEY_HOME);
- break;
- case 0xcf:
- kbd_put_keysym(QEMU_KEY_END);
- break;
- case 0xc9:
- kbd_put_keysym(QEMU_KEY_PAGEUP);
- break;
- case 0xd1:
- kbd_put_keysym(QEMU_KEY_PAGEDOWN);
- break;
- default:
- kbd_put_keysym(sym);
- break;
- }
- }
- }
-}
-
-static void key_event(VncState *vs, int down, uint32_t sym)
-{
- do_key_event(vs, down, sym);
-}
-
-static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h)
-{
-
- set_bits_in_row(vs, vs->update_row, x, y, w, h);
-
- vs->has_update = 1;
-}
-
-static void framebuffer_update_request(VncState *vs, int incremental,
- int x_position, int y_position,
- int w, int h)
-{
- if (!incremental)
- framebuffer_set_updated(vs, x_position, y_position, w, h);
- vs->visible_x = x_position;
- vs->visible_y = y_position;
- vs->visible_w = w;
- vs->visible_h = h;
-
- vs->update_requested++;
- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
-}
-
-static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
-{
- int i;
-
- vs->has_hextile = 0;
- vs->has_resize = 0;
- vs->has_pointer_type_change = 0;
- vs->has_WMVi = 0;
- vs->absolute = -1;
- vs->ds->dpy_copy = NULL;
-
- for (i = n_encodings - 1; i >= 0; i--) {
- switch (encodings[i]) {
- case 0: /* Raw */
- vs->has_hextile = 0;
- break;
- case 1: /* CopyRect */
- vs->ds->dpy_copy = vnc_copy;
- break;
- case 5: /* Hextile */
- vs->has_hextile = 1;
- break;
- case -223: /* DesktopResize */
- vs->has_resize = 1;
- break;
- case -257:
- vs->has_pointer_type_change = 1;
- break;
- case 0x574D5669:
- vs->has_WMVi = 1;
- default:
- break;
- }
- }
-
- check_pointer_type_change(vs, kbd_mouse_is_absolute());
-}
-
-static void set_pixel_format(VncState *vs,
- int bits_per_pixel, int depth,
- int big_endian_flag, int true_color_flag,
- int red_max, int green_max, int blue_max,
- int red_shift, int green_shift, int blue_shift)
-{
- int host_big_endian_flag;
-
-#ifdef WORDS_BIGENDIAN
- host_big_endian_flag = 1;
-#else
- host_big_endian_flag = 0;
-#endif
- if (!true_color_flag) {
- fail:
- vnc_client_error(vs);
- return;
- }
- if (bits_per_pixel == 32 &&
- bits_per_pixel == vs->depth * 8 &&
- host_big_endian_flag == big_endian_flag &&
- red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
- red_shift == 16 && green_shift == 8 && blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_32;
- } else
- if (bits_per_pixel == 16 &&
- bits_per_pixel == vs->depth * 8 &&
- host_big_endian_flag == big_endian_flag &&
- red_max == 31 && green_max == 63 && blue_max == 31 &&
- red_shift == 11 && green_shift == 5 && blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_16;
- } else
- if (bits_per_pixel == 8 &&
- bits_per_pixel == vs->depth * 8 &&
- red_max == 7 && green_max == 7 && blue_max == 3 &&
- red_shift == 5 && green_shift == 2 && blue_shift == 0) {
- vs->depth = 1;
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_8;
- } else
- {
- /* generic and slower case */
- if (bits_per_pixel != 8 &&
- bits_per_pixel != 16 &&
- bits_per_pixel != 32)
- goto fail;
- if (vs->depth == 4) {
- vs->send_hextile_tile = send_hextile_tile_generic_32;
- } else if (vs->depth == 2) {
- vs->send_hextile_tile = send_hextile_tile_generic_16;
- } else {
- vs->send_hextile_tile = send_hextile_tile_generic_8;
- }
-
- vs->pix_big_endian = big_endian_flag;
- vs->write_pixels = vnc_write_pixels_generic;
- }
-
- vs->red_shift = red_shift;
- vs->red_max = red_max;
- vs->green_shift = green_shift;
- vs->green_max = green_max;
- vs->blue_shift = blue_shift;
- vs->blue_max = blue_max;
- vs->pix_bpp = bits_per_pixel / 8;
-}
-
-static void pixel_format_message (VncState *vs) {
- char pad[3] = { 0, 0, 0 };
-
- vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
- if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */
- else vnc_write_u8(vs, vs->depth * 8); /* depth */
-
-#ifdef WORDS_BIGENDIAN
- vnc_write_u8(vs, 1); /* big-endian-flag */
-#else
- vnc_write_u8(vs, 0); /* big-endian-flag */
-#endif
- vnc_write_u8(vs, 1); /* true-color-flag */
- if (vs->depth == 4) {
- vnc_write_u16(vs, 0xFF); /* red-max */
- vnc_write_u16(vs, 0xFF); /* green-max */
- vnc_write_u16(vs, 0xFF); /* blue-max */
- vnc_write_u8(vs, 16); /* red-shift */
- vnc_write_u8(vs, 8); /* green-shift */
- vnc_write_u8(vs, 0); /* blue-shift */
- vs->send_hextile_tile = send_hextile_tile_32;
- } else if (vs->depth == 2) {
- vnc_write_u16(vs, 31); /* red-max */
- vnc_write_u16(vs, 63); /* green-max */
- vnc_write_u16(vs, 31); /* blue-max */
- vnc_write_u8(vs, 11); /* red-shift */
- vnc_write_u8(vs, 5); /* green-shift */
- vnc_write_u8(vs, 0); /* blue-shift */
- vs->send_hextile_tile = send_hextile_tile_16;
- } else if (vs->depth == 1) {
- /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
- vnc_write_u16(vs, 7); /* red-max */
- vnc_write_u16(vs, 7); /* green-max */
- vnc_write_u16(vs, 3); /* blue-max */
- vnc_write_u8(vs, 5); /* red-shift */
- vnc_write_u8(vs, 2); /* green-shift */
- vnc_write_u8(vs, 0); /* blue-shift */
- vs->send_hextile_tile = send_hextile_tile_8;
- }
- vs->red_max = vs->red_max1;
- vs->green_max = vs->green_max1;
- vs->blue_max = vs->blue_max1;
- vs->red_shift = vs->red_shift1;
- vs->green_shift = vs->green_shift1;
- vs->blue_shift = vs->blue_shift1;
- vs->pix_bpp = vs->depth * 8;
- vs->write_pixels = vnc_write_pixels_copy;
-
- vnc_write(vs, pad, 3); /* padding */
-}
-
-static void vnc_dpy_setdata(DisplayState *ds, void *pixels)
-{
- ds->data = pixels;
-}
-
-static void vnc_colourdepth(DisplayState *ds, int depth)
-{
- int host_big_endian_flag;
- struct VncState *vs = ds->opaque;
-
- switch (depth) {
- case 24:
- ds->shared_buf = 0;
- if (ds->depth == 32) return;
- depth = 32;
- break;
- case 8:
- case 0:
- ds->shared_buf = 0;
- return;
- default:
- ds->shared_buf = 1;
- break;
- }
-
-#ifdef WORDS_BIGENDIAN
- host_big_endian_flag = 1;
-#else
- host_big_endian_flag = 0;
-#endif
-
- switch (depth) {
- case 8:
- vs->depth = depth / 8;
- vs->red_max1 = 7;
- vs->green_max1 = 7;
- vs->blue_max1 = 3;
- vs->red_shift1 = 5;
- vs->green_shift1 = 2;
- vs->blue_shift1 = 0;
- break;
- case 16:
- vs->depth = depth / 8;
- vs->red_max1 = 31;
- vs->green_max1 = 63;
- vs->blue_max1 = 31;
- vs->red_shift1 = 11;
- vs->green_shift1 = 5;
- vs->blue_shift1 = 0;
- break;
- case 32:
- vs->depth = 4;
- vs->red_max1 = 255;
- vs->green_max1 = 255;
- vs->blue_max1 = 255;
- vs->red_shift1 = 16;
- vs->green_shift1 = 8;
- vs->blue_shift1 = 0;
- break;
- default:
- return;
- }
- if (vs->switchbpp) {
- vnc_client_error(vs);
- } else if (vs->csock != -1 && vs->has_WMVi) {
- /* Sending a WMVi message to notify the client*/
- if (vs->update_requested) {
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
- pixel_format_message(vs);
- vnc_flush(vs);
- vs->update_requested--;
- } else {
- enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
- }
- } else {
- if (vs->pix_bpp == 4 && vs->depth == 4 &&
- host_big_endian_flag == vs->pix_big_endian &&
- vs->red_max == 0xff && vs->green_max == 0xff && vs->blue_max == 0xff &&
- vs->red_shift == 16 && vs->green_shift == 8 && vs->blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_32;
- } else if (vs->pix_bpp == 2 && vs->depth == 2 &&
- host_big_endian_flag == vs->pix_big_endian &&
- vs->red_max == 31 && vs->green_max == 63 && vs->blue_max == 31 &&
- vs->red_shift == 11 && vs->green_shift == 5 && vs->blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_16;
- } else if (vs->pix_bpp == 1 && vs->depth == 1 &&
- host_big_endian_flag == vs->pix_big_endian &&
- vs->red_max == 7 && vs->green_max == 7 && vs->blue_max == 3 &&
- vs->red_shift == 5 && vs->green_shift == 2 && vs->blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_8;
- } else {
- if (vs->depth == 4) {
- vs->send_hextile_tile = send_hextile_tile_generic_32;
- } else if (vs->depth == 2) {
- vs->send_hextile_tile = send_hextile_tile_generic_16;
- } else {
- vs->send_hextile_tile = send_hextile_tile_generic_8;
- }
- vs->write_pixels = vnc_write_pixels_generic;
- }
- }
-}
-
-static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
-{
- int i;
- uint16_t limit;
-
- switch (data[0]) {
- case 0:
- if (len == 1)
- return 20;
-
- set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
- read_u8(data, 6), read_u8(data, 7),
- read_u16(data, 8), read_u16(data, 10),
- read_u16(data, 12), read_u8(data, 14),
- read_u8(data, 15), read_u8(data, 16));
- break;
- case 2:
- if (len == 1)
- return 4;
-
- if (len == 4) {
- uint16_t v;
- v = read_u16(data, 2);
- if (v)
- return 4 + v * 4;
- }
-
- limit = read_u16(data, 2);
- for (i = 0; i < limit; i++) {
- int32_t val = read_s32(data, 4 + (i * 4));
- memcpy(data + 4 + (i * 4), &val, sizeof(val));
- }
-
- set_encodings(vs, (int32_t *)(data + 4), limit);
- break;
- case 3:
- if (len == 1)
- return 10;
-
- framebuffer_update_request(vs,
- read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
- read_u16(data, 6), read_u16(data, 8));
- break;
- case 4:
- if (len == 1)
- return 8;
-
- vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- qemu_advance_timer(vs->timer,
- qemu_get_clock(rt_clock) + vs->timer_interval);
- key_event(vs, read_u8(data, 1), read_u32(data, 4));
- break;
- case 5:
- if (len == 1)
- return 6;
-
- vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- qemu_advance_timer(vs->timer,
- qemu_get_clock(rt_clock) + vs->timer_interval);
- pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
- break;
- case 6:
- if (len == 1)
- return 8;
-
- if (len == 8) {
- uint32_t v;
- v = read_u32(data, 4);
- if (v)
- return 8 + v;
- }
-
- client_cut_text(vs, read_u32(data, 4), (char *)(data + 8));
- break;
- default:
- printf("Msg: %d\n", data[0]);
- vnc_client_error(vs);
- break;
- }
-
- vnc_read_when(vs, protocol_client_msg, 1);
- return 0;
-}
-
-static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
-{
- size_t l;
-
- vga_hw_update();
-
- vs->width = vs->ds->width;
- vs->height = vs->ds->height;
- vnc_write_u16(vs, vs->ds->width);
- vnc_write_u16(vs, vs->ds->height);
-
- pixel_format_message(vs);
-
- l = strlen(domain_name);
- vnc_write_u32(vs, l);
- vnc_write(vs, domain_name, l);
-
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_msg, 1);
-
- return 0;
-}
-
-
-static void make_challenge(VncState *vs)
-{
- int i;
-
- srand(time(NULL)+getpid()+getpid()*987654+rand());
-
- for (i = 0 ; i < sizeof(vs->challenge) ; i++)
- vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-}
-
-static int protocol_client_auth_vnc(VncState *vs, char *data, size_t len)
-{
- char response[VNC_AUTH_CHALLENGE_SIZE];
- int i, j, pwlen;
- char key[8];
-
- if (!vs->password || !vs->password[0]) {
- VNC_DEBUG("No password configured on server");
- vnc_write_u32(vs, 1); /* Reject auth */
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_flush(vs);
- vnc_client_error(vs);
- return 0;
- }
-
- memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
-
- /* Calculate the expected challenge response */
- pwlen = strlen(vs->password);
- for (i=0; i<sizeof(key); i++)
- key[i] = i<pwlen ? vs->password[i] : 0;
- deskey(key, EN0);
- for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
- des(response+j, response+j);
-
- /* Compare expected vs actual challenge response */
- if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
- VNC_DEBUG("Client challenge reponse did not match\n");
- vnc_write_u32(vs, 1); /* Reject auth */
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Accepting VNC challenge response\n");
- vnc_write_u32(vs, 0); /* Accept auth */
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_init, 1);
- }
- return 0;
-}
-
-static int start_auth_vnc(VncState *vs)
-{
- make_challenge(vs);
- /* Send client a 'random' challenge */
- vnc_write(vs, vs->challenge, sizeof(vs->challenge));
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
- return 0;
-}
-
-
-#if CONFIG_VNC_TLS
-#define DH_BITS 1024
-static gnutls_dh_params_t dh_params;
-
-static int vnc_tls_initialize(void)
-{
- static int tlsinitialized = 0;
-
- if (tlsinitialized)
- return 1;
-
- if (gnutls_global_init () < 0)
- return 0;
-
- /* XXX ought to re-generate diffie-hellmen params periodically */
- if (gnutls_dh_params_init (&dh_params) < 0)
- return 0;
- if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
- return 0;
-
-#if _VNC_DEBUG == 2
- gnutls_global_set_log_level(10);
- gnutls_global_set_log_function(vnc_debug_gnutls_log);
-#endif
-
- tlsinitialized = 1;
-
- return 1;
-}
-
-static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
-{
- gnutls_anon_server_credentials anon_cred;
- int ret;
-
- if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
- VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
- return NULL;
- }
-
- gnutls_anon_set_server_dh_params(anon_cred, dh_params);
-
- return anon_cred;
-}
-
-
-static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
-{
- gnutls_certificate_credentials_t x509_cred;
- int ret;
-
- if (!vs->x509cacert) {
- VNC_DEBUG("No CA x509 certificate specified\n");
- return NULL;
- }
- if (!vs->x509cert) {
- VNC_DEBUG("No server x509 certificate specified\n");
- return NULL;
- }
- if (!vs->x509key) {
- VNC_DEBUG("No server private key specified\n");
- return NULL;
- }
-
- if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
- VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
- return NULL;
- }
- if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
- vs->x509cacert,
- GNUTLS_X509_FMT_PEM)) < 0) {
- VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
- gnutls_certificate_free_credentials(x509_cred);
- return NULL;
- }
-
- if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
- vs->x509cert,
- vs->x509key,
- GNUTLS_X509_FMT_PEM)) < 0) {
- VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
- gnutls_certificate_free_credentials(x509_cred);
- return NULL;
- }
-
- if (vs->x509cacrl) {
- if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
- vs->x509cacrl,
- GNUTLS_X509_FMT_PEM)) < 0) {
- VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
- gnutls_certificate_free_credentials(x509_cred);
- return NULL;
- }
- }
-
- gnutls_certificate_set_dh_params (x509_cred, dh_params);
-
- return x509_cred;
-}
-
-static int vnc_validate_certificate(struct VncState *vs)
-{
- int ret;
- unsigned int status;
- const gnutls_datum_t *certs;
- unsigned int nCerts, i;
- time_t now;
-
- VNC_DEBUG("Validating client certificate\n");
- if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
- VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
- return -1;
- }
-
- if ((now = time(NULL)) == ((time_t)-1)) {
- return -1;
- }
-
- if (status != 0) {
- if (status & GNUTLS_CERT_INVALID)
- VNC_DEBUG("The certificate is not trusted.\n");
-
- if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
- VNC_DEBUG("The certificate hasn't got a known issuer.\n");
-
- if (status & GNUTLS_CERT_REVOKED)
- VNC_DEBUG("The certificate has been revoked.\n");
-
- if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
- VNC_DEBUG("The certificate uses an insecure algorithm\n");
-
- return -1;
- } else {
- VNC_DEBUG("Certificate is valid!\n");
- }
-
- /* Only support x509 for now */
- if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
- return -1;
-
- if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
- return -1;
-
- for (i = 0 ; i < nCerts ; i++) {
- gnutls_x509_crt_t cert;
- VNC_DEBUG ("Checking certificate chain %d\n", i);
- if (gnutls_x509_crt_init (&cert) < 0)
- return -1;
-
- if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- if (gnutls_x509_crt_get_expiration_time (cert) < now) {
- VNC_DEBUG("The certificate has expired\n");
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- if (gnutls_x509_crt_get_activation_time (cert) > now) {
- VNC_DEBUG("The certificate is not yet activated\n");
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- if (gnutls_x509_crt_get_activation_time (cert) > now) {
- VNC_DEBUG("The certificate is not yet activated\n");
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- gnutls_x509_crt_deinit (cert);
- }
-
- return 0;
-}
-
-
-static int start_auth_vencrypt_subauth(VncState *vs)
-{
- switch (vs->subauth) {
- case VNC_AUTH_VENCRYPT_TLSNONE:
- case VNC_AUTH_VENCRYPT_X509NONE:
- VNC_DEBUG("Accept TLS auth none\n");
- vnc_write_u32(vs, 0); /* Accept auth completion */
- vnc_read_when(vs, protocol_client_init, 1);
- break;
-
- case VNC_AUTH_VENCRYPT_TLSVNC:
- case VNC_AUTH_VENCRYPT_X509VNC:
- VNC_DEBUG("Start TLS auth VNC\n");
- return start_auth_vnc(vs);
-
- default: /* Should not be possible, but just in case */
- VNC_DEBUG("Reject auth %d\n", vs->auth);
- vnc_write_u8(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Unsupported authentication type";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- }
-
- return 0;
-}
-
-static void vnc_handshake_io(void *opaque);
-
-static int vnc_continue_handshake(struct VncState *vs) {
- int ret;
-
- if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
- if (!gnutls_error_is_fatal(ret)) {
- VNC_DEBUG("Handshake interrupted (blocking)\n");
- if (!gnutls_record_get_direction(vs->tls_session))
- qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
- else
- qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
- return 0;
- }
- VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
- vnc_client_error(vs);
- return -1;
- }
-
- if (vs->x509verify) {
- if (vnc_validate_certificate(vs) < 0) {
- VNC_DEBUG("Client verification failed\n");
- vnc_client_error(vs);
- return -1;
- } else {
- VNC_DEBUG("Client verification passed\n");
- }
- }
-
- VNC_DEBUG("Handshake done, switching to TLS data mode\n");
- vs->wiremode = VNC_WIREMODE_TLS;
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
-
- return start_auth_vencrypt_subauth(vs);
-}
-
-static void vnc_handshake_io(void *opaque) {
- struct VncState *vs = (struct VncState *)opaque;
-
- VNC_DEBUG("Handshake IO continue\n");
- vnc_continue_handshake(vs);
-}
-
-#define NEED_X509_AUTH(vs) \
- ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
- (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
- (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
-
-
-static int vnc_start_tls(struct VncState *vs) {
- static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
- static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
- static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
- static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
-
- VNC_DEBUG("Do TLS setup\n");
- if (vnc_tls_initialize() < 0) {
- VNC_DEBUG("Failed to init TLS\n");
- vnc_client_error(vs);
- return -1;
- }
- if (vs->tls_session == NULL) {
- if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_set_default_priority(vs->tls_session) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (NEED_X509_AUTH(vs)) {
- gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
- if (!x509_cred) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
- if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- gnutls_certificate_free_credentials(x509_cred);
- vnc_client_error(vs);
- return -1;
- }
- if (vs->x509verify) {
- VNC_DEBUG("Requesting a client certificate\n");
- gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
- }
-
- } else {
- gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
- if (!anon_cred) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
- if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- gnutls_anon_free_server_credentials(anon_cred);
- vnc_client_error(vs);
- return -1;
- }
- }
-
- gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
- gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
- gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
- }
-
- VNC_DEBUG("Start TLS handshake process\n");
- return vnc_continue_handshake(vs);
-}
-
-static int protocol_client_vencrypt_auth(VncState *vs, char *data, size_t len)
-{
- int auth = read_u32(data, 0);
-
- if (auth != vs->subauth) {
- VNC_DEBUG("Rejecting auth %d\n", auth);
- vnc_write_u8(vs, 0); /* Reject auth */
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
- vnc_write_u8(vs, 1); /* Accept auth */
- vnc_flush(vs);
-
- if (vnc_start_tls(vs) < 0) {
- VNC_DEBUG("Failed to complete TLS\n");
- return 0;
- }
-
- if (vs->wiremode == VNC_WIREMODE_TLS) {
- VNC_DEBUG("Starting VeNCrypt subauth\n");
- return start_auth_vencrypt_subauth(vs);
- } else {
- VNC_DEBUG("TLS handshake blocked\n");
- return 0;
- }
- }
- return 0;
-}
-
-static int protocol_client_vencrypt_init(VncState *vs, char *data, size_t len)
-{
- if (data[0] != 0 ||
- data[1] != 2) {
- VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
- vnc_write_u8(vs, 1); /* Reject version */
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
- vnc_write_u8(vs, 0); /* Accept version */
- vnc_write_u8(vs, 1); /* Number of sub-auths */
- vnc_write_u32(vs, vs->subauth); /* The supported auth */
- vnc_flush(vs);
- vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
- }
- return 0;
-}
-
-static int start_auth_vencrypt(VncState *vs)
-{
- /* Send VeNCrypt version 0.2 */
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 2);
-
- vnc_read_when(vs, protocol_client_vencrypt_init, 2);
- return 0;
-}
-#endif /* CONFIG_VNC_TLS */
-
-static int protocol_client_auth(VncState *vs, char *data, size_t len)
-{
- /* We only advertise 1 auth scheme at a time, so client
- * must pick the one we sent. Verify this */
- if (data[0] != vs->auth) { /* Reject auth */
- VNC_DEBUG("Reject auth %d\n", (int)data[0]);
- vnc_write_u32(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- } else { /* Accept requested auth */
- VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
- switch (vs->auth) {
- case VNC_AUTH_NONE:
- VNC_DEBUG("Accept auth none\n");
- if (vs->minor >= 8) {
- vnc_write_u32(vs, 0); /* Accept auth completion */
- vnc_flush(vs);
- }
- vnc_read_when(vs, protocol_client_init, 1);
- break;
-
- case VNC_AUTH_VNC:
- VNC_DEBUG("Start VNC auth\n");
- return start_auth_vnc(vs);
-
-#if CONFIG_VNC_TLS
- case VNC_AUTH_VENCRYPT:
- VNC_DEBUG("Accept VeNCrypt auth\n");;
- return start_auth_vencrypt(vs);
-#endif /* CONFIG_VNC_TLS */
-
- default: /* Should not be possible, but just in case */
- VNC_DEBUG("Reject auth %d\n", vs->auth);
- vnc_write_u8(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- }
- }
- return 0;
-}
-
-static int protocol_version(VncState *vs, char *version, size_t len)
-{
- char local[13];
-
- memcpy(local, version, 12);
- local[12] = 0;
-
- if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
- VNC_DEBUG("Malformed protocol version %s\n", local);
- vnc_client_error(vs);
- return 0;
- }
- VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
- if (vs->major != 3 ||
- (vs->minor != 3 &&
- vs->minor != 4 &&
- vs->minor != 5 &&
- vs->minor != 7 &&
- vs->minor != 8)) {
- VNC_DEBUG("Unsupported client version\n");
- vnc_write_u32(vs, VNC_AUTH_INVALID);
- vnc_flush(vs);
- vnc_client_error(vs);
- return 0;
- }
- /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
- * as equivalent to v3.3 by servers
- */
- if (vs->minor == 4 || vs->minor == 5)
- vs->minor = 3;
-
- if (vs->minor == 3) {
- if (vs->auth == VNC_AUTH_NONE) {
- VNC_DEBUG("Tell client auth none\n");
- vnc_write_u32(vs, vs->auth);
- vnc_flush(vs);
- vnc_read_when(vs, protocol_client_init, 1);
- } else if (vs->auth == VNC_AUTH_VNC) {
- VNC_DEBUG("Tell client VNC auth\n");
- vnc_write_u32(vs, vs->auth);
- vnc_flush(vs);
- start_auth_vnc(vs);
- } else {
- VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
- vnc_write_u32(vs, VNC_AUTH_INVALID);
- vnc_flush(vs);
- vnc_client_error(vs);
- }
- } else {
- VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
- vnc_write_u8(vs, 1); /* num auth */
- vnc_write_u8(vs, vs->auth);
- vnc_read_when(vs, protocol_client_auth, 1);
- vnc_flush(vs);
- }
-
- return 0;
-}
-
-static void vnc_listen_read(void *opaque)
-{
- VncState *vs = opaque;
- struct sockaddr_in addr;
- socklen_t addrlen = sizeof(addr);
-
- vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
- if (vs->csock != -1) {
- VNC_DEBUG("New client on socket %d\n", vs->csock);
- vs->ds->idle = 0;
- socket_set_nonblock(vs->csock);
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
- vnc_write(vs, "RFB 003.008\n", 12);
- vnc_flush(vs);
- vnc_read_when(vs, protocol_version, 12);
- framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height);
- vs->has_resize = 0;
- vs->has_hextile = 0;
- vs->update_requested = 0;
- vs->ds->dpy_copy = NULL;
- vnc_timer_init(vs);
- }
-}
-
-extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
-
-void vnc_display_init(DisplayState *ds)
-{
- VncState *vs;
-
- vs = qemu_mallocz(sizeof(VncState));
- if (!vs)
- exit(1);
-
- ds->opaque = vs;
- ds->idle = 1;
- vnc_state = vs;
- vs->display = NULL;
- vs->password = NULL;
-
- vs->lsock = -1;
- vs->csock = -1;
- vs->last_x = -1;
- vs->last_y = -1;
-
- vs->ds = ds;
-
- if (!keyboard_layout)
- keyboard_layout = "en-us";
-
- vs->kbd_layout = init_keyboard_layout(keyboard_layout);
- if (!vs->kbd_layout)
- exit(1);
- vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
-
- vs->ds->data = NULL;
- vs->ds->dpy_update = vnc_dpy_update;
- vs->ds->dpy_resize = vnc_dpy_resize;
- vs->ds->dpy_setdata = vnc_dpy_setdata;
- vs->ds->dpy_resize_shared = vnc_dpy_resize_shared;
- vs->ds->dpy_refresh = vnc_dpy_refresh;
-
- vs->ds->width = 640;
- vs->ds->height = 400;
- vs->ds->linesize = 640 * 4;
- vnc_dpy_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL);
-}
-
-#if CONFIG_VNC_TLS
-static int vnc_set_x509_credential(VncState *vs,
- const char *certdir,
- const char *filename,
- char **cred,
- int ignoreMissing)
-{
- struct stat sb;
-
- if (*cred) {
- qemu_free(*cred);
- *cred = NULL;
- }
-
- if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
- return -1;
-
- strcpy(*cred, certdir);
- strcat(*cred, "/");
- strcat(*cred, filename);
-
- VNC_DEBUG("Check %s\n", *cred);
- if (stat(*cred, &sb) < 0) {
- qemu_free(*cred);
- *cred = NULL;
- if (ignoreMissing && errno == ENOENT)
- return 0;
- return -1;
- }
-
- return 0;
-}
-
-static int vnc_set_x509_credential_dir(VncState *vs,
- const char *certdir)
-{
- if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
- goto cleanup;
- if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
- goto cleanup;
- if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
- goto cleanup;
- if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
- goto cleanup;
-
- return 0;
-
- cleanup:
- qemu_free(vs->x509cacert);
- qemu_free(vs->x509cacrl);
- qemu_free(vs->x509cert);
- qemu_free(vs->x509key);
- vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
- return -1;
-}
-#endif /* CONFIG_VNC_TLS */
-
-void vnc_display_close(DisplayState *ds)
-{
- VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
-
- if (vs->display) {
- qemu_free(vs->display);
- vs->display = NULL;
- }
- if (vs->lsock != -1) {
- qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
- close(vs->lsock);
- vs->lsock = -1;
- }
- if (vs->csock != -1) {
- qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
- closesocket(vs->csock);
- vs->csock = -1;
- buffer_reset(&vs->input);
- buffer_reset(&vs->output);
- free_queue(vs);
- vs->update_requested = 0;
-#if CONFIG_VNC_TLS
- if (vs->tls_session) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- }
- vs->wiremode = VNC_WIREMODE_CLEAR;
-#endif /* CONFIG_VNC_TLS */
- }
- vs->auth = VNC_AUTH_INVALID;
-#if CONFIG_VNC_TLS
- vs->subauth = VNC_AUTH_INVALID;
- vs->x509verify = 0;
-#endif
-}
-
-int parse_host_port(struct sockaddr_in *saddr, const char *str);
-
-
-
-int vnc_display_password(DisplayState *ds, const char *password)
-{
- VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
-
- if (vs->password) {
- qemu_free(vs->password);
- vs->password = NULL;
- }
- if (password && password[0]) {
- if (!(vs->password = qemu_strdup(password)))
- return -1;
- }
-
- return 0;
-}
-
-int vnc_display_open(DisplayState *ds, const char *display, int find_unused)
-{
- struct sockaddr *addr;
- struct sockaddr_in iaddr;
-#ifndef NO_UNIX_SOCKETS
- struct sockaddr_un uaddr;
-#endif
-#ifndef CONFIG_STUBDOM
- int reuse_addr, ret;
-#endif
- socklen_t addrlen;
- const char *p;
- VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
- const char *options;
- int password = 0;
-#if CONFIG_VNC_TLS
- int tls = 0, x509 = 0;
-#endif
-
- if (display == NULL)
- display = "localhost:0";
-
- vnc_display_close(ds);
- if (strcmp(display, "none") == 0)
- return 0;
-
- if (!(vs->display = strdup(display)))
- return -1;
-
- options = display;
- while ((options = strchr(options, ','))) {
- options++;
- if (strncmp(options, "password", 8) == 0) {
- password = 1; /* Require password auth */
- } else if (strncmp(options, "switchbpp", 9) == 0) {
- vs->switchbpp = 1;
-#if CONFIG_VNC_TLS
- } else if (strncmp(options, "tls", 3) == 0) {
- tls = 1; /* Require TLS */
- } else if (strncmp(options, "x509", 4) == 0) {
- char *start, *end;
- x509 = 1; /* Require x509 certificates */
- if (strncmp(options, "x509verify", 10) == 0)
- vs->x509verify = 1; /* ...and verify client certs */
-
- /* Now check for 'x509=/some/path' postfix
- * and use that to setup x509 certificate/key paths */
- start = strchr(options, '=');
- end = strchr(options, ',');
- if (start && (!end || (start < end))) {
- int len = end ? end-(start+1) : strlen(start+1);
- char *path = qemu_malloc(len+1);
- strncpy(path, start+1, len);
- path[len] = '\0';
- VNC_DEBUG("Trying certificate path '%s'\n", path);
- if (vnc_set_x509_credential_dir(vs, path) < 0) {
- fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
- qemu_free(path);
- qemu_free(vs->display);
- vs->display = NULL;
- return -1;
- }
- qemu_free(path);
- } else {
- fprintf(stderr, "No certificate path provided\n");
- qemu_free(vs->display);
- vs->display = NULL;
- return -1;
- }
-#endif
- }
- }
-
- if (password) {
-#if CONFIG_VNC_TLS
- if (tls) {
- vs->auth = VNC_AUTH_VENCRYPT;
- if (x509) {
- VNC_DEBUG("Initializing VNC server with x509 password auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
- } else {
- VNC_DEBUG("Initializing VNC server with TLS password auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
- }
- } else {
-#endif
- VNC_DEBUG("Initializing VNC server with password auth\n");
- vs->auth = VNC_AUTH_VNC;
-#if CONFIG_VNC_TLS
- vs->subauth = VNC_AUTH_INVALID;
- }
-#endif
- } else {
-#if CONFIG_VNC_TLS
- if (tls) {
- vs->auth = VNC_AUTH_VENCRYPT;
- if (x509) {
- VNC_DEBUG("Initializing VNC server with x509 no auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
- } else {
- VNC_DEBUG("Initializing VNC server with TLS no auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
- }
- } else {
-#endif
- VNC_DEBUG("Initializing VNC server with no auth\n");
- vs->auth = VNC_AUTH_NONE;
-#if CONFIG_VNC_TLS
- vs->subauth = VNC_AUTH_INVALID;
- }
-#endif
- }
-#ifndef NO_UNIX_SOCKETS
- if (strstart(display, "unix:", &p)) {
- addr = (struct sockaddr *)&uaddr;
- addrlen = sizeof(uaddr);
-
- vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (vs->lsock == -1) {
- fprintf(stderr, "Could not create socket\n");
- free(vs->display);
- vs->display = NULL;
- return -1;
- }
-
- uaddr.sun_family = AF_UNIX;
- memset(uaddr.sun_path, 0, 108);
- snprintf(uaddr.sun_path, 108, "%s", p);
-
- unlink(uaddr.sun_path);
- } else
-#endif
- {
- addr = (struct sockaddr *)&iaddr;
- addrlen = sizeof(iaddr);
-
- if (parse_host_port(&iaddr, display) < 0) {
- fprintf(stderr, "Could not parse VNC address\n");
- free(vs->display);
- vs->display = NULL;
- return -1;
- }
-
-#ifdef CONFIG_STUBDOM
- {
- struct ip_addr ipaddr = { iaddr.sin_addr.s_addr };
- struct ip_addr netmask = { 0 };
- struct ip_addr gw = { 0 };
- networking_set_addr(&ipaddr, &netmask, &gw);
- }
-#endif
-
- iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
-
- vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
- if (vs->lsock == -1) {
- fprintf(stderr, "Could not create socket\n");
- free(vs->display);
- vs->display = NULL;
- return -1;
- }
-
-#ifndef CONFIG_STUBDOM
- reuse_addr = 1;
- ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
- (const char *)&reuse_addr, sizeof(reuse_addr));
- if (ret == -1) {
- fprintf(stderr, "setsockopt() failed\n");
- close(vs->lsock);
- vs->lsock = -1;
- free(vs->display);
- vs->display = NULL;
- return -1;
- }
-#endif
- }
-
- while (bind(vs->lsock, addr, addrlen) == -1) {
- if (find_unused && errno == EADDRINUSE) {
- iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 1);
- continue;
- }
- fprintf(stderr, "bind() failed\n");
- close(vs->lsock);
- vs->lsock = -1;
- free(vs->display);
- vs->display = NULL;
- return -1;
- }
-
- if (listen(vs->lsock, 1) == -1) {
- fprintf(stderr, "listen() failed\n");
- close(vs->lsock);
- vs->lsock = -1;
- free(vs->display);
- vs->display = NULL;
- return -1;
- }
-
- if (qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs) < 0)
- return -1;
-
- return ntohs(iaddr.sin_port);
-}
-
-#ifndef CONFIG_STUBDOM
-int vnc_start_viewer(int port)
-{
- int pid, i, open_max;
- char s[16];
-
- sprintf(s, ":%d", port);
-
- switch (pid = fork()) {
- case -1:
- fprintf(stderr, "vncviewer failed fork\n");
- exit(1);
-
- case 0: /* child */
- open_max = sysconf(_SC_OPEN_MAX);
- for (i = 0; i < open_max; i++)
- if (i != STDIN_FILENO &&
- i != STDOUT_FILENO &&
- i != STDERR_FILENO)
- close(i);
- execlp("vncviewer", "vncviewer", s, NULL);
- fprintf(stderr, "vncviewer execlp failed\n");
- exit(1);
-
- default:
- return pid;
- }
-}
-#endif
-
diff --git a/tools/ioemu/vnc_keysym.h b/tools/ioemu/vnc_keysym.h
deleted file mode 100644
index aa0fd9b5f7..0000000000
--- a/tools/ioemu/vnc_keysym.h
+++ /dev/null
@@ -1,386 +0,0 @@
-typedef struct {
- const char* name;
- int keysym;
-} name2keysym_t;
-static name2keysym_t name2keysym[]={
-/* ascii */
- { "space", 0x020},
- { "exclam", 0x021},
- { "quotedbl", 0x022},
- { "numbersign", 0x023},
- { "dollar", 0x024},
- { "percent", 0x025},
- { "ampersand", 0x026},
- { "apostrophe", 0x027},
- { "parenleft", 0x028},
- { "parenright", 0x029},
- { "asterisk", 0x02a},
- { "plus", 0x02b},
- { "comma", 0x02c},
- { "minus", 0x02d},
- { "period", 0x02e},
- { "slash", 0x02f},
- { "0", 0x030},
- { "1", 0x031},
- { "2", 0x032},
- { "3", 0x033},
- { "4", 0x034},
- { "5", 0x035},
- { "6", 0x036},
- { "7", 0x037},
- { "8", 0x038},
- { "9", 0x039},
- { "colon", 0x03a},
- { "semicolon", 0x03b},
- { "less", 0x03c},
- { "equal", 0x03d},
- { "greater", 0x03e},
- { "question", 0x03f},
- { "at", 0x040},
- { "A", 0x041},
- { "B", 0x042},
- { "C", 0x043},
- { "D", 0x044},
- { "E", 0x045},
- { "F", 0x046},
- { "G", 0x047},
- { "H", 0x048},
- { "I", 0x049},
- { "J", 0x04a},
- { "K", 0x04b},
- { "L", 0x04c},
- { "M", 0x04d},
- { "N", 0x04e},
- { "O", 0x04f},
- { "P", 0x050},
- { "Q", 0x051},
- { "R", 0x052},
- { "S", 0x053},
- { "T", 0x054},
- { "U", 0x055},
- { "V", 0x056},
- { "W", 0x057},
- { "X", 0x058},
- { "Y", 0x059},
- { "Z", 0x05a},
- { "bracketleft", 0x05b},
- { "backslash", 0x05c},
- { "bracketright", 0x05d},
- { "asciicircum", 0x05e},
- { "underscore", 0x05f},
- { "grave", 0x060},
- { "a", 0x061},
- { "b", 0x062},
- { "c", 0x063},
- { "d", 0x064},
- { "e", 0x065},
- { "f", 0x066},
- { "g", 0x067},
- { "h", 0x068},
- { "i", 0x069},
- { "j", 0x06a},
- { "k", 0x06b},
- { "l", 0x06c},
- { "m", 0x06d},
- { "n", 0x06e},
- { "o", 0x06f},
- { "p", 0x070},
- { "q", 0x071},
- { "r", 0x072},
- { "s", 0x073},
- { "t", 0x074},
- { "u", 0x075},
- { "v", 0x076},
- { "w", 0x077},
- { "x", 0x078},
- { "y", 0x079},
- { "z", 0x07a},
- { "braceleft", 0x07b},
- { "bar", 0x07c},
- { "braceright", 0x07d},
- { "asciitilde", 0x07e},
-
-/* latin 1 extensions */
-{ "nobreakspace", 0x0a0},
-{ "exclamdown", 0x0a1},
-{ "cent", 0x0a2},
-{ "sterling", 0x0a3},
-{ "currency", 0x0a4},
-{ "yen", 0x0a5},
-{ "brokenbar", 0x0a6},
-{ "section", 0x0a7},
-{ "diaeresis", 0x0a8},
-{ "copyright", 0x0a9},
-{ "ordfeminine", 0x0aa},
-{ "guillemotleft", 0x0ab},
-{ "notsign", 0x0ac},
-{ "hyphen", 0x0ad},
-{ "registered", 0x0ae},
-{ "macron", 0x0af},
-{ "degree", 0x0b0},
-{ "plusminus", 0x0b1},
-{ "twosuperior", 0x0b2},
-{ "threesuperior", 0x0b3},
-{ "acute", 0x0b4},
-{ "mu", 0x0b5},
-{ "paragraph", 0x0b6},
-{ "periodcentered", 0x0b7},
-{ "cedilla", 0x0b8},
-{ "onesuperior", 0x0b9},
-{ "masculine", 0x0ba},
-{ "guillemotright", 0x0bb},
-{ "onequarter", 0x0bc},
-{ "onehalf", 0x0bd},
-{ "threequarters", 0x0be},
-{ "questiondown", 0x0bf},
-{ "Agrave", 0x0c0},
-{ "Aacute", 0x0c1},
-{ "Acircumflex", 0x0c2},
-{ "Atilde", 0x0c3},
-{ "Adiaeresis", 0x0c4},
-{ "Aring", 0x0c5},
-{ "AE", 0x0c6},
-{ "Ccedilla", 0x0c7},
-{ "Egrave", 0x0c8},
-{ "Eacute", 0x0c9},
-{ "Ecircumflex", 0x0ca},
-{ "Ediaeresis", 0x0cb},
-{ "Igrave", 0x0cc},
-{ "Iacute", 0x0cd},
-{ "Icircumflex", 0x0ce},
-{ "Idiaeresis", 0x0cf},
-{ "ETH", 0x0d0},
-{ "Eth", 0x0d0},
-{ "Ntilde", 0x0d1},
-{ "Ograve", 0x0d2},
-{ "Oacute", 0x0d3},
-{ "Ocircumflex", 0x0d4},
-{ "Otilde", 0x0d5},
-{ "Odiaeresis", 0x0d6},
-{ "multiply", 0x0d7},
-{ "Ooblique", 0x0d8},
-{ "Oslash", 0x0d8},
-{ "Ugrave", 0x0d9},
-{ "Uacute", 0x0da},
-{ "Ucircumflex", 0x0db},
-{ "Udiaeresis", 0x0dc},
-{ "Yacute", 0x0dd},
-{ "THORN", 0x0de},
-{ "Thorn", 0x0de},
-{ "ssharp", 0x0df},
-{ "agrave", 0x0e0},
-{ "aacute", 0x0e1},
-{ "acircumflex", 0x0e2},
-{ "atilde", 0x0e3},
-{ "adiaeresis", 0x0e4},
-{ "aring", 0x0e5},
-{ "ae", 0x0e6},
-{ "ccedilla", 0x0e7},
-{ "egrave", 0x0e8},
-{ "eacute", 0x0e9},
-{ "ecircumflex", 0x0ea},
-{ "ediaeresis", 0x0eb},
-{ "igrave", 0x0ec},
-{ "iacute", 0x0ed},
-{ "icircumflex", 0x0ee},
-{ "idiaeresis", 0x0ef},
-{ "eth", 0x0f0},
-{ "ntilde", 0x0f1},
-{ "ograve", 0x0f2},
-{ "oacute", 0x0f3},
-{ "ocircumflex", 0x0f4},
-{ "otilde", 0x0f5},
-{ "odiaeresis", 0x0f6},
-{ "division", 0x0f7},
-{ "oslash", 0x0f8},
-{ "ooblique", 0x0f8},
-{ "ugrave", 0x0f9},
-{ "uacute", 0x0fa},
-{ "ucircumflex", 0x0fb},
-{ "udiaeresis", 0x0fc},
-{ "yacute", 0x0fd},
-{ "thorn", 0x0fe},
-{ "ydiaeresis", 0x0ff},
-{"EuroSign", 0x20ac}, /* XK_EuroSign */
-
-/* latin 2 extensions */
-{ "Aogonek", 0x01a1},
-{ "breve", 0x01a2},
-{ "Lstroke", 0x01a3},
-{ "Lcaron", 0x01a5},
-{ "Sacute", 0x01a6},
-{ "Scaron", 0x01a9},
-{ "Scedilla", 0x01aa},
-{ "Tcaron", 0x01ab},
-{ "Zacute", 0x01ac},
-{ "Zcaron", 0x01ae},
-{ "Zabovedot", 0x01af},
-{ "aogonek", 0x01b1},
-{ "ogonek", 0x01b2},
-{ "lstroke", 0x01b3},
-{ "lcaron", 0x01b5},
-{ "sacute", 0x01b6},
-{ "caron", 0x01b7},
-{ "scaron", 0x01b9},
-{ "scedilla", 0x01ba},
-{ "tcaron", 0x01bb},
-{ "zacute", 0x01bc},
-{ "doubleacute", 0x01bd},
-{ "zcaron", 0x01be},
-{ "zabovedot", 0x01bf},
-{ "Racute", 0x01c0},
-{ "Abreve", 0x01c3},
-{ "Lacute", 0x01c5},
-{ "Cacute", 0x01c6},
-{ "Ccaron", 0x01c8},
-{ "Eogonek", 0x01ca},
-{ "Ecaron", 0x01cc},
-{ "Dcaron", 0x01cf},
-{ "Dstroke", 0x01d0},
-{ "Nacute", 0x01d1},
-{ "Ncaron", 0x01d2},
-{ "Odoubleacute", 0x01d5},
-{ "Rcaron", 0x01d8},
-{ "Uring", 0x01d9},
-{ "Udoubleacute", 0x01db},
-{ "Tcedilla", 0x01de},
-{ "racute", 0x01e0},
-{ "abreve", 0x01e3},
-{ "lacute", 0x01e5},
-{ "cacute", 0x01e6},
-{ "ccaron", 0x01e8},
-{ "eogonek", 0x01ea},
-{ "ecaron", 0x01ec},
-{ "dcaron", 0x01ef},
-{ "dstroke", 0x01f0},
-{ "nacute", 0x01f1},
-{ "ncaron", 0x01f2},
-{ "odoubleacute", 0x01f5},
-{ "udoubleacute", 0x01fb},
-{ "rcaron", 0x01f8},
-{ "uring", 0x01f9},
-{ "tcedilla", 0x01fe},
-{ "abovedot", 0x01ff},
-
- /* modifiers */
-{"Control_L", 0xffe3}, /* XK_Control_L */
-{"Control_R", 0xffe4}, /* XK_Control_R */
-{"Alt_L", 0xffe9}, /* XK_Alt_L */
-{"Alt_R", 0xffea}, /* XK_Alt_R */
-{"Caps_Lock", 0xffe5}, /* XK_Caps_Lock */
-{"Meta_L", 0xffe7}, /* XK_Meta_L */
-{"Meta_R", 0xffe8}, /* XK_Meta_R */
-{"Shift_L", 0xffe1}, /* XK_Shift_L */
-{"Shift_R", 0xffe2}, /* XK_Shift_R */
-{"Super_L", 0xffeb}, /* XK_Super_L */
-{"Super_R", 0xffec}, /* XK_Super_R */
-{"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
-
- /* special keys */
-{"BackSpace", 0xff08}, /* XK_BackSpace */
-{"Tab", 0xff09}, /* XK_Tab */
-{"Return", 0xff0d}, /* XK_Return */
-{"Right", 0xff53}, /* XK_Right */
-{"Left", 0xff51}, /* XK_Left */
-{"Up", 0xff52}, /* XK_Up */
-{"Down", 0xff54}, /* XK_Down */
-{"Page_Down", 0xff56}, /* XK_Page_Down */
-{"Page_Up", 0xff55}, /* XK_Page_Up */
-{"Insert", 0xff63}, /* XK_Insert */
-{"Delete", 0xffff}, /* XK_Delete */
-{"Home", 0xff50}, /* XK_Home */
-{"End", 0xff57}, /* XK_End */
-{"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
-{"KP_Home", 0xff95},
-{"KP_Left", 0xff96},
-{"KP_Up", 0xff97},
-{"KP_Right", 0xff98},
-{"KP_Down", 0xff99},
-{"KP_Prior", 0xff9a},
-{"KP_Page_Up", 0xff9a},
-{"KP_Next", 0xff9b},
-{"KP_Page_Down", 0xff9b},
-{"KP_End", 0xff9c},
-{"KP_Begin", 0xff9d},
-{"KP_Insert", 0xff9e},
-{"KP_Delete", 0xff9f},
-{"F1", 0xffbe}, /* XK_F1 */
-{"F2", 0xffbf}, /* XK_F2 */
-{"F3", 0xffc0}, /* XK_F3 */
-{"F4", 0xffc1}, /* XK_F4 */
-{"F5", 0xffc2}, /* XK_F5 */
-{"F6", 0xffc3}, /* XK_F6 */
-{"F7", 0xffc4}, /* XK_F7 */
-{"F8", 0xffc5}, /* XK_F8 */
-{"F9", 0xffc6}, /* XK_F9 */
-{"F10", 0xffc7}, /* XK_F10 */
-{"F11", 0xffc8}, /* XK_F11 */
-{"F12", 0xffc9}, /* XK_F12 */
-{"F13", 0xffca}, /* XK_F13 */
-{"F14", 0xffcb}, /* XK_F14 */
-{"F15", 0xffcc}, /* XK_F15 */
-{"Sys_Req", 0xff15}, /* XK_Sys_Req */
-{"KP_0", 0xffb0}, /* XK_KP_0 */
-{"KP_1", 0xffb1}, /* XK_KP_1 */
-{"KP_2", 0xffb2}, /* XK_KP_2 */
-{"KP_3", 0xffb3}, /* XK_KP_3 */
-{"KP_4", 0xffb4}, /* XK_KP_4 */
-{"KP_5", 0xffb5}, /* XK_KP_5 */
-{"KP_6", 0xffb6}, /* XK_KP_6 */
-{"KP_7", 0xffb7}, /* XK_KP_7 */
-{"KP_8", 0xffb8}, /* XK_KP_8 */
-{"KP_9", 0xffb9}, /* XK_KP_9 */
-{"KP_Add", 0xffab}, /* XK_KP_Add */
-{"KP_Separator", 0xffac},/* XK_KP_Separator */
-{"KP_Decimal", 0xffae}, /* XK_KP_Decimal */
-{"KP_Divide", 0xffaf}, /* XK_KP_Divide */
-{"KP_Enter", 0xff8d}, /* XK_KP_Enter */
-{"KP_Equal", 0xffbd}, /* XK_KP_Equal */
-{"KP_Multiply", 0xffaa}, /* XK_KP_Multiply */
-{"KP_Subtract", 0xffad}, /* XK_KP_Subtract */
-{"help", 0xff6a}, /* XK_Help */
-{"Menu", 0xff67}, /* XK_Menu */
-{"Print", 0xff61}, /* XK_Print */
-{"Mode_switch", 0xff7e}, /* XK_Mode_switch */
-{"Num_Lock", 0xff7f}, /* XK_Num_Lock */
-{"Pause", 0xff13}, /* XK_Pause */
-{"Escape", 0xff1b}, /* XK_Escape */
-{"ISO_Left_Tab", 0xfe20},/* XK_ISO_Left_Tab */
-
- /* localized keys */
-{"BackApostrophe", 0xff21},
-{"Muhenkan", 0xff22},
-{"Katakana", 0xff27},
-{"Hankaku", 0xff29},
-{"Zenkaku_Hankaku", 0xff2a},
-{"Henkan_Mode_Real", 0xff23},
-{"Henkan_Mode_Ultra", 0xff3e},
-{"backslash_ja", 0xffa5},
-{"Katakana_Real", 0xff25},
-{"Eisu_toggle", 0xff30},
-
- /* dead keys */
-{"dead_grave", 0xfe50},
-{"dead_acute", 0xfe51},
-{"dead_circumflex", 0xfe52},
-{"dead_tilde", 0xfe53},
-{"dead_macron", 0xfe54},
-{"dead_brev", 0xfe55},
-{"dead_abovedot", 0xfe56},
-{"dead_diaeresis", 0xfe57},
-{"dead_abovering", 0xfe58},
-{"dead_doubleacute", 0xfe59},
-{"dead_caron", 0xfe5a},
-{"dead_cedilla", 0xfe5b},
-{"dead_ogonek", 0xfe5c},
-{"dead_iota", 0xfe5d},
-{"dead_voiced_sound", 0xfe5e},
-{"dead_semivoiced_sound", 0xfe5f},
-{"dead_belowdot", 0xfe60},
-{"dead_hook", 0xfe61},
-{"dead_horn", 0xfe62},
-
-
-{0,0},
-};
-
diff --git a/tools/ioemu/vnchextile.h b/tools/ioemu/vnchextile.h
deleted file mode 100644
index 29b74840f5..0000000000
--- a/tools/ioemu/vnchextile.h
+++ /dev/null
@@ -1,209 +0,0 @@
-#define CONCAT_I(a, b) a ## b
-#define CONCAT(a, b) CONCAT_I(a, b)
-#define pixel_t CONCAT(uint, CONCAT(BPP, _t))
-#ifdef GENERIC
-#define NAME CONCAT(generic_, BPP)
-#else
-#define NAME BPP
-#endif
-
-static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
- int x, int y, int w, int h,
- void *last_bg_,
- void *last_fg_,
- int *has_bg, int *has_fg)
-{
- uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
- pixel_t *irow = (pixel_t *)row;
- int j, i;
- pixel_t *last_bg = (pixel_t *)last_bg_;
- pixel_t *last_fg = (pixel_t *)last_fg_;
- pixel_t bg = 0;
- pixel_t fg = 0;
- int n_colors = 0;
- int bg_count = 0;
- int fg_count = 0;
- int flags = 0;
- uint8_t data[(vs->pix_bpp + 2) * 16 * 16];
- int n_data = 0;
- int n_subtiles = 0;
-
- for (j = 0; j < h; j++) {
- for (i = 0; i < w; i++) {
- switch (n_colors) {
- case 0:
- bg = irow[i];
- n_colors = 1;
- break;
- case 1:
- if (irow[i] != bg) {
- fg = irow[i];
- n_colors = 2;
- }
- break;
- case 2:
- if (irow[i] != bg && irow[i] != fg) {
- n_colors = 3;
- } else {
- if (irow[i] == bg)
- bg_count++;
- else if (irow[i] == fg)
- fg_count++;
- }
- break;
- default:
- break;
- }
- }
- if (n_colors > 2)
- break;
- irow += vs->ds->linesize / sizeof(pixel_t);
- }
-
- if (n_colors > 1 && fg_count > bg_count) {
- pixel_t tmp = fg;
- fg = bg;
- bg = tmp;
- }
-
- if (!*has_bg || *last_bg != bg) {
- flags |= 0x02;
- *has_bg = 1;
- *last_bg = bg;
- }
-
- if (!*has_fg || *last_fg != fg) {
- flags |= 0x04;
- *has_fg = 1;
- *last_fg = fg;
- }
-
- switch (n_colors) {
- case 1:
- n_data = 0;
- break;
- case 2:
- flags |= 0x08;
-
- irow = (pixel_t *)row;
-
- for (j = 0; j < h; j++) {
- int min_x = -1;
- for (i = 0; i < w; i++) {
- if (irow[i] == fg) {
- if (min_x == -1)
- min_x = i;
- } else if (min_x != -1) {
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- min_x = -1;
- }
- }
- if (min_x != -1) {
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- }
- irow += vs->ds->linesize / sizeof(pixel_t);
- }
- break;
- case 3:
- flags |= 0x18;
-
- irow = (pixel_t *)row;
-
- if (!*has_bg || *last_bg != bg)
- flags |= 0x02;
-
- for (j = 0; j < h; j++) {
- int has_color = 0;
- int min_x = -1;
- pixel_t color = 0; /* shut up gcc */
-
- for (i = 0; i < w; i++) {
- if (!has_color) {
- if (irow[i] == bg)
- continue;
- color = irow[i];
- min_x = i;
- has_color = 1;
- } else if (irow[i] != color) {
- has_color = 0;
-#ifdef GENERIC
- vnc_convert_pixel(vs, data + n_data, color);
- n_data += vs->pix_bpp;
-#else
- memcpy(data + n_data, &color, sizeof(color));
- n_data += sizeof(pixel_t);
-#endif
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
-
- min_x = -1;
- if (irow[i] != bg) {
- color = irow[i];
- min_x = i;
- has_color = 1;
- }
- }
- }
- if (has_color) {
-#ifdef GENERIC
- vnc_convert_pixel(vs, data + n_data, color);
- n_data += vs->pix_bpp;
-#else
- memcpy(data + n_data, &color, sizeof(color));
- n_data += sizeof(pixel_t);
-#endif
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- }
- irow += vs->ds->linesize / sizeof(pixel_t);
- }
-
- /* A SubrectsColoured subtile invalidates the foreground color */
- *has_fg = 0;
- if (n_data > (w * h * sizeof(pixel_t))) {
- n_colors = 4;
- flags = 0x01;
- *has_bg = 0;
-
- /* we really don't have to invalidate either the bg or fg
- but we've lost the old values. oh well. */
- }
- default:
- break;
- }
-
- if (n_colors > 3) {
- flags = 0x01;
- *has_fg = 0;
- *has_bg = 0;
- n_colors = 4;
- }
-
- vnc_write_u8(vs, flags);
- if (n_colors < 4) {
- if (flags & 0x02)
- vs->write_pixels(vs, last_bg, sizeof(pixel_t));
- if (flags & 0x04)
- vs->write_pixels(vs, last_fg, sizeof(pixel_t));
- if (n_subtiles) {
- vnc_write_u8(vs, n_subtiles);
- vnc_write(vs, data, n_data);
- }
- } else {
- for (j = 0; j < h; j++) {
- vs->write_pixels(vs, row, w * vs->depth);
- row += vs->ds->linesize;
- }
- }
-}
-
-#undef NAME
-#undef pixel_t
-#undef CONCAT_I
-#undef CONCAT
diff --git a/tools/ioemu/x86_64.ld b/tools/ioemu/x86_64.ld
deleted file mode 100644
index 878dafbe79..0000000000
--- a/tools/ioemu/x86_64.ld
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Default linker script, for normal executables */
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(_start)
-SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0x90909090
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x90909090
- .fini :
- {
- KEEP (*(.fini))
- } =0x90909090
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
- /* Ensure the __preinit_array_start label is properly aligned. We
- could instead move the label definition inside the section, but
- the linker would then create the section even if it turns out to
- be empty, which isn't pretty. */
- . = ALIGN(64 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
- .dynamic : { *(.dynamic) }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- /* We don't want to include the .ctor section from
- from the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .got : { *(.got.plt) *(.got) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections. */
- . = ALIGN(64 / 8);
- }
- . = ALIGN(64 / 8);
- _end = .;
- PROVIDE (end = .);
- . = DATA_SEGMENT_END (.);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-}
diff --git a/tools/ioemu/x_keymap.c b/tools/ioemu/x_keymap.c
deleted file mode 100644
index 9f72fc3ebf..0000000000
--- a/tools/ioemu/x_keymap.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-static const uint8_t x_keycode_to_pc_keycode[115] = {
- 0xc7, /* 97 Home */
- 0xc8, /* 98 Up */
- 0xc9, /* 99 PgUp */
- 0xcb, /* 100 Left */
- 0x4c, /* 101 KP-5 */
- 0xcd, /* 102 Right */
- 0xcf, /* 103 End */
- 0xd0, /* 104 Down */
- 0xd1, /* 105 PgDn */
- 0xd2, /* 106 Ins */
- 0xd3, /* 107 Del */
- 0x9c, /* 108 Enter */
- 0x9d, /* 109 Ctrl-R */
- 0x0, /* 110 Pause */
- 0xb7, /* 111 Print */
- 0xb5, /* 112 Divide */
- 0xb8, /* 113 Alt-R */
- 0xc6, /* 114 Break */
- 0x0, /* 115 */
- 0x0, /* 116 */
- 0x0, /* 117 */
- 0x0, /* 118 */
- 0x0, /* 119 */
- 0x0, /* 120 */
- 0x0, /* 121 */
- 0x0, /* 122 */
- 0x0, /* 123 */
- 0x0, /* 124 */
- 0x0, /* 125 */
- 0x0, /* 126 */
- 0x0, /* 127 */
- 0x0, /* 128 */
- 0x79, /* 129 Henkan */
- 0x0, /* 130 */
- 0x7b, /* 131 Muhenkan */
- 0x0, /* 132 */
- 0x7d, /* 133 Yen */
- 0x0, /* 134 */
- 0x0, /* 135 */
- 0x47, /* 136 KP_7 */
- 0x48, /* 137 KP_8 */
- 0x49, /* 138 KP_9 */
- 0x4b, /* 139 KP_4 */
- 0x4c, /* 140 KP_5 */
- 0x4d, /* 141 KP_6 */
- 0x4f, /* 142 KP_1 */
- 0x50, /* 143 KP_2 */
- 0x51, /* 144 KP_3 */
- 0x52, /* 145 KP_0 */
- 0x53, /* 146 KP_. */
- 0x47, /* 147 KP_HOME */
- 0x48, /* 148 KP_UP */
- 0x49, /* 149 KP_PgUp */
- 0x4b, /* 150 KP_Left */
- 0x4c, /* 151 KP_ */
- 0x4d, /* 152 KP_Right */
- 0x4f, /* 153 KP_End */
- 0x50, /* 154 KP_Down */
- 0x51, /* 155 KP_PgDn */
- 0x52, /* 156 KP_Ins */
- 0x53, /* 157 KP_Del */
- 0x0, /* 158 */
- 0x0, /* 159 */
- 0x0, /* 160 */
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 170 */
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 180 */
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 190 */
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 200 */
- 0x0, /* 201 */
- 0x0, /* 202 */
- 0x0, /* 203 */
- 0x0, /* 204 */
- 0x0, /* 205 */
- 0x0, /* 206 */
- 0x0, /* 207 */
- 0x70, /* 208 Hiragana_Katakana */
- 0x0, /* 209 */
- 0x0, /* 210 */
- 0x73, /* 211 backslash */
-};
-
-uint8_t _translate_keycode(const int key)
-{
- return x_keycode_to_pc_keycode[key];
-}
diff --git a/tools/ioemu/xenfbfront.c b/tools/ioemu/xenfbfront.c
deleted file mode 100644
index d4428275ec..0000000000
--- a/tools/ioemu/xenfbfront.c
+++ /dev/null
@@ -1,315 +0,0 @@
-#include <stdint.h>
-#include <xen/io/fbif.h>
-#include <xen/io/kbdif.h>
-#include <semaphore.h>
-#include <sched.h>
-#include <fbfront.h>
-
-#include <hw/xenfb.h>
-
-#include "vl.h"
-
-typedef struct XenFBState {
- struct semaphore kbd_sem;
- struct kbdfront_dev *kbd_dev;
- struct fbfront_dev *fb_dev;
- void *vga_vram, *nonshared_vram;
- DisplayState *ds;
-} XenFBState;
-
-XenFBState *xs;
-
-static char *kbd_path, *fb_path;
-
-static unsigned char linux2scancode[KEY_MAX + 1];
-
-int xenfb_connect_vkbd(const char *path)
-{
- kbd_path = strdup(path);
- return 0;
-}
-
-int xenfb_connect_vfb(const char *path)
-{
- fb_path = strdup(path);
- return 0;
-}
-
-static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
-{
- XenFBState *xs = ds->opaque;
- struct fbfront_dev *fb_dev = xs->fb_dev;
- if (!fb_dev)
- return;
- fbfront_update(fb_dev, x, y, w, h);
-}
-
-static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
-{
- XenFBState *xs = ds->opaque;
- struct fbfront_dev *fb_dev = xs->fb_dev;
- int offset;
-
- fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize);
- ds->width = w;
- ds->height = h;
- if (!depth) {
- ds->shared_buf = 0;
- ds->depth = 32;
- } else {
- ds->shared_buf = 1;
- ds->depth = depth;
- }
- if (!linesize)
- ds->shared_buf = 0;
- if (!ds->shared_buf)
- linesize = w * 4;
- ds->linesize = linesize;
- if (!fb_dev)
- return;
- if (ds->shared_buf) {
- offset = pixels - xs->vga_vram;
- ds->data = pixels;
- fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
- } else {
- ds->data = xs->nonshared_vram;
- fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
- }
-}
-
-static void xenfb_pv_resize(DisplayState *ds, int w, int h)
-{
- xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
-}
-
-static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
-{
- XenFBState *xs = ds->opaque;
- struct fbfront_dev *fb_dev = xs->fb_dev;
- int offset = pixels - xs->vga_vram;
- ds->data = pixels;
- if (!fb_dev)
- return;
- fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
-}
-
-static void xenfb_pv_refresh(DisplayState *ds)
-{
- vga_hw_update();
-}
-
-static void xenfb_fb_handler(void *opaque)
-{
-#define FB_NUM_BATCH 4
- union xenfb_in_event buf[FB_NUM_BATCH];
- int n, i;
- XenFBState *xs = opaque;
- DisplayState *ds = xs->ds;
-
- n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
- for (i = 0; i < n; i++) {
- switch (buf[i].type) {
- case XENFB_TYPE_REFRESH_PERIOD:
- if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
- /* Sleeping interval */
- ds->idle = 1;
- ds->gui_timer_interval = 500;
- } else {
- /* Set interval */
- ds->idle = 0;
- ds->gui_timer_interval = buf[i].refresh_period.period;
- }
- default:
- /* ignore unknown events */
- break;
- }
- }
-}
-
-static void xenfb_kbd_handler(void *opaque)
-{
-#define KBD_NUM_BATCH 64
- union xenkbd_in_event buf[KBD_NUM_BATCH];
- int n, i;
- XenFBState *xs = opaque;
- DisplayState *s = xs->ds;
- static int buttons;
- static int x, y;
-
- n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
- for (i = 0; i < n; i++) {
- switch (buf[i].type) {
-
- case XENKBD_TYPE_MOTION:
- fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
- break;
-
- case XENKBD_TYPE_POS:
- {
- int new_x = buf[i].pos.abs_x;
- int new_y = buf[i].pos.abs_y;
- if (new_x >= s->width)
- new_x = s->width - 1;
- if (new_y >= s->height)
- new_y = s->height - 1;
- if (kbd_mouse_is_absolute()) {
- kbd_mouse_event(
- new_x * 0x7FFF / (s->width - 1),
- new_y * 0x7FFF / (s->height - 1),
- buf[i].pos.rel_z,
- buttons);
- } else {
- kbd_mouse_event(
- new_x - x,
- new_y - y,
- buf[i].pos.rel_z,
- buttons);
- }
- x = new_x;
- y = new_y;
- break;
- }
-
- case XENKBD_TYPE_KEY:
- {
- int keycode = buf[i].key.keycode;
- int button = 0;
-
- if (keycode == BTN_LEFT)
- button = MOUSE_EVENT_LBUTTON;
- else if (keycode == BTN_RIGHT)
- button = MOUSE_EVENT_RBUTTON;
- else if (keycode == BTN_MIDDLE)
- button = MOUSE_EVENT_MBUTTON;
-
- if (button) {
- if (buf[i].key.pressed)
- buttons |= button;
- else
- buttons &= ~button;
- if (kbd_mouse_is_absolute())
- kbd_mouse_event(
- x * 0x7FFF / (s->width - 1),
- y * 0x7FFF / (s->height - 1),
- 0,
- buttons);
- else
- kbd_mouse_event(0, 0, 0, buttons);
- } else {
- int scancode = linux2scancode[keycode];
- if (!scancode) {
- fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
- break;
- }
- if (scancode & 0x80) {
- kbd_put_keycode(0xe0);
- scancode &= 0x7f;
- }
- if (!buf[i].key.pressed)
- scancode |= 0x80;
- kbd_put_keycode(scancode);
- }
- break;
- }
- }
- }
-}
-
-static void kbdfront_thread(void *p)
-{
- int scancode, keycode;
- XenFBState *xs = p;
- xs->kbd_dev = init_kbdfront(kbd_path, 1);
- if (!xs->kbd_dev) {
- fprintf(stderr,"can't open keyboard\n");
- exit(1);
- }
- up(&xs->kbd_sem);
- for (scancode = 0; scancode < 128; scancode++) {
- keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
- linux2scancode[keycode] = scancode;
- keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
- linux2scancode[keycode] = scancode | 0x80;
- }
-}
-
-int xenfb_pv_display_init(DisplayState *ds)
-{
- if (!fb_path || !kbd_path)
- return -1;
-
- xs = qemu_mallocz(sizeof(XenFBState));
- if (!xs)
- return -1;
-
- init_SEMAPHORE(&xs->kbd_sem, 0);
- xs->ds = ds;
-
- create_thread("kbdfront", kbdfront_thread, (void*) xs);
-
- ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
- memset(ds->data, 0, VGA_RAM_SIZE);
- ds->opaque = xs;
- ds->depth = 32;
- ds->bgr = 0;
- ds->width = 640;
- ds->height = 400;
- ds->linesize = 640 * 4;
- ds->dpy_update = xenfb_pv_update;
- ds->dpy_resize = xenfb_pv_resize;
- ds->dpy_resize_shared = xenfb_pv_resize_shared;
- ds->dpy_setdata = xenfb_pv_setdata;
- ds->dpy_refresh = xenfb_pv_refresh;
- return 0;
-}
-
-int xenfb_pv_display_start(void *data)
-{
- DisplayState *ds;
- struct fbfront_dev *fb_dev;
- int kbd_fd, fb_fd;
- int offset = 0;
- unsigned long *mfns;
- int n = VGA_RAM_SIZE / PAGE_SIZE;
- int i;
-
- if (!fb_path || !kbd_path)
- return 0;
-
- ds = xs->ds;
- xs->vga_vram = data;
- mfns = malloc(2 * n * sizeof(*mfns));
- for (i = 0; i < n; i++)
- mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
- for (i = 0; i < n; i++)
- mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
-
- fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n);
- free(mfns);
- if (!fb_dev) {
- fprintf(stderr,"can't open frame buffer\n");
- exit(1);
- }
- free(fb_path);
-
- if (ds->shared_buf) {
- offset = (void*) ds->data - xs->vga_vram;
- } else {
- offset = VGA_RAM_SIZE;
- ds->data = xs->nonshared_vram;
- }
- if (offset)
- fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
-
- down(&xs->kbd_sem);
- free(kbd_path);
-
- kbd_fd = kbdfront_open(xs->kbd_dev);
- qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
-
- fb_fd = fbfront_open(fb_dev);
- qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
-
- xs->fb_dev = fb_dev;
- return 0;
-}
diff --git a/tools/ioemu/xenstore.c b/tools/ioemu/xenstore.c
deleted file mode 100644
index 6fc9733a58..0000000000
--- a/tools/ioemu/xenstore.c
+++ /dev/null
@@ -1,931 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file "COPYING" in the main directory of
- * this archive for more details.
- *
- * Copyright (C) 2006 Christian Limpach
- * Copyright (C) 2006 XenSource Ltd.
- *
- */
-
-#include "vl.h"
-#include "block_int.h"
-#include <unistd.h>
-#ifndef CONFIG_STUBDOM
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-struct xs_handle *xsh = NULL;
-static char *media_filename[MAX_DISKS + MAX_SCSI_DISKS];
-static QEMUTimer *insert_timer = NULL;
-
-#define UWAIT_MAX (30*1000000) /* thirty seconds */
-#define UWAIT (100000) /* 1/10th second */
-
-static int pasprintf(char **buf, const char *fmt, ...)
-{
- va_list ap;
- int ret = 0;
-
- if (*buf)
- free(*buf);
- va_start(ap, fmt);
- if (vasprintf(buf, fmt, ap) == -1) {
- buf = NULL;
- ret = -1;
- }
- va_end(ap);
- return ret;
-}
-
-static void insert_media(void *opaque)
-{
- int i;
-
- for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
- if (media_filename[i] && bs_table[i]) {
- do_change(bs_table[i]->device_name, media_filename[i]);
- free(media_filename[i]);
- media_filename[i] = NULL;
- }
- }
-}
-
-void xenstore_check_new_media_present(int timeout)
-{
-
- if (insert_timer == NULL)
- insert_timer = qemu_new_timer(rt_clock, insert_media, NULL);
- qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
-}
-
-static void waitForDevice(char *fn)
-{
- struct stat sbuf;
- int status;
- int uwait = UWAIT_MAX;
-
- do {
- status = stat(fn, &sbuf);
- if (!status) break;
- usleep(UWAIT);
- uwait -= UWAIT;
- } while (uwait > 0);
-
- return;
-}
-
-#define DIRECT_PCI_STR_LEN 160
-char direct_pci_str[DIRECT_PCI_STR_LEN];
-void xenstore_parse_domain_config(int hvm_domid)
-{
- char **e = NULL;
- char *buf = NULL, *path;
- char *fpath = NULL, *bpath = NULL,
- *dev = NULL, *params = NULL, *type = NULL, *drv = NULL;
- int i, is_scsi, is_hdN = 0;
- unsigned int len, num, hd_index, pci_devid = 0;
- BlockDriverState *bs;
- BlockDriver *format;
-
- for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
- media_filename[i] = NULL;
-
- xsh = xs_daemon_open();
- if (xsh == NULL) {
- fprintf(logfile, "Could not contact xenstore for domain config\n");
- return;
- }
-
- path = xs_get_domain_path(xsh, hvm_domid);
- if (path == NULL) {
- fprintf(logfile, "xs_get_domain_path() error\n");
- goto out;
- }
-
- if (pasprintf(&buf, "%s/device/vbd", path) == -1)
- goto out;
-
- e = xs_directory(xsh, XBT_NULL, buf, &num);
- if (e == NULL)
- num = 0;
-
- for (i = 0; i < num; i++) {
- /* read the backend path */
- if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
- continue;
- free(bpath);
- bpath = xs_read(xsh, XBT_NULL, buf, &len);
- if (bpath == NULL)
- continue;
- /* read the name of the device */
- if (pasprintf(&buf, "%s/dev", bpath) == -1)
- continue;
- free(dev);
- dev = xs_read(xsh, XBT_NULL, buf, &len);
- if (dev == NULL)
- continue;
- if (!strncmp(dev, "hd", 2)) {
- is_hdN = 1;
- break;
- }
- }
-
- for (i = 0; i < num; i++) {
- format = NULL; /* don't know what the format is yet */
-
- /* read the backend path */
- if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
- continue;
- free(bpath);
- bpath = xs_read(xsh, XBT_NULL, buf, &len);
- if (bpath == NULL)
- continue;
- /* read the name of the device */
- if (pasprintf(&buf, "%s/dev", bpath) == -1)
- continue;
- free(dev);
- dev = xs_read(xsh, XBT_NULL, buf, &len);
- if (dev == NULL)
- continue;
- /* Change xvdN to look like hdN */
- if (!is_hdN && !strncmp(dev, "xvd", 3)) {
- fprintf(logfile, "Change xvd%c to look like hd%c\n",
- dev[3], dev[3]);
- memmove(dev, dev+1, strlen(dev));
- dev[0] = 'h';
- dev[1] = 'd';
- }
- is_scsi = !strncmp(dev, "sd", 2);
- if ((strncmp(dev, "hd", 2) && !is_scsi) || strlen(dev) != 3 )
- continue;
- hd_index = dev[2] - 'a';
- if (hd_index >= (is_scsi ? MAX_SCSI_DISKS : MAX_DISKS))
- continue;
- /* read the type of the device */
- if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
- continue;
- free(type);
- type = xs_read(xsh, XBT_NULL, buf, &len);
- if (pasprintf(&buf, "%s/params", bpath) == -1)
- continue;
- free(params);
- params = xs_read(xsh, XBT_NULL, buf, &len);
- if (params == NULL)
- continue;
- /* read the name of the device */
- if (pasprintf(&buf, "%s/type", bpath) == -1)
- continue;
- free(drv);
- drv = xs_read(xsh, XBT_NULL, buf, &len);
- if (drv == NULL)
- continue;
- /* Obtain blktap sub-type prefix */
- if (!strcmp(drv, "tap") && params[0]) {
- char *offset = strchr(params, ':');
- if (!offset)
- continue ;
- free(drv);
- drv = malloc(offset - params + 1);
- memcpy(drv, params, offset - params);
- drv[offset - params] = '\0';
- if (!strcmp(drv, "aio"))
- /* qemu does aio anyway if it can */
- format = &bdrv_raw;
- memmove(params, offset+1, strlen(offset+1)+1 );
- fprintf(logfile, "Strip off blktap sub-type prefix to %s (drv '%s')\n", params, drv);
- }
- /* Prefix with /dev/ if needed */
- if (!strcmp(drv, "phy") && params[0] != '/') {
- char *newparams = malloc(5 + strlen(params) + 1);
- sprintf(newparams, "/dev/%s", params);
- free(params);
- params = newparams;
- format = &bdrv_raw;
- }
-
- /*
- * check if device has a phantom vbd; the phantom is hooked
- * to the frontend device (for ease of cleanup), so lookup
- * the frontend device, and see if there is a phantom_vbd
- * if there is, we will use resolution as the filename
- */
- if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
- continue;
- free(fpath);
- fpath = xs_read(xsh, XBT_NULL, buf, &len);
- if (fpath) {
- if (pasprintf(&buf, "%s/dev", fpath) == -1)
- continue;
- free(params);
- params = xs_read(xsh, XBT_NULL, buf , &len);
- if (params) {
- /*
- * wait for device, on timeout silently fail because we will
- * fail to open below
- */
- waitForDevice(params);
- }
- }
-
- bs = bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)] = bdrv_new(dev);
- /* check if it is a cdrom */
- if (type && !strcmp(type, "cdrom")) {
- bdrv_set_type_hint(bs, BDRV_TYPE_CDROM);
- if (pasprintf(&buf, "%s/params", bpath) != -1)
- xs_watch(xsh, buf, dev);
- }
-
- /* open device now if media present */
-#ifdef CONFIG_STUBDOM
- if (pasprintf(&buf, "%s/device/vbd/%s", path, e[i]) == -1)
- continue;
- if (bdrv_open2(bs, buf, 0 /* snapshot */, &bdrv_vbd) == 0) {
- pstrcpy(bs->filename, sizeof(bs->filename), params);
- continue;
- }
-#endif
-
- if (params[0]) {
- if (!format) {
- if (!drv) {
- fprintf(stderr, "qemu: type (image format) not specified for vbd '%s' or image '%s'\n", buf, params);
- continue;
- }
- if (!strcmp(drv,"qcow")) {
- /* autoguess qcow vs qcow2 */
- } else if (!strcmp(drv,"file") || !strcmp(drv,"phy")) {
- format = &bdrv_raw;
- } else {
- format = bdrv_find_format(drv);
- if (!format) {
- fprintf(stderr, "qemu: type (image format) '%s' unknown for vbd '%s' or image '%s'\n", drv, buf, params);
- continue;
- }
- }
- }
- if (bdrv_open2(bs, params, 0 /* snapshot */, format) < 0)
- fprintf(stderr, "qemu: could not open vbd '%s' or hard disk image '%s' (drv '%s' format '%s')\n", buf, params, drv ? drv : "?", format ? format->format_name : "0");
- }
- }
-
-#ifdef CONFIG_STUBDOM
- if (pasprintf(&buf, "%s/device/vkbd", path) == -1)
- goto out;
-
- free(e);
- e = xs_directory(xsh, XBT_NULL, buf, &num);
-
- if (e) {
- for (i = 0; i < num; i++) {
- if (pasprintf(&buf, "%s/device/vkbd/%s", path, e[i]) == -1)
- continue;
- xenfb_connect_vkbd(buf);
- }
- }
-
- if (pasprintf(&buf, "%s/device/vfb", path) == -1)
- goto out;
-
- free(e);
- e = xs_directory(xsh, XBT_NULL, buf, &num);
-
- if (e) {
- for (i = 0; i < num; i++) {
- if (pasprintf(&buf, "%s/device/vfb/%s", path, e[i]) == -1)
- continue;
- xenfb_connect_vfb(buf);
- }
- }
-#endif
-
-
- /* Set a watch for log-dirty requests from the migration tools */
- if (pasprintf(&buf, "/local/domain/0/device-model/%u/logdirty/next-active",
- domid) != -1) {
- xs_watch(xsh, buf, "logdirty");
- fprintf(logfile, "Watching %s\n", buf);
- }
-
- /* Set a watch for suspend requests from the migration tools */
- if (pasprintf(&buf,
- "/local/domain/0/device-model/%u/command", domid) != -1) {
- xs_watch(xsh, buf, "dm-command");
- fprintf(logfile, "Watching %s\n", buf);
- }
-
- /* get the pci pass-through parameter */
- if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/num_devs",
- hvm_domid, pci_devid) == -1)
- goto out;
-
- free(params);
- params = xs_read(xsh, XBT_NULL, buf, &len);
- if (params == NULL)
- goto out;
- num = atoi(params);
-
- for ( i = 0; i < num; i++ ) {
- if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/dev-%d",
- hvm_domid, pci_devid, i) != -1) {
- free(dev);
- dev = xs_read(xsh, XBT_NULL, buf, &len);
-
- if ( strlen(dev) + strlen(direct_pci_str) > DIRECT_PCI_STR_LEN ) {
- fprintf(stderr, "qemu: too many pci pass-through devices\n");
- memset(direct_pci_str, 0, DIRECT_PCI_STR_LEN);
- goto out;
- }
-
- /* append to direct_pci_str */
- if ( dev ) {
- strcat(direct_pci_str, dev);
- strcat(direct_pci_str, "-");
- }
- }
- }
-
-
- out:
- free(type);
- free(params);
- free(dev);
- free(bpath);
- free(buf);
- free(path);
- free(e);
- free(drv);
- return;
-}
-
-int xenstore_fd(void)
-{
- if (xsh)
- return xs_fileno(xsh);
- return -1;
-}
-
-unsigned long *logdirty_bitmap = NULL;
-unsigned long logdirty_bitmap_size;
-extern int vga_ram_size, bios_size;
-
-void xenstore_process_logdirty_event(void)
-{
- char *act;
- static char *active_path = NULL;
- static char *next_active_path = NULL;
- static char *seg = NULL;
- unsigned int len;
- int i;
-
- if (!seg) {
- char *path = NULL, *key_ascii, key_terminated[17] = {0,};
- key_t key;
- int shmid;
-
- /* Find and map the shared memory segment for log-dirty bitmaps */
- if (pasprintf(&path,
- "/local/domain/0/device-model/%u/logdirty/key",
- domid) == -1) {
- fprintf(logfile, "Log-dirty: out of memory\n");
- exit(1);
- }
-
- key_ascii = xs_read(xsh, XBT_NULL, path, &len);
- free(path);
-
- if (!key_ascii)
- /* No key yet: wait for the next watch */
- return;
-
-#ifdef CONFIG_STUBDOM
- /* We pass the writes to hypervisor */
- seg = (void*)1;
-#else
- strncpy(key_terminated, key_ascii, 16);
- free(key_ascii);
- key = (key_t) strtoull(key_terminated, NULL, 16);
-
- /* Figure out how bit the log-dirty bitmaps are */
- logdirty_bitmap_size = xc_memory_op(xc_handle,
- XENMEM_maximum_gpfn, &domid) + 1;
- logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
- / HOST_LONG_BITS); /* longs */
- logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
-
- /* Map the shared-memory segment */
- fprintf(logfile, "%s: key=%16.16llx size=%lu\n", __FUNCTION__,
- (unsigned long long)key, logdirty_bitmap_size);
-
- shmid = shmget(key, 2 * logdirty_bitmap_size, S_IRUSR|S_IWUSR);
- if (shmid == -1) {
- fprintf(logfile, "Log-dirty: shmget failed: segment %16.16llx "
- "(%s)\n", (unsigned long long)key, strerror(errno));
- exit(1);
- }
-
- seg = shmat(shmid, NULL, 0);
- if (seg == (void *)-1) {
- fprintf(logfile, "Log-dirty: shmat failed: segment %16.16llx "
- "(%s)\n", (unsigned long long)key, strerror(errno));
- exit(1);
- }
-
- fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
-
- /* Double-check that the bitmaps are the size we expect */
- if (logdirty_bitmap_size != *(uint32_t *)seg) {
- fprintf(logfile, "Log-dirty: got %u, calc %lu\n",
- *(uint32_t *)seg, logdirty_bitmap_size);
- /* Stale key: wait for next watch */
- shmdt(seg);
- seg = NULL;
- return;
- }
-#endif
-
- /* Remember the paths for the next-active and active entries */
- if (pasprintf(&active_path,
- "/local/domain/0/device-model/%u/logdirty/active",
- domid) == -1) {
- fprintf(logfile, "Log-dirty: out of memory\n");
- exit(1);
- }
- if (pasprintf(&next_active_path,
- "/local/domain/0/device-model/%u/logdirty/next-active",
- domid) == -1) {
- fprintf(logfile, "Log-dirty: out of memory\n");
- exit(1);
- }
- }
-
- fprintf(logfile, "Triggered log-dirty buffer switch\n");
-
- /* Read the required active buffer from the store */
- act = xs_read(xsh, XBT_NULL, next_active_path, &len);
- if (!act) {
- fprintf(logfile, "Log-dirty: can't read next-active\n");
- exit(1);
- }
-
- /* Switch buffers */
- i = act[0] - '0';
- if (i != 0 && i != 1) {
- fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
- exit(1);
- }
- logdirty_bitmap = (unsigned long *)(seg + i * logdirty_bitmap_size);
-
- /* Ack that we've switched */
- xs_write(xsh, XBT_NULL, active_path, act, len);
- free(act);
-}
-
-
-/* Accept state change commands from the control tools */
-static void xenstore_process_dm_command_event(void)
-{
- char *path = NULL, *command = NULL, *par = NULL;
- unsigned int len;
- extern int suspend_requested;
-
- if (pasprintf(&path,
- "/local/domain/0/device-model/%u/command", domid) == -1) {
- fprintf(logfile, "out of memory reading dm command\n");
- goto out;
- }
- command = xs_read(xsh, XBT_NULL, path, &len);
- if (!command)
- goto out;
-
- if (!strncmp(command, "save", len)) {
- fprintf(logfile, "dm-command: pause and save state\n");
- suspend_requested = 1;
- } else if (!strncmp(command, "continue", len)) {
- fprintf(logfile, "dm-command: continue after state save\n");
- suspend_requested = 0;
- } else if (!strncmp(command, "pci-rem", len)) {
- fprintf(logfile, "dm-command: hot remove pass-through pci dev \n");
-
- if (pasprintf(&path,
- "/local/domain/0/device-model/%u/parameter", domid) == -1) {
- fprintf(logfile, "out of memory reading dm command parameter\n");
- goto out;
- }
- par = xs_read(xsh, XBT_NULL, path, &len);
- if (!par)
- goto out;
-
- do_pci_del(par);
- free(par);
- } else if (!strncmp(command, "pci-ins", len)) {
- fprintf(logfile, "dm-command: hot insert pass-through pci dev \n");
-
- if (pasprintf(&path,
- "/local/domain/0/device-model/%u/parameter", domid) == -1) {
- fprintf(logfile, "out of memory reading dm command parameter\n");
- goto out;
- }
- par = xs_read(xsh, XBT_NULL, path, &len);
- if (!par)
- goto out;
-
- do_pci_add(par);
- free(par);
- } else {
- fprintf(logfile, "dm-command: unknown command\"%*s\"\n", len, command);
- }
-
- out:
- free(path);
- free(command);
-}
-
-void xenstore_record_dm(char *subpath, char *state)
-{
- char *path = NULL;
-
- if (pasprintf(&path,
- "/local/domain/0/device-model/%u/%s", domid, subpath) == -1) {
- fprintf(logfile, "out of memory recording dm \n");
- goto out;
- }
- if (!xs_write(xsh, XBT_NULL, path, state, strlen(state)))
- fprintf(logfile, "error recording dm \n");
-
- out:
- free(path);
-}
-
-void xenstore_record_dm_state(char *state)
-{
- xenstore_record_dm("state", state);
-}
-
-void xenstore_process_event(void *opaque)
-{
- char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
- unsigned int len, num, hd_index;
-
- vec = xs_read_watch(xsh, &num);
- if (!vec)
- return;
-
- if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
- xenstore_process_logdirty_event();
- goto out;
- }
-
- if (!strcmp(vec[XS_WATCH_TOKEN], "dm-command")) {
- xenstore_process_dm_command_event();
- goto out;
- }
-
- if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
- strlen(vec[XS_WATCH_TOKEN]) != 3)
- goto out;
- hd_index = vec[XS_WATCH_TOKEN][2] - 'a';
- image = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
- if (image == NULL)
- goto out; /* gone */
-
- /* Strip off blktap sub-type prefix */
- bpath = strdup(vec[XS_WATCH_PATH]);
- if (bpath == NULL)
- goto out;
- if ((offset = strrchr(bpath, '/')) != NULL)
- *offset = '\0';
- if (pasprintf(&buf, "%s/type", bpath) == -1)
- goto out;
- drv = xs_read(xsh, XBT_NULL, buf, &len);
- if (drv && !strcmp(drv, "tap") && ((offset = strchr(image, ':')) != NULL))
- memmove(image, offset+1, strlen(offset+1)+1);
-
- if (!strcmp(image, bs_table[hd_index]->filename))
- goto out; /* identical */
-
- do_eject(0, vec[XS_WATCH_TOKEN]);
- bs_table[hd_index]->filename[0] = 0;
- if (media_filename[hd_index]) {
- free(media_filename[hd_index]);
- media_filename[hd_index] = NULL;
- }
-
- if (image[0]) {
- media_filename[hd_index] = strdup(image);
- xenstore_check_new_media_present(5000);
- }
-
- out:
- free(drv);
- free(buf);
- free(bpath);
- free(image);
- free(vec);
-}
-
-void xenstore_write_vncport(int display)
-{
- char *buf = NULL, *path;
- char *portstr = NULL;
-
- if (xsh == NULL)
- return;
-
- path = xs_get_domain_path(xsh, domid);
- if (path == NULL) {
- fprintf(logfile, "xs_get_domain_path() error\n");
- goto out;
- }
-
- if (pasprintf(&buf, "%s/console/vnc-port", path) == -1)
- goto out;
-
- if (pasprintf(&portstr, "%d", display) == -1)
- goto out;
-
- if (xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)) == 0)
- fprintf(logfile, "xs_write() vncport failed\n");
-
- out:
- free(portstr);
- free(buf);
-}
-
-void xenstore_write_vslots(char *vslots)
-{
- char *path = NULL;
- int pci_devid = 0;
-
- if (pasprintf(&path,
- "/local/domain/0/backend/pci/%u/%u/vslots", domid, pci_devid) == -1) {
- fprintf(logfile, "out of memory when updating vslots.\n");
- goto out;
- }
- if (!xs_write(xsh, XBT_NULL, path, vslots, strlen(vslots)))
- fprintf(logfile, "error updating vslots \n");
-
- out:
- free(path);
-}
-
-void xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen)
-{
- char *buf = NULL, *path, *uuid = NULL, *passwd = NULL;
- unsigned int i, len;
-
- pwbuf[0] = '\0';
-
- if (xsh == NULL)
- return;
-
- path = xs_get_domain_path(xsh, domid);
- if (path == NULL) {
- fprintf(logfile, "xs_get_domain_path() error. domid %d.\n", domid);
- return;
- }
-
- pasprintf(&buf, "%s/vm", path);
- free(path);
- uuid = xs_read(xsh, XBT_NULL, buf, &len);
- if (uuid == NULL) {
- fprintf(logfile, "xs_read(): uuid get error. %s.\n", buf);
- free(buf);
- return;
- }
-
- pasprintf(&buf, "%s/vncpasswd", uuid);
- free(uuid);
- passwd = xs_read(xsh, XBT_NULL, buf, &len);
- if (passwd == NULL) {
- fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf);
- free(buf);
- return;
- }
-
- if (len >= pwbuflen)
- {
- fprintf(logfile, "xenstore_read_vncpasswd(): truncated password to avoid buffer overflow\n");
- len = pwbuflen - 1;
- }
-
- for (i=0; i<len; i++)
- pwbuf[i] = passwd[i];
- pwbuf[len] = '\0';
- passwd[0] = '\0';
- if (xs_write(xsh, XBT_NULL, buf, passwd, 1) == 0)
- fprintf(logfile, "xs_write() vncpasswd failed.\n");
-
- free(passwd);
- free(buf);
-}
-
-
-/*
- * get all device instances of a certain type
- */
-char **xenstore_domain_get_devices(struct xs_handle *handle,
- const char *devtype, unsigned int *num)
-{
- char *path;
- char *buf = NULL;
- char **e = NULL;
-
- path = xs_get_domain_path(handle, domid);
- if (path == NULL)
- goto out;
-
- if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
- goto out;
-
- e = xs_directory(handle, XBT_NULL, buf, num);
-
- out:
- free(path);
- free(buf);
- return e;
-}
-
-/*
- * Check whether a domain has devices of the given type
- */
-int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype)
-{
- int rc = 0;
- unsigned int num;
- char **e = xenstore_domain_get_devices(handle, devtype, &num);
- if (e)
- rc = 1;
- free(e);
- return rc;
-}
-
-/*
- * Function that creates a path to a variable of an instance of a
- * certain device
- */
-static char *get_device_variable_path(const char *devtype, const char *inst,
- const char *var)
-{
- char *buf = NULL;
- if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s",
- devtype,
- domid,
- inst,
- var) == -1) {
- free(buf);
- buf = NULL;
- }
- return buf;
-}
-
-char *xenstore_backend_read_variable(struct xs_handle *handle,
- const char *devtype, const char *inst,
- const char *var)
-{
- char *value = NULL;
- char *buf = NULL;
- unsigned int len;
-
- buf = get_device_variable_path(devtype, inst, var);
- if (NULL == buf)
- goto out;
-
- value = xs_read(handle, XBT_NULL, buf, &len);
-
- free(buf);
-
- out:
- return value;
-}
-
-/*
- Read the hotplug status variable from the backend given the type
- of device and its instance.
-*/
-char *xenstore_read_hotplug_status(struct xs_handle *handle,
- const char *devtype, const char *inst)
-{
- return xenstore_backend_read_variable(handle, devtype, inst,
- "hotplug-status");
-}
-
-/*
- Subscribe to the hotplug status of a device given the type of device and
- its instance.
- In case an error occurrs, a negative number is returned.
- */
-int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
- const char *devtype,
- const char *inst,
- const char *token)
-{
- int rc = 0;
- char *path = get_device_variable_path(devtype, inst, "hotplug-status");
-
- if (path == NULL)
- return -1;
-
- if (0 == xs_watch(handle, path, token))
- rc = -2;
-
- free(path);
-
- return rc;
-}
-
-/*
- * Unsubscribe from a subscription to the status of a hotplug variable of
- * a device.
- */
-int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
- const char *devtype,
- const char *inst,
- const char *token)
-{
- int rc = 0;
- char *path;
- path = get_device_variable_path(devtype, inst, "hotplug-status");
- if (path == NULL)
- return -1;
-
- if (0 == xs_unwatch(handle, path, token))
- rc = -2;
-
- free(path);
-
- return rc;
-}
-
-char *xenstore_vm_read(int domid, char *key, unsigned int *len)
-{
- char *buf = NULL, *path = NULL, *value = NULL;
-
- if (xsh == NULL)
- goto out;
-
- path = xs_get_domain_path(xsh, domid);
- if (path == NULL) {
- fprintf(logfile, "xs_get_domain_path(%d): error\n", domid);
- goto out;
- }
-
- pasprintf(&buf, "%s/vm", path);
- free(path);
- path = xs_read(xsh, XBT_NULL, buf, NULL);
- if (path == NULL) {
- fprintf(logfile, "xs_read(%s): read error\n", buf);
- goto out;
- }
-
- pasprintf(&buf, "%s/%s", path, key);
- value = xs_read(xsh, XBT_NULL, buf, len);
- if (value == NULL) {
- fprintf(logfile, "xs_read(%s): read error\n", buf);
- goto out;
- }
-
- out:
- free(path);
- free(buf);
- return value;
-}
-
-int xenstore_vm_write(int domid, char *key, char *value)
-{
- char *buf = NULL, *path = NULL;
- int rc = -1;
-
- if (xsh == NULL)
- goto out;
-
- path = xs_get_domain_path(xsh, domid);
- if (path == NULL) {
- fprintf(logfile, "xs_get_domain_path: error\n");
- goto out;
- }
-
- pasprintf(&buf, "%s/vm", path);
- free(path);
- path = xs_read(xsh, XBT_NULL, buf, NULL);
- if (path == NULL) {
- fprintf(logfile, "xs_read(%s): read error\n", buf);
- goto out;
- }
-
- pasprintf(&buf, "%s/%s", path, key);
- rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value));
- if (rc == 0) {
- fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key);
- goto out;
- }
-
- out:
- free(path);
- free(buf);
- return rc;
-}