Explorar o código

Merge remote-tracking branch 'origin/master' into pci

Conflicts:
	hw/virtio-pci.c
Michael S. Tsirkin %!s(int64=14) %!d(string=hai) anos
pai
achega
befeac45d4
Modificáronse 100 ficheiros con 2280 adicións e 4193 borrados
  1. 7 1
      Changelog
  2. 2 2
      MAINTAINERS
  3. 5 2
      Makefile
  4. 13 11
      Makefile.objs
  5. 23 14
      Makefile.target
  6. 40 14
      QMP/qmp.py
  7. 0 4
      alpha-dis.c
  8. 5 0
      arch_init.c
  9. 1 0
      arch_init.h
  10. 0 2
      audio/audio_pt_int.c
  11. 2 2
      audio/mixeng_template.h
  12. 0 1
      audio/sdlaudio.c
  13. 9 40
      block.c
  14. 0 5
      block.h
  15. 1 1
      block/qcow2-cluster.c
  16. 7 4
      block/qcow2-refcount.c
  17. 4 3
      block/qcow2.c
  18. 2 0
      block/qcow2.h
  19. 125 4
      block/qed.c
  20. 7 0
      block/qed.h
  21. 76 3
      block/raw-posix.c
  22. 6 6
      block/raw-win32.c
  23. 294 411
      block/rbd.c
  24. 0 71
      block/rbd_types.h
  25. 2 2
      block/sheepdog.c
  26. 4 2
      block/vdi.c
  27. 14 8
      block/vmdk.c
  28. 0 1
      block_int.h
  29. 4 3
      blockdev.c
  30. 1 0
      blockdev.h
  31. 1 1
      bsd-user/main.c
  32. 1 1
      bsd-user/qemu.h
  33. 0 1
      bsd-user/syscall.c
  34. 1 1
      compatfd.c
  35. 176 98
      configure
  36. 1 1
      console.c
  37. 49 18
      cpu-all.h
  38. 2 0
      cpu-common.h
  39. 35 641
      cpu-exec.c
  40. 0 3
      darwin-user/signal.c
  41. 1 1
      darwin-user/syscall.c
  42. 9 0
      default-configs/alpha-softmmu.mak
  43. 1 0
      default-configs/pci.mak
  44. 1 0
      default-configs/s390x-linux-user.mak
  45. 3 0
      dis-asm.h
  46. 1 1
      disas.c
  47. 114 66
      docs/qdev-device-use.txt
  48. 38 0
      docs/usb2.txt
  49. 140 0
      error.c
  50. 70 0
      error.h
  51. 29 0
      error_int.h
  52. 5 2
      exec-all.h
  53. 110 18
      exec.c
  54. 0 540
      fpu/softfloat-native.c
  55. 0 531
      fpu/softfloat-native.h
  56. 0 7
      fpu/softfloat-specialize.h
  57. 34 69
      fpu/softfloat.c
  58. 17 62
      fpu/softfloat.h
  59. 0 7
      fsdev/file-op-9p.h
  60. 28 0
      fsdev/qemu-fsdev-dummy.c
  61. 6 6
      gdbstub.c
  62. 5 4
      hmp-commands.hx
  63. 1 1
      hppa-dis.c
  64. 3 2
      hw/9pfs/virtio-9p-debug.c
  65. 173 0
      hw/9pfs/virtio-9p-device.c
  66. 66 72
      hw/9pfs/virtio-9p-local.c
  67. 15 7
      hw/9pfs/virtio-9p-posix-acl.c
  68. 7 4
      hw/9pfs/virtio-9p-xattr-user.c
  69. 4 3
      hw/9pfs/virtio-9p-xattr.c
  70. 6 3
      hw/9pfs/virtio-9p-xattr.h
  71. 35 130
      hw/9pfs/virtio-9p.c
  72. 7 0
      hw/9pfs/virtio-9p.h
  73. 1 5
      hw/ac97.c
  74. 3 1
      hw/acpi_piix4.c
  75. 0 1048
      hw/alpha_palcode.c
  76. 4 1
      hw/bitbang_i2c.c
  77. 1 0
      hw/boards.h
  78. 3 3
      hw/bt-hid.c
  79. 1 1
      hw/bt.h
  80. 1 1
      hw/eepro100.c
  81. 5 5
      hw/eeprom93xx.c
  82. 70 49
      hw/esp.c
  83. 30 5
      hw/ide/ahci.c
  84. 10 7
      hw/ide/core.c
  85. 3 3
      hw/ide/ich.c
  86. 1 1
      hw/ide/internal.h
  87. 2 6
      hw/ide/pci.c
  88. 64 17
      hw/ide/qdev.c
  89. 1 1
      hw/lan9118.c
  90. 130 84
      hw/lsi53c895a.c
  91. 1 1
      hw/msi.c
  92. 1 1
      hw/msix.c
  93. 1 1
      hw/mst_fpga.c
  94. 1 1
      hw/multiboot.c
  95. 20 17
      hw/pc.c
  96. 6 5
      hw/pc.h
  97. 64 7
      hw/pc_piix.c
  98. 5 3
      hw/pci.c
  99. 1 1
      hw/pci.h
  100. 1 0
      hw/pci_ids.h

+ 7 - 1
Changelog

@@ -1,3 +1,9 @@
+This file documents changes for QEMU releases 0.12 and earlier.
+For changelog information for later releases, see
+http://wiki.qemu.org/ChangeLog or look at the git history for
+more detailed information.
+
+
 version 0.12.0:
 version 0.12.0:
 
 
   - Update to SeaBIOS 0.5.0
   - Update to SeaBIOS 0.5.0
@@ -525,7 +531,7 @@ version 0.1.5:
 
 
  - ppc64 support + personality() patch (Rusty Russell)
  - ppc64 support + personality() patch (Rusty Russell)
  - first Alpha CPU patches (Falk Hueffner)
  - first Alpha CPU patches (Falk Hueffner)
- - removed bfd.h dependancy
+ - removed bfd.h dependency
  - fixed shrd, shld, idivl and divl on PowerPC.
  - fixed shrd, shld, idivl and divl on PowerPC.
  - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
  - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
 
 

+ 2 - 2
MAINTAINERS

@@ -56,8 +56,8 @@ M: Paul Brook <paul@codesourcery.com>
 Guest CPU cores (TCG):
 Guest CPU cores (TCG):
 ----------------------
 ----------------------
 Alpha
 Alpha
-M: qemu-devel@nongnu.org
-S: Orphan
+M: Richard Henderson <rth@twiddle.net>
+S: Maintained
 F: target-alpha/
 F: target-alpha/
 
 
 ARM
 ARM

+ 5 - 2
Makefile

@@ -88,6 +88,8 @@ include $(SRC_PATH)/Makefile.objs
 endif
 endif
 
 
 $(common-obj-y): $(GENERATED_HEADERS)
 $(common-obj-y): $(GENERATED_HEADERS)
+subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-malloc.o qemu-timer-common.o
+
 $(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis
 $(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis
 
 
 $(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(trace-obj-y) subdir-libdis-user subdir-libuser
 $(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(trace-obj-y) subdir-libdis-user subdir-libuser
@@ -132,14 +134,14 @@ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 
 
 check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o: $(GENERATED_HEADERS)
 check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o: $(GENERATED_HEADERS)
 
 
-CHECK_PROG_DEPS = qemu-malloc.o $(oslib-obj-y) $(trace-obj-y)
+CHECK_PROG_DEPS = qemu-malloc.o $(oslib-obj-y) $(trace-obj-y) qemu-tool.o
 
 
 check-qint: check-qint.o qint.o $(CHECK_PROG_DEPS)
 check-qint: check-qint.o qint.o $(CHECK_PROG_DEPS)
 check-qstring: check-qstring.o qstring.o $(CHECK_PROG_DEPS)
 check-qstring: check-qstring.o qstring.o $(CHECK_PROG_DEPS)
 check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(CHECK_PROG_DEPS)
 check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(CHECK_PROG_DEPS)
 check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS)
 check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS)
 check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
 check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
-check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o $(CHECK_PROG_DEPS)
+check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o qemu-error.o $(CHECK_PROG_DEPS)
 
 
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
 
@@ -183,6 +185,7 @@ ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \
 pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
 pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
 pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
+mpc8544ds.dtb \
 multiboot.bin linuxboot.bin \
 multiboot.bin linuxboot.bin \
 s390-zipl.rom \
 s390-zipl.rom \
 spapr-rtas.bin slof.bin
 spapr-rtas.bin slof.bin

+ 13 - 11
Makefile.objs

@@ -2,13 +2,13 @@
 # QObject
 # QObject
 qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
 qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
 qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
 qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
-qobject-obj-y += qerror.o
+qobject-obj-y += qerror.o error.o
 
 
 #######################################################################
 #######################################################################
 # oslib-obj-y is code depending on the OS (win32 vs posix)
 # oslib-obj-y is code depending on the OS (win32 vs posix)
 oslib-obj-y = osdep.o
 oslib-obj-y = osdep.o
-oslib-obj-$(CONFIG_WIN32) += oslib-win32.o
-oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
+oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
+oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
 
 
 #######################################################################
 #######################################################################
 # block-obj-y is code used by both qemu system emulation and qemu-img
 # block-obj-y is code used by both qemu system emulation and qemu-img
@@ -45,12 +45,14 @@ net-nested-$(CONFIG_SLIRP) += slirp.o
 net-nested-$(CONFIG_VDE) += vde.o
 net-nested-$(CONFIG_VDE) += vde.o
 net-obj-y += $(addprefix net/, $(net-nested-y))
 net-obj-y += $(addprefix net/, $(net-nested-y))
 
 
-ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS),yy)
+ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
 # Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
 # Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
 # only pull in the actual virtio-9p device if we also enabled virtio.
 # only pull in the actual virtio-9p device if we also enabled virtio.
 CONFIG_REALLY_VIRTFS=y
 CONFIG_REALLY_VIRTFS=y
+fsdev-nested-y = qemu-fsdev.o
+else
+fsdev-nested-y = qemu-fsdev-dummy.o
 endif
 endif
-fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o
 fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
 fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
 
 
 ######################################################################
 ######################################################################
@@ -143,8 +145,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
 common-obj-$(CONFIG_VNC) += $(addprefix ui/, $(vnc-obj-y))
 common-obj-$(CONFIG_VNC) += $(addprefix ui/, $(vnc-obj-y))
 
 
 common-obj-y += iov.o acl.o
 common-obj-y += iov.o acl.o
-common-obj-$(CONFIG_POSIX) += qemu-thread-posix.o compatfd.o
-common-obj-$(CONFIG_WIN32) += qemu-thread-win32.o
+common-obj-$(CONFIG_POSIX) += compatfd.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += qemu-timer.o qemu-timer-common.o
 common-obj-y += qemu-timer.o qemu-timer-common.o
 
 
@@ -171,6 +172,7 @@ user-obj-y += cutils.o cache-utils.o
 hw-obj-y =
 hw-obj-y =
 hw-obj-y += vl.o loader.o
 hw-obj-y += vl.o loader.o
 hw-obj-$(CONFIG_VIRTIO) += virtio.o virtio-console.o
 hw-obj-$(CONFIG_VIRTIO) += virtio.o virtio-console.o
+hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 hw-obj-y += fw_cfg.o
 hw-obj-y += fw_cfg.o
 hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o
 hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o
 hw-obj-$(CONFIG_PCI) += msix.o msi.o
 hw-obj-$(CONFIG_PCI) += msix.o msi.o
@@ -194,6 +196,7 @@ hw-obj-$(CONFIG_PCSPK) += pcspk.o
 hw-obj-$(CONFIG_PCKBD) += pckbd.o
 hw-obj-$(CONFIG_PCKBD) += pckbd.o
 hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
 hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
 hw-obj-$(CONFIG_USB_OHCI) += usb-ohci.o
 hw-obj-$(CONFIG_USB_OHCI) += usb-ohci.o
+hw-obj-$(CONFIG_USB_EHCI) += usb-ehci.o
 hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
@@ -285,12 +288,11 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o
 adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 
 
-9pfs-nested-$(CONFIG_REALLY_VIRTFS) = virtio-9p-debug.o
+9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
 
 
-hw-obj-$(CONFIG_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
-$(addprefix 9pfs/, $(9pfs-nested-y)): CFLAGS +=  -I$(SRC_PATH)/hw/
+hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 
 
 
 
 ######################################################################
 ######################################################################
@@ -335,7 +337,7 @@ trace-dtrace.h: trace-dtrace.dtrace
 	$(call quiet-command,dtrace -o $@ -h -s $<, "  GEN   trace-dtrace.h")
 	$(call quiet-command,dtrace -o $@ -h -s $<, "  GEN   trace-dtrace.h")
 
 
 # Normal practice is to name DTrace probe file with a '.d' extension
 # Normal practice is to name DTrace probe file with a '.d' extension
-# but that gets picked up by QEMU's Makefile as an external dependancy
+# but that gets picked up by QEMU's Makefile as an external dependency
 # rule file. So we use '.dtrace' instead
 # rule file. So we use '.dtrace' instead
 trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
 trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
 trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak
 trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak

+ 23 - 14
Makefile.target

@@ -71,8 +71,7 @@ all: $(PROGS) stap
 # cpu emulator library
 # cpu emulator library
 libobj-y = exec.o translate-all.o cpu-exec.o translate.o
 libobj-y = exec.o translate-all.o cpu-exec.o translate.o
 libobj-y += tcg/tcg.o
 libobj-y += tcg/tcg.o
-libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o
-libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o
+libobj-y += fpu/softfloat.o
 libobj-y += op_helper.o helper.o
 libobj-y += op_helper.o helper.o
 ifeq ($(TARGET_BASE_ARCH), i386)
 ifeq ($(TARGET_BASE_ARCH), i386)
 libobj-y += cpuid.o
 libobj-y += cpuid.o
@@ -94,10 +93,10 @@ tcg/tcg.o: cpu.h
 
 
 # HELPER_CFLAGS is used for all the code compiled with static register
 # HELPER_CFLAGS is used for all the code compiled with static register
 # variables
 # variables
-%_helper.o cpu-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+%_helper.o cpu-exec.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
 
 
 # Note: this is a workaround. The real fix is to avoid compiling
 # Note: this is a workaround. The real fix is to avoid compiling
-# cpu_signal_handler() in cpu-exec.c.
+# cpu_signal_handler() in user-exec.c.
 signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
 signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
 
 
 #########################################################
 #########################################################
@@ -110,7 +109,7 @@ $(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR
 QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
 QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
 obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
 obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
       elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
       elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
-      qemu-malloc.o $(oslib-obj-y)
+      qemu-malloc.o user-exec.o $(oslib-obj-y)
 
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 obj-$(TARGET_HAS_BFLT) += flatload.o
 
 
@@ -148,7 +147,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000
 LIBS+=-lmx
 LIBS+=-lmx
 
 
 obj-y = main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \
 obj-y = main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \
-        gdbstub.o
+        gdbstub.o user-exec.o
 
 
 obj-i386-y += ioport-user.o
 obj-i386-y += ioport-user.o
 
 
@@ -170,7 +169,7 @@ $(call set-vpath, $(SRC_PATH)/bsd-user)
 QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH)
 QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH)
 
 
 obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
 obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
-        gdbstub.o uaccess.o
+        gdbstub.o uaccess.o user-exec.o
 
 
 obj-i386-y += ioport-user.o
 obj-i386-y += ioport-user.o
 
 
@@ -191,10 +190,9 @@ obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
 # need to fix this properly
 # need to fix this properly
 obj-$(CONFIG_NO_PCI) += pci-stub.o
 obj-$(CONFIG_NO_PCI) += pci-stub.o
 obj-$(CONFIG_VIRTIO) += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
 obj-$(CONFIG_VIRTIO) += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 obj-y += vhost_net.o
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
-obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p.o
+obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
 obj-y += rwhandler.o
 obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
@@ -206,7 +204,19 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
 
 # xen backend driver support
 # xen backend driver support
-obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
+obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
+
+ifeq ($(TARGET_BASE_ARCH), i386)
+  CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
+else
+  CONFIG_NO_XEN = y
+endif
+# xen support
+CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y)
+obj-i386-$(CONFIG_XEN) += xen-all.o
+obj-$(CONFIG_NO_XEN) += xen-stub.o
+obj-i386-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o
+obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o
 
 
 # Inter-VM PCI shared memory
 # Inter-VM PCI shared memory
 CONFIG_IVSHMEM =
 CONFIG_IVSHMEM =
@@ -220,7 +230,7 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
 # Hardware support
 # Hardware support
 obj-i386-y += vga.o
 obj-i386-y += vga.o
 obj-i386-y += mc146818rtc.o i8259.o pc.o
 obj-i386-y += mc146818rtc.o i8259.o pc.o
-obj-i386-y += cirrus_vga.o apic.o ioapic.o piix_pci.o
+obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
 obj-i386-y += vmport.o
 obj-i386-y += vmport.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
 obj-i386-y += debugcon.o multiboot.o
 obj-i386-y += debugcon.o multiboot.o
@@ -364,7 +374,8 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
 
 
 obj-s390x-y = s390-virtio-bus.o s390-virtio.o
 obj-s390x-y = s390-virtio-bus.o s390-virtio.o
 
 
-obj-alpha-y = alpha_palcode.o
+obj-alpha-y = i8259.o mc146818rtc.o
+obj-alpha-y += vga.o cirrus_vga.o
 
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 
@@ -401,8 +412,6 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
 qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
 qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 
 
-9pfs/virtio-9p.o: CFLAGS +=  -I$(SRC_PATH)/hw/
-
 clean:
 clean:
 	rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
 	rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
 	rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o
 	rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o

+ 40 - 14
QMP/qmp.py

@@ -22,19 +22,24 @@ class QMPCapabilitiesError(QMPError):
     pass
     pass
 
 
 class QEMUMonitorProtocol:
 class QEMUMonitorProtocol:
-    def __init__(self, address):
+    def __init__(self, address, server=False):
         """
         """
         Create a QEMUMonitorProtocol class.
         Create a QEMUMonitorProtocol class.
 
 
         @param address: QEMU address, can be either a unix socket path (string)
         @param address: QEMU address, can be either a unix socket path (string)
                         or a tuple in the form ( address, port ) for a TCP
                         or a tuple in the form ( address, port ) for a TCP
                         connection
                         connection
-        @note No connection is established, this is done by the connect() method
+        @param server: server mode listens on the socket (bool)
+        @raise socket.error on socket connection errors
+        @note No connection is established, this is done by the connect() or
+              accept() methods
         """
         """
         self.__events = []
         self.__events = []
         self.__address = address
         self.__address = address
         self.__sock = self.__get_sock()
         self.__sock = self.__get_sock()
-        self.__sockfile = self.__sock.makefile()
+        if server:
+            self.__sock.bind(self.__address)
+            self.__sock.listen(1)
 
 
     def __get_sock(self):
     def __get_sock(self):
         if isinstance(self.__address, tuple):
         if isinstance(self.__address, tuple):
@@ -43,7 +48,18 @@ def __get_sock(self):
             family = socket.AF_UNIX
             family = socket.AF_UNIX
         return socket.socket(family, socket.SOCK_STREAM)
         return socket.socket(family, socket.SOCK_STREAM)
 
 
-    def __json_read(self):
+    def __negotiate_capabilities(self):
+        self.__sockfile = self.__sock.makefile()
+        greeting = self.__json_read()
+        if greeting is None or not greeting.has_key('QMP'):
+            raise QMPConnectError
+        # Greeting seems ok, negotiate capabilities
+        resp = self.cmd('qmp_capabilities')
+        if "return" in resp:
+            return greeting
+        raise QMPCapabilitiesError
+
+    def __json_read(self, only_event=False):
         while True:
         while True:
             data = self.__sockfile.readline()
             data = self.__sockfile.readline()
             if not data:
             if not data:
@@ -51,7 +67,8 @@ def __json_read(self):
             resp = json.loads(data)
             resp = json.loads(data)
             if 'event' in resp:
             if 'event' in resp:
                 self.__events.append(resp)
                 self.__events.append(resp)
-                continue
+                if not only_event:
+                    continue
             return resp
             return resp
 
 
     error = socket.error
     error = socket.error
@@ -66,14 +83,19 @@ def connect(self):
         @raise QMPCapabilitiesError if fails to negotiate capabilities
         @raise QMPCapabilitiesError if fails to negotiate capabilities
         """
         """
         self.__sock.connect(self.__address)
         self.__sock.connect(self.__address)
-        greeting = self.__json_read()
-        if greeting is None or not greeting.has_key('QMP'):
-            raise QMPConnectError
-        # Greeting seems ok, negotiate capabilities
-        resp = self.cmd('qmp_capabilities')
-        if "return" in resp:
-            return greeting
-        raise QMPCapabilitiesError
+        return self.__negotiate_capabilities()
+
+    def accept(self):
+        """
+        Await connection from QMP Monitor and perform capabilities negotiation.
+
+        @return QMP greeting dict
+        @raise socket.error on socket connection errors
+        @raise QMPConnectError if the greeting is not received
+        @raise QMPCapabilitiesError if fails to negotiate capabilities
+        """
+        self.__sock, _ = self.__sock.accept()
+        return self.__negotiate_capabilities()
 
 
     def cmd_obj(self, qmp_cmd):
     def cmd_obj(self, qmp_cmd):
         """
         """
@@ -106,9 +128,11 @@ def cmd(self, name, args=None, id=None):
             qmp_cmd['id'] = id
             qmp_cmd['id'] = id
         return self.cmd_obj(qmp_cmd)
         return self.cmd_obj(qmp_cmd)
 
 
-    def get_events(self):
+    def get_events(self, wait=False):
         """
         """
         Get a list of available QMP events.
         Get a list of available QMP events.
+
+        @param wait: block until an event is available (bool)
         """
         """
         self.__sock.setblocking(0)
         self.__sock.setblocking(0)
         try:
         try:
@@ -118,6 +142,8 @@ def get_events(self):
                 # No data available
                 # No data available
                 pass
                 pass
         self.__sock.setblocking(1)
         self.__sock.setblocking(1)
+        if not self.__events and wait:
+            self.__json_read(only_event=True)
         return self.__events
         return self.__events
 
 
     def clear_events(self):
     def clear_events(self):

+ 0 - 4
alpha-dis.c

@@ -238,10 +238,6 @@ extern const unsigned alpha_num_operands;
 #define AXP_REG_SP	30
 #define AXP_REG_SP	30
 #define AXP_REG_ZERO	31
 #define AXP_REG_ZERO	31
 
 
-#define bfd_mach_alpha_ev4  0x10
-#define bfd_mach_alpha_ev5  0x20
-#define bfd_mach_alpha_ev6  0x30
-
 enum bfd_reloc_code_real {
 enum bfd_reloc_code_real {
     BFD_RELOC_23_PCREL_S2,
     BFD_RELOC_23_PCREL_S2,
     BFD_RELOC_ALPHA_HINT
     BFD_RELOC_ALPHA_HINT

+ 5 - 0
arch_init.c

@@ -709,6 +709,11 @@ int audio_available(void)
 #endif
 #endif
 }
 }
 
 
+int tcg_available(void)
+{
+    return 1;
+}
+
 int kvm_available(void)
 int kvm_available(void)
 {
 {
 #ifdef CONFIG_KVM
 #ifdef CONFIG_KVM

+ 1 - 0
arch_init.h

@@ -27,6 +27,7 @@ void do_smbios_option(const char *optarg);
 void cpudef_init(void);
 void cpudef_init(void);
 int audio_available(void);
 int audio_available(void);
 void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus);
 void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus);
+int tcg_available(void);
 int kvm_available(void);
 int kvm_available(void);
 int xen_available(void);
 int xen_available(void);
 
 

+ 0 - 2
audio/audio_pt_int.c

@@ -6,8 +6,6 @@
 #include "audio_int.h"
 #include "audio_int.h"
 #include "audio_pt_int.h"
 #include "audio_pt_int.h"
 
 
-#include <signal.h>
-
 static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
 static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
                                        const char *fmt, ...)
                                        const char *fmt, ...)
 {
 {

+ 2 - 2
audio/mixeng_template.h

@@ -46,7 +46,7 @@ static mixeng_real inline glue (conv_, ET) (IN_T v)
 #endif
 #endif
 #else  /* !RECIPROCAL */
 #else  /* !RECIPROCAL */
 #ifdef SIGNED
 #ifdef SIGNED
-    return nv / (mixeng_real) (IN_MAX - IN_MIN);
+    return nv / (mixeng_real) ((mixeng_real) IN_MAX - IN_MIN);
 #else
 #else
     return (nv - HALF) / (mixeng_real) IN_MAX;
     return (nv - HALF) / (mixeng_real) IN_MAX;
 #endif
 #endif
@@ -63,7 +63,7 @@ static IN_T inline glue (clip_, ET) (mixeng_real v)
     }
     }
 
 
 #ifdef SIGNED
 #ifdef SIGNED
-    return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
+    return ENDIAN_CONVERT ((IN_T) (v * ((mixeng_real) IN_MAX - IN_MIN)));
 #else
 #else
     return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
     return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
 #endif
 #endif

+ 0 - 1
audio/sdlaudio.c

@@ -32,7 +32,6 @@
 #elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
 #elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
 #include <pthread.h>
 #include <pthread.h>
 #endif
 #endif
-#include <signal.h>
 #endif
 #endif
 
 
 #define AUDIO_CAP "sdl"
 #define AUDIO_CAP "sdl"

+ 9 - 40
block.c

@@ -439,13 +439,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
     bs->drv = drv;
     bs->drv = drv;
     bs->opaque = qemu_mallocz(drv->instance_size);
     bs->opaque = qemu_mallocz(drv->instance_size);
 
 
-    /*
-     * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a
-     * write cache to the guest.  We do need the fdatasync to flush
-     * out transactions for block allocations, and we maybe have a
-     * volatile write cache in our backing device to deal with.
-     */
-    if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE))
+    if (flags & BDRV_O_CACHE_WB)
         bs->enable_write_cache = 1;
         bs->enable_write_cache = 1;
 
 
     /*
     /*
@@ -455,7 +449,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
 
 
     /*
     /*
-     * Snapshots should be writeable.
+     * Snapshots should be writable.
      */
      */
     if (bs->is_temporary) {
     if (bs->is_temporary) {
         open_flags |= BDRV_O_RDWR;
         open_flags |= BDRV_O_RDWR;
@@ -747,7 +741,7 @@ DeviceState *bdrv_get_attached(BlockDriverState *bs)
  * Run consistency checks on an image
  * Run consistency checks on an image
  *
  *
  * Returns 0 if the check could be completed (it doesn't mean that the image is
  * Returns 0 if the check could be completed (it doesn't mean that the image is
- * free of errors) or -errno when an internal error occured. The results of the
+ * free of errors) or -errno when an internal error occurred. The results of the
  * check are stored in res.
  * check are stored in res.
  */
  */
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
@@ -1305,13 +1299,6 @@ void bdrv_set_geometry_hint(BlockDriverState *bs,
     bs->secs = secs;
     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)
 void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
 {
 {
     bs->translation = translation;
     bs->translation = translation;
@@ -1428,11 +1415,6 @@ void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
     }
     }
 }
 }
 
 
-int bdrv_get_type_hint(BlockDriverState *bs)
-{
-    return bs->type;
-}
-
 int bdrv_get_translation_hint(BlockDriverState *bs)
 int bdrv_get_translation_hint(BlockDriverState *bs)
 {
 {
     return bs->translation;
     return bs->translation;
@@ -1704,9 +1686,8 @@ static void bdrv_print_dict(QObject *obj, void *opaque)
 
 
     bs_dict = qobject_to_qdict(obj);
     bs_dict = qobject_to_qdict(obj);
 
 
-    monitor_printf(mon, "%s: type=%s removable=%d",
+    monitor_printf(mon, "%s: removable=%d",
                         qdict_get_str(bs_dict, "device"),
                         qdict_get_str(bs_dict, "device"),
-                        qdict_get_str(bs_dict, "type"),
                         qdict_get_bool(bs_dict, "removable"));
                         qdict_get_bool(bs_dict, "removable"));
 
 
     if (qdict_get_bool(bs_dict, "removable")) {
     if (qdict_get_bool(bs_dict, "removable")) {
@@ -1747,23 +1728,10 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
 
 
     QTAILQ_FOREACH(bs, &bdrv_states, list) {
     QTAILQ_FOREACH(bs, &bdrv_states, list) {
         QObject *bs_obj;
         QObject *bs_obj;
-        const char *type = "unknown";
-
-        switch(bs->type) {
-        case BDRV_TYPE_HD:
-            type = "hd";
-            break;
-        case BDRV_TYPE_CDROM:
-            type = "cdrom";
-            break;
-        case BDRV_TYPE_FLOPPY:
-            type = "floppy";
-            break;
-        }
 
 
-        bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, "
+        bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
                                     "'removable': %i, 'locked': %i }",
                                     "'removable': %i, 'locked': %i }",
-                                    bs->device_name, type, bs->removable,
+                                    bs->device_name, bs->removable,
                                     bs->locked);
                                     bs->locked);
 
 
         if (bs->drv) {
         if (bs->drv) {
@@ -2913,7 +2881,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
                     char *options, uint64_t img_size, int flags)
                     char *options, uint64_t img_size, int flags)
 {
 {
     QEMUOptionParameter *param = NULL, *create_options = NULL;
     QEMUOptionParameter *param = NULL, *create_options = NULL;
-    QEMUOptionParameter *backing_fmt, *backing_file;
+    QEMUOptionParameter *backing_fmt, *backing_file, *size;
     BlockDriverState *bs = NULL;
     BlockDriverState *bs = NULL;
     BlockDriver *drv, *proto_drv;
     BlockDriver *drv, *proto_drv;
     BlockDriver *backing_drv = NULL;
     BlockDriver *backing_drv = NULL;
@@ -2996,7 +2964,8 @@ int bdrv_img_create(const char *filename, const char *fmt,
 
 
     // The size for the image must always be specified, with one exception:
     // The size for the image must always be specified, with one exception:
     // If we are using a backing file, we can obtain the size from there
     // If we are using a backing file, we can obtain the size from there
-    if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {
+    size = get_option_parameter(param, BLOCK_OPT_SIZE);
+    if (size && size->value.n == -1) {
         if (backing_file && backing_file->value.s) {
         if (backing_file && backing_file->value.s) {
             uint64_t size;
             uint64_t size;
             char buf[32];
             char buf[32];

+ 0 - 5
block.h

@@ -152,9 +152,6 @@ int bdrv_has_zero_init(BlockDriverState *bs);
 int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
 int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
 	int *pnum);
 	int *pnum);
 
 
-#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_AUTO   0
 #define BIOS_ATA_TRANSLATION_NONE   1
 #define BIOS_ATA_TRANSLATION_NONE   1
 #define BIOS_ATA_TRANSLATION_LBA    2
 #define BIOS_ATA_TRANSLATION_LBA    2
@@ -163,7 +160,6 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
 
 
 void bdrv_set_geometry_hint(BlockDriverState *bs,
 void bdrv_set_geometry_hint(BlockDriverState *bs,
                             int cyls, int heads, int secs);
                             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_set_translation_hint(BlockDriverState *bs, int translation);
 void bdrv_get_geometry_hint(BlockDriverState *bs,
 void bdrv_get_geometry_hint(BlockDriverState *bs,
                             int *pcyls, int *pheads, int *psecs);
                             int *pcyls, int *pheads, int *psecs);
@@ -177,7 +173,6 @@ typedef enum FDriveType {
 void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
 void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
                                    int *max_track, int *last_sect,
                                    int *max_track, int *last_sect,
                                    FDriveType drive_in, FDriveType *drive);
                                    FDriveType drive_in, FDriveType *drive);
-int bdrv_get_type_hint(BlockDriverState *bs);
 int bdrv_get_translation_hint(BlockDriverState *bs);
 int bdrv_get_translation_hint(BlockDriverState *bs);
 void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
 void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
                        BlockErrorAction on_write_error);
                        BlockErrorAction on_write_error);

+ 1 - 1
block/qcow2-cluster.c

@@ -70,7 +70,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
 
 
     ret = qcow2_cache_flush(bs, s->refcount_block_cache);
     ret = qcow2_cache_flush(bs, s->refcount_block_cache);
     if (ret < 0) {
     if (ret < 0) {
-        return ret;
+        goto fail;
     }
     }
 
 
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);

+ 7 - 4
block/qcow2-refcount.c

@@ -1063,7 +1063,7 @@ fail:
  * Checks an image for refcount consistency.
  * Checks an image for refcount consistency.
  *
  *
  * Returns 0 if no errors are found, the number of errors in case the image is
  * Returns 0 if no errors are found, the number of errors in case the image is
- * detected as corrupted, and -errno when an internal error occured.
+ * detected as corrupted, and -errno when an internal error occurred.
  */
  */
 int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
 int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
 {
 {
@@ -1086,7 +1086,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
     ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
     ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
                        s->l1_table_offset, s->l1_size, 1);
                        s->l1_table_offset, s->l1_size, 1);
     if (ret < 0) {
     if (ret < 0) {
-        return ret;
+        goto fail;
     }
     }
 
 
     /* snapshots */
     /* snapshots */
@@ -1095,7 +1095,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
         ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
         ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
             sn->l1_table_offset, sn->l1_size, 0);
             sn->l1_table_offset, sn->l1_size, 0);
         if (ret < 0) {
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
         }
     }
     }
     inc_refcounts(bs, res, refcount_table, nb_clusters,
     inc_refcounts(bs, res, refcount_table, nb_clusters,
@@ -1159,8 +1159,11 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
         }
         }
     }
     }
 
 
+    ret = 0;
+
+fail:
     qemu_free(refcount_table);
     qemu_free(refcount_table);
 
 
-    return 0;
+    return ret;
 }
 }
 
 

+ 4 - 3
block/qcow2.c

@@ -229,7 +229,7 @@ static int qcow2_open(BlockDriverState *bs, int flags)
     }
     }
 
 
     /* alloc L2 table/refcount block cache */
     /* alloc L2 table/refcount block cache */
-    writethrough = ((flags & BDRV_O_CACHE_MASK) == 0);
+    writethrough = ((flags & BDRV_O_CACHE_WB) == 0);
     s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE, writethrough);
     s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE, writethrough);
     s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE,
     s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE,
         writethrough);
         writethrough);
@@ -1036,7 +1036,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
     const char *backing_fmt = NULL;
     const char *backing_fmt = NULL;
     uint64_t sectors = 0;
     uint64_t sectors = 0;
     int flags = 0;
     int flags = 0;
-    size_t cluster_size = 65536;
+    size_t cluster_size = DEFAULT_CLUSTER_SIZE;
     int prealloc = 0;
     int prealloc = 0;
 
 
     /* Read out options */
     /* Read out options */
@@ -1343,7 +1343,8 @@ static QEMUOptionParameter qcow2_create_options[] = {
     {
     {
         .name = BLOCK_OPT_CLUSTER_SIZE,
         .name = BLOCK_OPT_CLUSTER_SIZE,
         .type = OPT_SIZE,
         .type = OPT_SIZE,
-        .help = "qcow2 cluster size"
+        .help = "qcow2 cluster size",
+        .value = { .n = DEFAULT_CLUSTER_SIZE },
     },
     },
     {
     {
         .name = BLOCK_OPT_PREALLOC,
         .name = BLOCK_OPT_PREALLOC,

+ 2 - 0
block/qcow2.h

@@ -54,6 +54,8 @@
 /* Must be at least 4 to cover all cases of refcount table growth */
 /* Must be at least 4 to cover all cases of refcount table growth */
 #define REFCOUNT_CACHE_SIZE 4
 #define REFCOUNT_CACHE_SIZE 4
 
 
+#define DEFAULT_CLUSTER_SIZE 65536
+
 typedef struct QCowHeader {
 typedef struct QCowHeader {
     uint32_t magic;
     uint32_t magic;
     uint32_t version;
     uint32_t version;

+ 125 - 4
block/qed.c

@@ -12,6 +12,7 @@
  *
  *
  */
  */
 
 
+#include "qemu-timer.h"
 #include "trace.h"
 #include "trace.h"
 #include "qed.h"
 #include "qed.h"
 #include "qerror.h"
 #include "qerror.h"
@@ -291,6 +292,88 @@ static CachedL2Table *qed_new_l2_table(BDRVQEDState *s)
 
 
 static void qed_aio_next_io(void *opaque, int ret);
 static void qed_aio_next_io(void *opaque, int ret);
 
 
+static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
+{
+    assert(!s->allocating_write_reqs_plugged);
+
+    s->allocating_write_reqs_plugged = true;
+}
+
+static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
+{
+    QEDAIOCB *acb;
+
+    assert(s->allocating_write_reqs_plugged);
+
+    s->allocating_write_reqs_plugged = false;
+
+    acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
+    if (acb) {
+        qed_aio_next_io(acb, 0);
+    }
+}
+
+static void qed_finish_clear_need_check(void *opaque, int ret)
+{
+    /* Do nothing */
+}
+
+static void qed_flush_after_clear_need_check(void *opaque, int ret)
+{
+    BDRVQEDState *s = opaque;
+
+    bdrv_aio_flush(s->bs, qed_finish_clear_need_check, s);
+
+    /* No need to wait until flush completes */
+    qed_unplug_allocating_write_reqs(s);
+}
+
+static void qed_clear_need_check(void *opaque, int ret)
+{
+    BDRVQEDState *s = opaque;
+
+    if (ret) {
+        qed_unplug_allocating_write_reqs(s);
+        return;
+    }
+
+    s->header.features &= ~QED_F_NEED_CHECK;
+    qed_write_header(s, qed_flush_after_clear_need_check, s);
+}
+
+static void qed_need_check_timer_cb(void *opaque)
+{
+    BDRVQEDState *s = opaque;
+
+    /* The timer should only fire when allocating writes have drained */
+    assert(!QSIMPLEQ_FIRST(&s->allocating_write_reqs));
+
+    trace_qed_need_check_timer_cb(s);
+
+    qed_plug_allocating_write_reqs(s);
+
+    /* Ensure writes are on disk before clearing flag */
+    bdrv_aio_flush(s->bs, qed_clear_need_check, s);
+}
+
+static void qed_start_need_check_timer(BDRVQEDState *s)
+{
+    trace_qed_start_need_check_timer(s);
+
+    /* Use vm_clock so we don't alter the image file while suspended for
+     * migration.
+     */
+    qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) +
+                   get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT);
+}
+
+/* It's okay to call this multiple times or when no timer is started */
+static void qed_cancel_need_check_timer(BDRVQEDState *s)
+{
+    trace_qed_cancel_need_check_timer(s);
+    qemu_del_timer(s->need_check_timer);
+}
+
 static int bdrv_qed_open(BlockDriverState *bs, int flags)
 static int bdrv_qed_open(BlockDriverState *bs, int flags)
 {
 {
     BDRVQEDState *s = bs->opaque;
     BDRVQEDState *s = bs->opaque;
@@ -406,7 +489,10 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
             BdrvCheckResult result = {0};
             BdrvCheckResult result = {0};
 
 
             ret = qed_check(s, &result, true);
             ret = qed_check(s, &result, true);
-            if (!ret && !result.corruptions && !result.check_errors) {
+            if (ret) {
+                goto out;
+            }
+            if (!result.corruptions && !result.check_errors) {
                 /* Ensure fixes reach storage before clearing check bit */
                 /* Ensure fixes reach storage before clearing check bit */
                 bdrv_flush(s->bs);
                 bdrv_flush(s->bs);
 
 
@@ -416,6 +502,9 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
         }
         }
     }
     }
 
 
+    s->need_check_timer = qemu_new_timer_ns(vm_clock,
+                                            qed_need_check_timer_cb, s);
+
 out:
 out:
     if (ret) {
     if (ret) {
         qed_free_l2_cache(&s->l2_cache);
         qed_free_l2_cache(&s->l2_cache);
@@ -428,6 +517,9 @@ static void bdrv_qed_close(BlockDriverState *bs)
 {
 {
     BDRVQEDState *s = bs->opaque;
     BDRVQEDState *s = bs->opaque;
 
 
+    qed_cancel_need_check_timer(s);
+    qemu_free_timer(s->need_check_timer);
+
     /* Ensure writes reach stable storage */
     /* Ensure writes reach stable storage */
     bdrv_flush(bs->file);
     bdrv_flush(bs->file);
 
 
@@ -809,6 +901,8 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
         acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
         acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
         if (acb) {
         if (acb) {
             qed_aio_next_io(acb, 0);
             qed_aio_next_io(acb, 0);
+        } else if (s->header.features & QED_F_NEED_CHECK) {
+            qed_start_need_check_timer(s);
         }
         }
     }
     }
 }
 }
@@ -1014,11 +1108,17 @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
 {
 {
     BDRVQEDState *s = acb_to_s(acb);
     BDRVQEDState *s = acb_to_s(acb);
 
 
+    /* Cancel timer when the first allocating request comes in */
+    if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) {
+        qed_cancel_need_check_timer(s);
+    }
+
     /* Freeze this request if another allocating write is in progress */
     /* Freeze this request if another allocating write is in progress */
     if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
     if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
         QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next);
         QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next);
     }
     }
-    if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
+    if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) ||
+        s->allocating_write_reqs_plugged) {
         return; /* wait for existing request to finish */
         return; /* wait for existing request to finish */
     }
     }
 
 
@@ -1233,7 +1333,27 @@ static BlockDriverAIOCB *bdrv_qed_aio_flush(BlockDriverState *bs,
 
 
 static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset)
 static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset)
 {
 {
-    return -ENOTSUP;
+    BDRVQEDState *s = bs->opaque;
+    uint64_t old_image_size;
+    int ret;
+
+    if (!qed_is_image_size_valid(offset, s->header.cluster_size,
+                                 s->header.table_size)) {
+        return -EINVAL;
+    }
+
+    /* Shrinking is currently not supported */
+    if ((uint64_t)offset < s->header.image_size) {
+        return -ENOTSUP;
+    }
+
+    old_image_size = s->header.image_size;
+    s->header.image_size = offset;
+    ret = qed_write_header_sync(s);
+    if (ret < 0) {
+        s->header.image_size = old_image_size;
+    }
+    return ret;
 }
 }
 
 
 static int64_t bdrv_qed_getlength(BlockDriverState *bs)
 static int64_t bdrv_qed_getlength(BlockDriverState *bs)
@@ -1344,7 +1464,8 @@ static QEMUOptionParameter qed_create_options[] = {
     }, {
     }, {
         .name = BLOCK_OPT_CLUSTER_SIZE,
         .name = BLOCK_OPT_CLUSTER_SIZE,
         .type = OPT_SIZE,
         .type = OPT_SIZE,
-        .help = "Cluster size (in bytes)"
+        .help = "Cluster size (in bytes)",
+        .value = { .n = QED_DEFAULT_CLUSTER_SIZE },
     }, {
     }, {
         .name = BLOCK_OPT_TABLE_SIZE,
         .name = BLOCK_OPT_TABLE_SIZE,
         .type = OPT_SIZE,
         .type = OPT_SIZE,

+ 7 - 0
block/qed.h

@@ -78,6 +78,9 @@ enum {
     QED_MIN_TABLE_SIZE = 1,        /* in clusters */
     QED_MIN_TABLE_SIZE = 1,        /* in clusters */
     QED_MAX_TABLE_SIZE = 16,
     QED_MAX_TABLE_SIZE = 16,
     QED_DEFAULT_TABLE_SIZE = 4,
     QED_DEFAULT_TABLE_SIZE = 4,
+
+    /* Delay to flush and clean image after last allocating write completes */
+    QED_NEED_CHECK_TIMEOUT = 5,    /* in seconds */
 };
 };
 
 
 typedef struct {
 typedef struct {
@@ -157,6 +160,10 @@ typedef struct {
 
 
     /* Allocating write request queue */
     /* Allocating write request queue */
     QSIMPLEQ_HEAD(, QEDAIOCB) allocating_write_reqs;
     QSIMPLEQ_HEAD(, QEDAIOCB) allocating_write_reqs;
+    bool allocating_write_reqs_plugged;
+
+    /* Periodic flush and clear need check flag */
+    QEMUTimer *need_check_timer;
 } BDRVQEDState;
 } BDRVQEDState;
 
 
 enum {
 enum {

+ 76 - 3
block/raw-posix.c

@@ -43,7 +43,6 @@
 
 
 #ifdef __sun__
 #ifdef __sun__
 #define _POSIX_PTHREAD_SEMANTICS 1
 #define _POSIX_PTHREAD_SEMANTICS 1
-#include <signal.h>
 #include <sys/dkio.h>
 #include <sys/dkio.h>
 #endif
 #endif
 #ifdef __linux__
 #ifdef __linux__
@@ -53,7 +52,6 @@
 #include <linux/fd.h>
 #include <linux/fd.h>
 #endif
 #endif
 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include <signal.h>
 #include <sys/disk.h>
 #include <sys/disk.h>
 #include <sys/cdio.h>
 #include <sys/cdio.h>
 #endif
 #endif
@@ -64,6 +62,13 @@
 #include <sys/dkio.h>
 #include <sys/dkio.h>
 #endif
 #endif
 
 
+#ifdef __NetBSD__
+#include <sys/ioctl.h>
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#include <sys/disk.h>
+#endif
+
 #ifdef __DragonFly__
 #ifdef __DragonFly__
 #include <sys/ioctl.h>
 #include <sys/ioctl.h>
 #include <sys/diskslice.h>
 #include <sys/diskslice.h>
@@ -136,12 +141,55 @@ static int64_t raw_getlength(BlockDriverState *bs);
 static int cdrom_reopen(BlockDriverState *bs);
 static int cdrom_reopen(BlockDriverState *bs);
 #endif
 #endif
 
 
+#if defined(__NetBSD__)
+static int raw_normalize_devicepath(const char **filename)
+{
+    static char namebuf[PATH_MAX];
+    const char *dp, *fname;
+    struct stat sb;
+
+    fname = *filename;
+    dp = strrchr(fname, '/');
+    if (lstat(fname, &sb) < 0) {
+        fprintf(stderr, "%s: stat failed: %s\n",
+            fname, strerror(errno));
+        return -errno;
+    }
+
+    if (!S_ISBLK(sb.st_mode)) {
+        return 0;
+    }
+
+    if (dp == NULL) {
+        snprintf(namebuf, PATH_MAX, "r%s", fname);
+    } else {
+        snprintf(namebuf, PATH_MAX, "%.*s/r%s",
+            (int)(dp - fname), fname, dp + 1);
+    }
+    fprintf(stderr, "%s is a block device", fname);
+    *filename = namebuf;
+    fprintf(stderr, ", using %s\n", *filename);
+
+    return 0;
+}
+#else
+static int raw_normalize_devicepath(const char **filename)
+{
+    return 0;
+}
+#endif
+
 static int raw_open_common(BlockDriverState *bs, const char *filename,
 static int raw_open_common(BlockDriverState *bs, const char *filename,
                            int bdrv_flags, int open_flags)
                            int bdrv_flags, int open_flags)
 {
 {
     BDRVRawState *s = bs->opaque;
     BDRVRawState *s = bs->opaque;
     int fd, ret;
     int fd, ret;
 
 
+    ret = raw_normalize_devicepath(&filename);
+    if (ret != 0) {
+        return ret;
+    }
+
     s->open_flags = open_flags | O_BINARY;
     s->open_flags = open_flags | O_BINARY;
     s->open_flags &= ~O_ACCMODE;
     s->open_flags &= ~O_ACCMODE;
     if (bdrv_flags & BDRV_O_RDWR) {
     if (bdrv_flags & BDRV_O_RDWR) {
@@ -154,7 +202,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
      * and O_DIRECT for no caching. */
      * and O_DIRECT for no caching. */
     if ((bdrv_flags & BDRV_O_NOCACHE))
     if ((bdrv_flags & BDRV_O_NOCACHE))
         s->open_flags |= O_DIRECT;
         s->open_flags |= O_DIRECT;
-    else if (!(bdrv_flags & BDRV_O_CACHE_WB))
+    if (!(bdrv_flags & BDRV_O_CACHE_WB))
         s->open_flags |= O_DSYNC;
         s->open_flags |= O_DSYNC;
 
 
     s->fd = -1;
     s->fd = -1;
@@ -622,6 +670,31 @@ static int64_t raw_getlength(BlockDriverState *bs)
     } else
     } else
         return st.st_size;
         return st.st_size;
 }
 }
+#elif defined(__NetBSD__)
+static int64_t raw_getlength(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    int fd = s->fd;
+    struct stat st;
+
+    if (fstat(fd, &st))
+        return -1;
+    if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
+        struct dkwedge_info dkw;
+
+        if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) {
+            return dkw.dkw_size * 512;
+        } else {
+            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;
+}
 #elif defined(__sun__)
 #elif defined(__sun__)
 static int64_t raw_getlength(BlockDriverState *bs)
 static int64_t raw_getlength(BlockDriverState *bs)
 {
 {

+ 6 - 6
block/raw-win32.c

@@ -88,9 +88,9 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
     }
     }
 
 
     overlapped = FILE_ATTRIBUTE_NORMAL;
     overlapped = FILE_ATTRIBUTE_NORMAL;
-    if ((flags & BDRV_O_NOCACHE))
-        overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
-    else if (!(flags & BDRV_O_CACHE_WB))
+    if (flags & BDRV_O_NOCACHE)
+        overlapped |= FILE_FLAG_NO_BUFFERING;
+    if (!(flags & BDRV_O_CACHE_WB))
         overlapped |= FILE_FLAG_WRITE_THROUGH;
         overlapped |= FILE_FLAG_WRITE_THROUGH;
     s->hfile = CreateFile(filename, access_flags,
     s->hfile = CreateFile(filename, access_flags,
                           FILE_SHARE_READ, NULL,
                           FILE_SHARE_READ, NULL,
@@ -349,9 +349,9 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
     create_flags = OPEN_EXISTING;
     create_flags = OPEN_EXISTING;
 
 
     overlapped = FILE_ATTRIBUTE_NORMAL;
     overlapped = FILE_ATTRIBUTE_NORMAL;
-    if ((flags & BDRV_O_NOCACHE))
-        overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
-    else if (!(flags & BDRV_O_CACHE_WB))
+    if (flags & BDRV_O_NOCACHE)
+        overlapped |= FILE_FLAG_NO_BUFFERING;
+    if (!(flags & BDRV_O_CACHE_WB))
         overlapped |= FILE_FLAG_WRITE_THROUGH;
         overlapped |= FILE_FLAG_WRITE_THROUGH;
     s->hfile = CreateFile(filename, access_flags,
     s->hfile = CreateFile(filename, access_flags,
                           FILE_SHARE_READ, NULL,
                           FILE_SHARE_READ, NULL,

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 294 - 411
block/rbd.c


+ 0 - 71
block/rbd_types.h

@@ -1,71 +0,0 @@
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation.  See file COPYING.LIB.
- *
- */
-
-#ifndef CEPH_RBD_TYPES_H
-#define CEPH_RBD_TYPES_H
-
-
-/*
- * rbd image 'foo' consists of objects
- *   foo.rbd      - image metadata
- *   foo.00000000
- *   foo.00000001
- *   ...          - data
- */
-
-#define RBD_SUFFIX              ".rbd"
-#define RBD_DIRECTORY           "rbd_directory"
-#define RBD_INFO                "rbd_info"
-
-#define RBD_DEFAULT_OBJ_ORDER   22   /* 4MB */
-
-#define RBD_MAX_OBJ_NAME_SIZE   96
-#define RBD_MAX_BLOCK_NAME_SIZE 24
-#define RBD_MAX_SEG_NAME_SIZE   128
-
-#define RBD_COMP_NONE           0
-#define RBD_CRYPT_NONE          0
-
-#define RBD_HEADER_TEXT         "<<< Rados Block Device Image >>>\n"
-#define RBD_HEADER_SIGNATURE    "RBD"
-#define RBD_HEADER_VERSION      "001.005"
-
-struct rbd_info {
-    uint64_t max_id;
-} __attribute__ ((packed));
-
-struct rbd_obj_snap_ondisk {
-    uint64_t id;
-    uint64_t image_size;
-} __attribute__((packed));
-
-struct rbd_obj_header_ondisk {
-    char text[40];
-    char block_name[RBD_MAX_BLOCK_NAME_SIZE];
-    char signature[4];
-    char version[8];
-    struct {
-        uint8_t order;
-        uint8_t crypt_type;
-        uint8_t comp_type;
-        uint8_t unused;
-    } __attribute__((packed)) options;
-    uint64_t image_size;
-    uint64_t snap_seq;
-    uint32_t snap_count;
-    uint32_t reserved;
-    uint64_t snap_names_len;
-    struct rbd_obj_snap_ondisk snaps[0];
-} __attribute__((packed));
-
-
-#endif

+ 2 - 2
block/sheepdog.c

@@ -196,7 +196,7 @@ static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
     return hval;
     return hval;
 }
 }
 
 
-static inline int is_data_obj_writeable(SheepdogInode *inode, unsigned int idx)
+static inline int is_data_obj_writable(SheepdogInode *inode, unsigned int idx)
 {
 {
     return inode->vdi_id == inode->data_vdi_id[idx];
     return inode->vdi_id == inode->data_vdi_id[idx];
 }
 }
@@ -1577,7 +1577,7 @@ static void sd_readv_writev_bh_cb(void *p)
 
 
             create = 1;
             create = 1;
         } else if (acb->aiocb_type == AIOCB_WRITE_UDATA
         } else if (acb->aiocb_type == AIOCB_WRITE_UDATA
-                   && !is_data_obj_writeable(inode, idx)) {
+                   && !is_data_obj_writable(inode, idx)) {
             /* Copy-On-Write */
             /* Copy-On-Write */
             create = 1;
             create = 1;
             old_oid = oid;
             old_oid = oid;

+ 4 - 2
block/vdi.c

@@ -87,6 +87,7 @@ void uuid_unparse(const uuid_t uu, char *out);
 #define MiB     (KiB * KiB)
 #define MiB     (KiB * KiB)
 
 
 #define SECTOR_SIZE 512
 #define SECTOR_SIZE 512
+#define DEFAULT_CLUSTER_SIZE (1 * MiB)
 
 
 #if defined(CONFIG_VDI_DEBUG)
 #if defined(CONFIG_VDI_DEBUG)
 #define logout(fmt, ...) \
 #define logout(fmt, ...) \
@@ -803,7 +804,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
     int result = 0;
     int result = 0;
     uint64_t bytes = 0;
     uint64_t bytes = 0;
     uint32_t blocks;
     uint32_t blocks;
-    size_t block_size = 1 * MiB;
+    size_t block_size = DEFAULT_CLUSTER_SIZE;
     uint32_t image_type = VDI_TYPE_DYNAMIC;
     uint32_t image_type = VDI_TYPE_DYNAMIC;
     VdiHeader header;
     VdiHeader header;
     size_t i;
     size_t i;
@@ -921,7 +922,8 @@ static QEMUOptionParameter vdi_create_options[] = {
     {
     {
         .name = BLOCK_OPT_CLUSTER_SIZE,
         .name = BLOCK_OPT_CLUSTER_SIZE,
         .type = OPT_SIZE,
         .type = OPT_SIZE,
-        .help = "VDI cluster (block) size"
+        .help = "VDI cluster (block) size",
+        .value = { .n = DEFAULT_CLUSTER_SIZE },
     },
     },
 #endif
 #endif
 #if defined(CONFIG_VDI_STATIC_IMAGE)
 #if defined(CONFIG_VDI_STATIC_IMAGE)

+ 14 - 8
block/vmdk.c

@@ -716,11 +716,11 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
         return -errno;
         return -errno;
     magic = cpu_to_be32(VMDK4_MAGIC);
     magic = cpu_to_be32(VMDK4_MAGIC);
     memset(&header, 0, sizeof(header));
     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);
+    header.version = 1;
+    header.flags = 3; /* ?? */
+    header.capacity = total_size;
+    header.granularity = 128;
+    header.num_gtes_per_gte = 512;
 
 
     grains = (total_size + header.granularity - 1) / header.granularity;
     grains = (total_size + header.granularity - 1) / header.granularity;
     gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
     gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
@@ -736,6 +736,12 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
          header.granularity - 1) / header.granularity) *
          header.granularity - 1) / header.granularity) *
         header.granularity;
         header.granularity;
 
 
+    /* swap endianness for all header fields */
+    header.version = cpu_to_le32(header.version);
+    header.flags = cpu_to_le32(header.flags);
+    header.capacity = cpu_to_le64(header.capacity);
+    header.granularity = cpu_to_le64(header.granularity);
+    header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte);
     header.desc_offset = cpu_to_le64(header.desc_offset);
     header.desc_offset = cpu_to_le64(header.desc_offset);
     header.desc_size = cpu_to_le64(header.desc_size);
     header.desc_size = cpu_to_le64(header.desc_size);
     header.rgd_offset = cpu_to_le64(header.rgd_offset);
     header.rgd_offset = cpu_to_le64(header.rgd_offset);
@@ -759,7 +765,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
         goto exit;
         goto exit;
     }
     }
 
 
-    ret = ftruncate(fd, header.grain_offset << 9);
+    ret = ftruncate(fd, le64_to_cpu(header.grain_offset) << 9);
     if (ret < 0) {
     if (ret < 0) {
         ret = -errno;
         ret = -errno;
         goto exit;
         goto exit;
@@ -767,7 +773,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
 
 
     /* write grain directory */
     /* write grain directory */
     lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
     lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
-    for (i = 0, tmp = header.rgd_offset + gd_size;
+    for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_size;
          i < gt_count; i++, tmp += gt_size) {
          i < gt_count; i++, tmp += gt_size) {
         ret = qemu_write_full(fd, &tmp, sizeof(tmp));
         ret = qemu_write_full(fd, &tmp, sizeof(tmp));
         if (ret != sizeof(tmp)) {
         if (ret != sizeof(tmp)) {
@@ -778,7 +784,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
 
 
     /* write backup grain directory */
     /* write backup grain directory */
     lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
     lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
-    for (i = 0, tmp = header.gd_offset + gd_size;
+    for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_size;
          i < gt_count; i++, tmp += gt_size) {
          i < gt_count; i++, tmp += gt_size) {
         ret = qemu_write_full(fd, &tmp, sizeof(tmp));
         ret = qemu_write_full(fd, &tmp, sizeof(tmp));
         if (ret != sizeof(tmp)) {
         if (ret != sizeof(tmp)) {

+ 0 - 1
block_int.h

@@ -194,7 +194,6 @@ struct BlockDriverState {
     /* NOTE: the following infos are only hints for real hardware
     /* NOTE: the following infos are only hints for real hardware
        drivers. They are not used by the block driver */
        drivers. They are not used by the block driver */
     int cyls, heads, secs, translation;
     int cyls, heads, secs, translation;
-    int type;
     BlockErrorAction on_read_error, on_write_error;
     BlockErrorAction on_read_error, on_write_error;
     char device_name[32];
     char device_name[32];
     unsigned long *dirty_bitmap;
     unsigned long *dirty_bitmap;

+ 4 - 3
blockdev.c

@@ -326,7 +326,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 
 
     if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
     if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
         if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
         if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
-            bdrv_flags |= BDRV_O_NOCACHE;
+            bdrv_flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
         } else if (!strcmp(buf, "writeback")) {
         } else if (!strcmp(buf, "writeback")) {
             bdrv_flags |= BDRV_O_CACHE_WB;
             bdrv_flags |= BDRV_O_CACHE_WB;
         } else if (!strcmp(buf, "unsafe")) {
         } else if (!strcmp(buf, "unsafe")) {
@@ -487,7 +487,8 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
             }
             }
 	    break;
 	    break;
 	case MEDIA_CDROM:
 	case MEDIA_CDROM:
-            bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
+            bdrv_set_removable(dinfo->bdrv, 1);
+            dinfo->media_cd = 1;
 	    break;
 	    break;
 	}
 	}
         break;
         break;
@@ -495,7 +496,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
         /* FIXME: This isn't really a floppy, but it's a reasonable
         /* FIXME: This isn't really a floppy, but it's a reasonable
            approximation.  */
            approximation.  */
     case IF_FLOPPY:
     case IF_FLOPPY:
-        bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
+        bdrv_set_removable(dinfo->bdrv, 1);
         break;
         break;
     case IF_PFLASH:
     case IF_PFLASH:
     case IF_MTD:
     case IF_MTD:

+ 1 - 0
blockdev.h

@@ -33,6 +33,7 @@ struct DriveInfo {
     int bus;
     int bus;
     int unit;
     int unit;
     int auto_del;               /* see blockdev_mark_auto_del() */
     int auto_del;               /* see blockdev_mark_auto_del() */
+    int media_cd;
     QemuOpts *opts;
     QemuOpts *opts;
     char serial[BLOCK_SERIAL_STRLEN + 1];
     char serial[BLOCK_SERIAL_STRLEN + 1];
     QTAILQ_ENTRY(DriveInfo) next;
     QTAILQ_ENTRY(DriveInfo) next;

+ 1 - 1
bsd-user/main.c

@@ -237,7 +237,7 @@ void cpu_loop(CPUX86State *env)
             break;
             break;
 #ifndef TARGET_ABI32
 #ifndef TARGET_ABI32
         case EXCP_SYSCALL:
         case EXCP_SYSCALL:
-            /* syscall from syscall intruction */
+            /* syscall from syscall instruction */
             if (bsd_type == target_freebsd)
             if (bsd_type == target_freebsd)
                 env->regs[R_EAX] = do_freebsd_syscall(env,
                 env->regs[R_EAX] = do_freebsd_syscall(env,
                                                       env->regs[R_EAX],
                                                       env->regs[R_EAX],

+ 1 - 1
bsd-user/qemu.h

@@ -323,7 +323,7 @@ abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
 abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
 abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
 
 
 /* Functions for accessing guest memory.  The tget and tput functions
 /* Functions for accessing guest memory.  The tget and tput functions
-   read/write single values, byteswapping as neccessary.  The lock_user
+   read/write single values, byteswapping as necessary.  The lock_user
    gets a pointer to a contiguous area of guest memory, but does not perform
    gets a pointer to a contiguous area of guest memory, but does not perform
    and byteswapping.  lock_user may return either a pointer to the guest
    and byteswapping.  lock_user may return either a pointer to the guest
    memory, or a temporary buffer.  */
    memory, or a temporary buffer.  */

+ 0 - 1
bsd-user/syscall.c

@@ -31,7 +31,6 @@
 #include <sys/syscall.h>
 #include <sys/syscall.h>
 #include <sys/param.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <sys/sysctl.h>
-#include <signal.h>
 #include <utime.h>
 #include <utime.h>
 
 
 #include "qemu.h"
 #include "qemu.h"

+ 1 - 1
compatfd.c

@@ -29,7 +29,7 @@ static void *sigwait_compat(void *opaque)
     sigset_t all;
     sigset_t all;
 
 
     sigfillset(&all);
     sigfillset(&all);
-    sigprocmask(SIG_BLOCK, &all, NULL);
+    pthread_sigmask(SIG_BLOCK, &all, NULL);
 
 
     while (1) {
     while (1) {
         int sig;
         int sig;

+ 176 - 98
configure

@@ -127,6 +127,7 @@ vnc_jpeg=""
 vnc_png=""
 vnc_png=""
 vnc_thread="no"
 vnc_thread="no"
 xen=""
 xen=""
+xen_ctrl_version=""
 linux_aio=""
 linux_aio=""
 attr=""
 attr=""
 vhost_net=""
 vhost_net=""
@@ -228,7 +229,7 @@ sdl_config="${cross_prefix}${SDL_CONFIG-sdl-config}"
 # default flags for all hosts
 # default flags for all hosts
 QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
 QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
 CFLAGS="-g $CFLAGS"
 CFLAGS="-g $CFLAGS"
-QEMU_CFLAGS="-Wall -Wundef -Wendif-labels -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
+QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
 QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
 QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
 QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
 QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
 QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
 QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
@@ -822,6 +823,75 @@ esac
 
 
 [ -z "$guest_base" ] && guest_base="$host_guest_base"
 [ -z "$guest_base" ] && guest_base="$host_guest_base"
 
 
+
+default_target_list=""
+
+# these targets are portable
+if [ "$softmmu" = "yes" ] ; then
+    default_target_list="\
+i386-softmmu \
+x86_64-softmmu \
+alpha-softmmu \
+arm-softmmu \
+cris-softmmu \
+lm32-softmmu \
+m68k-softmmu \
+microblaze-softmmu \
+microblazeel-softmmu \
+mips-softmmu \
+mipsel-softmmu \
+mips64-softmmu \
+mips64el-softmmu \
+ppc-softmmu \
+ppcemb-softmmu \
+ppc64-softmmu \
+sh4-softmmu \
+sh4eb-softmmu \
+sparc-softmmu \
+sparc64-softmmu \
+s390x-softmmu \
+"
+fi
+# the following are Linux specific
+if [ "$linux_user" = "yes" ] ; then
+    default_target_list="${default_target_list}\
+i386-linux-user \
+x86_64-linux-user \
+alpha-linux-user \
+arm-linux-user \
+armeb-linux-user \
+cris-linux-user \
+m68k-linux-user \
+microblaze-linux-user \
+microblazeel-linux-user \
+mips-linux-user \
+mipsel-linux-user \
+ppc-linux-user \
+ppc64-linux-user \
+ppc64abi32-linux-user \
+sh4-linux-user \
+sh4eb-linux-user \
+sparc-linux-user \
+sparc64-linux-user \
+sparc32plus-linux-user \
+unicore32-linux-user \
+s390x-linux-user \
+"
+fi
+# the following are Darwin specific
+if [ "$darwin_user" = "yes" ] ; then
+    default_target_list="$default_target_list i386-darwin-user ppc-darwin-user "
+fi
+# the following are BSD specific
+if [ "$bsd_user" = "yes" ] ; then
+    default_target_list="${default_target_list}\
+i386-bsd-user \
+x86_64-bsd-user \
+sparc-bsd-user \
+sparc64-bsd-user \
+"
+fi
+
 if test x"$show_help" = x"yes" ; then
 if test x"$show_help" = x"yes" ; then
 cat << EOF
 cat << EOF
 
 
@@ -834,7 +904,9 @@ echo "  --help                   print this message"
 echo "  --prefix=PREFIX          install in PREFIX [$prefix]"
 echo "  --prefix=PREFIX          install in PREFIX [$prefix]"
 echo "  --interp-prefix=PREFIX   where to find shared libraries, etc."
 echo "  --interp-prefix=PREFIX   where to find shared libraries, etc."
 echo "                           use %M for cpu name [$interp_prefix]"
 echo "                           use %M for cpu name [$interp_prefix]"
-echo "  --target-list=LIST       set target list [$target_list]"
+echo "  --target-list=LIST       set target list (default: build everything)"
+echo "Available targets: $default_target_list" | \
+    fold -s -w 53 | sed -e 's/^/                           /'
 echo ""
 echo ""
 echo "Advanced options (experts only):"
 echo "Advanced options (experts only):"
 echo "  --source-path=PATH       path of source code [$source_path]"
 echo "  --source-path=PATH       path of source code [$source_path]"
@@ -895,6 +967,7 @@ echo "  --disable-check-utests   disable check unit-tests"
 echo "  --enable-check-utests    enable check unit-tests"
 echo "  --enable-check-utests    enable check unit-tests"
 echo "  --disable-bluez          disable bluez stack connectivity"
 echo "  --disable-bluez          disable bluez stack connectivity"
 echo "  --enable-bluez           enable bluez stack connectivity"
 echo "  --enable-bluez           enable bluez stack connectivity"
+echo "  --disable-slirp          disable SLIRP userspace network connectivity"
 echo "  --disable-kvm            disable KVM acceleration support"
 echo "  --disable-kvm            disable KVM acceleration support"
 echo "  --enable-kvm             enable KVM acceleration support"
 echo "  --enable-kvm             enable KVM acceleration support"
 echo "  --disable-nptl           disable usermode NPTL support"
 echo "  --disable-nptl           disable usermode NPTL support"
@@ -965,7 +1038,7 @@ fi
 gcc_flags="-Wold-style-declaration -Wold-style-definition -Wtype-limits"
 gcc_flags="-Wold-style-declaration -Wold-style-definition -Wtype-limits"
 gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_flags"
 gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_flags"
 gcc_flags="-Wmissing-include-dirs -Wempty-body -Wnested-externs $gcc_flags"
 gcc_flags="-Wmissing-include-dirs -Wempty-body -Wnested-externs $gcc_flags"
-gcc_flags="-fstack-protector-all $gcc_flags"
+gcc_flags="-fstack-protector-all -Wendif-labels $gcc_flags"
 cat > $TMPC << EOF
 cat > $TMPC << EOF
 int main(void) { return 0; }
 int main(void) { return 0; }
 EOF
 EOF
@@ -1004,70 +1077,8 @@ if test "$solaris" = "yes" ; then
   fi
   fi
 fi
 fi
 
 
-
 if test -z "$target_list" ; then
 if test -z "$target_list" ; then
-# these targets are portable
-    if [ "$softmmu" = "yes" ] ; then
-        target_list="\
-i386-softmmu \
-x86_64-softmmu \
-arm-softmmu \
-cris-softmmu \
-lm32-softmmu \
-m68k-softmmu \
-microblaze-softmmu \
-microblazeel-softmmu \
-mips-softmmu \
-mipsel-softmmu \
-mips64-softmmu \
-mips64el-softmmu \
-ppc-softmmu \
-ppcemb-softmmu \
-ppc64-softmmu \
-sh4-softmmu \
-sh4eb-softmmu \
-sparc-softmmu \
-sparc64-softmmu \
-"
-    fi
-# the following are Linux specific
-    if [ "$linux_user" = "yes" ] ; then
-        target_list="${target_list}\
-i386-linux-user \
-x86_64-linux-user \
-alpha-linux-user \
-arm-linux-user \
-armeb-linux-user \
-cris-linux-user \
-m68k-linux-user \
-microblaze-linux-user \
-microblazeel-linux-user \
-mips-linux-user \
-mipsel-linux-user \
-ppc-linux-user \
-ppc64-linux-user \
-ppc64abi32-linux-user \
-sh4-linux-user \
-sh4eb-linux-user \
-sparc-linux-user \
-sparc64-linux-user \
-sparc32plus-linux-user \
-unicore32-linux-user \
-"
-    fi
-# the following are Darwin specific
-    if [ "$darwin_user" = "yes" ] ; then
-        target_list="$target_list i386-darwin-user ppc-darwin-user "
-    fi
-# the following are BSD specific
-    if [ "$bsd_user" = "yes" ] ; then
-        target_list="${target_list}\
-i386-bsd-user \
-x86_64-bsd-user \
-sparc-bsd-user \
-sparc64-bsd-user \
-"
-    fi
+    target_list="$default_target_list"
 else
 else
     target_list=`echo "$target_list" | sed -e 's/,/ /g'`
     target_list=`echo "$target_list" | sed -e 's/,/ /g'`
 fi
 fi
@@ -1180,20 +1191,81 @@ fi
 
 
 if test "$xen" != "no" ; then
 if test "$xen" != "no" ; then
   xen_libs="-lxenstore -lxenctrl -lxenguest"
   xen_libs="-lxenstore -lxenctrl -lxenguest"
+
+  # Xen unstable
   cat > $TMPC <<EOF
   cat > $TMPC <<EOF
 #include <xenctrl.h>
 #include <xenctrl.h>
 #include <xs.h>
 #include <xs.h>
-int main(void) { xs_daemon_open(); xc_interface_open(); return 0; }
+#include <stdint.h>
+#include <xen/hvm/hvm_info_table.h>
+#if !defined(HVM_MAX_VCPUS)
+# error HVM_MAX_VCPUS not defined
+#endif
+int main(void) {
+  xc_interface *xc;
+  xs_daemon_open();
+  xc = xc_interface_open(0, 0, 0);
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  xc_gnttab_open(NULL, 0);
+  return 0;
+}
 EOF
 EOF
   if compile_prog "" "$xen_libs" ; then
   if compile_prog "" "$xen_libs" ; then
+    xen_ctrl_version=410
     xen=yes
     xen=yes
-    libs_softmmu="$xen_libs $libs_softmmu"
+
+  # Xen 4.0.0
+  elif (
+      cat > $TMPC <<EOF
+#include <xenctrl.h>
+#include <xs.h>
+#include <stdint.h>
+#include <xen/hvm/hvm_info_table.h>
+#if !defined(HVM_MAX_VCPUS)
+# error HVM_MAX_VCPUS not defined
+#endif
+int main(void) {
+  xs_daemon_open();
+  xc_interface_open();
+  xc_gnttab_open();
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  return 0;
+}
+EOF
+      compile_prog "" "$xen_libs"
+    ) ; then
+    xen_ctrl_version=400
+    xen=yes
+
+  # Xen 3.3.0, 3.4.0
+  elif (
+      cat > $TMPC <<EOF
+#include <xenctrl.h>
+#include <xs.h>
+int main(void) {
+  xs_daemon_open();
+  xc_interface_open();
+  xc_gnttab_open();
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  return 0;
+}
+EOF
+      compile_prog "" "$xen_libs"
+    ) ; then
+    xen_ctrl_version=330
+    xen=yes
+
+  # Xen not found or unsupported
   else
   else
     if test "$xen" = "yes" ; then
     if test "$xen" = "yes" ; then
       feature_not_found "xen"
       feature_not_found "xen"
     fi
     fi
     xen=no
     xen=no
   fi
   fi
+
+  if test "$xen" = yes; then
+    libs_softmmu="$xen_libs $libs_softmmu"
+  fi
 fi
 fi
 
 
 ##########################################
 ##########################################
@@ -1638,7 +1710,7 @@ fi
 if test "$curl" != "no" ; then
 if test "$curl" != "no" ; then
   cat > $TMPC << EOF
   cat > $TMPC << EOF
 #include <curl/curl.h>
 #include <curl/curl.h>
-int main(void) { return curl_easy_init(); }
+int main(void) { curl_easy_init(); curl_multi_setopt(0, 0, 0); return 0; }
 EOF
 EOF
   curl_cflags=`$curlconfig --cflags 2>/dev/null`
   curl_cflags=`$curlconfig --cflags 2>/dev/null`
   curl_libs=`$curlconfig --libs 2>/dev/null`
   curl_libs=`$curlconfig --libs 2>/dev/null`
@@ -1771,6 +1843,21 @@ recent kvm-kmod from http://sourceforge.net/projects/kvm."
   fi
   fi
 fi
 fi
 
 
+##########################################
+# test for ppc kvm pvr setting
+
+if test "$kvm" = "yes" && test "$cpu" = "ppc" -o "$cpu" = "ppc64"; then
+            cat > $TMPC <<EOF
+    #include <asm/kvm.h>
+    int main(void) { struct kvm_sregs s; s.pvr = 0; return 0; }
+EOF
+    if compile_prog "$kvm_cflags" "" ; then
+        kvm_ppc_pvr=yes
+    else
+        kvm_ppc_pvr=no
+    fi
+fi
+
 ##########################################
 ##########################################
 # test for vhost net
 # test for vhost net
 
 
@@ -1831,41 +1918,24 @@ fi
 if test "$rbd" != "no" ; then
 if test "$rbd" != "no" ; then
   cat > $TMPC <<EOF
   cat > $TMPC <<EOF
 #include <stdio.h>
 #include <stdio.h>
-#include <rados/librados.h>
-int main(void) { rados_initialize(0, NULL); return 0; }
-EOF
-  rbd_libs="-lrados"
-  if compile_prog "" "$rbd_libs" ; then
-    librados_too_old=no
-    cat > $TMPC <<EOF
-#include <stdio.h>
-#include <rados/librados.h>
-#ifndef CEPH_OSD_TMAP_SET
-#error missing CEPH_OSD_TMAP_SET
-#endif
+#include <rbd/librbd.h>
 int main(void) {
 int main(void) {
-    int (*func)(const rados_pool_t pool, uint64_t *snapid) = rados_selfmanaged_snap_create;
-    rados_initialize(0, NULL);
+    rados_t cluster;
+    rados_create(&cluster, NULL);
     return 0;
     return 0;
 }
 }
 EOF
 EOF
-    if compile_prog "" "$rbd_libs" ; then
-      rbd=yes
-      libs_tools="$rbd_libs $libs_tools"
-      libs_softmmu="$rbd_libs $libs_softmmu"
-    else
-      rbd=no
-      librados_too_old=yes
-    fi
+  rbd_libs="-lrbd -lrados"
+  if compile_prog "" "$rbd_libs" ; then
+    rbd=yes
+    libs_tools="$rbd_libs $libs_tools"
+    libs_softmmu="$rbd_libs $libs_softmmu"
   else
   else
     if test "$rbd" = "yes" ; then
     if test "$rbd" = "yes" ; then
       feature_not_found "rados block device"
       feature_not_found "rados block device"
     fi
     fi
     rbd=no
     rbd=no
   fi
   fi
-  if test "$librados_too_old" = "yes" ; then
-    echo "-> Your librados version is too old - upgrade needed to have rbd support"
-  fi
 fi
 fi
 
 
 ##########################################
 ##########################################
@@ -2345,7 +2415,7 @@ int main(void) { spice_server_new(); return 0; }
 EOF
 EOF
   spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
   spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
   spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
   spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
-  if $pkg_config --atleast-version=0.5.3 spice-server >/dev/null 2>&1 && \
+  if $pkg_config --atleast-version=0.6.0 spice-server >/dev/null 2>&1 && \
      compile_prog "$spice_cflags" "$spice_libs" ; then
      compile_prog "$spice_cflags" "$spice_libs" ; then
     spice="yes"
     spice="yes"
     libs_softmmu="$libs_softmmu $spice_libs"
     libs_softmmu="$libs_softmmu $spice_libs"
@@ -2540,7 +2610,7 @@ if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) -a \
         "$softmmu" = yes ; then
         "$softmmu" = yes ; then
   roms="optionrom"
   roms="optionrom"
 fi
 fi
-if test "$cpu" = "ppc64" ; then
+if test "$cpu" = "ppc64" -a "$targetos" != "Darwin" ; then
   roms="$roms spapr-rtas"
   roms="$roms spapr-rtas"
 fi
 fi
 
 
@@ -2855,6 +2925,7 @@ if test "$bluez" = "yes" ; then
 fi
 fi
 if test "$xen" = "yes" ; then
 if test "$xen" = "yes" ; then
   echo "CONFIG_XEN=y" >> $config_host_mak
   echo "CONFIG_XEN=y" >> $config_host_mak
+  echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
 fi
 fi
 if test "$io_thread" = "yes" ; then
 if test "$io_thread" = "yes" ; then
   echo "CONFIG_IOTHREAD=y" >> $config_host_mak
   echo "CONFIG_IOTHREAD=y" >> $config_host_mak
@@ -3235,7 +3306,11 @@ echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
 case "$target_arch2" in
 case "$target_arch2" in
   i386|x86_64)
   i386|x86_64)
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
+      target_phys_bits=64
       echo "CONFIG_XEN=y" >> $config_target_mak
       echo "CONFIG_XEN=y" >> $config_target_mak
+      if test "$cpu" = "i386" -o "$cpu" = "x86_64"; then
+          echo "CONFIG_XEN_MAPCACHE=y" >> $config_target_mak
+      fi
     fi
     fi
 esac
 esac
 case "$target_arch2" in
 case "$target_arch2" in
@@ -3257,6 +3332,9 @@ case "$target_arch2" in
       if test $vhost_net = "yes" ; then
       if test $vhost_net = "yes" ; then
         echo "CONFIG_VHOST_NET=y" >> $config_target_mak
         echo "CONFIG_VHOST_NET=y" >> $config_target_mak
       fi
       fi
+      if test "$kvm_ppc_pvr" = "yes" ; then
+        echo "CONFIG_KVM_PPC_PVR=y" >> $config_target_mak
+      fi
     fi
     fi
 esac
 esac
 if test "$target_bigendian" = "yes" ; then
 if test "$target_bigendian" = "yes" ; then
@@ -3291,8 +3369,6 @@ if test ! -z "$gdb_xml_files" ; then
   echo "TARGET_XML_FILES=$list" >> $config_target_mak
   echo "TARGET_XML_FILES=$list" >> $config_target_mak
 fi
 fi
 
 
-echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
-
 if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
 if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
   echo "TARGET_HAS_BFLT=y" >> $config_target_mak
   echo "TARGET_HAS_BFLT=y" >> $config_target_mak
 fi
 fi
@@ -3457,11 +3533,13 @@ done # for target in $targets
 
 
 # build tree in object directory in case the source is not in the current directory
 # build tree in object directory in case the source is not in the current directory
 DIRS="tests tests/cris slirp audio block net pc-bios/optionrom"
 DIRS="tests tests/cris slirp audio block net pc-bios/optionrom"
+DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS fsdev ui"
 DIRS="$DIRS fsdev ui"
 FILES="Makefile tests/Makefile"
 FILES="Makefile tests/Makefile"
 FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
 FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
+FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
 for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.rom $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do
 for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.rom $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do
     FILES="$FILES pc-bios/`basename $bios_file`"
     FILES="$FILES pc-bios/`basename $bios_file`"

+ 1 - 1
console.c

@@ -180,7 +180,7 @@ void vga_hw_screen_dump(const char *filename)
     active_console = consoles[0];
     active_console = consoles[0];
     /* There is currently no way of specifying which screen we want to dump,
     /* There is currently no way of specifying which screen we want to dump,
        so always dump the first one.  */
        so always dump the first one.  */
-    if (consoles[0]->hw_screen_dump)
+    if (consoles[0] && consoles[0]->hw_screen_dump)
         consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
         consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
     active_console = previous_active_console;
     active_console = previous_active_console;
 }
 }

+ 49 - 18
cpu-all.h

@@ -123,8 +123,7 @@ typedef union {
    endian ! */
    endian ! */
 typedef union {
 typedef union {
     float64 d;
     float64 d;
-#if defined(HOST_WORDS_BIGENDIAN) \
-    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
+#if defined(HOST_WORDS_BIGENDIAN)
     struct {
     struct {
         uint32_t upper;
         uint32_t upper;
         uint32_t lower;
         uint32_t lower;
@@ -138,7 +137,6 @@ typedef union {
     uint64_t ll;
     uint64_t ll;
 } CPU_DoubleU;
 } CPU_DoubleU;
 
 
-#if defined(FLOATX80)
 typedef union {
 typedef union {
      floatx80 d;
      floatx80 d;
      struct {
      struct {
@@ -146,9 +144,7 @@ typedef union {
          uint16_t upper;
          uint16_t upper;
      } l;
      } l;
 } CPU_LDoubleU;
 } CPU_LDoubleU;
-#endif
 
 
-#if defined(CONFIG_SOFTFLOAT)
 typedef union {
 typedef union {
     float128 q;
     float128 q;
 #if defined(HOST_WORDS_BIGENDIAN)
 #if defined(HOST_WORDS_BIGENDIAN)
@@ -175,7 +171,6 @@ typedef union {
     } ll;
     } ll;
 #endif
 #endif
 } CPU_QuadU;
 } CPU_QuadU;
-#endif
 
 
 /* CPU memory access without any memory or io remapping */
 /* CPU memory access without any memory or io remapping */
 
 
@@ -786,18 +781,54 @@ void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
 extern CPUState *first_cpu;
 extern CPUState *first_cpu;
 extern CPUState *cpu_single_env;
 extern CPUState *cpu_single_env;
 
 
-#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 */
-#define CPU_INTERRUPT_DEBUG  0x80 /* Debug event occured.  */
-#define CPU_INTERRUPT_VIRQ   0x100 /* virtual interrupt pending.  */
-#define CPU_INTERRUPT_NMI    0x200 /* NMI pending. */
-#define CPU_INTERRUPT_INIT   0x400 /* INIT pending. */
-#define CPU_INTERRUPT_SIPI   0x800 /* SIPI pending. */
-#define CPU_INTERRUPT_MCE    0x1000 /* (x86 only) MCE pending. */
+/* Flags for use in ENV->INTERRUPT_PENDING.
+
+   The numbers assigned here are non-sequential in order to preserve
+   binary compatibility with the vmstate dump.  Bit 0 (0x0001) was
+   previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
+   the vmstate dump.  */
+
+/* External hardware interrupt pending.  This is typically used for
+   interrupts from devices.  */
+#define CPU_INTERRUPT_HARD        0x0002
+
+/* Exit the current TB.  This is typically used when some system-level device
+   makes some change to the memory mapping.  E.g. the a20 line change.  */
+#define CPU_INTERRUPT_EXITTB      0x0004
+
+/* Halt the CPU.  */
+#define CPU_INTERRUPT_HALT        0x0020
+
+/* Debug event pending.  */
+#define CPU_INTERRUPT_DEBUG       0x0080
+
+/* Several target-specific external hardware interrupts.  Each target/cpu.h
+   should define proper names based on these defines.  */
+#define CPU_INTERRUPT_TGT_EXT_0   0x0008
+#define CPU_INTERRUPT_TGT_EXT_1   0x0010
+#define CPU_INTERRUPT_TGT_EXT_2   0x0040
+#define CPU_INTERRUPT_TGT_EXT_3   0x0200
+#define CPU_INTERRUPT_TGT_EXT_4   0x1000
+
+/* Several target-specific internal interrupts.  These differ from the
+   preceeding target-specific interrupts in that they are intended to
+   originate from within the cpu itself, typically in response to some
+   instruction being executed.  These, therefore, are not masked while
+   single-stepping within the debugger.  */
+#define CPU_INTERRUPT_TGT_INT_0   0x0100
+#define CPU_INTERRUPT_TGT_INT_1   0x0400
+#define CPU_INTERRUPT_TGT_INT_2   0x0800
+
+/* First unused bit: 0x2000.  */
+
+/* The set of all bits that should be masked when single-stepping.  */
+#define CPU_INTERRUPT_SSTEP_MASK \
+    (CPU_INTERRUPT_HARD          \
+     | CPU_INTERRUPT_TGT_EXT_0   \
+     | CPU_INTERRUPT_TGT_EXT_1   \
+     | CPU_INTERRUPT_TGT_EXT_2   \
+     | CPU_INTERRUPT_TGT_EXT_3   \
+     | CPU_INTERRUPT_TGT_EXT_4)
 
 
 #ifndef CONFIG_USER_ONLY
 #ifndef CONFIG_USER_ONLY
 typedef void (*CPUInterruptHandler)(CPUState *, int);
 typedef void (*CPUInterruptHandler)(CPUState *, int);

+ 2 - 0
cpu-common.h

@@ -61,12 +61,14 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
                         ram_addr_t size, void *host);
                         ram_addr_t size, void *host);
 ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size);
 ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size);
 void qemu_ram_free(ram_addr_t addr);
 void qemu_ram_free(ram_addr_t addr);
+void qemu_ram_free_from_ptr(ram_addr_t addr);
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should only be used for ram local to a device.  */
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
 void *qemu_get_ram_ptr(ram_addr_t addr);
 /* Same but slower, to use for migration, where the order of
 /* Same but slower, to use for migration, where the order of
  * RAMBlocks must not change. */
  * RAMBlocks must not change. */
 void *qemu_safe_ram_ptr(ram_addr_t addr);
 void *qemu_safe_ram_ptr(ram_addr_t addr);
+void qemu_put_ram_ptr(void *addr);
 /* This should not be used by devices.  */
 /* This should not be used by devices.  */
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
 ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);

+ 35 - 641
cpu-exec.c

@@ -23,22 +23,6 @@
 #include "kvm.h"
 #include "kvm.h"
 #include "qemu-barrier.h"
 #include "qemu-barrier.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>
-#ifdef __linux__
-#include <sys/ucontext.h>
-#endif
-#endif
-
 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
 // Work around ugly bugs in glibc that mangle global register contents
 // Work around ugly bugs in glibc that mangle global register contents
 #undef env
 #undef env
@@ -48,7 +32,6 @@
 int tb_invalidated_flag;
 int tb_invalidated_flag;
 
 
 //#define CONFIG_DEBUG_EXEC
 //#define CONFIG_DEBUG_EXEC
-//#define DEBUG_SIGNAL
 
 
 int qemu_cpu_has_work(CPUState *env)
 int qemu_cpu_has_work(CPUState *env)
 {
 {
@@ -64,37 +47,17 @@ void cpu_loop_exit(void)
 /* exit the current TB from a signal handler. The host registers are
 /* exit the current TB from a signal handler. The host registers are
    restored in a state compatible with the CPU emulator
    restored in a state compatible with the CPU emulator
  */
  */
+#if defined(CONFIG_SOFTMMU)
 void cpu_resume_from_signal(CPUState *env1, void *puc)
 void cpu_resume_from_signal(CPUState *env1, void *puc)
 {
 {
-#if !defined(CONFIG_SOFTMMU)
-#ifdef __linux__
-    struct ucontext *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#endif
-#endif
-
     env = env1;
     env = env1;
 
 
     /* XXX: restore cpu registers saved in host registers */
     /* XXX: restore cpu registers saved in host registers */
 
 
-#if !defined(CONFIG_SOFTMMU)
-    if (puc) {
-        /* XXX: use siglongjmp ? */
-#ifdef __linux__
-#ifdef __ia64
-        sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
-#else
-        sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
-#endif
-#elif defined(__OpenBSD__)
-        sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
-#endif
-    }
-#endif
     env->exception_index = -1;
     env->exception_index = -1;
     longjmp(env->jmp_env, 1);
     longjmp(env->jmp_env, 1);
 }
 }
+#endif
 
 
 /* Execute the code without caching the generated code. An interpreter
 /* Execute the code without caching the generated code. An interpreter
    could be used if available. */
    could be used if available. */
@@ -360,10 +323,7 @@ int cpu_exec(CPUState *env1)
                 if (unlikely(interrupt_request)) {
                 if (unlikely(interrupt_request)) {
                     if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
                     if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
                         /* Mask out external interrupts for this step. */
                         /* Mask out external interrupts for this step. */
-                        interrupt_request &= ~(CPU_INTERRUPT_HARD |
-                                               CPU_INTERRUPT_FIQ |
-                                               CPU_INTERRUPT_SMI |
-                                               CPU_INTERRUPT_NMI);
+                        interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
                     }
                     }
                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
                         env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
                         env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
@@ -492,9 +452,6 @@ int cpu_exec(CPUState *env1)
                                 next_tb = 0;
                                 next_tb = 0;
                             }
                             }
                         }
                         }
-		    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
-			//do_interrupt(0, 0, 0, 0, 0);
-			env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
 		    }
 		    }
 #elif defined(TARGET_ARM)
 #elif defined(TARGET_ARM)
                     if (interrupt_request & CPU_INTERRUPT_FIQ
                     if (interrupt_request & CPU_INTERRUPT_FIQ
@@ -509,7 +466,7 @@ int cpu_exec(CPUState *env1)
                        jump normally, then does the exception return when the
                        jump normally, then does the exception return when the
                        CPU tries to execute code at the magic address.
                        CPU tries to execute code at the magic address.
                        This will cause the magic PC value to be pushed to
                        This will cause the magic PC value to be pushed to
-                       the stack if an interrupt occured at the wrong time.
+                       the stack if an interrupt occurred at the wrong time.
                        We avoid this by disabling interrupts when
                        We avoid this by disabling interrupts when
                        pc contains a magic address.  */
                        pc contains a magic address.  */
                     if (interrupt_request & CPU_INTERRUPT_HARD
                     if (interrupt_request & CPU_INTERRUPT_HARD
@@ -531,9 +488,36 @@ int cpu_exec(CPUState *env1)
                         next_tb = 0;
                         next_tb = 0;
                     }
                     }
 #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_ALPHA)
-                    if (interrupt_request & CPU_INTERRUPT_HARD) {
-                        do_interrupt(env);
-                        next_tb = 0;
+                    {
+                        int idx = -1;
+                        /* ??? This hard-codes the OSF/1 interrupt levels.  */
+		        switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
+                        case 0 ... 3:
+                            if (interrupt_request & CPU_INTERRUPT_HARD) {
+                                idx = EXCP_DEV_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 4:
+                            if (interrupt_request & CPU_INTERRUPT_TIMER) {
+                                idx = EXCP_CLK_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 5:
+                            if (interrupt_request & CPU_INTERRUPT_SMP) {
+                                idx = EXCP_SMP_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 6:
+                            if (interrupt_request & CPU_INTERRUPT_MCHK) {
+                                idx = EXCP_MCHK;
+                            }
+                        }
+                        if (idx >= 0) {
+                            env->exception_index = idx;
+                            env->error_code = 0;
+                            do_interrupt(env);
+                            next_tb = 0;
+                        }
                     }
                     }
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_CRIS)
                     if (interrupt_request & CPU_INTERRUPT_HARD
                     if (interrupt_request & CPU_INTERRUPT_HARD
@@ -569,7 +553,7 @@ int cpu_exec(CPUState *env1)
                         next_tb = 0;
                         next_tb = 0;
                     }
                     }
 #endif
 #endif
-                   /* Don't use the cached interupt_request value,
+                   /* Don't use the cached interrupt_request value,
                       do_interrupt may have updated the EXITTB flag. */
                       do_interrupt may have updated the EXITTB flag. */
                     if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
                     if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
                         env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
                         env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
@@ -709,593 +693,3 @@ int cpu_exec(CPUState *env1)
     cpu_single_env = NULL;
     cpu_single_env = NULL;
     return ret;
     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 {
-        helper_load_seg(seg_reg, selector);
-    }
-    env = saved_env;
-}
-
-void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
-{
-    CPUX86State *saved_env;
-
-    saved_env = env;
-    env = s;
-
-    helper_fsave(ptr, data32);
-
-    env = saved_env;
-}
-
-void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
-{
-    CPUX86State *saved_env;
-
-    saved_env = env;
-    env = s;
-
-    helper_frstor(ptr, data32);
-
-    env = saved_env;
-}
-
-#endif /* TARGET_I386 */
-
-#if !defined(CONFIG_SOFTMMU)
-
-#if defined(TARGET_I386)
-#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code)
-#else
-#define EXCEPTION_ACTION cpu_loop_exit()
-#endif
-
-/* '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_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 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);
-    }
-
-    /* we restore the process signal mask as the sigreturn should
-       do it (XXX: use sigsetjmp) */
-    sigprocmask(SIG_SETMASK, old_set, NULL);
-    EXCEPTION_ACTION;
-
-    /* never comes here */
-    return 1;
-}
-
-#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)
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#elif defined (__NetBSD__)
-# include <ucontext.h>
-
-# 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])
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#elif defined (__FreeBSD__) || defined(__DragonFly__)
-# include <ucontext.h>
-
-# define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext.mc_eip))
-# define TRAP_sig(context)    ((context)->uc_mcontext.mc_trapno)
-# define ERROR_sig(context)   ((context)->uc_mcontext.mc_err)
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#elif defined(__OpenBSD__)
-# define EIP_sig(context)     ((context)->sc_eip)
-# define TRAP_sig(context)    ((context)->sc_trapno)
-# define ERROR_sig(context)   ((context)->sc_err)
-# define MASK_sig(context)    ((context)->sc_mask)
-#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])
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
-    ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#else
-    struct ucontext *uc = puc;
-#endif
-    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);
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             trapno == 0xe ?
-                             (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc), puc);
-}
-
-#elif defined(__x86_64__)
-
-#ifdef __NetBSD__
-#define PC_sig(context)       _UC_MACHINE_PC(context)
-#define TRAP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
-#define ERROR_sig(context)    ((context)->uc_mcontext.__gregs[_REG_ERR])
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#elif defined(__OpenBSD__)
-#define PC_sig(context)       ((context)->sc_rip)
-#define TRAP_sig(context)     ((context)->sc_trapno)
-#define ERROR_sig(context)    ((context)->sc_err)
-#define MASK_sig(context)     ((context)->sc_mask)
-#elif defined (__FreeBSD__) || defined(__DragonFly__)
-#include <ucontext.h>
-
-#define PC_sig(context)  (*((unsigned long*)&(context)->uc_mcontext.mc_rip))
-#define TRAP_sig(context)     ((context)->uc_mcontext.mc_trapno)
-#define ERROR_sig(context)    ((context)->uc_mcontext.mc_err)
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#else
-#define PC_sig(context)       ((context)->uc_mcontext.gregs[REG_RIP])
-#define TRAP_sig(context)     ((context)->uc_mcontext.gregs[REG_TRAPNO])
-#define ERROR_sig(context)    ((context)->uc_mcontext.gregs[REG_ERR])
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    unsigned long pc;
-#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
-    ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#else
-    struct ucontext *uc = puc;
-#endif
-
-    pc = PC_sig(uc);
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             TRAP_sig(uc) == 0xe ?
-                             (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc), puc);
-}
-
-#elif defined(_ARCH_PPC)
-
-/***********************************************************************
- * 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 */
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include <ucontext.h>
-# define IAR_sig(context)		((context)->uc_mcontext.mc_srr0)
-# define MSR_sig(context)		((context)->uc_mcontext.mc_srr1)
-# define CTR_sig(context)		((context)->uc_mcontext.mc_ctr)
-# define XER_sig(context)		((context)->uc_mcontext.mc_xer)
-# define LR_sig(context)		((context)->uc_mcontext.mc_lr)
-# define CR_sig(context)		((context)->uc_mcontext.mc_cr)
-/* Exception Registers access */
-# define DAR_sig(context)		((context)->uc_mcontext.mc_dar)
-# define DSISR_sig(context)		((context)->uc_mcontext.mc_dsisr)
-# define TRAP_sig(context)		((context)->uc_mcontext.mc_exc)
-#endif /* __FreeBSD__|| __FreeBSD_kernel__ */
-
-#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;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    ucontext_t *uc = puc;
-#else
-    struct ucontext *uc = puc;
-#endif
-    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;
-    int is_write;
-    uint32_t insn;
-#if !defined(__arch64__) || defined(CONFIG_SOLARIS)
-    uint32_t *regs = (uint32_t *)(info + 1);
-    void *sigmask = (regs + 20);
-    /* XXX: is there a standard glibc define ? */
-    unsigned long pc = regs[1];
-#else
-#ifdef __linux__
-    struct sigcontext *sc = puc;
-    unsigned long pc = sc->sigc_regs.tpc;
-    void *sigmask = (void *)sc->sigc_mask;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-    unsigned long pc = uc->sc_pc;
-    void *sigmask = (void *)(long)uc->sc_mask;
-#endif
-#endif
-
-    /* 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 0x15: // stba
-      case 0x06: // sth
-      case 0x16: // stha
-      case 0x04: // st
-      case 0x14: // sta
-      case 0x07: // std
-      case 0x17: // stda
-      case 0x0e: // stx
-      case 0x1e: // stxa
-      case 0x24: // stf
-      case 0x34: // stfa
-      case 0x27: // stdf
-      case 0x37: // stdfa
-      case 0x26: // stqf
-      case 0x36: // stqfa
-      case 0x25: // stfsr
-      case 0x3c: // casa
-      case 0x3e: // casxa
-	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;
-
-#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
-    pc = uc->uc_mcontext.gregs[R15];
-#else
-    pc = uc->uc_mcontext.arm_pc;
-#endif
-    /* 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,
-                             (sigset_t *)&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;
-    uint16_t *pinsn;
-    int is_write = 0;
-
-    pc = uc->uc_mcontext.psw.addr;
-
-    /* ??? On linux, the non-rt signal handler has 4 (!) arguments instead
-       of the normal 2 arguments.  The 3rd argument contains the "int_code"
-       from the hardware which does in fact contain the is_write value.
-       The rt signal handler, as far as I can tell, does not give this value
-       at all.  Not that we could get to it from here even if it were.  */
-    /* ??? This is not even close to complete, since it ignores all
-       of the read-modify-write instructions.  */
-    pinsn = (uint16_t *)pc;
-    switch (pinsn[0] >> 8) {
-    case 0x50: /* ST */
-    case 0x42: /* STC */
-    case 0x40: /* STH */
-        is_write = 1;
-        break;
-    case 0xc4: /* RIL format insns */
-        switch (pinsn[0] & 0xf) {
-        case 0xf: /* STRL */
-        case 0xb: /* STGRL */
-        case 0x7: /* STHRL */
-            is_write = 1;
-        }
-        break;
-    case 0xe3: /* RXY format insns */
-        switch (pinsn[2] & 0xff) {
-        case 0x50: /* STY */
-        case 0x24: /* STG */
-        case 0x72: /* STCY */
-        case 0x70: /* STHY */
-        case 0x8e: /* STPQ */
-        case 0x3f: /* STRVH */
-        case 0x3e: /* STRV */
-        case 0x2f: /* STRVG */
-            is_write = 1;
-        }
-        break;
-    }
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__mips__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    struct ucontext *uc = puc;
-    greg_t pc = uc->uc_mcontext.pc;
-    int is_write;
-
-    /* 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(__hppa__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    struct siginfo *info = pinfo;
-    struct ucontext *uc = puc;
-    unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
-    uint32_t insn = *(uint32_t *)pc;
-    int is_write = 0;
-
-    /* XXX: need kernel patch to get write flag faster.  */
-    switch (insn >> 26) {
-    case 0x1a: /* STW */
-    case 0x19: /* STH */
-    case 0x18: /* STB */
-    case 0x1b: /* STWM */
-        is_write = 1;
-        break;
-
-    case 0x09: /* CSTWX, FSTWX, FSTWS */
-    case 0x0b: /* CSTDX, FSTDX, FSTDS */
-        /* Distinguish from coprocessor load ... */
-        is_write = (insn >> 9) & 1;
-        break;
-
-    case 0x03:
-        switch ((insn >> 6) & 15) {
-        case 0xa: /* STWS */
-        case 0x9: /* STHS */
-        case 0x8: /* STBS */
-        case 0xe: /* STWAS */
-        case 0xc: /* STBYS */
-            is_write = 1;
-        }
-        break;
-    }
-
-    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) */

+ 0 - 3
darwin-user/signal.c

@@ -21,7 +21,6 @@
 #include <string.h>
 #include <string.h>
 #include <stdarg.h>
 #include <stdarg.h>
 #include <unistd.h>
 #include <unistd.h>
-#include <signal.h>
 #include <errno.h>
 #include <errno.h>
 #include <sys/ucontext.h>
 #include <sys/ucontext.h>
 
 
@@ -32,8 +31,6 @@
 #undef uc_link
 #undef uc_link
 #endif
 #endif
 
 
-#include <signal.h>
-
 #include "qemu.h"
 #include "qemu.h"
 #include "qemu-common.h"
 #include "qemu-common.h"
 
 

+ 1 - 1
darwin-user/syscall.c

@@ -977,7 +977,7 @@ long do_unix_syscall_indirect(void *cpu_env, int num)
 #elif TARGET_PPC
 #elif TARGET_PPC
     {
     {
         int i;
         int i;
-        /* XXX: not really needed those regs are volatile accross calls */
+        /* XXX: not really needed those regs are volatile across calls */
         uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr;
         uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr;
         for(i = 11; i > 3; i--)
         for(i = 11; i > 3; i--)
             *regs[i] = *regs[i-1];
             *regs[i] = *regs[i-1];

+ 9 - 0
default-configs/alpha-softmmu.mak

@@ -0,0 +1,9 @@
+# Default configuration for alpha-softmmu
+
+include pci.mak
+CONFIG_SERIAL=y
+CONFIG_I8254=y
+CONFIG_VGA_PCI=y
+CONFIG_IDE_CORE=y
+CONFIG_IDE_QDEV=y
+CONFIG_VMWARE_VGA=y

+ 1 - 0
default-configs/pci.mak

@@ -3,6 +3,7 @@ CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO=y
 CONFIG_USB_UHCI=y
 CONFIG_USB_UHCI=y
 CONFIG_USB_OHCI=y
 CONFIG_USB_OHCI=y
+CONFIG_USB_EHCI=y
 CONFIG_NE2000_PCI=y
 CONFIG_NE2000_PCI=y
 CONFIG_EEPRO100_PCI=y
 CONFIG_EEPRO100_PCI=y
 CONFIG_PCNET_PCI=y
 CONFIG_PCNET_PCI=y

+ 1 - 0
default-configs/s390x-linux-user.mak

@@ -0,0 +1 @@
+# Default configuration for s390x-linux-user

+ 3 - 0
dis-asm.h

@@ -184,6 +184,9 @@ enum bfd_architecture
 #define bfd_mach_sh5        0x50
 #define bfd_mach_sh5        0x50
   bfd_arch_alpha,      /* Dec Alpha */
   bfd_arch_alpha,      /* Dec Alpha */
 #define bfd_mach_alpha 1
 #define bfd_mach_alpha 1
+#define bfd_mach_alpha_ev4  0x10
+#define bfd_mach_alpha_ev5  0x20
+#define bfd_mach_alpha_ev6  0x30
   bfd_arch_arm,        /* Advanced Risc Machines ARM */
   bfd_arch_arm,        /* Advanced Risc Machines ARM */
 #define bfd_mach_arm_unknown	0
 #define bfd_mach_arm_unknown	0
 #define bfd_mach_arm_2		1
 #define bfd_mach_arm_2		1

+ 1 - 1
disas.c

@@ -205,7 +205,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
     disasm_info.mach = bfd_mach_sh4;
     disasm_info.mach = bfd_mach_sh4;
     print_insn = print_insn_sh;
     print_insn = print_insn_sh;
 #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_ALPHA)
-    disasm_info.mach = bfd_mach_alpha;
+    disasm_info.mach = bfd_mach_alpha_ev6;
     print_insn = print_insn_alpha;
     print_insn = print_insn_alpha;
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_CRIS)
     if (flags != 32) {
     if (flags != 32) {

+ 114 - 66
docs/qdev-device-use.txt

@@ -8,20 +8,23 @@ more buses for children.  You can specify a device's parent bus with
 
 
 A device typically has a device address on its parent bus.  For buses
 A device typically has a device address on its parent bus.  For buses
 where this address can be configured, devices provide a bus-specific
 where this address can be configured, devices provide a bus-specific
-property.  These are
-
-    bus     property name       value format
-    PCI     addr                %x.%x (dev.fn, .fn optional)
-    I2C     address             %u
-    SCSI    scsi-id             %u
+property.  Examples:
+
+    bus         property name       value format
+    PCI         addr                %x.%x    (dev.fn, .fn optional)
+    I2C         address             %u
+    SCSI        scsi-id             %u
+    IDE         unit                %u
+    HDA         cad                 %u
+    virtio-serial-bus  nr           %u
+    ccid-bus    slot                %u
+    USB         port                %d(.%d)*    (port.port...)
 
 
 Example: device i440FX-pcihost is on the root bus, and provides a PCI
 Example: device i440FX-pcihost is on the root bus, and provides a PCI
 bus named pci.0.  To put a FOO device into its slot 4, use -device
 bus named pci.0.  To put a FOO device into its slot 4, use -device
 FOO,bus=/i440FX-pcihost/pci.0,addr=4.  The abbreviated form bus=pci.0
 FOO,bus=/i440FX-pcihost/pci.0,addr=4.  The abbreviated form bus=pci.0
 also works as long as the bus name is unique.
 also works as long as the bus name is unique.
 
 
-Note: the USB device address can't be controlled at this time.
-
 === Block Devices ===
 === Block Devices ===
 
 
 A QEMU block device (drive) has a host and a guest part.
 A QEMU block device (drive) has a host and a guest part.
@@ -44,28 +47,43 @@ The new way keeps the parts separate: you create the host part with
 
 
 The various old ways to define drives all boil down to the common form
 The various old ways to define drives all boil down to the common form
 
 
-    -drive if=TYPE,index=IDX,bus=BUS,unit=UNIT,HOST-OPTS...
+    -drive if=TYPE,bus=BUS,unit=UNIT,OPTS...
 
 
 TYPE, BUS and UNIT identify the controller device, which of its buses
 TYPE, BUS and UNIT identify the controller device, which of its buses
 to use, and the drive's address on that bus.  Details depend on TYPE.
 to use, and the drive's address on that bus.  Details depend on TYPE.
-IDX is an alternative way to specify BUS and UNIT.
+
+Instead of bus=BUS,unit=UNIT, you can also say index=IDX.
 
 
 In the new way, this becomes something like
 In the new way, this becomes something like
 
 
    -drive if=none,id=DRIVE-ID,HOST-OPTS...
    -drive if=none,id=DRIVE-ID,HOST-OPTS...
    -device DEVNAME,drive=DRIVE-ID,DEV-OPTS...
    -device DEVNAME,drive=DRIVE-ID,DEV-OPTS...
 
 
-The -device argument differs in detail for each kind of drive:
+The old OPTS get split into HOST-OPTS and DEV-OPTS as follows:
 
 
-* if=ide
+* file, format, snapshot, cache, aio, readonly, rerror, werror go into
+  HOST-OPTS.
+
+* cyls, head, secs and trans go into HOST-OPTS.  Future work: they
+  should go into DEV-OPTS instead.
+
+* serial goes into DEV-OPTS, for devices supporting serial numbers.
+  For other devices, it goes nowhere.
 
 
-  -device ide-drive,drive=DRIVE-ID,bus=IDE-BUS,unit=UNIT
+* media is special.  In the old way, it selects disk vs. CD-ROM with
+  if=ide, if=scsi and if=xen.  The new way uses DEVNAME for that.
+  Additionally, readonly=on goes into HOST-OPTS.
 
 
-  where IDE-BUS identifies an IDE bus, normally either ide.0 or ide.1,
-  and UNIT is either 0 or 1.
+* addr is special, see if=virtio below.
 
 
-  Bug: new way does not work for ide.1 unit 0 (in old terms: index=2)
-  unless you disable the default CD-ROM with -nodefaults.
+The -device argument differs in detail for each type of drive:
+
+* if=ide
+
+  -device DEVNAME,drive=DRIVE-ID,bus=IDE-BUS,unit=UNIT
+
+  where DEVNAME is either ide-hd or ide-cd, IDE-BUS identifies an IDE
+  bus, normally either ide.0 or ide.1, and UNIT is either 0 or 1.
 
 
 * if=scsi
 * if=scsi
 
 
@@ -77,27 +95,25 @@ The -device argument differs in detail for each kind of drive:
   As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to
   As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to
   control the PCI device address.
   control the PCI device address.
 
 
-  This SCSI controller a single SCSI bus, named ID.0.  Put a disk on
-  it:
+  This SCSI controller provides a single SCSI bus, named ID.0.  Put a
+  disk on it:
 
 
-  -device scsi-disk,drive=DRIVE-ID,bus=ID.0,scsi-id=SCSI-ID,removable=RMB
+  -device DEVNAME,drive=DRIVE-ID,bus=ID.0,scsi-id=UNIT
 
 
-  The (optional) removable parameter lets you override the SCSI INQUIRY
-  removable (RMB) bit for non CD-ROM devices.  It is ignored for CD-ROM devices
-  which are always removable.  RMB is "on" or "off".
+  where DEVNAME is either scsi-hd, scsi-cd or scsi-generic.
 
 
 * if=floppy
 * if=floppy
 
 
-  -global isa-fdc,driveA=DRIVE-ID,driveB=DRIVE-ID
+  -global isa-fdc.driveA=DRIVE-ID
+  -global isa-fdc.driveB=DRIVE-ID
 
 
   This is -global instead of -device, because the floppy controller is
   This is -global instead of -device, because the floppy controller is
   created automatically, and we want to configure that one, not create
   created automatically, and we want to configure that one, not create
   a second one (which isn't possible anyway).
   a second one (which isn't possible anyway).
 
 
-  Omitting a drive parameter makes that drive empty.
-
-  Bug: driveA works only if you disable the default floppy drive with
-  -nodefaults.
+  Without any -global isa-fdc,... you get an empty driveA and no
+  driveB.  You can use -nodefaults to suppress the default driveA, see
+  "Default Devices".
 
 
 * if=virtio
 * if=virtio
 
 
@@ -105,11 +121,12 @@ The -device argument differs in detail for each kind of drive:
 
 
   This lets you control PCI device class and MSI-X vectors.
   This lets you control PCI device class and MSI-X vectors.
 
 
-  IOEVENTFD controls whether or not ioeventfd is used for virtqueue notify.  It
-  can be set to on (default) or off.
+  IOEVENTFD controls whether or not ioeventfd is used for virtqueue
+  notify.  It can be set to on (default) or off.
 
 
   As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to
   As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to
-  control the PCI device address.
+  control the PCI device address.  This replaces option addr available
+  with -drive if=virtio.
 
 
 * if=pflash, if=mtd, if=sd, if=xen are not yet available with -device
 * if=pflash, if=mtd, if=sd, if=xen are not yet available with -device
 
 
@@ -117,15 +134,20 @@ For USB devices, the old way is actually different:
 
 
     -usbdevice disk:format=FMT:FILENAME
     -usbdevice disk:format=FMT:FILENAME
 
 
-Provides much less control than -drive's HOST-OPTS...  The new way
-fixes that:
+Provides much less control than -drive's OPTS...  The new way fixes
+that:
 
 
     -device usb-storage,drive=DRIVE-ID,removable=RMB
     -device usb-storage,drive=DRIVE-ID,removable=RMB
 
 
-The removable parameter gives control over the SCSI INQUIRY removable (RMB)
-bit.  USB thumbdrives usually set removable=on, while USB hard disks set
-removable=off.  See the if=scsi description above for details on the removable
-parameter, which applies only to scsi-disk devices and not to scsi-generic.
+The removable parameter gives control over the SCSI INQUIRY removable
+(RMB) bit.  USB thumbdrives usually set removable=on, while USB hard
+disks set removable=off.
+
+Bug: usb-storage pretends to be a block device, but it's really a SCSI
+controller that can serve only a single device, which it creates
+automatically.  The automatic creation guesses what kind of guest part
+to create from the host part, like -drive if=scsi.  Host and guest
+part are not cleanly separated.
 
 
 === Character Devices ===
 === Character Devices ===
 
 
@@ -170,7 +192,9 @@ The appropriate DEVNAME depends on the machine type.  For type "pc":
   -device usb-braille,chardev=braille,vendorid=VID,productid=PRID
   -device usb-braille,chardev=braille,vendorid=VID,productid=PRID
   -chardev braille,id=braille
   -chardev braille,id=braille
 
 
-* -virtioconsole is still being worked on
+* -virtioconsole becomes
+  -device virtio-serial-pci,class=C,vectors=V,ioeventfd=IOEVENTFD,max_ports=N
+  -device virtconsole,is_console=NUM,nr=NR,name=NAME
 
 
 LEGACY-CHARDEV translates to -chardev HOST-OPTS... as follows:
 LEGACY-CHARDEV translates to -chardev HOST-OPTS... as follows:
 
 
@@ -219,38 +243,29 @@ LEGACY-CHARDEV to refer to a host part defined with -chardev.
 
 
 === Network Devices ===
 === Network Devices ===
 
 
-A QEMU network device (NIC) has a host and a guest part.
+Host and guest part of network devices have always been separate.
 
 
-The old ways to define NICs define host and guest part together.  It
-looks like this:
+The old way to define the guest part looks like this:
 
 
-    -net nic,vlan=VLAN,macaddr=MACADDR,model=MODEL,name=ID,addr=STR,vectors=V
+    -net nic,netdev=NET-ID,macaddr=MACADDR,model=MODEL,name=ID,addr=STR,vectors=V
 
 
 Except for USB it looks like this:
 Except for USB it looks like this:
 
 
-    -usbdevice net:vlan=VLAN,macaddr=MACADDR,name=ID,addr=STR,vectors=V
+    -usbdevice net:netdev=NET-ID,macaddr=MACADDR,name=ID
 
 
-The new way keeps the parts separate: you create the host part with
--netdev, and the guest device with -device, like this:
+The new way is -device:
 
 
-    -netdev type=TYPE,id=NET-ID
     -device DEVNAME,netdev=NET-ID,mac=MACADDR,DEV-OPTS...
     -device DEVNAME,netdev=NET-ID,mac=MACADDR,DEV-OPTS...
 
 
-Unlike the old way, this creates just a network device, not a VLAN.
-If you really want a VLAN, create it the usual way, then create the
-guest device like this:
-
-    -device DEVNAME,vlan=VLAN,mac=MACADDR,DEV-OPTS...
-
 DEVNAME equals MODEL, except for virtio you have to name the virtio
 DEVNAME equals MODEL, except for virtio you have to name the virtio
 device appropriate for the bus (virtio-net-pci for PCI), and for USB
 device appropriate for the bus (virtio-net-pci for PCI), and for USB
-NIC you have to use usb-net.
+you have to use usb-net.
 
 
 The old name=ID parameter becomes the usual id=ID with -device.
 The old name=ID parameter becomes the usual id=ID with -device.
 
 
 For PCI devices, you can add bus=PCI-BUS,addr=DEVFN to control the PCI
 For PCI devices, you can add bus=PCI-BUS,addr=DEVFN to control the PCI
 device address, as usual.  The old -net nic provides parameter addr
 device address, as usual.  The old -net nic provides parameter addr
-for that, it is silently ignored when the NIC is not a PCI device.
+for that, which is silently ignored when the NIC is not a PCI device.
 
 
 For virtio-net-pci, you can control whether or not ioeventfd is used for
 For virtio-net-pci, you can control whether or not ioeventfd is used for
 virtqueue notify by setting ioeventfd= to on or off (default).
 virtqueue notify by setting ioeventfd= to on or off (default).
@@ -264,20 +279,25 @@ devices and ne2k_isa are.
 
 
 Some PCI devices aren't available with -net nic, e.g. i82558a.
 Some PCI devices aren't available with -net nic, e.g. i82558a.
 
 
-Bug: usb-net does not work, yet.  Patch posted.
+To connect to a VLAN instead of an ordinary host part, replace
+netdev=NET-ID by vlan=VLAN.
 
 
 === Graphics Devices ===
 === Graphics Devices ===
 
 
 Host and guest part of graphics devices have always been separate.
 Host and guest part of graphics devices have always been separate.
 
 
-The old way to define the guest graphics device is -vga VGA.
+The old way to define the guest graphics device is -vga VGA.  Not all
+machines support all -vga options.
 
 
-The new way is -device.  Map from -vga argument to -device:
+The new way is -device.  The mapping from -vga argument to -device
+depends on the machine type.  For machine "pc", it's:
 
 
     std         -device VGA
     std         -device VGA
     cirrus      -device cirrus-vga
     cirrus      -device cirrus-vga
     vmware      -device vmware-svga
     vmware      -device vmware-svga
-    xenfb       not yet available with -device
+    qxl         -device qxl-vga
+    none        -nodefaults
+                disables more than just VGA, see "Default Devices"
 
 
 As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to control
 As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to control
 the PCI device address.
 the PCI device address.
@@ -285,13 +305,16 @@ the PCI device address.
 -device VGA supports properties bios-offset and bios-size, but they
 -device VGA supports properties bios-offset and bios-size, but they
 aren't used with machine type "pc".
 aren't used with machine type "pc".
 
 
-Bug: -device cirrus-vga and -device vmware-svga require -nodefaults.
+For machine "isapc", it's
 
 
-Bug: the new way requires PCI; ISA VGA is not yet available with
--device.
+    std         -device isa-vga
+    cirrus      not yet available with -device
+    none        -nodefaults
+                disables more than just VGA, see "Default Devices"
 
 
-Bug: the new way doesn't work for machine type "pc", because it
-violates obscure device initialization ordering constraints.
+Bug: the new way doesn't work for machine types "pc" and "isapc",
+because it violates obscure device initialization ordering
+constraints.
 
 
 === Audio Devices ===
 === Audio Devices ===
 
 
@@ -308,6 +331,7 @@ Map from -soundhw sound card name to -device:
     cs4231a     -device cs4231a,iobase=IOADDR,irq=IRQ,dma=DMA
     cs4231a     -device cs4231a,iobase=IOADDR,irq=IRQ,dma=DMA
     es1370      -device ES1370
     es1370      -device ES1370
     gus         -device gus,iobase=IOADDR,irq=IRQ,dma=DMA,freq=F
     gus         -device gus,iobase=IOADDR,irq=IRQ,dma=DMA,freq=F
+    hda         -device intel-hda,msi=MSI -device hda-duplex
     sb16        -device sb16,iobase=IOADDR,irq=IRQ,dma=DMA,dma16=DMA16,version=V
     sb16        -device sb16,iobase=IOADDR,irq=IRQ,dma=DMA,dma16=DMA16,version=V
     adlib       not yet available with -device
     adlib       not yet available with -device
     pcspk       not yet available with -device
     pcspk       not yet available with -device
@@ -321,9 +345,10 @@ The old way to define a virtual USB device is -usbdevice DRIVER:OPTS...
 
 
 The new way is -device DEVNAME,DEV-OPTS...  Details depend on DRIVER:
 The new way is -device DEVNAME,DEV-OPTS...  Details depend on DRIVER:
 
 
+* ccid            -device usb-ccid
+* keyboard        -device usb-kbd
 * mouse           -device usb-mouse
 * mouse           -device usb-mouse
 * tablet          -device usb-tablet
 * tablet          -device usb-tablet
-* keyboard        -device usb-kdb
 * wacom-tablet    -device usb-wacom-tablet
 * wacom-tablet    -device usb-wacom-tablet
 * host:...        See "Host Device Assignment"
 * host:...        See "Host Device Assignment"
 * disk:...        See "Block Devices"
 * disk:...        See "Block Devices"
@@ -353,7 +378,7 @@ The new way is
 
 
     -device pci-assign,host=ADDR,iommu=IOMMU,id=ID
     -device pci-assign,host=ADDR,iommu=IOMMU,id=ID
 
 
-The old dma=none becomes iommu=0 with -device.
+The old dma=none becomes iommu=off with -device.
 
 
 The old way to assign a host USB device is
 The old way to assign a host USB device is
 
 
@@ -365,4 +390,27 @@ The new way is
 
 
     -device usb-host,hostbus=BUS,hostaddr=ADDR,vendorid=VID,productid=PRID
     -device usb-host,hostbus=BUS,hostaddr=ADDR,vendorid=VID,productid=PRID
 
 
-where left out or zero BUS, ADDR, VID, PRID serve as wildcard.
+Omitted options match anything, just like the old way's wildcard.
+
+=== Default Devices ===
+
+QEMU creates a number of devices by default, depending on the machine
+type.
+
+-device DEVNAME... and global DEVNAME... suppress default devices for
+some DEVNAMEs:
+
+    default device      suppressing DEVNAMEs
+    CD-ROM              ide-cd, ide-drive, scsi-cd
+    isa-fdc's driveA    isa-fdc
+    parallel            isa-parallel
+    serial              isa-serial
+    VGA                 VGA, cirrus-vga, vmware-svga
+    virtioconsole       virtio-serial-pci, virtio-serial-s390, virtio-serial
+
+The default NIC is connected to a default part created along with it.
+It is *not* suppressed by configuring a NIC with -device (you may call
+that a bug).  -net and -netdev suppress the default NIC.
+
+-nodefaults suppresses all the default devices mentioned above, plus a
+few other things such as default SD-Card drive and default monitor.

+ 38 - 0
docs/usb2.txt

@@ -0,0 +1,38 @@
+
+USB 2.0 Quick Start
+===================
+
+The QEMU EHCI Adapter does *not* support companion controllers.  That
+implies there are two completely separate USB busses: One USB 1.1 bus
+driven by the UHCI controller and one USB 2.0 bus driven by the EHCI
+controller.  Devices must be attached to the correct controller
+manually.
+
+The '-usb' switch will make qemu create the UHCI controller as part of
+the PIIX3 chipset.  The USB 1.1 bus will carry the name "usb.0".
+
+You can use the standard -device switch to add a EHCI controller to
+your virtual machine.  It is strongly recommended to specify an ID for
+the controller so the USB 2.0 bus gets a individual name, for example
+'-device usb-ehci,id=ehci".  This will give you a USB 2.0 bus named
+"ehci.0".
+
+I strongly recomment to also use -device to attach usb devices because
+you can specify the bus they should be attached to this way.  Here is
+a complete example:
+
+    qemu -M pc ${otheroptions}                           \
+        -drive if=none,id=usbstick,file=/path/to/image   \
+        -usb                                             \
+        -device usb-ehci,id=ehci                         \
+        -device usb-tablet,bus=usb.0                     \
+        -device usb-storage,bus=ehci.0,drive=usbstick
+
+This attaches a usb tablet to the UHCI adapter and a usb mass storage
+device to the EHCI adapter.
+
+enjoy,
+  Gerd
+
+--
+Gerd Hoffmann <kraxel@redhat.com>

+ 140 - 0
error.c

@@ -0,0 +1,140 @@
+/*
+ * QEMU Error Objects
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.  See
+ * the COPYING.LIB file in the top-level directory.
+ */
+#include "error.h"
+#include "error_int.h"
+#include "qemu-objects.h"
+#include "qerror.h"
+#include <assert.h>
+
+struct Error
+{
+    QDict *obj;
+    const char *fmt;
+    char *msg;
+};
+
+void error_set(Error **errp, const char *fmt, ...)
+{
+    Error *err;
+    va_list ap;
+
+    if (errp == NULL) {
+        return;
+    }
+
+    err = qemu_mallocz(sizeof(*err));
+
+    va_start(ap, fmt);
+    err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap));
+    va_end(ap);
+    err->fmt = fmt;
+
+    *errp = err;
+}
+
+bool error_is_set(Error **errp)
+{
+    return (errp && *errp);
+}
+
+const char *error_get_pretty(Error *err)
+{
+    if (err->msg == NULL) {
+        QString *str;
+        str = qerror_format(err->fmt, err->obj);
+        err->msg = qemu_strdup(qstring_get_str(str));
+        QDECREF(str);
+    }
+
+    return err->msg;
+}
+
+const char *error_get_field(Error *err, const char *field)
+{
+    if (strcmp(field, "class") == 0) {
+        return qdict_get_str(err->obj, field);
+    } else {
+        QDict *dict = qdict_get_qdict(err->obj, "data");
+        return qdict_get_str(dict, field);
+    }
+}
+
+QDict *error_get_data(Error *err)
+{
+    QDict *data = qdict_get_qdict(err->obj, "data");
+    QINCREF(data);
+    return data;
+}
+
+void error_set_field(Error *err, const char *field, const char *value)
+{
+    QDict *dict = qdict_get_qdict(err->obj, "data");
+    return qdict_put(dict, field, qstring_from_str(value));
+}
+
+void error_free(Error *err)
+{
+    if (err) {
+        QDECREF(err->obj);
+        qemu_free(err->msg);
+        qemu_free(err);
+    }
+}
+
+bool error_is_type(Error *err, const char *fmt)
+{
+    const char *error_class;
+    char *ptr;
+    char *end;
+
+    ptr = strstr(fmt, "'class': '");
+    assert(ptr != NULL);
+    ptr += strlen("'class': '");
+
+    end = strchr(ptr, '\'');
+    assert(end != NULL);
+
+    error_class = error_get_field(err, "class");
+    if (strlen(error_class) != end - ptr) {
+        return false;
+    }
+
+    return strncmp(ptr, error_class, end - ptr) == 0;
+}
+
+void error_propagate(Error **dst_err, Error *local_err)
+{
+    if (dst_err) {
+        *dst_err = local_err;
+    } else if (local_err) {
+        error_free(local_err);
+    }
+}
+
+QObject *error_get_qobject(Error *err)
+{
+    QINCREF(err->obj);
+    return QOBJECT(err->obj);
+}
+
+void error_set_qobject(Error **errp, QObject *obj)
+{
+    Error *err;
+    if (errp == NULL) {
+        return;
+    }
+    err = qemu_mallocz(sizeof(*err));
+    err->obj = qobject_to_qdict(obj);
+    qobject_incref(obj);
+
+    *errp = err;
+}

+ 70 - 0
error.h

@@ -0,0 +1,70 @@
+/*
+ * QEMU Error Objects
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.  See
+ * the COPYING.LIB file in the top-level directory.
+ */
+#ifndef ERROR_H
+#define ERROR_H
+
+#include <stdbool.h>
+
+/**
+ * A class representing internal errors within QEMU.  An error has a string
+ * typename and optionally a set of named string parameters.
+ */
+typedef struct Error Error;
+
+/**
+ * Set an indirect pointer to an error given a printf-style format parameter.
+ * Currently, qerror.h defines these error formats.  This function is not
+ * meant to be used outside of QEMU.
+ */
+void error_set(Error **err, const char *fmt, ...)
+    __attribute__((format(printf, 2, 3)));
+
+/**
+ * Returns true if an indirect pointer to an error is pointing to a valid
+ * error object.
+ */
+bool error_is_set(Error **err);
+
+/**
+ * Get a human readable representation of an error object.
+ */
+const char *error_get_pretty(Error *err);
+
+/**
+ * Get an individual named error field.
+ */
+const char *error_get_field(Error *err, const char *field);
+
+/**
+ * Get an individual named error field.
+ */
+void error_set_field(Error *err, const char *field, const char *value);
+
+/**
+ * Propagate an error to an indirect pointer to an error.  This function will
+ * always transfer ownership of the error reference and handles the case where
+ * dst_err is NULL correctly.
+ */
+void error_propagate(Error **dst_err, Error *local_err);
+
+/**
+ * Free an error object.
+ */
+void error_free(Error *err);
+
+/**
+ * Determine if an error is of a speific type (based on the qerror format).
+ * Non-QEMU users should get the `class' field to identify the error type.
+ */
+bool error_is_type(Error *err, const char *fmt);
+
+#endif

+ 29 - 0
error_int.h

@@ -0,0 +1,29 @@
+/*
+ * QEMU Error Objects
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.  See
+ * the COPYING.LIB file in the top-level directory.
+ */
+#ifndef QEMU_ERROR_INT_H
+#define QEMU_ERROR_INT_H
+
+#include "qemu-common.h"
+#include "qobject.h"
+#include "qdict.h"
+#include "error.h"
+
+/**
+ * Internal QEMU functions for working with Error.
+ *
+ * These are used to convert QErrors to Errors
+ */
+QDict *error_get_data(Error *err);
+QObject *error_get_qobject(Error *err);
+void error_set_qobject(Error **errp, QObject *obj);
+  
+#endif

+ 5 - 2
exec-all.h

@@ -43,7 +43,11 @@ typedef ram_addr_t tb_page_addr_t;
 typedef struct TranslationBlock TranslationBlock;
 typedef struct TranslationBlock TranslationBlock;
 
 
 /* XXX: make safe guess about sizes */
 /* XXX: make safe guess about sizes */
+#if (HOST_LONG_BITS == 32) && (TARGET_LONG_BITS == 64)
+#define MAX_OP_PER_INSTR 128
+#else
 #define MAX_OP_PER_INSTR 96
 #define MAX_OP_PER_INSTR 96
+#endif
 
 
 #if HOST_LONG_BITS == 32
 #if HOST_LONG_BITS == 32
 #define MAX_OPC_PARAM_PER_ARG 2
 #define MAX_OPC_PARAM_PER_ARG 2
@@ -95,7 +99,6 @@ void QEMU_NORETURN cpu_loop_exit(void);
 int page_unprotect(target_ulong address, unsigned long pc, void *puc);
 int page_unprotect(target_ulong address, unsigned long pc, void *puc);
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access);
                                    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_page(CPUState *env, target_ulong addr);
 void tlb_flush(CPUState *env, int flush_global);
 void tlb_flush(CPUState *env, int flush_global);
 #if !defined(CONFIG_USER_ONLY)
 #if !defined(CONFIG_USER_ONLY)
@@ -322,7 +325,7 @@ static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong add
     }
     }
     pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
     pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
     if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
     if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
-#if defined(TARGET_SPARC) || defined(TARGET_MIPS)
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
         do_unassigned_access(addr, 0, 1, 0, 4);
         do_unassigned_access(addr, 0, 1, 0, 4);
 #else
 #else
         cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
         cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);

+ 110 - 18
exec.c

@@ -32,10 +32,10 @@
 #include "hw/qdev.h"
 #include "hw/qdev.h"
 #include "osdep.h"
 #include "osdep.h"
 #include "kvm.h"
 #include "kvm.h"
+#include "hw/xen.h"
 #include "qemu-timer.h"
 #include "qemu-timer.h"
 #if defined(CONFIG_USER_ONLY)
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
 #include <qemu.h>
-#include <signal.h>
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <sys/param.h>
 #include <sys/param.h>
 #if __FreeBSD_version >= 700104
 #if __FreeBSD_version >= 700104
@@ -51,6 +51,8 @@
 #include <libutil.h>
 #include <libutil.h>
 #endif
 #endif
 #endif
 #endif
+#else /* !CONFIG_USER_ONLY */
+#include "xen-mapcache.h"
 #endif
 #endif
 
 
 //#define DEBUG_TB_INVALIDATE
 //#define DEBUG_TB_INVALIDATE
@@ -2085,7 +2087,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     /* we modify the TLB cache so that the dirty bit will be set again
     /* we modify the TLB cache so that the dirty bit will be set again
        when accessing the range */
        when accessing the range */
     start1 = (unsigned long)qemu_safe_ram_ptr(start);
     start1 = (unsigned long)qemu_safe_ram_ptr(start);
-    /* Chek that we don't span multiple blocks - this breaks the
+    /* Check that we don't span multiple blocks - this breaks the
        address comparisons below.  */
        address comparisons below.  */
     if ((unsigned long)qemu_safe_ram_ptr(end - 1) - start1
     if ((unsigned long)qemu_safe_ram_ptr(end - 1) - start1
             != (end - 1) - start) {
             != (end - 1) - start) {
@@ -2916,6 +2918,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
         }
         }
     }
     }
 
 
+    new_block->offset = find_ram_offset(size);
     if (host) {
     if (host) {
         new_block->host = host;
         new_block->host = host;
         new_block->flags |= RAM_PREALLOC_MASK;
         new_block->flags |= RAM_PREALLOC_MASK;
@@ -2933,18 +2936,28 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
 #endif
 #endif
         } else {
         } else {
 #if defined(TARGET_S390X) && defined(CONFIG_KVM)
 #if defined(TARGET_S390X) && defined(CONFIG_KVM)
-            /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */
-            new_block->host = mmap((void*)0x1000000, size,
+            /* S390 KVM requires the topmost vma of the RAM to be smaller than
+               an system defined value, which is at least 256GB. Larger systems
+               have larger values. We put the guest between the end of data
+               segment (system break) and this value. We use 32GB as a base to
+               have enough room for the system break to grow. */
+            new_block->host = mmap((void*)0x800000000, size,
                                    PROT_EXEC|PROT_READ|PROT_WRITE,
                                    PROT_EXEC|PROT_READ|PROT_WRITE,
-                                   MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+                                   MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+            if (new_block->host == MAP_FAILED) {
+                fprintf(stderr, "Allocating RAM failed\n");
+                abort();
+            }
 #else
 #else
-            new_block->host = qemu_vmalloc(size);
+            if (xen_mapcache_enabled()) {
+                xen_ram_alloc(new_block->offset, size);
+            } else {
+                new_block->host = qemu_vmalloc(size);
+            }
 #endif
 #endif
             qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
             qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
         }
         }
     }
     }
-
-    new_block->offset = find_ram_offset(size);
     new_block->length = size;
     new_block->length = size;
 
 
     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
@@ -2965,6 +2978,19 @@ ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size)
     return qemu_ram_alloc_from_ptr(dev, name, size, NULL);
     return qemu_ram_alloc_from_ptr(dev, name, size, NULL);
 }
 }
 
 
+void qemu_ram_free_from_ptr(ram_addr_t addr)
+{
+    RAMBlock *block;
+
+    QLIST_FOREACH(block, &ram_list.blocks, next) {
+        if (addr == block->offset) {
+            QLIST_REMOVE(block, next);
+            qemu_free(block);
+            return;
+        }
+    }
+}
+
 void qemu_ram_free(ram_addr_t addr)
 void qemu_ram_free(ram_addr_t addr)
 {
 {
     RAMBlock *block;
     RAMBlock *block;
@@ -2989,7 +3015,11 @@ void qemu_ram_free(ram_addr_t addr)
 #if defined(TARGET_S390X) && defined(CONFIG_KVM)
 #if defined(TARGET_S390X) && defined(CONFIG_KVM)
                 munmap(block->host, block->length);
                 munmap(block->host, block->length);
 #else
 #else
-                qemu_vfree(block->host);
+                if (xen_mapcache_enabled()) {
+                    qemu_invalidate_entry(block->host);
+                } else {
+                    qemu_vfree(block->host);
+                }
 #endif
 #endif
             }
             }
             qemu_free(block);
             qemu_free(block);
@@ -3078,6 +3108,16 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
                 QLIST_REMOVE(block, next);
                 QLIST_REMOVE(block, next);
                 QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
                 QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
             }
             }
+            if (xen_mapcache_enabled()) {
+                /* We need to check if the requested address is in the RAM
+                 * because we don't want to map the entire memory in QEMU.
+                 */
+                if (block->offset == 0) {
+                    return qemu_map_cache(addr, 0, 1);
+                } else if (block->host == NULL) {
+                    block->host = xen_map_block(block->offset, block->length);
+                }
+            }
             return block->host + (addr - block->offset);
             return block->host + (addr - block->offset);
         }
         }
     }
     }
@@ -3097,6 +3137,16 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
 
 
     QLIST_FOREACH(block, &ram_list.blocks, next) {
     QLIST_FOREACH(block, &ram_list.blocks, next) {
         if (addr - block->offset < block->length) {
         if (addr - block->offset < block->length) {
+            if (xen_mapcache_enabled()) {
+                /* We need to check if the requested address is in the RAM
+                 * because we don't want to map the entire memory in QEMU.
+                 */
+                if (block->offset == 0) {
+                    return qemu_map_cache(addr, 0, 1);
+                } else if (block->host == NULL) {
+                    block->host = xen_map_block(block->offset, block->length);
+                }
+            }
             return block->host + (addr - block->offset);
             return block->host + (addr - block->offset);
         }
         }
     }
     }
@@ -3107,17 +3157,48 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
     return NULL;
     return NULL;
 }
 }
 
 
+void qemu_put_ram_ptr(void *addr)
+{
+    trace_qemu_put_ram_ptr(addr);
+
+    if (xen_mapcache_enabled()) {
+        RAMBlock *block;
+
+        QLIST_FOREACH(block, &ram_list.blocks, next) {
+            if (addr == block->host) {
+                break;
+            }
+        }
+        if (block && block->host) {
+            xen_unmap_block(block->host, block->length);
+            block->host = NULL;
+        } else {
+            qemu_map_cache_unlock(addr);
+        }
+    }
+}
+
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
 {
     RAMBlock *block;
     RAMBlock *block;
     uint8_t *host = ptr;
     uint8_t *host = ptr;
 
 
     QLIST_FOREACH(block, &ram_list.blocks, next) {
     QLIST_FOREACH(block, &ram_list.blocks, next) {
+        /* This case append when the block is not mapped. */
+        if (block->host == NULL) {
+            continue;
+        }
         if (host - block->host < block->length) {
         if (host - block->host < block->length) {
             *ram_addr = block->offset + (host - block->host);
             *ram_addr = block->offset + (host - block->host);
             return 0;
             return 0;
         }
         }
     }
     }
+
+    if (xen_mapcache_enabled()) {
+        *ram_addr = qemu_ram_addr_from_mapcache(ptr);
+        return 0;
+    }
+
     return -1;
     return -1;
 }
 }
 
 
@@ -3139,7 +3220,7 @@ static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 0, 0, 0, 1);
     do_unassigned_access(addr, 0, 0, 0, 1);
 #endif
 #endif
     return 0;
     return 0;
@@ -3150,7 +3231,7 @@ static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 0, 0, 0, 2);
     do_unassigned_access(addr, 0, 0, 0, 2);
 #endif
 #endif
     return 0;
     return 0;
@@ -3161,7 +3242,7 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 0, 0, 0, 4);
     do_unassigned_access(addr, 0, 0, 0, 4);
 #endif
 #endif
     return 0;
     return 0;
@@ -3172,7 +3253,7 @@ static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_
 #ifdef DEBUG_UNASSIGNED
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 1, 0, 0, 1);
     do_unassigned_access(addr, 1, 0, 0, 1);
 #endif
 #endif
 }
 }
@@ -3182,7 +3263,7 @@ static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_
 #ifdef DEBUG_UNASSIGNED
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 1, 0, 0, 2);
     do_unassigned_access(addr, 1, 0, 0, 2);
 #endif
 #endif
 }
 }
@@ -3192,7 +3273,7 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
 #ifdef DEBUG_UNASSIGNED
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 1, 0, 0, 4);
     do_unassigned_access(addr, 1, 0, 0, 4);
 #endif
 #endif
 }
 }
@@ -3812,6 +3893,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                     cpu_physical_memory_set_dirty_flags(
                     cpu_physical_memory_set_dirty_flags(
                         addr1, (0xff & ~CODE_DIRTY_FLAG));
                         addr1, (0xff & ~CODE_DIRTY_FLAG));
                 }
                 }
+                qemu_put_ram_ptr(ptr);
             }
             }
         } else {
         } else {
             if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
             if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
@@ -3839,9 +3921,9 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                 }
                 }
             } else {
             } else {
                 /* RAM case */
                 /* RAM case */
-                ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
-                    (addr & ~TARGET_PAGE_MASK);
-                memcpy(buf, ptr, l);
+                ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK);
+                memcpy(buf, ptr + (addr & ~TARGET_PAGE_MASK), l);
+                qemu_put_ram_ptr(ptr);
             }
             }
         }
         }
         len -= l;
         len -= l;
@@ -3882,6 +3964,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
             /* ROM/RAM case */
             /* ROM/RAM case */
             ptr = qemu_get_ram_ptr(addr1);
             ptr = qemu_get_ram_ptr(addr1);
             memcpy(ptr, buf, l);
             memcpy(ptr, buf, l);
+            qemu_put_ram_ptr(ptr);
         }
         }
         len -= l;
         len -= l;
         buf += l;
         buf += l;
@@ -4023,6 +4106,15 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
                 access_len -= l;
                 access_len -= l;
             }
             }
         }
         }
+        if (xen_mapcache_enabled()) {
+            uint8_t *buffer1 = buffer;
+            uint8_t *end_buffer = buffer + len;
+
+            while (buffer1 < end_buffer) {
+                qemu_put_ram_ptr(buffer1);
+                buffer1 += TARGET_PAGE_SIZE;
+            }
+        }
         return;
         return;
     }
     }
     if (is_write) {
     if (is_write) {

+ 0 - 540
fpu/softfloat-native.c

@@ -1,540 +0,0 @@
-/* Native implementation of soft float functions. Only a single status
-   context is supported */
-#include "softfloat.h"
-#include <math.h>
-#if defined(CONFIG_SOLARIS)
-#include <fenv.h>
-#endif
-
-void set_float_rounding_mode(int val STATUS_PARAM)
-{
-    STATUS(float_rounding_mode) = val;
-#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) || \
-    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
-    fpsetround(val);
-#else
-    fesetround(val);
-#endif
-}
-
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM)
-{
-    STATUS(floatx80_rounding_precision) = val;
-}
-#endif
-
-#if defined(CONFIG_BSD) || \
-    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 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))
-#if !defined(__sparc__) && \
-    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
-extern long double rintl(long double);
-extern long double scalbnl(long double, int);
-
-long long
-llrintl(long double x) {
-	return ((long long) rintl(x));
-}
-
-long
-lrintl(long double x) {
-	return ((long) rintl(x));
-}
-
-long double
-ldexpl(long double x, int n) {
-	return (scalbnl(x, n));
-}
-#endif
-#endif
-
-#if defined(_ARCH_PPC)
-
-/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
-static 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;
-}
-
-float32 uint32_to_float32(unsigned int v STATUS_PARAM)
-{
-    return (float32)v;
-}
-
-float64 int32_to_float64(int v STATUS_PARAM)
-{
-    return (float64)v;
-}
-
-float64 uint32_to_float64(unsigned 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;
-}
-float32 uint64_to_float32( uint64_t v STATUS_PARAM)
-{
-    return (float32)v;
-}
-float64 int64_to_float64( int64_t v STATUS_PARAM)
-{
-    return (float64)v;
-}
-float64 uint64_to_float64( uint64_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
-
-unsigned int float32_to_uint32( float32 a STATUS_PARAM)
-{
-    int64_t v;
-    unsigned int res;
-
-    v = llrintf(a);
-    if (v < 0) {
-        res = 0;
-    } else if (v > 0xffffffff) {
-        res = 0xffffffff;
-    } else {
-        res = v;
-    }
-    return res;
-}
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
-{
-    int64_t v;
-    unsigned int res;
-
-    v = (int64_t)a;
-    if (v < 0) {
-        res = 0;
-    } else if (v > 0xffffffff) {
-        res = 0xffffffff;
-    } else {
-        res = v;
-    }
-    return res;
-}
-
-/*----------------------------------------------------------------------------
-| 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 float_relation_less;
-    } else if (a == b) {
-        return float_relation_equal;
-    } else if (a > b) {
-        return float_relation_greater;
-    } else {
-        return float_relation_unordered;
-    }
-}
-int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
-{
-    if (isless(a, b)) {
-        return float_relation_less;
-    } else if (a == b) {
-        return float_relation_equal;
-    } else if (isgreater(a, b)) {
-        return float_relation_greater;
-    } else {
-        return float_relation_unordered;
-    }
-}
-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 );
-}
-
-int float32_is_quiet_nan( float32 a1 )
-{
-    float32u u;
-    uint64_t a;
-    u.f = a1;
-    a = u.i;
-    return ( 0xFF800000 < ( a<<1 ) );
-}
-
-int float32_is_any_nan( float32 a1 )
-{
-    float32u u;
-    uint32_t a;
-    u.f = a1;
-    a = u.i;
-    return (a & ~(1 << 31)) > 0x7f800000U;
-}
-
-/*----------------------------------------------------------------------------
-| 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
-
-unsigned int float64_to_uint32( float64 a STATUS_PARAM)
-{
-    int64_t v;
-    unsigned int res;
-
-    v = llrint(a);
-    if (v < 0) {
-        res = 0;
-    } else if (v > 0xffffffff) {
-        res = 0xffffffff;
-    } else {
-        res = v;
-    }
-    return res;
-}
-unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
-{
-    int64_t v;
-    unsigned int res;
-
-    v = (int64_t)a;
-    if (v < 0) {
-        res = 0;
-    } else if (v > 0xffffffff) {
-        res = 0xffffffff;
-    } else {
-        res = v;
-    }
-    return res;
-}
-uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
-{
-    int64_t v;
-
-    v = llrint(a + (float64)INT64_MIN);
-
-    return v - INT64_MIN;
-}
-uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
-{
-    int64_t v;
-
-    v = (int64_t)(a + (float64)INT64_MIN);
-
-    return v - INT64_MIN;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-#if defined(__sun__) && \
-    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
-static inline float64 trunc(float64 x)
-{
-    return x < 0 ? -floor(-x) : floor(x);
-}
-#endif
-float64 float64_trunc_to_int( float64 a STATUS_PARAM )
-{
-    return trunc(a);
-}
-
-float64 float64_round_to_int( float64 a STATUS_PARAM )
-{
-    return rint(a);
-}
-
-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 float_relation_less;
-    } else if (a == b) {
-        return float_relation_equal;
-    } else if (a > b) {
-        return float_relation_greater;
-    } else {
-        return float_relation_unordered;
-    }
-}
-int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
-{
-    if (isless(a, b)) {
-        return float_relation_less;
-    } else if (a == b) {
-        return float_relation_equal;
-    } else if (isgreater(a, b)) {
-        return float_relation_greater;
-    } else {
-        return float_relation_unordered;
-    }
-}
-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_quiet_nan( float64 a1 )
-{
-    float64u u;
-    uint64_t a;
-    u.f = a1;
-    a = u.i;
-
-    return ( LIT64( 0xFFF0000000000000 ) < (uint64_t) ( a<<1 ) );
-
-}
-
-int float64_is_any_nan( float64 a1 )
-{
-    float64u u;
-    uint64_t a;
-    u.f = a1;
-    a = u.i;
-
-    return (a & ~(1ULL << 63)) > LIT64 (0x7FF0000000000000 );
-}
-
-#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 float_relation_less;
-    } else if (a == b) {
-        return float_relation_equal;
-    } else if (a > b) {
-        return float_relation_greater;
-    } else {
-        return float_relation_unordered;
-    }
-}
-int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
-{
-    if (isless(a, b)) {
-        return float_relation_less;
-    } else if (a == b) {
-        return float_relation_equal;
-    } else if (isgreater(a, b)) {
-        return float_relation_greater;
-    } else {
-        return float_relation_unordered;
-    }
-}
-int floatx80_is_signaling_nan( floatx80 a1)
-{
-    floatx80u u;
-    uint64_t aLow;
-    u.f = a1;
-
-    aLow = u.i.low & ~ LIT64( 0x4000000000000000 );
-    return
-           ( ( u.i.high & 0x7FFF ) == 0x7FFF )
-        && (uint64_t) ( aLow<<1 )
-        && ( u.i.low == aLow );
-}
-
-int floatx80_is_quiet_nan( floatx80 a1 )
-{
-    floatx80u u;
-    u.f = a1;
-    return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( u.i.low<<1 );
-}
-
-int floatx80_is_any_nan( floatx80 a1 )
-{
-    floatx80u u;
-    u.f = a1;
-    return ((u.i.high & 0x7FFF) == 0x7FFF) && ( u.i.low<<1 );
-}
-
-#endif

+ 0 - 531
fpu/softfloat-native.h

@@ -1,531 +0,0 @@
-/* Native implementation of soft float functions */
-#include <math.h>
-
-#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) \
-    || defined(CONFIG_SOLARIS)
-#include <ieeefp.h>
-#define fabsf(f) ((float)fabs(f))
-#else
-#include <fenv.h>
-#endif
-
-#if defined(__OpenBSD__) || defined(__NetBSD__)
-#include <sys/param.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(CONFIG_SOLARIS) && \
-           ((CONFIG_SOLARIS_VERSION <= 9 ) || \
-           ((CONFIG_SOLARIS_VERSION == 10) && (__GNUC__ < 4))) \
-    || (defined(__OpenBSD__) && (OpenBSD < 200811))
-/*
- * 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.
- */
-#if defined(__OpenBSD__)
-#define unordered(x, y) (isnan(x) || isnan(y))
-#endif
-
-#ifdef __NetBSD__
-#ifndef isgreater
-#define isgreater(x, y)		__builtin_isgreater(x, y)
-#endif
-#ifndef isgreaterequal
-#define isgreaterequal(x, y)	__builtin_isgreaterequal(x, y)
-#endif
-#ifndef isless
-#define isless(x, y)		__builtin_isless(x, y)
-#endif
-#ifndef islessequal
-#define islessequal(x, y)	__builtin_islessequal(x, y)
-#endif
-#ifndef isunordered
-#define isunordered(x, y)	__builtin_isunordered(x, y)
-#endif
-#endif
-
-
-#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
-
-#if defined(__sun__) && !defined(CONFIG_NEEDS_LIBSUNMATH)
-
-#ifndef isnan
-# define isnan(x) \
-    (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
-     : sizeof (x) == sizeof (double) ? isnan_d (x) \
-     : isnan_f (x))
-static inline int isnan_f  (float       x) { return x != x; }
-static inline int isnan_d  (double      x) { return x != x; }
-static inline int isnan_ld (long double x) { return x != x; }
-#endif
-
-#ifndef isinf
-# define isinf(x) \
-    (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
-     : sizeof (x) == sizeof (double) ? isinf_d (x) \
-     : isinf_f (x))
-static inline int isinf_f  (float       x) { return isnan (x - x); }
-static inline int isinf_d  (double      x) { return isnan (x - x); }
-static inline int isinf_ld (long double x) { return isnan (x - x); }
-#endif
-#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(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) \
-    || defined(CONFIG_SOLARIS)
-#if defined(__OpenBSD__)
-#define FE_RM FP_RM
-#define FE_RP FP_RP
-#define FE_RZ FP_RZ
-#endif
-enum {
-    float_round_nearest_even = FP_RN,
-    float_round_down         = FP_RM,
-    float_round_up           = FP_RP,
-    float_round_to_zero      = FP_RZ
-};
-#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 {
-    int float_rounding_mode;
-#ifdef FLOATX80
-    int 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);
-float32 uint32_to_float32( unsigned int STATUS_PARAM);
-float64 int32_to_float64( 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);
-float32 uint64_to_float32( uint64_t STATUS_PARAM);
-float64 int64_to_float64( int64_t STATUS_PARAM);
-float64 uint64_to_float64( uint64_t v 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 constants.
-*----------------------------------------------------------------------------*/
-#define float32_zero (0.0)
-#define float32_one (1.0)
-#define float32_ln2 (0.6931471)
-#define float32_pi (3.1415926)
-#define float32_half (0.5)
-
-/*----------------------------------------------------------------------------
-| 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 a STATUS_PARAM);
-unsigned int float32_to_uint32_round_to_zero( float32 a 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_quiet( 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( 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);
-}
-INLINE int float32_unordered_quiet( 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 );
-int float32_is_quiet_nan( float32 );
-int float32_is_any_nan( float32 );
-
-INLINE float32 float32_abs(float32 a)
-{
-    return fabsf(a);
-}
-
-INLINE float32 float32_chs(float32 a)
-{
-    return -a;
-}
-
-INLINE float32 float32_is_infinity(float32 a)
-{
-    return fpclassify(a) == FP_INFINITE;
-}
-
-INLINE float32 float32_is_neg(float32 a)
-{
-    float32u u;
-    u.f = a;
-    return u.i >> 31;
-}
-
-INLINE float32 float32_is_zero(float32 a)
-{
-    return fpclassify(a) == FP_ZERO;
-}
-
-INLINE float32 float32_scalbn(float32 a, int n STATUS_PARAM)
-{
-    return scalbnf(a, n);
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion constants.
-*----------------------------------------------------------------------------*/
-#define float64_zero (0.0)
-#define float64_one (1.0)
-#define float64_ln2 (0.693147180559945)
-#define float64_pi (3.141592653589793)
-#define float64_half (0.5)
-
-/*----------------------------------------------------------------------------
-| 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 );
-uint64_t float64_to_uint64( float64 STATUS_PARAM );
-uint64_t float64_to_uint64_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_quiet( 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( 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);
-}
-INLINE int float64_unordered_quiet( 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_any_nan( float64 );
-int float64_is_quiet_nan( float64 );
-
-INLINE float64 float64_abs(float64 a)
-{
-    return fabs(a);
-}
-
-INLINE float64 float64_chs(float64 a)
-{
-    return -a;
-}
-
-INLINE float64 float64_is_infinity(float64 a)
-{
-    return fpclassify(a) == FP_INFINITE;
-}
-
-INLINE float64 float64_is_neg(float64 a)
-{
-    float64u u;
-    u.f = a;
-    return u.i >> 63;
-}
-
-INLINE float64 float64_is_zero(float64 a)
-{
-    return fpclassify(a) == FP_ZERO;
-}
-
-INLINE float64 float64_scalbn(float64 a, int n STATUS_PARAM)
-{
-    return scalbn(a, n);
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion constants.
-*----------------------------------------------------------------------------*/
-#define floatx80_zero (0.0L)
-#define floatx80_one (1.0L)
-#define floatx80_ln2 (0.69314718055994530943L)
-#define floatx80_pi (3.14159265358979323851L)
-#define floatx80_half (0.5L)
-
-/*----------------------------------------------------------------------------
-| 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_quiet( 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( 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);
-}
-INLINE int floatx80_unordered_quiet( 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 );
-int floatx80_is_quiet_nan( floatx80 );
-int floatx80_is_any_nan( floatx80 );
-
-INLINE floatx80 floatx80_abs(floatx80 a)
-{
-    return fabsl(a);
-}
-
-INLINE floatx80 floatx80_chs(floatx80 a)
-{
-    return -a;
-}
-
-INLINE floatx80 floatx80_is_infinity(floatx80 a)
-{
-    return fpclassify(a) == FP_INFINITE;
-}
-
-INLINE floatx80 floatx80_is_neg(floatx80 a)
-{
-    floatx80u u;
-    u.f = a;
-    return u.i.high >> 15;
-}
-
-INLINE floatx80 floatx80_is_zero(floatx80 a)
-{
-    return fpclassify(a) == FP_ZERO;
-}
-
-INLINE floatx80 floatx80_scalbn(floatx80 a, int n STATUS_PARAM)
-{
-    return scalbnl(a, n);
-}
-
-#endif

+ 0 - 7
fpu/softfloat-specialize.h

@@ -523,8 +523,6 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
     }
     }
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is a
 | Returns 1 if the extended double-precision floating-point value `a' is a
 | quiet NaN; otherwise returns 0. This slightly differs from the same
 | quiet NaN; otherwise returns 0. This slightly differs from the same
@@ -681,10 +679,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
     }
     }
 }
 }
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
 | NaN; otherwise returns 0.
 | NaN; otherwise returns 0.
@@ -820,4 +814,3 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
     }
     }
 }
 }
 
 
-#endif

+ 34 - 69
fpu/softfloat.c

@@ -64,12 +64,10 @@ void set_float_exception_flags(int val STATUS_PARAM)
     STATUS(float_exception_flags) = val;
     STATUS(float_exception_flags) = val;
 }
 }
 
 
-#ifdef FLOATX80
 void set_floatx80_rounding_precision(int val STATUS_PARAM)
 void set_floatx80_rounding_precision(int val STATUS_PARAM)
 {
 {
     STATUS(floatx80_rounding_precision) = val;
     STATUS(floatx80_rounding_precision) = val;
 }
 }
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the fraction bits of the half-precision floating-point value `a'.
 | Returns the fraction bits of the half-precision floating-point value `a'.
@@ -341,7 +339,10 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, uint32_t zSig STATUS
             return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
             return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
         }
         }
         if ( zExp < 0 ) {
         if ( zExp < 0 ) {
-            if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
+            if (STATUS(flush_to_zero)) {
+                float_raise(float_flag_output_denormal STATUS_VAR);
+                return packFloat32(zSign, 0, 0);
+            }
             isTiny =
             isTiny =
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                 || ( zExp < -1 )
                 || ( zExp < -1 )
@@ -520,7 +521,10 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, uint64_t zSig STATUS
             return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
             return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
         }
         }
         if ( zExp < 0 ) {
         if ( zExp < 0 ) {
-            if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
+            if (STATUS(flush_to_zero)) {
+                float_raise(float_flag_output_denormal STATUS_VAR);
+                return packFloat64(zSign, 0, 0);
+            }
             isTiny =
             isTiny =
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                 || ( zExp < -1 )
                 || ( zExp < -1 )
@@ -558,8 +562,6 @@ static float64
 
 
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the fraction bits of the extended double-precision floating-point
 | Returns the fraction bits of the extended double-precision floating-point
 | value `a'.
 | value `a'.
@@ -699,7 +701,10 @@ static floatx80
             goto overflow;
             goto overflow;
         }
         }
         if ( zExp <= 0 ) {
         if ( zExp <= 0 ) {
-            if ( STATUS(flush_to_zero) ) return packFloatx80( zSign, 0, 0 );
+            if (STATUS(flush_to_zero)) {
+                float_raise(float_flag_output_denormal STATUS_VAR);
+                return packFloatx80(zSign, 0, 0);
+            }
             isTiny =
             isTiny =
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                 || ( zExp < 0 )
                 || ( zExp < 0 )
@@ -842,10 +847,6 @@ static floatx80
 
 
 }
 }
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the least-significant 64 fraction bits of the quadruple-precision
 | Returns the least-significant 64 fraction bits of the quadruple-precision
 | floating-point value `a'.
 | floating-point value `a'.
@@ -1030,7 +1031,10 @@ static float128
             return packFloat128( zSign, 0x7FFF, 0, 0 );
             return packFloat128( zSign, 0x7FFF, 0, 0 );
         }
         }
         if ( zExp < 0 ) {
         if ( zExp < 0 ) {
-            if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
+            if (STATUS(flush_to_zero)) {
+                float_raise(float_flag_output_denormal STATUS_VAR);
+                return packFloat128(zSign, 0, 0, 0);
+            }
             isTiny =
             isTiny =
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                 || ( zExp < -1 )
                 || ( zExp < -1 )
@@ -1106,8 +1110,6 @@ static float128
 
 
 }
 }
 
 
-#endif
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the 32-bit two's complement integer `a'
 | Returns the result of converting the 32-bit two's complement integer `a'
 | to the single-precision floating-point format.  The conversion is performed
 | to the single-precision floating-point format.  The conversion is performed
@@ -1147,8 +1149,6 @@ float64 int32_to_float64( int32 a STATUS_PARAM )
 
 
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the 32-bit two's complement integer `a'
 | Returns the result of converting the 32-bit two's complement integer `a'
 | to the extended double-precision floating-point format.  The conversion
 | to the extended double-precision floating-point format.  The conversion
@@ -1172,10 +1172,6 @@ floatx80 int32_to_floatx80( int32 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the 32-bit two's complement integer `a' to
 | Returns the result of converting the 32-bit two's complement integer `a' to
 | the quadruple-precision floating-point format.  The conversion is performed
 | the quadruple-precision floating-point format.  The conversion is performed
@@ -1198,8 +1194,6 @@ float128 int32_to_float128( int32 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the 64-bit two's complement integer `a'
 | Returns the result of converting the 64-bit two's complement integer `a'
 | to the single-precision floating-point format.  The conversion is performed
 | to the single-precision floating-point format.  The conversion is performed
@@ -1279,8 +1273,6 @@ float64 uint64_to_float64( uint64 a STATUS_PARAM )
 
 
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the 64-bit two's complement integer `a'
 | Returns the result of converting the 64-bit two's complement integer `a'
 | to the extended double-precision floating-point format.  The conversion
 | to the extended double-precision floating-point format.  The conversion
@@ -1302,10 +1294,6 @@ floatx80 int64_to_floatx80( int64 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the 64-bit two's complement integer `a' to
 | Returns the result of converting the 64-bit two's complement integer `a' to
 | the quadruple-precision floating-point format.  The conversion is performed
 | the quadruple-precision floating-point format.  The conversion is performed
@@ -1339,8 +1327,6 @@ float128 int64_to_float128( int64 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the single-precision floating-point value
 | Returns the result of converting the single-precision floating-point value
 | `a' to the 32-bit two's complement integer format.  The conversion is
 | `a' to the 32-bit two's complement integer format.  The conversion is
@@ -1578,8 +1564,6 @@ float64 float32_to_float64( float32 a STATUS_PARAM )
 
 
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the single-precision floating-point value
 | Returns the result of converting the single-precision floating-point value
 | `a' to the extended double-precision floating-point format.  The conversion
 | `a' to the extended double-precision floating-point format.  The conversion
@@ -1610,10 +1594,6 @@ floatx80 float32_to_floatx80( float32 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the single-precision floating-point value
 | Returns the result of converting the single-precision floating-point value
 | `a' to the double-precision floating-point format.  The conversion is
 | `a' to the double-precision floating-point format.  The conversion is
@@ -1644,8 +1624,6 @@ float128 float32_to_float128( float32 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Rounds the single-precision floating-point value `a' to an integer, and
 | Rounds the single-precision floating-point value `a' to an integer, and
 | returns the result as a single-precision floating-point value.  The
 | returns the result as a single-precision floating-point value.  The
@@ -1761,7 +1739,12 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
             return a;
             return a;
         }
         }
         if ( aExp == 0 ) {
         if ( aExp == 0 ) {
-            if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
+            if (STATUS(flush_to_zero)) {
+                if (aSig | bSig) {
+                    float_raise(float_flag_output_denormal STATUS_VAR);
+                }
+                return packFloat32(zSign, 0, 0);
+            }
             return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
             return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
         }
         }
         zSig = 0x40000000 + aSig + bSig;
         zSig = 0x40000000 + aSig + bSig;
@@ -2922,8 +2905,6 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
     return packFloat16(aSign, aExp + 14, aSig >> 13);
     return packFloat16(aSign, aExp + 14, aSig >> 13);
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the double-precision floating-point value
 | Returns the result of converting the double-precision floating-point value
 | `a' to the extended double-precision floating-point format.  The conversion
 | `a' to the extended double-precision floating-point format.  The conversion
@@ -2955,10 +2936,6 @@ floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the double-precision floating-point value
 | Returns the result of converting the double-precision floating-point value
 | `a' to the quadruple-precision floating-point format.  The conversion is
 | `a' to the quadruple-precision floating-point format.  The conversion is
@@ -2990,8 +2967,6 @@ float128 float64_to_float128( float64 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Rounds the double-precision floating-point value `a' to an integer, and
 | Rounds the double-precision floating-point value `a' to an integer, and
 | returns the result as a double-precision floating-point value.  The
 | returns the result as a double-precision floating-point value.  The
@@ -3120,7 +3095,12 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
             return a;
             return a;
         }
         }
         if ( aExp == 0 ) {
         if ( aExp == 0 ) {
-            if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
+            if (STATUS(flush_to_zero)) {
+                if (aSig | bSig) {
+                    float_raise(float_flag_output_denormal STATUS_VAR);
+                }
+                return packFloat64(zSign, 0, 0);
+            }
             return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
             return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
         }
         }
         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
@@ -3794,8 +3774,6 @@ int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM )
     return 0;
     return 0;
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the extended double-precision floating-
 | Returns the result of converting the extended double-precision floating-
 | point value `a' to the 32-bit two's complement integer format.  The
 | point value `a' to the 32-bit two's complement integer format.  The
@@ -4008,8 +3986,6 @@ float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
 
 
 }
 }
 
 
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the extended double-precision floating-
 | Returns the result of converting the extended double-precision floating-
 | point value `a' to the quadruple-precision floating-point format.  The
 | point value `a' to the quadruple-precision floating-point format.  The
@@ -4034,8 +4010,6 @@ float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Rounds the extended double-precision floating-point value `a' to an integer,
 | Rounds the extended double-precision floating-point value `a' to an integer,
 | and returns the result as an extended quadruple-precision floating-point
 | and returns the result as an extended quadruple-precision floating-point
@@ -4827,10 +4801,6 @@ int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
     return 0;
     return 0;
 }
 }
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the quadruple-precision floating-point
 | Returns the result of converting the quadruple-precision floating-point
 | value `a' to the 32-bit two's complement integer format.  The conversion
 | value `a' to the 32-bit two's complement integer format.  The conversion
@@ -5080,8 +5050,6 @@ float64 float128_to_float64( float128 a STATUS_PARAM )
 
 
 }
 }
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Returns the result of converting the quadruple-precision floating-point
 | Returns the result of converting the quadruple-precision floating-point
 | value `a' to the extended double-precision floating-point format.  The
 | value `a' to the extended double-precision floating-point format.  The
@@ -5117,8 +5085,6 @@ floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
 
 
 }
 }
 
 
-#endif
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Rounds the quadruple-precision floating-point value `a' to an integer, and
 | Rounds the quadruple-precision floating-point value `a' to an integer, and
 | returns the result as a quadruple-precision floating-point value.  The
 | returns the result as a quadruple-precision floating-point value.  The
@@ -5282,7 +5248,12 @@ static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM
         }
         }
         add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
         add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
         if ( aExp == 0 ) {
         if ( aExp == 0 ) {
-            if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
+            if (STATUS(flush_to_zero)) {
+                if (zSig0 | zSig1) {
+                    float_raise(float_flag_output_denormal STATUS_VAR);
+                }
+                return packFloat128(zSign, 0, 0, 0);
+            }
             return packFloat128( zSign, 0, zSig0, zSig1 );
             return packFloat128( zSign, 0, zSig0, zSig1 );
         }
         }
         zSig2 = 0;
         zSig2 = 0;
@@ -5993,8 +5964,6 @@ int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
     return 0;
     return 0;
 }
 }
 
 
-#endif
-
 /* misc functions */
 /* misc functions */
 float32 uint32_to_float32( unsigned int a STATUS_PARAM )
 float32 uint32_to_float32( unsigned int a STATUS_PARAM )
 {
 {
@@ -6396,7 +6365,6 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
     return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
     return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
 }
 }
 
 
-#ifdef FLOATX80
 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 {
 {
     flag aSign;
     flag aSign;
@@ -6427,9 +6395,7 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
     return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
     return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
                                           aSign, aExp, aSig, 0 STATUS_VAR );
                                           aSign, aExp, aSig, 0 STATUS_VAR );
 }
 }
-#endif
 
 
-#ifdef FLOAT128
 float128 float128_scalbn( float128 a, int n STATUS_PARAM )
 float128 float128_scalbn( float128 a, int n STATUS_PARAM )
 {
 {
     flag aSign;
     flag aSign;
@@ -6462,4 +6428,3 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
                                           STATUS_VAR );
                                           STATUS_VAR );
 
 
 }
 }
-#endif

+ 17 - 62
fpu/softfloat.h

@@ -74,24 +74,6 @@ typedef int64_t int64;
 #define SNAN_BIT_IS_ONE		0
 #define SNAN_BIT_IS_ONE		0
 #endif
 #endif
 
 
-/*----------------------------------------------------------------------------
-| 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(CONFIG_BSD)
-#define FLOATX80
-#endif
-#endif /* !CONFIG_SOFTFLOAT */
-
 #define STATUS_PARAM , float_status *status
 #define STATUS_PARAM , float_status *status
 #define STATUS(field) status->field
 #define STATUS(field) status->field
 #define STATUS_VAR , status
 #define STATUS_VAR , status
@@ -106,7 +88,6 @@ enum {
     float_relation_unordered =  2
     float_relation_unordered =  2
 };
 };
 
 
-#ifdef CONFIG_SOFTFLOAT
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE floating-point types.
 | Software IEC/IEEE floating-point types.
 *----------------------------------------------------------------------------*/
 *----------------------------------------------------------------------------*/
@@ -149,14 +130,11 @@ typedef uint64_t float64;
 #define const_float32(x) (x)
 #define const_float32(x) (x)
 #define const_float64(x) (x)
 #define const_float64(x) (x)
 #endif
 #endif
-#ifdef FLOATX80
 typedef struct {
 typedef struct {
     uint64_t low;
     uint64_t low;
     uint16_t high;
     uint16_t high;
 } floatx80;
 } floatx80;
 #define make_floatx80(exp, mant) ((floatx80) { mant, exp })
 #define make_floatx80(exp, mant) ((floatx80) { mant, exp })
-#endif
-#ifdef FLOAT128
 typedef struct {
 typedef struct {
 #ifdef HOST_WORDS_BIGENDIAN
 #ifdef HOST_WORDS_BIGENDIAN
     uint64_t high, low;
     uint64_t high, low;
@@ -164,7 +142,6 @@ typedef struct {
     uint64_t low, high;
     uint64_t low, high;
 #endif
 #endif
 } float128;
 } float128;
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE floating-point underflow tininess-detection mode.
 | Software IEC/IEEE floating-point underflow tininess-detection mode.
@@ -193,16 +170,15 @@ enum {
     float_flag_overflow  =  8,
     float_flag_overflow  =  8,
     float_flag_underflow = 16,
     float_flag_underflow = 16,
     float_flag_inexact   = 32,
     float_flag_inexact   = 32,
-    float_flag_input_denormal = 64
+    float_flag_input_denormal = 64,
+    float_flag_output_denormal = 128
 };
 };
 
 
 typedef struct float_status {
 typedef struct float_status {
     signed char float_detect_tininess;
     signed char float_detect_tininess;
     signed char float_rounding_mode;
     signed char float_rounding_mode;
     signed char float_exception_flags;
     signed char float_exception_flags;
-#ifdef FLOATX80
     signed char floatx80_rounding_precision;
     signed char floatx80_rounding_precision;
-#endif
     /* should denormalised results go to zero and set the inexact flag? */
     /* should denormalised results go to zero and set the inexact flag? */
     flag flush_to_zero;
     flag flush_to_zero;
     /* should denormalised inputs go to zero and set the input_denormal flag? */
     /* should denormalised inputs go to zero and set the input_denormal flag? */
@@ -232,9 +208,7 @@ INLINE int get_float_exception_flags(float_status *status)
 {
 {
     return STATUS(float_exception_flags);
     return STATUS(float_exception_flags);
 }
 }
-#ifdef FLOATX80
 void set_floatx80_rounding_precision(int val STATUS_PARAM);
 void set_floatx80_rounding_precision(int val STATUS_PARAM);
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Routine to raise any or all of the software IEC/IEEE floating-point
 | Routine to raise any or all of the software IEC/IEEE floating-point
@@ -249,22 +223,14 @@ float32 int32_to_float32( int32 STATUS_PARAM );
 float64 int32_to_float64( int32 STATUS_PARAM );
 float64 int32_to_float64( int32 STATUS_PARAM );
 float32 uint32_to_float32( unsigned int STATUS_PARAM );
 float32 uint32_to_float32( unsigned int STATUS_PARAM );
 float64 uint32_to_float64( unsigned int STATUS_PARAM );
 float64 uint32_to_float64( unsigned int STATUS_PARAM );
-#ifdef FLOATX80
 floatx80 int32_to_floatx80( int32 STATUS_PARAM );
 floatx80 int32_to_floatx80( int32 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
 float128 int32_to_float128( int32 STATUS_PARAM );
 float128 int32_to_float128( int32 STATUS_PARAM );
-#endif
 float32 int64_to_float32( int64 STATUS_PARAM );
 float32 int64_to_float32( int64 STATUS_PARAM );
 float32 uint64_to_float32( uint64 STATUS_PARAM );
 float32 uint64_to_float32( uint64 STATUS_PARAM );
 float64 int64_to_float64( int64 STATUS_PARAM );
 float64 int64_to_float64( int64 STATUS_PARAM );
 float64 uint64_to_float64( uint64 STATUS_PARAM );
 float64 uint64_to_float64( uint64 STATUS_PARAM );
-#ifdef FLOATX80
 floatx80 int64_to_floatx80( int64 STATUS_PARAM );
 floatx80 int64_to_floatx80( int64 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
 float128 int64_to_float128( int64 STATUS_PARAM );
 float128 int64_to_float128( int64 STATUS_PARAM );
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software half-precision conversion routines.
 | Software half-precision conversion routines.
@@ -302,12 +268,8 @@ uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
 int64 float32_to_int64( float32 STATUS_PARAM );
 int64 float32_to_int64( float32 STATUS_PARAM );
 int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM );
 int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM );
 float64 float32_to_float64( float32 STATUS_PARAM );
 float64 float32_to_float64( float32 STATUS_PARAM );
-#ifdef FLOATX80
 floatx80 float32_to_floatx80( float32 STATUS_PARAM );
 floatx80 float32_to_floatx80( float32 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
 float128 float32_to_float128( float32 STATUS_PARAM );
 float128 float32_to_float128( float32 STATUS_PARAM );
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE single-precision operations.
 | Software IEC/IEEE single-precision operations.
@@ -419,12 +381,8 @@ int64 float64_to_int64_round_to_zero( float64 STATUS_PARAM );
 uint64 float64_to_uint64 (float64 a STATUS_PARAM);
 uint64 float64_to_uint64 (float64 a STATUS_PARAM);
 uint64 float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
 uint64 float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
 float32 float64_to_float32( float64 STATUS_PARAM );
 float32 float64_to_float32( float64 STATUS_PARAM );
-#ifdef FLOATX80
 floatx80 float64_to_floatx80( float64 STATUS_PARAM );
 floatx80 float64_to_floatx80( float64 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
 float128 float64_to_float128( float64 STATUS_PARAM );
 float128 float64_to_float128( float64 STATUS_PARAM );
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision operations.
 | Software IEC/IEEE double-precision operations.
@@ -491,6 +449,11 @@ INLINE int float64_is_any_nan(float64 a)
     return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
     return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
 }
 }
 
 
+INLINE int float64_is_zero_or_denormal(float64 a)
+{
+    return (float64_val(a) & 0x7ff0000000000000LL) == 0;
+}
+
 INLINE float64 float64_set_sign(float64 a, int sign)
 INLINE float64 float64_set_sign(float64 a, int sign)
 {
 {
     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
@@ -517,8 +480,6 @@ INLINE float64 float64_set_sign(float64 a, int sign)
 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
 #endif
 #endif
 
 
-#ifdef FLOATX80
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision conversion routines.
 | Software IEC/IEEE extended double-precision conversion routines.
 *----------------------------------------------------------------------------*/
 *----------------------------------------------------------------------------*/
@@ -528,9 +489,7 @@ int64 floatx80_to_int64( floatx80 STATUS_PARAM );
 int64 floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
 int64 floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
 float32 floatx80_to_float32( floatx80 STATUS_PARAM );
 float32 floatx80_to_float32( floatx80 STATUS_PARAM );
 float64 floatx80_to_float64( floatx80 STATUS_PARAM );
 float64 floatx80_to_float64( floatx80 STATUS_PARAM );
-#ifdef FLOAT128
 float128 floatx80_to_float128( floatx80 STATUS_PARAM );
 float128 floatx80_to_float128( floatx80 STATUS_PARAM );
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision operations.
 | Software IEC/IEEE extended double-precision operations.
@@ -584,6 +543,11 @@ INLINE int floatx80_is_zero(floatx80 a)
     return (a.high & 0x7fff) == 0 && a.low == 0;
     return (a.high & 0x7fff) == 0 && a.low == 0;
 }
 }
 
 
+INLINE int floatx80_is_zero_or_denormal(floatx80 a)
+{
+    return (a.high & 0x7fff) == 0;
+}
+
 INLINE int floatx80_is_any_nan(floatx80 a)
 INLINE int floatx80_is_any_nan(floatx80 a)
 {
 {
     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
@@ -609,10 +573,6 @@ INLINE int floatx80_is_any_nan(floatx80 a)
 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
 #endif
 #endif
 
 
-#endif
-
-#ifdef FLOAT128
-
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE quadruple-precision conversion routines.
 | Software IEC/IEEE quadruple-precision conversion routines.
 *----------------------------------------------------------------------------*/
 *----------------------------------------------------------------------------*/
@@ -622,9 +582,7 @@ int64 float128_to_int64( float128 STATUS_PARAM );
 int64 float128_to_int64_round_to_zero( float128 STATUS_PARAM );
 int64 float128_to_int64_round_to_zero( float128 STATUS_PARAM );
 float32 float128_to_float32( float128 STATUS_PARAM );
 float32 float128_to_float32( float128 STATUS_PARAM );
 float64 float128_to_float64( float128 STATUS_PARAM );
 float64 float128_to_float64( float128 STATUS_PARAM );
-#ifdef FLOATX80
 floatx80 float128_to_floatx80( float128 STATUS_PARAM );
 floatx80 float128_to_floatx80( float128 STATUS_PARAM );
-#endif
 
 
 /*----------------------------------------------------------------------------
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE quadruple-precision operations.
 | Software IEC/IEEE quadruple-precision operations.
@@ -678,6 +636,11 @@ INLINE int float128_is_zero(float128 a)
     return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
     return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
 }
 }
 
 
+INLINE int float128_is_zero_or_denormal(float128 a)
+{
+    return (a.high & 0x7fff000000000000LL) == 0;
+}
+
 INLINE int float128_is_any_nan(float128 a)
 INLINE int float128_is_any_nan(float128 a)
 {
 {
     return ((a.high >> 48) & 0x7fff) == 0x7fff &&
     return ((a.high >> 48) & 0x7fff) == 0x7fff &&
@@ -696,12 +659,4 @@ INLINE int float128_is_any_nan(float128 a)
 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
 #endif
 #endif
 
 
-#endif
-
-#else /* CONFIG_SOFTFLOAT */
-
-#include "softfloat-native.h"
-
-#endif /* !CONFIG_SOFTFLOAT */
-
 #endif /* !SOFTFLOAT_H */
 #endif /* !SOFTFLOAT_H */

+ 0 - 7
fsdev/file-op-9p.h

@@ -97,11 +97,4 @@ typedef struct FileOperations
     void *opaque;
     void *opaque;
 } FileOperations;
 } FileOperations;
 
 
-static inline const char *rpath(FsContext *ctx, const char *path)
-{
-    /* FIXME: so wrong... */
-    static char buffer[4096];
-    snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
-    return buffer;
-}
 #endif
 #endif

+ 28 - 0
fsdev/qemu-fsdev-dummy.c

@@ -0,0 +1,28 @@
+/*
+ * Virtio 9p
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Gautham R Shenoy <ego@in.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 <stdio.h>
+#include <string.h>
+#include "qemu-fsdev.h"
+#include "qemu-config.h"
+
+int qemu_fsdev_add(QemuOpts *opts)
+{
+    return 0;
+}
+
+static void fsdev_register_config(void)
+{
+    qemu_add_opts(&qemu_fsdev_opts);
+    qemu_add_opts(&qemu_virtfs_opts);
+}
+machine_init(fsdev_register_config);

+ 6 - 6
gdbstub.c

@@ -1105,10 +1105,6 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
             env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
             env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
             /* set rounding mode */
             /* set rounding mode */
             RESTORE_ROUNDING_MODE;
             RESTORE_ROUNDING_MODE;
-#ifndef CONFIG_SOFTFLOAT
-            /* no floating point exception for native float */
-            SET_FP_ENABLE(env->active_fpu.fcr31, 0);
-#endif
             break;
             break;
         case 71: env->active_fpu.fcr0 = tmp; break;
         case 71: env->active_fpu.fcr0 = tmp; break;
         }
         }
@@ -1436,7 +1432,11 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
             /* XXX */
             /* XXX */
             break;
             break;
         case S390_PC_REGNUM: GET_REGL(env->psw.addr); break;
         case S390_PC_REGNUM: GET_REGL(env->psw.addr); break;
-        case S390_CC_REGNUM: GET_REG32(env->cc); break;
+        case S390_CC_REGNUM:
+            env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst,
+                                 env->cc_vr);
+            GET_REG32(env->cc_op);
+            break;
     }
     }
 
 
     return 0;
     return 0;
@@ -1462,7 +1462,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
             /* XXX */
             /* XXX */
             break;
             break;
         case S390_PC_REGNUM: env->psw.addr = tmpl; break;
         case S390_PC_REGNUM: env->psw.addr = tmpl; break;
-        case S390_CC_REGNUM: env->cc = tmp32; r=4; break;
+        case S390_CC_REGNUM: env->cc_op = tmp32; r=4; break;
     }
     }
 
 
     return r;
     return r;

+ 5 - 4
hmp-commands.hx

@@ -740,10 +740,11 @@ ETEXI
 #if defined(TARGET_I386)
 #if defined(TARGET_I386)
     {
     {
         .name       = "nmi",
         .name       = "nmi",
-        .args_type  = "cpu_index:i",
-        .params     = "cpu",
-        .help       = "inject an NMI on the given CPU",
-        .mhandler.cmd = do_inject_nmi,
+        .args_type  = "",
+        .params     = "",
+        .help       = "inject an NMI on all guest's CPUs",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_inject_nmi,
     },
     },
 #endif
 #endif
 STEXI
 STEXI

+ 1 - 1
hppa-dis.c

@@ -1645,7 +1645,7 @@ static const char *const fp_reg_names[] =
 
 
 typedef unsigned int CORE_ADDR;
 typedef unsigned int CORE_ADDR;
 
 
-/* Get at various relevent fields of an instruction word.  */
+/* Get at various relevant fields of an instruction word.  */
 
 
 #define MASK_5  0x1f
 #define MASK_5  0x1f
 #define MASK_10 0x3ff
 #define MASK_10 0x3ff

+ 3 - 2
hw/9pfs/virtio-9p-debug.c

@@ -10,8 +10,9 @@
  * the COPYING file in the top-level directory.
  * the COPYING file in the top-level directory.
  *
  *
  */
  */
-#include "virtio.h"
-#include "pc.h"
+
+#include "hw/virtio.h"
+#include "hw/pc.h"
 #include "virtio-9p.h"
 #include "virtio-9p.h"
 #include "virtio-9p-debug.h"
 #include "virtio-9p-debug.h"
 
 

+ 173 - 0
hw/9pfs/virtio-9p-device.c

@@ -0,0 +1,173 @@
+/*
+ * Virtio 9p backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * 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 "hw/virtio.h"
+#include "hw/pc.h"
+#include "qemu_socket.h"
+#include "hw/virtio-pci.h"
+#include "virtio-9p.h"
+#include "fsdev/qemu-fsdev.h"
+#include "virtio-9p-xattr.h"
+
+static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
+{
+    features |= 1 << VIRTIO_9P_MOUNT_TAG;
+    return features;
+}
+
+static V9fsState *to_virtio_9p(VirtIODevice *vdev)
+{
+    return (V9fsState *)vdev;
+}
+
+static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+    struct virtio_9p_config *cfg;
+    V9fsState *s = to_virtio_9p(vdev);
+
+    cfg = qemu_mallocz(sizeof(struct virtio_9p_config) +
+                        s->tag_len);
+    stw_raw(&cfg->tag_len, s->tag_len);
+    memcpy(cfg->tag, s->tag, s->tag_len);
+    memcpy(config, cfg, s->config_size);
+    qemu_free(cfg);
+}
+
+VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
+ {
+    V9fsState *s;
+    int i, len;
+    struct stat stat;
+    FsTypeEntry *fse;
+
+
+    s = (V9fsState *)virtio_common_init("virtio-9p",
+                                    VIRTIO_ID_9P,
+                                    sizeof(struct virtio_9p_config)+
+                                    MAX_TAG_LEN,
+                                    sizeof(V9fsState));
+
+    /* initialize pdu allocator */
+    QLIST_INIT(&s->free_list);
+    for (i = 0; i < (MAX_REQ - 1); i++) {
+        QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next);
+    }
+
+    s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output);
+
+    fse = get_fsdev_fsentry(conf->fsdev_id);
+
+    if (!fse) {
+        /* We don't have a fsdev identified by fsdev_id */
+        fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
+                "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL");
+        exit(1);
+    }
+
+    if (!fse->path || !conf->tag) {
+        /* we haven't specified a mount_tag or the path */
+        fprintf(stderr, "fsdev with id %s needs path "
+                "and Virtio-9p device needs mount_tag arguments\n",
+                conf->fsdev_id);
+        exit(1);
+    }
+
+    if (!strcmp(fse->security_model, "passthrough")) {
+        /* Files on the Fileserver set to client user credentials */
+        s->ctx.fs_sm = SM_PASSTHROUGH;
+        s->ctx.xops = passthrough_xattr_ops;
+    } else if (!strcmp(fse->security_model, "mapped")) {
+        /* Files on the fileserver are set to QEMU credentials.
+         * Client user credentials are saved in extended attributes.
+         */
+        s->ctx.fs_sm = SM_MAPPED;
+        s->ctx.xops = mapped_xattr_ops;
+    } else if (!strcmp(fse->security_model, "none")) {
+        /*
+         * Files on the fileserver are set to QEMU credentials.
+         */
+        s->ctx.fs_sm = SM_NONE;
+        s->ctx.xops = none_xattr_ops;
+    } else {
+        fprintf(stderr, "Default to security_model=none. You may want"
+                " enable advanced security model using "
+                "security option:\n\t security_model=passthrough\n\t "
+                "security_model=mapped\n");
+        s->ctx.fs_sm = SM_NONE;
+        s->ctx.xops = none_xattr_ops;
+    }
+
+    if (lstat(fse->path, &stat)) {
+        fprintf(stderr, "share path %s does not exist\n", fse->path);
+        exit(1);
+    } else if (!S_ISDIR(stat.st_mode)) {
+        fprintf(stderr, "share path %s is not a directory\n", fse->path);
+        exit(1);
+    }
+
+    s->ctx.fs_root = qemu_strdup(fse->path);
+    len = strlen(conf->tag);
+    if (len > MAX_TAG_LEN) {
+        len = MAX_TAG_LEN;
+    }
+    /* s->tag is non-NULL terminated string */
+    s->tag = qemu_malloc(len);
+    memcpy(s->tag, conf->tag, len);
+    s->tag_len = len;
+    s->ctx.uid = -1;
+
+    s->ops = fse->ops;
+    s->vdev.get_features = virtio_9p_get_features;
+    s->config_size = sizeof(struct virtio_9p_config) +
+                        s->tag_len;
+    s->vdev.get_config = virtio_9p_get_config;
+
+    return &s->vdev;
+}
+
+static int virtio_9p_init_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev;
+
+    vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
+    vdev->nvectors = proxy->nvectors;
+    virtio_init_pci(proxy, vdev);
+    /* make the actual value visible */
+    proxy->nvectors = vdev->nvectors;
+    return 0;
+}
+
+static PCIDeviceInfo virtio_9p_info = {
+    .qdev.name = "virtio-9p-pci",
+    .qdev.size = sizeof(VirtIOPCIProxy),
+    .init      = virtio_9p_init_pci,
+    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id = 0x1009,
+    .revision  = VIRTIO_PCI_ABI_VERSION,
+    .class_id  = 0x2,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
+        DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void virtio_9p_register_devices(void)
+{
+    pci_qdev_register(&virtio_9p_info);
+}
+
+device_init(virtio_9p_register_devices)

+ 66 - 72
hw/9pfs/virtio-9p-local.c

@@ -10,7 +10,8 @@
  * the COPYING file in the top-level directory.
  * the COPYING file in the top-level directory.
  *
  *
  */
  */
-#include "virtio.h"
+
+#include "hw/virtio.h"
 #include "virtio-9p.h"
 #include "virtio-9p.h"
 #include "virtio-9p-xattr.h"
 #include "virtio-9p-xattr.h"
 #include <arpa/inet.h>
 #include <arpa/inet.h>
@@ -24,7 +25,8 @@
 static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
 static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
 {
 {
     int err;
     int err;
-    err =  lstat(rpath(fs_ctx, path), stbuf);
+    char buffer[PATH_MAX];
+    err =  lstat(rpath(fs_ctx, path, buffer), stbuf);
     if (err) {
     if (err) {
         return err;
         return err;
     }
     }
@@ -34,19 +36,19 @@ static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
         gid_t tmp_gid;
         gid_t tmp_gid;
         mode_t tmp_mode;
         mode_t tmp_mode;
         dev_t tmp_dev;
         dev_t tmp_dev;
-        if (getxattr(rpath(fs_ctx, path), "user.virtfs.uid", &tmp_uid,
+        if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.uid", &tmp_uid,
                     sizeof(uid_t)) > 0) {
                     sizeof(uid_t)) > 0) {
             stbuf->st_uid = tmp_uid;
             stbuf->st_uid = tmp_uid;
         }
         }
-        if (getxattr(rpath(fs_ctx, path), "user.virtfs.gid", &tmp_gid,
+        if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.gid", &tmp_gid,
                     sizeof(gid_t)) > 0) {
                     sizeof(gid_t)) > 0) {
             stbuf->st_gid = tmp_gid;
             stbuf->st_gid = tmp_gid;
         }
         }
-        if (getxattr(rpath(fs_ctx, path), "user.virtfs.mode", &tmp_mode,
-                    sizeof(mode_t)) > 0) {
+        if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.mode",
+                    &tmp_mode, sizeof(mode_t)) > 0) {
             stbuf->st_mode = tmp_mode;
             stbuf->st_mode = tmp_mode;
         }
         }
-        if (getxattr(rpath(fs_ctx, path), "user.virtfs.rdev", &tmp_dev,
+        if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.rdev", &tmp_dev,
                         sizeof(dev_t)) > 0) {
                         sizeof(dev_t)) > 0) {
                 stbuf->st_rdev = tmp_dev;
                 stbuf->st_rdev = tmp_dev;
         }
         }
@@ -91,10 +93,12 @@ static int local_set_xattr(const char *path, FsCred *credp)
 static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
 static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
         FsCred *credp)
         FsCred *credp)
 {
 {
-    if (chmod(rpath(fs_ctx, path), credp->fc_mode & 07777) < 0) {
+    char buffer[PATH_MAX];
+    if (chmod(rpath(fs_ctx, path, buffer), credp->fc_mode & 07777) < 0) {
         return -1;
         return -1;
     }
     }
-    if (lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid) < 0) {
+    if (lchown(rpath(fs_ctx, path, buffer), credp->fc_uid,
+                credp->fc_gid) < 0) {
         /*
         /*
          * If we fail to change ownership and if we are
          * If we fail to change ownership and if we are
          * using security model none. Ignore the error
          * using security model none. Ignore the error
@@ -110,9 +114,10 @@ static ssize_t local_readlink(FsContext *fs_ctx, const char *path,
         char *buf, size_t bufsz)
         char *buf, size_t bufsz)
 {
 {
     ssize_t tsize = -1;
     ssize_t tsize = -1;
+    char buffer[PATH_MAX];
     if (fs_ctx->fs_sm == SM_MAPPED) {
     if (fs_ctx->fs_sm == SM_MAPPED) {
         int fd;
         int fd;
-        fd = open(rpath(fs_ctx, path), O_RDONLY);
+        fd = open(rpath(fs_ctx, path, buffer), O_RDONLY);
         if (fd == -1) {
         if (fd == -1) {
             return -1;
             return -1;
         }
         }
@@ -123,7 +128,7 @@ static ssize_t local_readlink(FsContext *fs_ctx, const char *path,
         return tsize;
         return tsize;
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
                (fs_ctx->fs_sm == SM_NONE)) {
                (fs_ctx->fs_sm == SM_NONE)) {
-        tsize = readlink(rpath(fs_ctx, path), buf, bufsz);
+        tsize = readlink(rpath(fs_ctx, path, buffer), buf, bufsz);
     }
     }
     return tsize;
     return tsize;
 }
 }
@@ -140,12 +145,14 @@ static int local_closedir(FsContext *ctx, DIR *dir)
 
 
 static int local_open(FsContext *ctx, const char *path, int flags)
 static int local_open(FsContext *ctx, const char *path, int flags)
 {
 {
-    return open(rpath(ctx, path), flags);
+    char buffer[PATH_MAX];
+    return open(rpath(ctx, path, buffer), flags);
 }
 }
 
 
 static DIR *local_opendir(FsContext *ctx, const char *path)
 static DIR *local_opendir(FsContext *ctx, const char *path)
 {
 {
-    return opendir(rpath(ctx, path));
+    char buffer[PATH_MAX];
+    return opendir(rpath(ctx, path, buffer));
 }
 }
 
 
 static void local_rewinddir(FsContext *ctx, DIR *dir)
 static void local_rewinddir(FsContext *ctx, DIR *dir)
@@ -200,11 +207,12 @@ static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
 
 
 static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
 static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
 {
 {
+    char buffer[PATH_MAX];
     if (fs_ctx->fs_sm == SM_MAPPED) {
     if (fs_ctx->fs_sm == SM_MAPPED) {
-        return local_set_xattr(rpath(fs_ctx, path), credp);
+        return local_set_xattr(rpath(fs_ctx, path, buffer), credp);
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
                (fs_ctx->fs_sm == SM_NONE)) {
                (fs_ctx->fs_sm == SM_NONE)) {
-        return chmod(rpath(fs_ctx, path), credp->fc_mode);
+        return chmod(rpath(fs_ctx, path, buffer), credp->fc_mode);
     }
     }
     return -1;
     return -1;
 }
 }
@@ -213,21 +221,24 @@ static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp)
 {
 {
     int err = -1;
     int err = -1;
     int serrno = 0;
     int serrno = 0;
+    char buffer[PATH_MAX];
 
 
     /* Determine the security model */
     /* Determine the security model */
     if (fs_ctx->fs_sm == SM_MAPPED) {
     if (fs_ctx->fs_sm == SM_MAPPED) {
-        err = mknod(rpath(fs_ctx, path), SM_LOCAL_MODE_BITS|S_IFREG, 0);
+        err = mknod(rpath(fs_ctx, path, buffer),
+                SM_LOCAL_MODE_BITS|S_IFREG, 0);
         if (err == -1) {
         if (err == -1) {
             return err;
             return err;
         }
         }
-        local_set_xattr(rpath(fs_ctx, path), credp);
+        local_set_xattr(rpath(fs_ctx, path, buffer), credp);
         if (err == -1) {
         if (err == -1) {
             serrno = errno;
             serrno = errno;
             goto err_end;
             goto err_end;
         }
         }
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
                (fs_ctx->fs_sm == SM_NONE)) {
                (fs_ctx->fs_sm == SM_NONE)) {
-        err = mknod(rpath(fs_ctx, path), credp->fc_mode, credp->fc_rdev);
+        err = mknod(rpath(fs_ctx, path, buffer), credp->fc_mode,
+                credp->fc_rdev);
         if (err == -1) {
         if (err == -1) {
             return err;
             return err;
         }
         }
@@ -240,7 +251,7 @@ static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp)
     return err;
     return err;
 
 
 err_end:
 err_end:
-    remove(rpath(fs_ctx, path));
+    remove(rpath(fs_ctx, path, buffer));
     errno = serrno;
     errno = serrno;
     return err;
     return err;
 }
 }
@@ -249,22 +260,23 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp)
 {
 {
     int err = -1;
     int err = -1;
     int serrno = 0;
     int serrno = 0;
+    char buffer[PATH_MAX];
 
 
     /* Determine the security model */
     /* Determine the security model */
     if (fs_ctx->fs_sm == SM_MAPPED) {
     if (fs_ctx->fs_sm == SM_MAPPED) {
-        err = mkdir(rpath(fs_ctx, path), SM_LOCAL_DIR_MODE_BITS);
+        err = mkdir(rpath(fs_ctx, path, buffer), SM_LOCAL_DIR_MODE_BITS);
         if (err == -1) {
         if (err == -1) {
             return err;
             return err;
         }
         }
         credp->fc_mode = credp->fc_mode|S_IFDIR;
         credp->fc_mode = credp->fc_mode|S_IFDIR;
-        err = local_set_xattr(rpath(fs_ctx, path), credp);
+        err = local_set_xattr(rpath(fs_ctx, path, buffer), credp);
         if (err == -1) {
         if (err == -1) {
             serrno = errno;
             serrno = errno;
             goto err_end;
             goto err_end;
         }
         }
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
                (fs_ctx->fs_sm == SM_NONE)) {
                (fs_ctx->fs_sm == SM_NONE)) {
-        err = mkdir(rpath(fs_ctx, path), credp->fc_mode);
+        err = mkdir(rpath(fs_ctx, path, buffer), credp->fc_mode);
         if (err == -1) {
         if (err == -1) {
             return err;
             return err;
         }
         }
@@ -277,7 +289,7 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp)
     return err;
     return err;
 
 
 err_end:
 err_end:
-    remove(rpath(fs_ctx, path));
+    remove(rpath(fs_ctx, path, buffer));
     errno = serrno;
     errno = serrno;
     return err;
     return err;
 }
 }
@@ -318,23 +330,24 @@ static int local_open2(FsContext *fs_ctx, const char *path, int flags,
     int fd = -1;
     int fd = -1;
     int err = -1;
     int err = -1;
     int serrno = 0;
     int serrno = 0;
+    char buffer[PATH_MAX];
 
 
     /* Determine the security model */
     /* Determine the security model */
     if (fs_ctx->fs_sm == SM_MAPPED) {
     if (fs_ctx->fs_sm == SM_MAPPED) {
-        fd = open(rpath(fs_ctx, path), flags, SM_LOCAL_MODE_BITS);
+        fd = open(rpath(fs_ctx, path, buffer), flags, SM_LOCAL_MODE_BITS);
         if (fd == -1) {
         if (fd == -1) {
             return fd;
             return fd;
         }
         }
         credp->fc_mode = credp->fc_mode|S_IFREG;
         credp->fc_mode = credp->fc_mode|S_IFREG;
         /* Set cleint credentials in xattr */
         /* Set cleint credentials in xattr */
-        err = local_set_xattr(rpath(fs_ctx, path), credp);
+        err = local_set_xattr(rpath(fs_ctx, path, buffer), credp);
         if (err == -1) {
         if (err == -1) {
             serrno = errno;
             serrno = errno;
             goto err_end;
             goto err_end;
         }
         }
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
                (fs_ctx->fs_sm == SM_NONE)) {
                (fs_ctx->fs_sm == SM_NONE)) {
-        fd = open(rpath(fs_ctx, path), flags, credp->fc_mode);
+        fd = open(rpath(fs_ctx, path, buffer), flags, credp->fc_mode);
         if (fd == -1) {
         if (fd == -1) {
             return fd;
             return fd;
         }
         }
@@ -348,7 +361,7 @@ static int local_open2(FsContext *fs_ctx, const char *path, int flags,
 
 
 err_end:
 err_end:
     close(fd);
     close(fd);
-    remove(rpath(fs_ctx, path));
+    remove(rpath(fs_ctx, path, buffer));
     errno = serrno;
     errno = serrno;
     return err;
     return err;
 }
 }
@@ -359,12 +372,13 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
 {
 {
     int err = -1;
     int err = -1;
     int serrno = 0;
     int serrno = 0;
+    char buffer[PATH_MAX];
 
 
     /* Determine the security model */
     /* Determine the security model */
     if (fs_ctx->fs_sm == SM_MAPPED) {
     if (fs_ctx->fs_sm == SM_MAPPED) {
         int fd;
         int fd;
         ssize_t oldpath_size, write_size;
         ssize_t oldpath_size, write_size;
-        fd = open(rpath(fs_ctx, newpath), O_CREAT|O_EXCL|O_RDWR,
+        fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,
                 SM_LOCAL_MODE_BITS);
                 SM_LOCAL_MODE_BITS);
         if (fd == -1) {
         if (fd == -1) {
             return fd;
             return fd;
@@ -384,18 +398,19 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
         close(fd);
         close(fd);
         /* Set cleint credentials in symlink's xattr */
         /* Set cleint credentials in symlink's xattr */
         credp->fc_mode = credp->fc_mode|S_IFLNK;
         credp->fc_mode = credp->fc_mode|S_IFLNK;
-        err = local_set_xattr(rpath(fs_ctx, newpath), credp);
+        err = local_set_xattr(rpath(fs_ctx, newpath, buffer), credp);
         if (err == -1) {
         if (err == -1) {
             serrno = errno;
             serrno = errno;
             goto err_end;
             goto err_end;
         }
         }
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
                (fs_ctx->fs_sm == SM_NONE)) {
                (fs_ctx->fs_sm == SM_NONE)) {
-        err = symlink(oldpath, rpath(fs_ctx, newpath));
+        err = symlink(oldpath, rpath(fs_ctx, newpath, buffer));
         if (err) {
         if (err) {
             return err;
             return err;
         }
         }
-        err = lchown(rpath(fs_ctx, newpath), credp->fc_uid, credp->fc_gid);
+        err = lchown(rpath(fs_ctx, newpath, buffer), credp->fc_uid,
+                credp->fc_gid);
         if (err == -1) {
         if (err == -1) {
             /*
             /*
              * If we fail to change ownership and if we are
              * If we fail to change ownership and if we are
@@ -411,70 +426,45 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
     return err;
     return err;
 
 
 err_end:
 err_end:
-    remove(rpath(fs_ctx, newpath));
+    remove(rpath(fs_ctx, newpath, buffer));
     errno = serrno;
     errno = serrno;
     return err;
     return err;
 }
 }
 
 
 static int local_link(FsContext *ctx, const char *oldpath, const char *newpath)
 static int local_link(FsContext *ctx, const char *oldpath, const char *newpath)
 {
 {
-    char *tmp = qemu_strdup(rpath(ctx, oldpath));
-    int err, serrno = 0;
-
-    if (tmp == NULL) {
-        return -ENOMEM;
-    }
-
-    err = link(tmp, rpath(ctx, newpath));
-    if (err == -1) {
-        serrno = errno;
-    }
-
-    qemu_free(tmp);
-
-    if (err == -1) {
-        errno = serrno;
-    }
+    char buffer[PATH_MAX], buffer1[PATH_MAX];
 
 
-    return err;
+    return link(rpath(ctx, oldpath, buffer), rpath(ctx, newpath, buffer1));
 }
 }
 
 
 static int local_truncate(FsContext *ctx, const char *path, off_t size)
 static int local_truncate(FsContext *ctx, const char *path, off_t size)
 {
 {
-    return truncate(rpath(ctx, path), size);
+    char buffer[PATH_MAX];
+    return truncate(rpath(ctx, path, buffer), size);
 }
 }
 
 
 static int local_rename(FsContext *ctx, const char *oldpath,
 static int local_rename(FsContext *ctx, const char *oldpath,
                         const char *newpath)
                         const char *newpath)
 {
 {
-    char *tmp;
-    int err;
-
-    tmp = qemu_strdup(rpath(ctx, oldpath));
-
-    err = rename(tmp, rpath(ctx, newpath));
-    if (err == -1) {
-        int serrno = errno;
-        qemu_free(tmp);
-        errno = serrno;
-    } else {
-        qemu_free(tmp);
-    }
-
-    return err;
+    char buffer[PATH_MAX], buffer1[PATH_MAX];
 
 
+    return rename(rpath(ctx, oldpath, buffer), rpath(ctx, newpath, buffer1));
 }
 }
 
 
 static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp)
 static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp)
 {
 {
+    char buffer[PATH_MAX];
     if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
     if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
             (fs_ctx->fs_sm == SM_PASSTHROUGH)) {
             (fs_ctx->fs_sm == SM_PASSTHROUGH)) {
-        return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
+        return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid,
+                credp->fc_gid);
     } else if (fs_ctx->fs_sm == SM_MAPPED) {
     } else if (fs_ctx->fs_sm == SM_MAPPED) {
-        return local_set_xattr(rpath(fs_ctx, path), credp);
+        return local_set_xattr(rpath(fs_ctx, path, buffer), credp);
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
     } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
                (fs_ctx->fs_sm == SM_NONE)) {
                (fs_ctx->fs_sm == SM_NONE)) {
-        return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
+        return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid,
+                credp->fc_gid);
     }
     }
     return -1;
     return -1;
 }
 }
@@ -482,12 +472,15 @@ static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp)
 static int local_utimensat(FsContext *s, const char *path,
 static int local_utimensat(FsContext *s, const char *path,
                            const struct timespec *buf)
                            const struct timespec *buf)
 {
 {
-    return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW);
+    char buffer[PATH_MAX];
+    return qemu_utimensat(AT_FDCWD, rpath(s, path, buffer), buf,
+            AT_SYMLINK_NOFOLLOW);
 }
 }
 
 
 static int local_remove(FsContext *ctx, const char *path)
 static int local_remove(FsContext *ctx, const char *path)
 {
 {
-    return remove(rpath(ctx, path));
+    char buffer[PATH_MAX];
+    return remove(rpath(ctx, path, buffer));
 }
 }
 
 
 static int local_fsync(FsContext *ctx, int fd, int datasync)
 static int local_fsync(FsContext *ctx, int fd, int datasync)
@@ -501,7 +494,8 @@ static int local_fsync(FsContext *ctx, int fd, int datasync)
 
 
 static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
 static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
 {
 {
-   return statfs(rpath(s, path), stbuf);
+    char buffer[PATH_MAX];
+   return statfs(rpath(s, path, buffer), stbuf);
 }
 }
 
 
 static ssize_t local_lgetxattr(FsContext *ctx, const char *path,
 static ssize_t local_lgetxattr(FsContext *ctx, const char *path,

+ 15 - 7
hw/9pfs/virtio-9p-posix-acl.c

@@ -13,7 +13,7 @@
 
 
 #include <sys/types.h>
 #include <sys/types.h>
 #include <attr/xattr.h>
 #include <attr/xattr.h>
-#include "virtio.h"
+#include "hw/virtio.h"
 #include "virtio-9p.h"
 #include "virtio-9p.h"
 #include "fsdev/file-op-9p.h"
 #include "fsdev/file-op-9p.h"
 #include "virtio-9p-xattr.h"
 #include "virtio-9p-xattr.h"
@@ -26,7 +26,8 @@
 static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
 static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
                                 const char *name, void *value, size_t size)
                                 const char *name, void *value, size_t size)
 {
 {
-    return lgetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size);
+    char buffer[PATH_MAX];
+    return lgetxattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS, value, size);
 }
 }
 
 
 static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
 static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
@@ -50,14 +51,17 @@ static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
 static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
 static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
                             void *value, size_t size, int flags)
                             void *value, size_t size, int flags)
 {
 {
-    return lsetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size, flags);
+    char buffer[PATH_MAX];
+    return lsetxattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS, value,
+            size, flags);
 }
 }
 
 
 static int mp_pacl_removexattr(FsContext *ctx,
 static int mp_pacl_removexattr(FsContext *ctx,
                                const char *path, const char *name)
                                const char *path, const char *name)
 {
 {
     int ret;
     int ret;
-    ret  = lremovexattr(rpath(ctx, path), MAP_ACL_ACCESS);
+    char buffer[PATH_MAX];
+    ret  = lremovexattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS);
     if (ret == -1 && errno == ENODATA) {
     if (ret == -1 && errno == ENODATA) {
         /*
         /*
          * We don't get ENODATA error when trying to remove a
          * We don't get ENODATA error when trying to remove a
@@ -73,7 +77,8 @@ static int mp_pacl_removexattr(FsContext *ctx,
 static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
 static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
                                 const char *name, void *value, size_t size)
                                 const char *name, void *value, size_t size)
 {
 {
-    return lgetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size);
+    char buffer[PATH_MAX];
+    return lgetxattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT, value, size);
 }
 }
 
 
 static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
 static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
@@ -97,14 +102,17 @@ static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
 static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
 static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
                             void *value, size_t size, int flags)
                             void *value, size_t size, int flags)
 {
 {
-    return lsetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size, flags);
+    char buffer[PATH_MAX];
+    return lsetxattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT, value,
+            size, flags);
 }
 }
 
 
 static int mp_dacl_removexattr(FsContext *ctx,
 static int mp_dacl_removexattr(FsContext *ctx,
                                const char *path, const char *name)
                                const char *path, const char *name)
 {
 {
     int ret;
     int ret;
-    ret  = lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT);
+    char buffer[PATH_MAX];
+    ret  = lremovexattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT);
     if (ret == -1 && errno == ENODATA) {
     if (ret == -1 && errno == ENODATA) {
         /*
         /*
          * We don't get ENODATA error when trying to remove a
          * We don't get ENODATA error when trying to remove a

+ 7 - 4
hw/9pfs/virtio-9p-xattr-user.c

@@ -12,7 +12,7 @@
  */
  */
 
 
 #include <sys/types.h>
 #include <sys/types.h>
-#include "virtio.h"
+#include "hw/virtio.h"
 #include "virtio-9p.h"
 #include "virtio-9p.h"
 #include "fsdev/file-op-9p.h"
 #include "fsdev/file-op-9p.h"
 #include "virtio-9p-xattr.h"
 #include "virtio-9p-xattr.h"
@@ -21,6 +21,7 @@
 static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
 static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
                                 const char *name, void *value, size_t size)
                                 const char *name, void *value, size_t size)
 {
 {
+    char buffer[PATH_MAX];
     if (strncmp(name, "user.virtfs.", 12) == 0) {
     if (strncmp(name, "user.virtfs.", 12) == 0) {
         /*
         /*
          * Don't allow fetch of user.virtfs namesapce
          * Don't allow fetch of user.virtfs namesapce
@@ -29,7 +30,7 @@ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
         errno = ENOATTR;
         errno = ENOATTR;
         return -1;
         return -1;
     }
     }
-    return lgetxattr(rpath(ctx, path), name, value, size);
+    return lgetxattr(rpath(ctx, path, buffer), name, value, size);
 }
 }
 
 
 static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
 static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
@@ -67,6 +68,7 @@ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
 static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
 static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
                             void *value, size_t size, int flags)
                             void *value, size_t size, int flags)
 {
 {
+    char buffer[PATH_MAX];
     if (strncmp(name, "user.virtfs.", 12) == 0) {
     if (strncmp(name, "user.virtfs.", 12) == 0) {
         /*
         /*
          * Don't allow fetch of user.virtfs namesapce
          * Don't allow fetch of user.virtfs namesapce
@@ -75,12 +77,13 @@ static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
         errno = EACCES;
         errno = EACCES;
         return -1;
         return -1;
     }
     }
-    return lsetxattr(rpath(ctx, path), name, value, size, flags);
+    return lsetxattr(rpath(ctx, path, buffer), name, value, size, flags);
 }
 }
 
 
 static int mp_user_removexattr(FsContext *ctx,
 static int mp_user_removexattr(FsContext *ctx,
                                const char *path, const char *name)
                                const char *path, const char *name)
 {
 {
+    char buffer[PATH_MAX];
     if (strncmp(name, "user.virtfs.", 12) == 0) {
     if (strncmp(name, "user.virtfs.", 12) == 0) {
         /*
         /*
          * Don't allow fetch of user.virtfs namesapce
          * Don't allow fetch of user.virtfs namesapce
@@ -89,7 +92,7 @@ static int mp_user_removexattr(FsContext *ctx,
         errno = EACCES;
         errno = EACCES;
         return -1;
         return -1;
     }
     }
-    return lremovexattr(rpath(ctx, path), name);
+    return lremovexattr(rpath(ctx, path, buffer), name);
 }
 }
 
 
 XattrOperations mapped_user_xattr = {
 XattrOperations mapped_user_xattr = {

+ 4 - 3
hw/9pfs/virtio-9p-xattr.c

@@ -11,7 +11,7 @@
  *
  *
  */
  */
 
 
-#include "virtio.h"
+#include "hw/virtio.h"
 #include "virtio-9p.h"
 #include "virtio-9p.h"
 #include "fsdev/file-op-9p.h"
 #include "fsdev/file-op-9p.h"
 #include "virtio-9p-xattr.h"
 #include "virtio-9p-xattr.h"
@@ -66,20 +66,21 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
                         void *value, size_t vsize)
                         void *value, size_t vsize)
 {
 {
     ssize_t size = 0;
     ssize_t size = 0;
+    char buffer[PATH_MAX];
     void *ovalue = value;
     void *ovalue = value;
     XattrOperations *xops;
     XattrOperations *xops;
     char *orig_value, *orig_value_start;
     char *orig_value, *orig_value_start;
     ssize_t xattr_len, parsed_len = 0, attr_len;
     ssize_t xattr_len, parsed_len = 0, attr_len;
 
 
     /* Get the actual len */
     /* Get the actual len */
-    xattr_len = llistxattr(rpath(ctx, path), value, 0);
+    xattr_len = llistxattr(rpath(ctx, path, buffer), value, 0);
     if (xattr_len <= 0) {
     if (xattr_len <= 0) {
         return xattr_len;
         return xattr_len;
     }
     }
 
 
     /* Now fetch the xattr and find the actual size */
     /* Now fetch the xattr and find the actual size */
     orig_value = qemu_malloc(xattr_len);
     orig_value = qemu_malloc(xattr_len);
-    xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
+    xattr_len = llistxattr(rpath(ctx, path, buffer), orig_value, xattr_len);
 
 
     /* store the orig pointer */
     /* store the orig pointer */
     orig_value_start = orig_value;
     orig_value_start = orig_value;

+ 6 - 3
hw/9pfs/virtio-9p-xattr.h

@@ -54,20 +54,23 @@ ssize_t pt_listxattr(FsContext *ctx, const char *path, char *name, void *value,
 static inline ssize_t pt_getxattr(FsContext *ctx, const char *path,
 static inline ssize_t pt_getxattr(FsContext *ctx, const char *path,
                                   const char *name, void *value, size_t size)
                                   const char *name, void *value, size_t size)
 {
 {
-    return lgetxattr(rpath(ctx, path), name, value, size);
+    char buffer[PATH_MAX];
+    return lgetxattr(rpath(ctx, path, buffer), name, value, size);
 }
 }
 
 
 static inline int pt_setxattr(FsContext *ctx, const char *path,
 static inline int pt_setxattr(FsContext *ctx, const char *path,
                               const char *name, void *value,
                               const char *name, void *value,
                               size_t size, int flags)
                               size_t size, int flags)
 {
 {
-    return lsetxattr(rpath(ctx, path), name, value, size, flags);
+    char buffer[PATH_MAX];
+    return lsetxattr(rpath(ctx, path, buffer), name, value, size, flags);
 }
 }
 
 
 static inline int pt_removexattr(FsContext *ctx,
 static inline int pt_removexattr(FsContext *ctx,
                                  const char *path, const char *name)
                                  const char *path, const char *name)
 {
 {
-    return lremovexattr(rpath(ctx, path), name);
+    char buffer[PATH_MAX];
+    return lremovexattr(rpath(ctx, path, buffer), name);
 }
 }
 
 
 static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path,
 static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path,

+ 35 - 130
hw/9pfs/virtio-9p.c

@@ -11,9 +11,10 @@
  *
  *
  */
  */
 
 
-#include "virtio.h"
-#include "pc.h"
+#include "hw/virtio.h"
+#include "hw/pc.h"
 #include "qemu_socket.h"
 #include "qemu_socket.h"
+#include "hw/virtio-pci.h"
 #include "virtio-9p.h"
 #include "virtio-9p.h"
 #include "fsdev/qemu-fsdev.h"
 #include "fsdev/qemu-fsdev.h"
 #include "virtio-9p-debug.h"
 #include "virtio-9p-debug.h"
@@ -194,7 +195,6 @@ static int v9fs_do_open2(V9fsState *s, char *fullname, uid_t uid, gid_t gid,
     cred.fc_uid = uid;
     cred.fc_uid = uid;
     cred.fc_gid = gid;
     cred.fc_gid = gid;
     cred.fc_mode = mode & 07777;
     cred.fc_mode = mode & 07777;
-    flags = flags;
 
 
     return s->ops->open2(&s->ctx, fullname, flags, &cred);
     return s->ops->open2(&s->ctx, fullname, flags, &cred);
 }
 }
@@ -423,6 +423,22 @@ static void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs)
     v9fs_string_sprintf(lhs, "%s", rhs->data);
     v9fs_string_sprintf(lhs, "%s", rhs->data);
 }
 }
 
 
+/*
+ * Return TRUE if s1 is an ancestor of s2.
+ *
+ * E.g. "a/b" is an ancestor of "a/b/c" but not of "a/bc/d".
+ * As a special case, We treat s1 as ancestor of s2 if they are same!
+ */
+static int v9fs_path_is_ancestor(V9fsString *s1, V9fsString *s2)
+{
+    if (!strncmp(s1->data, s2->data, s1->size)) {
+        if (s2->data[s1->size] == '\0' || s2->data[s1->size] == '/') {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 static size_t v9fs_string_size(V9fsString *str)
 static size_t v9fs_string_size(V9fsString *str)
 {
 {
     return str->size;
     return str->size;
@@ -2805,13 +2821,13 @@ static int v9fs_complete_rename(V9fsState *s, V9fsRenameState *vs)
             for (fidp = s->fid_list; fidp; fidp = fidp->next) {
             for (fidp = s->fid_list; fidp; fidp = fidp->next) {
                 if (vs->fidp == fidp) {
                 if (vs->fidp == fidp) {
                     /*
                     /*
-                    * we replace name of this fid towards the end
-                    * so that our below strcmp will work
+                    * we replace name of this fid towards the end so
+                    * that our below v9fs_path_is_ancestor check will
+                    * work
                     */
                     */
                     continue;
                     continue;
                 }
                 }
-                if (!strncmp(vs->fidp->path.data, fidp->path.data,
-                    strlen(vs->fidp->path.data))) {
+                if (v9fs_path_is_ancestor(&vs->fidp->path, &fidp->path)) {
                     /* replace the name */
                     /* replace the name */
                     v9fs_fix_path(&fidp->path, &vs->name,
                     v9fs_fix_path(&fidp->path, &vs->name,
                                   strlen(vs->fidp->path.data));
                                   strlen(vs->fidp->path.data));
@@ -3589,6 +3605,11 @@ static pdu_handler_t *pdu_handlers[] = {
     [P9_TREMOVE] = v9fs_remove,
     [P9_TREMOVE] = v9fs_remove,
 };
 };
 
 
+static void v9fs_op_not_supp(V9fsState *s, V9fsPDU *pdu)
+{
+    complete_pdu(s, pdu, -EOPNOTSUPP);
+}
+
 static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
 static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
 {
 {
     pdu_handler_t *handler;
     pdu_handler_t *handler;
@@ -3596,16 +3617,16 @@ static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
     if (debug_9p_pdu) {
     if (debug_9p_pdu) {
         pprint_pdu(pdu);
         pprint_pdu(pdu);
     }
     }
-
-    BUG_ON(pdu->id >= ARRAY_SIZE(pdu_handlers));
-
-    handler = pdu_handlers[pdu->id];
-    BUG_ON(handler == NULL);
-
+    if (pdu->id >= ARRAY_SIZE(pdu_handlers) ||
+        (pdu_handlers[pdu->id] == NULL)) {
+        handler = v9fs_op_not_supp;
+    } else {
+        handler = pdu_handlers[pdu->id];
+    }
     handler(s, pdu);
     handler(s, pdu);
 }
 }
 
 
-static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
+void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
 {
 {
     V9fsState *s = (V9fsState *)vdev;
     V9fsState *s = (V9fsState *)vdev;
     V9fsPDU *pdu;
     V9fsPDU *pdu;
@@ -3629,119 +3650,3 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
 
 
     free_pdu(s, pdu);
     free_pdu(s, pdu);
 }
 }
-
-static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
-{
-    features |= 1 << VIRTIO_9P_MOUNT_TAG;
-    return features;
-}
-
-static V9fsState *to_virtio_9p(VirtIODevice *vdev)
-{
-    return (V9fsState *)vdev;
-}
-
-static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-    struct virtio_9p_config *cfg;
-    V9fsState *s = to_virtio_9p(vdev);
-
-    cfg = qemu_mallocz(sizeof(struct virtio_9p_config) +
-                        s->tag_len);
-    stw_raw(&cfg->tag_len, s->tag_len);
-    memcpy(cfg->tag, s->tag, s->tag_len);
-    memcpy(config, cfg, s->config_size);
-    qemu_free(cfg);
-}
-
-VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
- {
-    V9fsState *s;
-    int i, len;
-    struct stat stat;
-    FsTypeEntry *fse;
-
-
-    s = (V9fsState *)virtio_common_init("virtio-9p",
-                                    VIRTIO_ID_9P,
-                                    sizeof(struct virtio_9p_config)+
-                                    MAX_TAG_LEN,
-                                    sizeof(V9fsState));
-
-    /* initialize pdu allocator */
-    QLIST_INIT(&s->free_list);
-    for (i = 0; i < (MAX_REQ - 1); i++) {
-	QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next);
-    }
-
-    s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output);
-
-    fse = get_fsdev_fsentry(conf->fsdev_id);
-
-    if (!fse) {
-        /* We don't have a fsdev identified by fsdev_id */
-        fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
-                "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL");
-        exit(1);
-    }
-
-    if (!fse->path || !conf->tag) {
-        /* we haven't specified a mount_tag or the path */
-        fprintf(stderr, "fsdev with id %s needs path "
-                "and Virtio-9p device needs mount_tag arguments\n",
-                conf->fsdev_id);
-        exit(1);
-    }
-
-    if (!strcmp(fse->security_model, "passthrough")) {
-        /* Files on the Fileserver set to client user credentials */
-        s->ctx.fs_sm = SM_PASSTHROUGH;
-        s->ctx.xops = passthrough_xattr_ops;
-    } else if (!strcmp(fse->security_model, "mapped")) {
-        /* Files on the fileserver are set to QEMU credentials.
-         * Client user credentials are saved in extended attributes.
-         */
-        s->ctx.fs_sm = SM_MAPPED;
-        s->ctx.xops = mapped_xattr_ops;
-    } else if (!strcmp(fse->security_model, "none")) {
-        /*
-         * Files on the fileserver are set to QEMU credentials.
-         */
-        s->ctx.fs_sm = SM_NONE;
-        s->ctx.xops = none_xattr_ops;
-    } else {
-        fprintf(stderr, "Default to security_model=none. You may want"
-                " enable advanced security model using "
-                "security option:\n\t security_model=passthrough \n\t "
-                "security_model=mapped\n");
-        s->ctx.fs_sm = SM_NONE;
-        s->ctx.xops = none_xattr_ops;
-    }
-
-    if (lstat(fse->path, &stat)) {
-        fprintf(stderr, "share path %s does not exist\n", fse->path);
-        exit(1);
-    } else if (!S_ISDIR(stat.st_mode)) {
-        fprintf(stderr, "share path %s is not a directory \n", fse->path);
-        exit(1);
-    }
-
-    s->ctx.fs_root = qemu_strdup(fse->path);
-    len = strlen(conf->tag);
-    if (len > MAX_TAG_LEN) {
-        len = MAX_TAG_LEN;
-    }
-    /* s->tag is non-NULL terminated string */
-    s->tag = qemu_malloc(len);
-    memcpy(s->tag, conf->tag, len);
-    s->tag_len = len;
-    s->ctx.uid = -1;
-
-    s->ops = fse->ops;
-    s->vdev.get_features = virtio_9p_get_features;
-    s->config_size = sizeof(struct virtio_9p_config) +
-                        s->tag_len;
-    s->vdev.get_config = virtio_9p_get_config;
-
-    return &s->vdev;
-}

+ 7 - 0
hw/9pfs/virtio-9p.h

@@ -101,6 +101,11 @@ enum p9_proto_version {
 #define P9_NOTAG    (u16)(~0)
 #define P9_NOTAG    (u16)(~0)
 #define P9_NOFID    (u32)(~0)
 #define P9_NOFID    (u32)(~0)
 #define P9_MAXWELEM 16
 #define P9_MAXWELEM 16
+static inline const char *rpath(FsContext *ctx, const char *path, char *buffer)
+{
+    snprintf(buffer, PATH_MAX, "%s/%s", ctx->fs_root, path);
+    return buffer;
+}
 
 
 /*
 /*
  * ample room for Twrite/Rread header
  * ample room for Twrite/Rread header
@@ -504,4 +509,6 @@ static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
     return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
     return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
 }
 }
 
 
+extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
+
 #endif
 #endif

+ 1 - 5
hw/ac97.c

@@ -1001,8 +1001,6 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
 
 
 static void write_bup (AC97LinkState *s, int elapsed)
 static void write_bup (AC97LinkState *s, int elapsed)
 {
 {
-    int written = 0;
-
     dolog ("write_bup\n");
     dolog ("write_bup\n");
     if (!(s->bup_flag & BUP_SET)) {
     if (!(s->bup_flag & BUP_SET)) {
         if (s->bup_flag & BUP_LAST) {
         if (s->bup_flag & BUP_LAST) {
@@ -1026,7 +1024,6 @@ static void write_bup (AC97LinkState *s, int elapsed)
                 return;
                 return;
             temp -= copied;
             temp -= copied;
             elapsed -= copied;
             elapsed -= copied;
-            written += copied;
         }
         }
     }
     }
 }
 }
@@ -1069,7 +1066,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,
 static void transfer_audio (AC97LinkState *s, int index, int elapsed)
 static void transfer_audio (AC97LinkState *s, int index, int elapsed)
 {
 {
     AC97BusMasterRegs *r = &s->bm_regs[index];
     AC97BusMasterRegs *r = &s->bm_regs[index];
-    int written = 0, stop = 0;
+    int stop = 0;
 
 
     if (s->invalid_freq[index]) {
     if (s->invalid_freq[index]) {
         AUD_log ("ac97", "attempt to use voice %d with invalid frequency %d\n",
         AUD_log ("ac97", "attempt to use voice %d with invalid frequency %d\n",
@@ -1114,7 +1111,6 @@ static void transfer_audio (AC97LinkState *s, int index, int elapsed)
         switch (index) {
         switch (index) {
         case PO_INDEX:
         case PO_INDEX:
             temp = write_audio (s, r, elapsed, &stop);
             temp = write_audio (s, r, elapsed, &stop);
-            written += temp;
             elapsed -= temp;
             elapsed -= temp;
             r->picb -= (temp >> 1);
             r->picb -= (temp >> 1);
             break;
             break;

+ 3 - 1
hw/acpi_piix4.c

@@ -471,11 +471,13 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
     BusState *bus = opaque;
     BusState *bus = opaque;
     DeviceState *qdev, *next;
     DeviceState *qdev, *next;
     PCIDevice *dev;
     PCIDevice *dev;
+    PCIDeviceInfo *info;
     int slot = ffs(val) - 1;
     int slot = ffs(val) - 1;
 
 
     QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
     QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
         dev = DO_UPCAST(PCIDevice, qdev, qdev);
         dev = DO_UPCAST(PCIDevice, qdev, qdev);
-        if (PCI_SLOT(dev->devfn) == slot) {
+        info = container_of(qdev->info, PCIDeviceInfo, qdev);
+        if (PCI_SLOT(dev->devfn) == slot && !info->no_hotplug) {
             qdev_free(qdev);
             qdev_free(qdev);
         }
         }
     }
     }

+ 0 - 1048
hw/alpha_palcode.c

@@ -1,1048 +0,0 @@
-/*
- *  Alpha emulation - PALcode emulation for qemu.
- *
- *  Copyright (c) 2007 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-
-/* Shared handlers */
-static void pal_reset (CPUState *env);
-/* Console handlers */
-static void pal_console_call (CPUState *env, uint32_t palcode);
-/* OpenVMS handlers */
-static void pal_openvms_call (CPUState *env, uint32_t palcode);
-/* UNIX / Linux handlers */
-static void pal_unix_call (CPUState *env, uint32_t palcode);
-
-pal_handler_t pal_handlers[] = {
-    /* Console handler */
-    {
-        .reset = &pal_reset,
-        .call_pal = &pal_console_call,
-    },
-    /* OpenVMS handler */
-    {
-        .reset = &pal_reset,
-        .call_pal = &pal_openvms_call,
-    },
-    /* UNIX / Linux handler */
-    {
-        .reset = &pal_reset,
-        .call_pal = &pal_unix_call,
-    },
-};
-
-#if 0
-/* One must explicitly check that the TB is valid and the FOE bit is reset */
-static void update_itb (void)
-{
-    /* This writes into a temp register, not the actual one */
-    mtpr(TB_TAG);
-    mtpr(TB_CTL);
-    /* This commits the TB update */
-    mtpr(ITB_PTE);
-}
-
-static void update_dtb (void);
-{
-    mtpr(TB_CTL);
-    /* This write into a temp register, not the actual one */
-    mtpr(TB_TAG);
-    /* This commits the TB update */
-    mtpr(DTB_PTE);
-}
-#endif
-
-static void pal_reset (CPUState *env)
-{
-}
-
-static void do_swappal (CPUState *env, uint64_t palid)
-{
-    pal_handler_t *pal_handler;
-
-    switch (palid) {
-    case 0 ... 2:
-        pal_handler = &pal_handlers[palid];
-        env->pal_handler = pal_handler;
-        env->ipr[IPR_PAL_BASE] = -1ULL;
-        (*pal_handler->reset)(env);
-        break;
-    case 3 ... 255:
-        /* Unknown identifier */
-        env->ir[0] = 1;
-        return;
-    default:
-        /* We were given the entry point address */
-        env->pal_handler = NULL;
-        env->ipr[IPR_PAL_BASE] = palid;
-        env->pc = env->ipr[IPR_PAL_BASE];
-        cpu_loop_exit();
-    }
-}
-
-static void pal_console_call (CPUState *env, uint32_t palcode)
-{
-    uint64_t palid;
-
-    if (palcode < 0x00000080) {
-        /* Privileged palcodes */
-        if (!(env->ps >> 3)) {
-            /* TODO: generate privilege exception */
-        }
-    }
-    switch (palcode) {
-    case 0x00000000:
-        /* HALT */
-        /* REQUIRED */
-        break;
-    case 0x00000001:
-        /* CFLUSH */
-        break;
-    case 0x00000002:
-        /* DRAINA */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000009:
-        /* CSERVE */
-        /* REQUIRED */
-        break;
-    case 0x0000000A:
-        /* SWPPAL */
-        /* REQUIRED */
-        palid = env->ir[16];
-        do_swappal(env, palid);
-        break;
-    case 0x00000080:
-        /* BPT */
-        /* REQUIRED */
-        break;
-    case 0x00000081:
-        /* BUGCHK */
-        /* REQUIRED */
-        break;
-    case 0x00000086:
-        /* IMB */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x0000009E:
-        /* RDUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x0000009F:
-        /* WRUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x000000AA:
-        /* GENTRAP */
-        /* REQUIRED */
-        break;
-    default:
-        break;
-    }
-}
-
-static void pal_openvms_call (CPUState *env, uint32_t palcode)
-{
-    uint64_t palid, val, oldval;
-
-    if (palcode < 0x00000080) {
-        /* Privileged palcodes */
-        if (!(env->ps >> 3)) {
-            /* TODO: generate privilege exception */
-        }
-    }
-    switch (palcode) {
-    case 0x00000000:
-        /* HALT */
-        /* REQUIRED */
-        break;
-    case 0x00000001:
-        /* CFLUSH */
-        break;
-    case 0x00000002:
-        /* DRAINA */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000003:
-        /* LDQP */
-        break;
-    case 0x00000004:
-        /* STQP */
-        break;
-    case 0x00000005:
-        /* SWPCTX */
-        break;
-    case 0x00000006:
-        /* MFPR_ASN */
-        if (cpu_alpha_mfpr(env, IPR_ASN, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000007:
-        /* MTPR_ASTEN */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_ASTEN, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000008:
-        /* MTPR_ASTSR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_ASTSR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000009:
-        /* CSERVE */
-        /* REQUIRED */
-        break;
-    case 0x0000000A:
-        /* SWPPAL */
-        /* REQUIRED */
-        palid = env->ir[16];
-        do_swappal(env, palid);
-        break;
-    case 0x0000000B:
-        /* MFPR_FEN */
-        if (cpu_alpha_mfpr(env, IPR_FEN, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000000C:
-        /* MTPR_FEN */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_FEN, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000000D:
-        /* MTPR_IPIR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000000E:
-        /* MFPR_IPL */
-        if (cpu_alpha_mfpr(env, IPR_IPL, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000000F:
-        /* MTPR_IPL */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_IPL, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000010:
-        /* MFPR_MCES */
-        if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000011:
-        /* MTPR_MCES */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000012:
-        /* MFPR_PCBB */
-        if (cpu_alpha_mfpr(env, IPR_PCBB, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000013:
-        /* MFPR_PRBR */
-        if (cpu_alpha_mfpr(env, IPR_PRBR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000014:
-        /* MTPR_PRBR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PRBR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000015:
-        /* MFPR_PTBR */
-        if (cpu_alpha_mfpr(env, IPR_PTBR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000016:
-        /* MFPR_SCBB */
-        if (cpu_alpha_mfpr(env, IPR_SCBB, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000017:
-        /* MTPR_SCBB */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_SCBB, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000018:
-        /* MTPR_SIRR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_SIRR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000019:
-        /* MFPR_SISR */
-        if (cpu_alpha_mfpr(env, IPR_SISR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000001A:
-        /* MFPR_TBCHK */
-        if (cpu_alpha_mfpr(env, IPR_TBCHK, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000001B:
-        /* MTPR_TBIA */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIA, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000001C:
-        /* MTPR_TBIAP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIAP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000001D:
-        /* MTPR_TBIS */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000001E:
-        /* MFPR_ESP */
-        if (cpu_alpha_mfpr(env, IPR_ESP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000001F:
-        /* MTPR_ESP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_ESP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000020:
-        /* MFPR_SSP */
-        if (cpu_alpha_mfpr(env, IPR_SSP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000021:
-        /* MTPR_SSP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_SSP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000022:
-        /* MFPR_USP */
-        if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000023:
-        /* MTPR_USP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000024:
-        /* MTPR_TBISD */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBISD, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000025:
-        /* MTPR_TBISI */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBISI, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000026:
-        /* MFPR_ASTEN */
-        if (cpu_alpha_mfpr(env, IPR_ASTEN, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000027:
-        /* MFPR_ASTSR */
-        if (cpu_alpha_mfpr(env, IPR_ASTSR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000029:
-        /* MFPR_VPTB */
-        if (cpu_alpha_mfpr(env, IPR_VPTB, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000002A:
-        /* MTPR_VPTB */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_VPTB, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002B:
-        /* MTPR_PERFMON */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002E:
-        /* MTPR_DATFX */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_DATFX, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000003E:
-        /* WTINT */
-        break;
-    case 0x0000003F:
-        /* MFPR_WHAMI */
-        if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000080:
-        /* BPT */
-        /* REQUIRED */
-        break;
-    case 0x00000081:
-        /* BUGCHK */
-        /* REQUIRED */
-        break;
-    case 0x00000082:
-        /* CHME */
-        break;
-    case 0x00000083:
-        /* CHMK */
-        break;
-    case 0x00000084:
-        /* CHMS */
-        break;
-    case 0x00000085:
-        /* CHMU */
-        break;
-    case 0x00000086:
-        /* IMB */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000087:
-        /* INSQHIL */
-        break;
-    case 0x00000088:
-        /* INSQTIL */
-        break;
-    case 0x00000089:
-        /* INSQHIQ */
-        break;
-    case 0x0000008A:
-        /* INSQTIQ */
-        break;
-    case 0x0000008B:
-        /* INSQUEL */
-        break;
-    case 0x0000008C:
-        /* INSQUEQ */
-        break;
-    case 0x0000008D:
-        /* INSQUEL/D */
-        break;
-    case 0x0000008E:
-        /* INSQUEQ/D */
-        break;
-    case 0x0000008F:
-        /* PROBER */
-        break;
-    case 0x00000090:
-        /* PROBEW */
-        break;
-    case 0x00000091:
-        /* RD_PS */
-        break;
-    case 0x00000092:
-        /* REI */
-        break;
-    case 0x00000093:
-        /* REMQHIL */
-        break;
-    case 0x00000094:
-        /* REMQTIL */
-        break;
-    case 0x00000095:
-        /* REMQHIQ */
-        break;
-    case 0x00000096:
-        /* REMQTIQ */
-        break;
-    case 0x00000097:
-        /* REMQUEL */
-        break;
-    case 0x00000098:
-        /* REMQUEQ */
-        break;
-    case 0x00000099:
-        /* REMQUEL/D */
-        break;
-    case 0x0000009A:
-        /* REMQUEQ/D */
-        break;
-    case 0x0000009B:
-        /* SWASTEN */
-        break;
-    case 0x0000009C:
-        /* WR_PS_SW */
-        break;
-    case 0x0000009D:
-        /* RSCC */
-        break;
-    case 0x0000009E:
-        /* READ_UNQ */
-        /* REQUIRED */
-        break;
-    case 0x0000009F:
-        /* WRITE_UNQ */
-        /* REQUIRED */
-        break;
-    case 0x000000A0:
-        /* AMOVRR */
-        break;
-    case 0x000000A1:
-        /* AMOVRM */
-        break;
-    case 0x000000A2:
-        /* INSQHILR */
-        break;
-    case 0x000000A3:
-        /* INSQTILR */
-        break;
-    case 0x000000A4:
-        /* INSQHIQR */
-        break;
-    case 0x000000A5:
-        /* INSQTIQR */
-        break;
-    case 0x000000A6:
-        /* REMQHILR */
-        break;
-    case 0x000000A7:
-        /* REMQTILR */
-        break;
-    case 0x000000A8:
-        /* REMQHIQR */
-        break;
-    case 0x000000A9:
-        /* REMQTIQR */
-        break;
-    case 0x000000AA:
-        /* GENTRAP */
-        /* REQUIRED */
-        break;
-    case 0x000000AE:
-        /* CLRFEN */
-        break;
-    default:
-        break;
-    }
-}
-
-static void pal_unix_call (CPUState *env, uint32_t palcode)
-{
-    uint64_t palid, val, oldval;
-
-    if (palcode < 0x00000080) {
-        /* Privileged palcodes */
-        if (!(env->ps >> 3)) {
-            /* TODO: generate privilege exception */
-        }
-    }
-    switch (palcode) {
-    case 0x00000000:
-        /* HALT */
-        /* REQUIRED */
-        break;
-    case 0x00000001:
-        /* CFLUSH */
-        break;
-    case 0x00000002:
-        /* DRAINA */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000009:
-        /* CSERVE */
-        /* REQUIRED */
-        break;
-    case 0x0000000A:
-        /* SWPPAL */
-        /* REQUIRED */
-        palid = env->ir[16];
-        do_swappal(env, palid);
-        break;
-    case 0x0000000D:
-        /* WRIPIR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000010:
-        /* RDMCES */
-        if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000011:
-        /* WRMCES */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002B:
-        /* WRFEN */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002D:
-        /* WRVPTPTR */
-        break;
-    case 0x00000030:
-        /* SWPCTX */
-        break;
-    case 0x00000031:
-        /* WRVAL */
-        break;
-    case 0x00000032:
-        /* RDVAL */
-        break;
-    case 0x00000033:
-        /* TBI */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000034:
-        /* WRENT */
-        break;
-    case 0x00000035:
-        /* SWPIPL */
-        break;
-    case 0x00000036:
-        /* RDPS */
-        break;
-    case 0x00000037:
-        /* WRKGP */
-        break;
-    case 0x00000038:
-        /* WRUSP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000039:
-        /* WRPERFMON */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000003A:
-        /* RDUSP */
-        if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000003C:
-        /* WHAMI */
-        if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000003D:
-        /* RETSYS */
-        break;
-    case 0x0000003E:
-        /* WTINT */
-        break;
-    case 0x0000003F:
-        /* RTI */
-        if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000080:
-        /* BPT */
-        /* REQUIRED */
-        break;
-    case 0x00000081:
-        /* BUGCHK */
-        /* REQUIRED */
-        break;
-    case 0x00000083:
-        /* CALLSYS */
-        break;
-    case 0x00000086:
-        /* IMB */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000092:
-        /* URTI */
-        break;
-    case 0x0000009E:
-        /* RDUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x0000009F:
-        /* WRUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x000000AA:
-        /* GENTRAP */
-        /* REQUIRED */
-        break;
-    case 0x000000AE:
-        /* CLRFEN */
-        break;
-    default:
-        break;
-    }
-}
-
-void call_pal (CPUState *env)
-{
-    pal_handler_t *pal_handler = env->pal_handler;
-
-    switch (env->exception_index) {
-    case EXCP_RESET:
-        (*pal_handler->reset)(env);
-        break;
-    case EXCP_MCHK:
-        (*pal_handler->machine_check)(env);
-        break;
-    case EXCP_ARITH:
-        (*pal_handler->arithmetic)(env);
-        break;
-    case EXCP_INTERRUPT:
-        (*pal_handler->interrupt)(env);
-        break;
-    case EXCP_DFAULT:
-        (*pal_handler->dfault)(env);
-        break;
-    case EXCP_DTB_MISS_PAL:
-        (*pal_handler->dtb_miss_pal)(env);
-        break;
-    case EXCP_DTB_MISS_NATIVE:
-        (*pal_handler->dtb_miss_native)(env);
-        break;
-    case EXCP_UNALIGN:
-        (*pal_handler->unalign)(env);
-        break;
-    case EXCP_ITB_MISS:
-        (*pal_handler->itb_miss)(env);
-        break;
-    case EXCP_ITB_ACV:
-        (*pal_handler->itb_acv)(env);
-        break;
-    case EXCP_OPCDEC:
-        (*pal_handler->opcdec)(env);
-        break;
-    case EXCP_FEN:
-        (*pal_handler->fen)(env);
-        break;
-    default:
-        if (env->exception_index >= EXCP_CALL_PAL &&
-            env->exception_index < EXCP_CALL_PALP) {
-            /* Unprivileged PAL call */
-            (*pal_handler->call_pal)
-                (env, (env->exception_index - EXCP_CALL_PAL) >> 6);
-        } else if (env->exception_index >= EXCP_CALL_PALP &&
-                   env->exception_index < EXCP_CALL_PALE) {
-            /* Privileged PAL call */
-            (*pal_handler->call_pal)
-                (env, ((env->exception_index - EXCP_CALL_PALP) >> 6) + 0x80);
-        } else {
-            /* Should never happen */
-        }
-        break;
-    }
-    env->ipr[IPR_EXC_ADDR] &= ~1;
-}
-
-void pal_init (CPUState *env)
-{
-    do_swappal(env, 0);
-}
-
-#if 0
-static uint64_t get_ptebase (CPUState *env, uint64_t vaddr)
-{
-    uint64_t virbnd, ptbr;
-
-    if ((env->features & FEATURE_VIRBND)) {
-        cpu_alpha_mfpr(env, IPR_VIRBND, &virbnd);
-        if (vaddr >= virbnd)
-            cpu_alpha_mfpr(env, IPR_SYSPTBR, &ptbr);
-        else
-            cpu_alpha_mfpr(env, IPR_PTBR, &ptbr);
-    } else {
-        cpu_alpha_mfpr(env, IPR_PTBR, &ptbr);
-    }
-
-    return ptbr;
-}
-
-static int get_page_bits (CPUState *env)
-{
-    /* XXX */
-    return 13;
-}
-
-static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
-                    uint64_t ptebase, int page_bits, uint64_t level,
-                    int mmu_idx, int rw)
-{
-    uint64_t pteaddr, pte, pfn;
-    uint8_t gh;
-    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user;
-
-    /* XXX: TOFIX */
-    is_user = mmu_idx == MMU_USER_IDX;
-    pteaddr = (ptebase << page_bits) + (8 * level);
-    pte = ldq_raw(pteaddr);
-    /* Decode all interresting PTE fields */
-    pfn = pte >> 32;
-    uwe = (pte >> 13) & 1;
-    kwe = (pte >> 12) & 1;
-    ure = (pte >> 9) & 1;
-    kre = (pte >> 8) & 1;
-    gh = (pte >> 5) & 3;
-    foE = (pte >> 3) & 1;
-    foW = (pte >> 2) & 1;
-    foR = (pte >> 1) & 1;
-    v = pte & 1;
-    ret = 0;
-    if (!v)
-        ret = 0x1;
-    /* Check access rights */
-    ar = 0;
-    if (is_user) {
-        if (ure)
-            ar |= PAGE_READ;
-        if (uwe)
-            ar |= PAGE_WRITE;
-        if (rw == 1 && !uwe)
-            ret |= 0x2;
-        if (rw != 1 && !ure)
-            ret |= 0x2;
-    } else {
-        if (kre)
-            ar |= PAGE_READ;
-        if (kwe)
-            ar |= PAGE_WRITE;
-        if (rw == 1 && !kwe)
-            ret |= 0x2;
-        if (rw != 1 && !kre)
-            ret |= 0x2;
-    }
-    if (rw == 0 && foR)
-        ret |= 0x4;
-    if (rw == 2 && foE)
-        ret |= 0x8;
-    if (rw == 1 && foW)
-        ret |= 0xC;
-    *pfnp = pfn;
-    if (zbitsp != NULL)
-        *zbitsp = page_bits + (3 * gh);
-    if (protp != NULL)
-        *protp = ar;
-
-    return ret;
-}
-
-static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
-                           uint64_t ptebase, int page_bits,
-                           uint64_t vaddr, int mmu_idx, int rw)
-{
-    uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
-    int lvl_bits, ret;
-
-    page_mask = (1ULL << page_bits) - 1ULL;
-    lvl_bits = page_bits - 3;
-    lvl_mask = (1ULL << lvl_bits) - 1ULL;
-    level3 = (vaddr >> page_bits) & lvl_mask;
-    level2 = (vaddr >> (page_bits + lvl_bits)) & lvl_mask;
-    level1 = (vaddr >> (page_bits + (2 * lvl_bits))) & lvl_mask;
-    /* Level 1 PTE */
-    ret = get_pte(&pfn, NULL, NULL, ptebase, page_bits, level1, 0, 0);
-    switch (ret) {
-    case 3:
-        /* Access violation */
-        return 2;
-    case 2:
-        /* translation not valid */
-        return 1;
-    default:
-        /* OK */
-        break;
-    }
-    /* Level 2 PTE */
-    ret = get_pte(&pfn, NULL, NULL, pfn, page_bits, level2, 0, 0);
-    switch (ret) {
-    case 3:
-        /* Access violation */
-        return 2;
-    case 2:
-        /* translation not valid */
-        return 1;
-    default:
-        /* OK */
-        break;
-    }
-    /* Level 3 PTE */
-    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
-    if (ret & 0x1) {
-        /* Translation not valid */
-        ret = 1;
-    } else if (ret & 2) {
-        /* Access violation */
-        ret = 2;
-    } else {
-        switch (ret & 0xC) {
-        case 0:
-            /* OK */
-            ret = 0;
-            break;
-        case 0x4:
-            /* Fault on read */
-            ret = 3;
-            break;
-        case 0x8:
-            /* Fault on execute */
-            ret = 4;
-            break;
-        case 0xC:
-            /* Fault on write */
-            ret = 5;
-            break;
-        }
-    }
-    *paddr = (pfn << page_bits) | (vaddr & page_mask);
-
-    return 0;
-}
-
-static int virtual_to_physical (CPUState *env, uint64_t *physp,
-                                int *zbitsp, int *protp,
-                                uint64_t virtual, int mmu_idx, int rw)
-{
-    uint64_t sva, ptebase;
-    int seg, page_bits, ret;
-
-    sva = ((int64_t)(virtual << (64 - VA_BITS))) >> (64 - VA_BITS);
-    if (sva != virtual)
-        seg = -1;
-    else
-        seg = sva >> (VA_BITS - 2);
-    virtual &= ~(0xFFFFFC0000000000ULL << (VA_BITS - 43));
-    ptebase = get_ptebase(env, virtual);
-    page_bits = get_page_bits(env);
-    ret = 0;
-    switch (seg) {
-    case 0:
-        /* seg1: 3 levels of PTE */
-        ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, mmu_idx, rw);
-        break;
-    case 1:
-        /* seg1: 2 levels of PTE */
-        ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, mmu_idx, rw);
-        break;
-    case 2:
-        /* kernel segment */
-        if (mmu_idx != 0) {
-            ret = 2;
-        } else {
-            *physp = virtual;
-        }
-        break;
-    case 3:
-        /* seg1: TB mapped */
-        ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, mmu_idx, rw);
-        break;
-    default:
-        ret = 1;
-        break;
-    }
-
-    return ret;
-}
-
-/* XXX: code provision */
-int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
-                              int mmu_idx, int is_softmmu)
-{
-    uint64_t physical, page_size, end;
-    int prot, zbits, ret;
-
-    ret = virtual_to_physical(env, &physical, &zbits, &prot,
-                              address, mmu_idx, rw);
-
-    switch (ret) {
-    case 0:
-        /* No fault */
-        page_size = 1ULL << zbits;
-        address &= ~(page_size - 1);
-        /* FIXME: page_size should probably be passed to tlb_set_page,
-           and this loop removed.   */
-        for (end = physical + page_size; physical < end; physical += 0x1000) {
-            tlb_set_page(env, address, physical, prot, mmu_idx,
-                         TARGET_PAGE_SIZE);
-            address += 0x1000;
-        }
-        ret = 0;
-        break;
-#if 0
-    case 1:
-        env->exception_index = EXCP_DFAULT;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    case 2:
-        env->exception_index = EXCP_ACCESS_VIOLATION;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    case 3:
-        env->exception_index = EXCP_FAULT_ON_READ;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    case 4:
-        env->exception_index = EXCP_FAULT_ON_EXECUTE;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-    case 5:
-        env->exception_index = EXCP_FAULT_ON_WRITE;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-#endif
-    default:
-        /* Should never happen */
-        env->exception_index = EXCP_MCHK;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    }
-
-    return ret;
-}
-#endif

+ 4 - 1
hw/bitbang_i2c.c

@@ -38,7 +38,8 @@ typedef enum bitbang_i2c_state {
     RECEIVING_BIT2,
     RECEIVING_BIT2,
     RECEIVING_BIT1,
     RECEIVING_BIT1,
     RECEIVING_BIT0,
     RECEIVING_BIT0,
-    SENDING_ACK
+    SENDING_ACK,
+    SENT_NACK
 } bitbang_i2c_state;
 } bitbang_i2c_state;
 
 
 struct bitbang_i2c_interface {
 struct bitbang_i2c_interface {
@@ -115,6 +116,7 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
     }
     }
     switch (i2c->state) {
     switch (i2c->state) {
     case STOPPED:
     case STOPPED:
+    case SENT_NACK:
         return bitbang_i2c_ret(i2c, 1);
         return bitbang_i2c_ret(i2c, 1);
 
 
     case SENDING_BIT7 ... SENDING_BIT0:
     case SENDING_BIT7 ... SENDING_BIT0:
@@ -155,6 +157,7 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
         i2c->state = RECEIVING_BIT7;
         i2c->state = RECEIVING_BIT7;
         if (data != 0) {
         if (data != 0) {
             DPRINTF("NACKED\n");
             DPRINTF("NACKED\n");
+            i2c->state = SENT_NACK;
             i2c_nack(i2c->bus);
             i2c_nack(i2c->bus);
         } else {
         } else {
             DPRINTF("ACKED\n");
             DPRINTF("ACKED\n");

+ 1 - 0
hw/boards.h

@@ -27,6 +27,7 @@ typedef struct QEMUMachine {
         no_cdrom:1,
         no_cdrom:1,
         no_sdcard:1;
         no_sdcard:1;
     int is_default;
     int is_default;
+    const char *default_machine_opts;
     GlobalProperty *compat_props;
     GlobalProperty *compat_props;
     struct QEMUMachine *next;
     struct QEMUMachine *next;
 } QEMUMachine;
 } QEMUMachine;

+ 3 - 3
hw/bt-hid.c

@@ -323,7 +323,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s,
             break;
             break;
         }
         }
         s->proto = parameter;
         s->proto = parameter;
-        s->usbdev->info->handle_control(s->usbdev, SET_PROTOCOL, s->proto, 0, 0,
+        s->usbdev->info->handle_control(s->usbdev, NULL, SET_PROTOCOL, s->proto, 0, 0,
                                         NULL);
                                         NULL);
         ret = BT_HS_SUCCESSFUL;
         ret = BT_HS_SUCCESSFUL;
         break;
         break;
@@ -333,7 +333,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s,
             ret = BT_HS_ERR_INVALID_PARAMETER;
             ret = BT_HS_ERR_INVALID_PARAMETER;
             break;
             break;
         }
         }
-        s->usbdev->info->handle_control(s->usbdev, GET_IDLE, 0, 0, 1,
+        s->usbdev->info->handle_control(s->usbdev, NULL, GET_IDLE, 0, 0, 1,
                         s->control->sdu_out(s->control, 1));
                         s->control->sdu_out(s->control, 1));
         s->control->sdu_submit(s->control);
         s->control->sdu_submit(s->control);
         break;
         break;
@@ -346,7 +346,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s,
 
 
         /* We don't need to know about the Idle Rate here really,
         /* We don't need to know about the Idle Rate here really,
          * so just pass it on to the device.  */
          * so just pass it on to the device.  */
-        ret = s->usbdev->info->handle_control(s->usbdev,
+        ret = s->usbdev->info->handle_control(s->usbdev, NULL,
                         SET_IDLE, data[1], 0, 0, NULL) ?
                         SET_IDLE, data[1], 0, 0, NULL) ?
                 BT_HS_SUCCESSFUL : BT_HS_ERR_INVALID_PARAMETER;
                 BT_HS_SUCCESSFUL : BT_HS_ERR_INVALID_PARAMETER;
         /* XXX: Does this generate a handshake? */
         /* XXX: Does this generate a handshake? */

+ 1 - 1
hw/bt.h

@@ -1441,7 +1441,7 @@ typedef struct {
 #define EVT_FLUSH_OCCURRED		0x11
 #define EVT_FLUSH_OCCURRED		0x11
 typedef struct {
 typedef struct {
     uint16_t	handle;
     uint16_t	handle;
-} __attribute__ ((packed)) evt_flush_occured;
+} __attribute__ ((packed)) evt_flush_occurred;
 #define EVT_FLUSH_OCCURRED_SIZE 2
 #define EVT_FLUSH_OCCURRED_SIZE 2
 
 
 #define EVT_ROLE_CHANGE			0x12
 #define EVT_ROLE_CHANGE			0x12

+ 1 - 1
hw/eepro100.c

@@ -1112,7 +1112,7 @@ static void eepro100_write_eeprom(eeprom_t * eeprom, uint8_t val)
 {
 {
     TRACE(EEPROM, logout("val=0x%02x\n", val));
     TRACE(EEPROM, logout("val=0x%02x\n", val));
 
 
-    /* mask unwriteable bits */
+    /* mask unwritable bits */
 #if 0
 #if 0
     val = SET_MASKED(val, 0x31, eeprom->value);
     val = SET_MASKED(val, 0x31, eeprom->value);
 #endif
 #endif

+ 5 - 5
hw/eeprom93xx.c

@@ -75,7 +75,7 @@ struct _eeprom_t {
     uint8_t  tick;
     uint8_t  tick;
     uint8_t  address;
     uint8_t  address;
     uint8_t  command;
     uint8_t  command;
-    uint8_t  writeable;
+    uint8_t  writable;
 
 
     uint8_t eecs;
     uint8_t eecs;
     uint8_t eesk;
     uint8_t eesk;
@@ -130,7 +130,7 @@ static const VMStateDescription vmstate_eeprom = {
         VMSTATE_UINT8(tick, eeprom_t),
         VMSTATE_UINT8(tick, eeprom_t),
         VMSTATE_UINT8(address, eeprom_t),
         VMSTATE_UINT8(address, eeprom_t),
         VMSTATE_UINT8(command, eeprom_t),
         VMSTATE_UINT8(command, eeprom_t),
-        VMSTATE_UINT8(writeable, eeprom_t),
+        VMSTATE_UINT8(writable, eeprom_t),
 
 
         VMSTATE_UINT8(eecs, eeprom_t),
         VMSTATE_UINT8(eecs, eeprom_t),
         VMSTATE_UINT8(eesk, eeprom_t),
         VMSTATE_UINT8(eesk, eeprom_t),
@@ -165,7 +165,7 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi)
         address = 0x0;
         address = 0x0;
     } else if (eeprom->eecs && ! eecs) {
     } else if (eeprom->eecs && ! eecs) {
         /* End chip select cycle. This triggers write / erase. */
         /* End chip select cycle. This triggers write / erase. */
-        if (eeprom->writeable) {
+        if (eeprom->writable) {
             uint8_t subcommand = address >> (eeprom->addrbits - 2);
             uint8_t subcommand = address >> (eeprom->addrbits - 2);
             if (command == 0 && subcommand == 2) {
             if (command == 0 && subcommand == 2) {
                 /* Erase all. */
                 /* Erase all. */
@@ -232,7 +232,7 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi)
                     switch (address >> (eeprom->addrbits - 2)) {
                     switch (address >> (eeprom->addrbits - 2)) {
                         case 0:
                         case 0:
                             logout("write disable command\n");
                             logout("write disable command\n");
-                            eeprom->writeable = 0;
+                            eeprom->writable = 0;
                             break;
                             break;
                         case 1:
                         case 1:
                             logout("write all command\n");
                             logout("write all command\n");
@@ -242,7 +242,7 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi)
                             break;
                             break;
                         case 3:
                         case 3:
                             logout("write enable command\n");
                             logout("write enable command\n");
-                            eeprom->writeable = 1;
+                            eeprom->writable = 1;
                             break;
                             break;
                     }
                     }
                 } else {
                 } else {

+ 70 - 49
hw/esp.c

@@ -61,10 +61,11 @@ struct ESPState {
     int32_t ti_size;
     int32_t ti_size;
     uint32_t ti_rptr, ti_wptr;
     uint32_t ti_rptr, ti_wptr;
     uint8_t ti_buf[TI_BUFSZ];
     uint8_t ti_buf[TI_BUFSZ];
-    uint32_t sense;
+    uint32_t status;
     uint32_t dma;
     uint32_t dma;
     SCSIBus bus;
     SCSIBus bus;
     SCSIDevice *current_dev;
     SCSIDevice *current_dev;
+    SCSIRequest *current_req;
     uint8_t cmdbuf[TI_BUFSZ];
     uint8_t cmdbuf[TI_BUFSZ];
     uint32_t cmdlen;
     uint32_t cmdlen;
     uint32_t do_cmd;
     uint32_t do_cmd;
@@ -187,6 +188,17 @@ static void esp_dma_enable(void *opaque, int irq, int level)
     }
     }
 }
 }
 
 
+static void esp_request_cancelled(SCSIRequest *req)
+{
+    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
+
+    if (req == s->current_req) {
+        scsi_req_unref(s->current_req);
+        s->current_req = NULL;
+        s->current_dev = NULL;
+    }
+}
+
 static uint32_t get_cmd(ESPState *s, uint8_t *buf)
 static uint32_t get_cmd(ESPState *s, uint8_t *buf)
 {
 {
     uint32_t dmalen;
     uint32_t dmalen;
@@ -209,7 +221,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
 
 
     if (s->current_dev) {
     if (s->current_dev) {
         /* Started a new command before the old one finished.  Cancel it.  */
         /* Started a new command before the old one finished.  Cancel it.  */
-        s->current_dev->info->cancel_io(s->current_dev, 0);
+        scsi_req_cancel(s->current_req);
         s->async_len = 0;
         s->async_len = 0;
     }
     }
 
 
@@ -232,7 +244,8 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
 
 
     DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
     DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
     lun = busid & 7;
     lun = busid & 7;
-    datalen = s->current_dev->info->send_command(s->current_dev, 0, buf, lun);
+    s->current_req = scsi_req_new(s->current_dev, 0, lun);
+    datalen = scsi_req_enqueue(s->current_req, buf);
     s->ti_size = datalen;
     s->ti_size = datalen;
     if (datalen != 0) {
     if (datalen != 0) {
         s->rregs[ESP_RSTAT] = STAT_TC;
         s->rregs[ESP_RSTAT] = STAT_TC;
@@ -240,11 +253,10 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
         s->dma_counter = 0;
         s->dma_counter = 0;
         if (datalen > 0) {
         if (datalen > 0) {
             s->rregs[ESP_RSTAT] |= STAT_DI;
             s->rregs[ESP_RSTAT] |= STAT_DI;
-            s->current_dev->info->read_data(s->current_dev, 0);
         } else {
         } else {
             s->rregs[ESP_RSTAT] |= STAT_DO;
             s->rregs[ESP_RSTAT] |= STAT_DO;
-            s->current_dev->info->write_data(s->current_dev, 0);
         }
         }
+        scsi_req_continue(s->current_req);
     }
     }
     s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
     s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
     s->rregs[ESP_RSEQ] = SEQ_CD;
     s->rregs[ESP_RSEQ] = SEQ_CD;
@@ -306,8 +318,8 @@ static void handle_satn_stop(ESPState *s)
 
 
 static void write_response(ESPState *s)
 static void write_response(ESPState *s)
 {
 {
-    DPRINTF("Transfer status (sense=%d)\n", s->sense);
-    s->ti_buf[0] = s->sense;
+    DPRINTF("Transfer status (status=%d)\n", s->status);
+    s->ti_buf[0] = s->status;
     s->ti_buf[1] = 0;
     s->ti_buf[1] = 0;
     if (s->dma) {
     if (s->dma) {
         s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
         s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
@@ -370,53 +382,56 @@ static void esp_do_dma(ESPState *s)
     else
     else
         s->ti_size -= len;
         s->ti_size -= len;
     if (s->async_len == 0) {
     if (s->async_len == 0) {
-        if (to_device) {
-            // ti_size is negative
-            s->current_dev->info->write_data(s->current_dev, 0);
-        } else {
-            s->current_dev->info->read_data(s->current_dev, 0);
-            /* If there is still data to be read from the device then
-               complete the DMA operation immediately.  Otherwise defer
-               until the scsi layer has completed.  */
-            if (s->dma_left == 0 && s->ti_size > 0) {
-                esp_dma_done(s);
-            }
+        scsi_req_continue(s->current_req);
+        /* If there is still data to be read from the device then
+           complete the DMA operation immediately.  Otherwise defer
+           until the scsi layer has completed.  */
+        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
+            return;
         }
         }
-    } else {
-        /* Partially filled a scsi buffer. Complete immediately.  */
-        esp_dma_done(s);
     }
     }
+
+    /* Partially filled a scsi buffer. Complete immediately.  */
+    esp_dma_done(s);
 }
 }
 
 
-static void esp_command_complete(SCSIBus *bus, int reason, uint32_t tag,
-                                 uint32_t arg)
+static void esp_command_complete(SCSIRequest *req, uint32_t status)
 {
 {
-    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, bus->qbus.parent);
+    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
 
 
-    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[ESP_RSTAT] = STAT_ST;
-        esp_dma_done(s);
+    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 (status) {
+        DPRINTF("Command failed\n");
+    }
+    s->status = status;
+    s->rregs[ESP_RSTAT] = STAT_ST;
+    esp_dma_done(s);
+    if (s->current_req) {
+        scsi_req_unref(s->current_req);
+        s->current_req = NULL;
         s->current_dev = NULL;
         s->current_dev = NULL;
-    } else {
-        DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
-        s->async_len = arg;
-        s->async_buf = s->current_dev->info->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 esp_transfer_data(SCSIRequest *req, uint32_t len)
+{
+    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
+
+    DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
+    s->async_len = len;
+    s->async_buf = scsi_req_get_buf(req);
+    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);
     }
     }
 }
 }
 
 
@@ -678,7 +693,7 @@ static const VMStateDescription vmstate_esp = {
         VMSTATE_UINT32(ti_rptr, ESPState),
         VMSTATE_UINT32(ti_rptr, ESPState),
         VMSTATE_UINT32(ti_wptr, ESPState),
         VMSTATE_UINT32(ti_wptr, ESPState),
         VMSTATE_BUFFER(ti_buf, ESPState),
         VMSTATE_BUFFER(ti_buf, ESPState),
-        VMSTATE_UINT32(sense, ESPState),
+        VMSTATE_UINT32(status, ESPState),
         VMSTATE_UINT32(dma, ESPState),
         VMSTATE_UINT32(dma, ESPState),
         VMSTATE_BUFFER(cmdbuf, ESPState),
         VMSTATE_BUFFER(cmdbuf, ESPState),
         VMSTATE_UINT32(cmdlen, ESPState),
         VMSTATE_UINT32(cmdlen, ESPState),
@@ -714,6 +729,12 @@ void esp_init(target_phys_addr_t espaddr, int it_shift,
     *dma_enable = qdev_get_gpio_in(dev, 1);
     *dma_enable = qdev_get_gpio_in(dev, 1);
 }
 }
 
 
+static const struct SCSIBusOps esp_scsi_ops = {
+    .transfer_data = esp_transfer_data,
+    .complete = esp_command_complete,
+    .cancel = esp_request_cancelled
+};
+
 static int esp_init1(SysBusDevice *dev)
 static int esp_init1(SysBusDevice *dev)
 {
 {
     ESPState *s = FROM_SYSBUS(ESPState, dev);
     ESPState *s = FROM_SYSBUS(ESPState, dev);
@@ -728,7 +749,7 @@ static int esp_init1(SysBusDevice *dev)
 
 
     qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2);
     qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2);
 
 
-    scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
+    scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, &esp_scsi_ops);
     return scsi_bus_legacy_handle_cmdline(&s->bus);
     return scsi_bus_legacy_handle_cmdline(&s->bus);
 }
 }
 
 

+ 30 - 5
hw/ide/ahci.c

@@ -884,8 +884,31 @@ static int handle_cmd(AHCIState *s, int port, int slot)
         }
         }
 
 
         if (ide_state->drive_kind != IDE_CD) {
         if (ide_state->drive_kind != IDE_CD) {
-            ide_set_sector(ide_state, (cmd_fis[6] << 16) | (cmd_fis[5] << 8) |
-                           cmd_fis[4]);
+            /*
+             * We set the sector depending on the sector defined in the FIS.
+             * Unfortunately, the spec isn't exactly obvious on this one.
+             *
+             * Apparently LBA48 commands set fis bytes 10,9,8,6,5,4 to the
+             * 48 bit sector number. ATA_CMD_READ_DMA_EXT is an example for
+             * such a command.
+             *
+             * Non-LBA48 commands however use 7[lower 4 bits],6,5,4 to define a
+             * 28-bit sector number. ATA_CMD_READ_DMA is an example for such
+             * a command.
+             *
+             * Since the spec doesn't explicitly state what each field should
+             * do, I simply assume non-used fields as reserved and OR everything
+             * together, independent of the command.
+             */
+            ide_set_sector(ide_state, ((uint64_t)cmd_fis[10] << 40)
+                                    | ((uint64_t)cmd_fis[9] << 32)
+                                    /* This is used for LBA48 commands */
+                                    | ((uint64_t)cmd_fis[8] << 24)
+                                    /* This is used for non-LBA48 commands */
+                                    | ((uint64_t)(cmd_fis[7] & 0xf) << 24)
+                                    | ((uint64_t)cmd_fis[6] << 16)
+                                    | ((uint64_t)cmd_fis[5] << 8)
+                                    | cmd_fis[4]);
         }
         }
 
 
         /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
         /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
@@ -1066,9 +1089,11 @@ static int ahci_dma_set_inactive(IDEDMA *dma)
 
 
     ad->dma_cb = NULL;
     ad->dma_cb = NULL;
 
 
-    /* maybe we still have something to process, check later */
-    ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
-    qemu_bh_schedule(ad->check_bh);
+    if (!ad->check_bh) {
+        /* maybe we still have something to process, check later */
+        ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
+        qemu_bh_schedule(ad->check_bh);
+    }
 
 
     return 0;
     return 0;
 }
 }

+ 10 - 7
hw/ide/core.c

@@ -430,7 +430,6 @@ void ide_dma_error(IDEState *s)
     s->error = ABRT_ERR;
     s->error = ABRT_ERR;
     s->status = READY_STAT | ERR_STAT;
     s->status = READY_STAT | ERR_STAT;
     ide_set_inactive(s);
     ide_set_inactive(s);
-    s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
     ide_set_irq(s->bus);
     ide_set_irq(s->bus);
 }
 }
 
 
@@ -500,8 +499,11 @@ handle_rw_error:
     n = s->nsector;
     n = s->nsector;
     s->io_buffer_index = 0;
     s->io_buffer_index = 0;
     s->io_buffer_size = n * 512;
     s->io_buffer_size = n * 512;
-    if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->is_read) == 0)
+    if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->is_read) == 0) {
+        /* The PRDs were too short. Reset the Active bit, but don't raise an
+         * interrupt. */
         goto eot;
         goto eot;
+    }
 
 
 #ifdef DEBUG_AIO
 #ifdef DEBUG_AIO
     printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, is_read=%d\n",
     printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, is_read=%d\n",
@@ -523,7 +525,6 @@ handle_rw_error:
     return;
     return;
 
 
 eot:
 eot:
-   s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
    ide_set_inactive(s);
    ide_set_inactive(s);
 }
 }
 
 
@@ -1592,13 +1593,15 @@ void ide_bus_reset(IDEBus *bus)
     bus->dma->ops->reset(bus->dma);
     bus->dma->ops->reset(bus->dma);
 }
 }
 
 
-int ide_init_drive(IDEState *s, BlockDriverState *bs,
+int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
                    const char *version, const char *serial)
                    const char *version, const char *serial)
 {
 {
     int cylinders, heads, secs;
     int cylinders, heads, secs;
     uint64_t nb_sectors;
     uint64_t nb_sectors;
 
 
     s->bs = bs;
     s->bs = bs;
+    s->drive_kind = kind;
+
     bdrv_get_geometry(bs, &nb_sectors);
     bdrv_get_geometry(bs, &nb_sectors);
     bdrv_guess_geometry(bs, &cylinders, &heads, &secs);
     bdrv_guess_geometry(bs, &cylinders, &heads, &secs);
     if (cylinders < 1 || cylinders > 16383) {
     if (cylinders < 1 || cylinders > 16383) {
@@ -1623,8 +1626,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs,
     s->smart_autosave = 1;
     s->smart_autosave = 1;
     s->smart_errors = 0;
     s->smart_errors = 0;
     s->smart_selftest_count = 0;
     s->smart_selftest_count = 0;
-    if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
-        s->drive_kind = IDE_CD;
+    if (kind == IDE_CD) {
         bdrv_set_change_cb(bs, cdrom_change_cb, s);
         bdrv_set_change_cb(bs, cdrom_change_cb, s);
         bs->buffer_alignment = 2048;
         bs->buffer_alignment = 2048;
     } else {
     } else {
@@ -1729,7 +1731,8 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
         dinfo = i == 0 ? hd0 : hd1;
         dinfo = i == 0 ? hd0 : hd1;
         ide_init1(bus, i);
         ide_init1(bus, i);
         if (dinfo) {
         if (dinfo) {
-            if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL,
+            if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
+                               dinfo->media_cd ? IDE_CD : IDE_HD, NULL,
                                *dinfo->serial ? dinfo->serial : NULL) < 0) {
                                *dinfo->serial ? dinfo->serial : NULL) < 0) {
                 error_report("Can't set up IDE drive %s", dinfo->id);
                 error_report("Can't set up IDE drive %s", dinfo->id);
                 exit(1);
                 exit(1);

+ 3 - 3
hw/ide/ich.c

@@ -90,12 +90,12 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
 
 
     qemu_register_reset(ahci_reset, d);
     qemu_register_reset(ahci_reset, d);
 
 
-    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
-    pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
-
     msi_init(dev, 0x50, 1, true, false);
     msi_init(dev, 0x50, 1, true, false);
     d->ahci.irq = d->card.irq[0];
     d->ahci.irq = d->card.irq[0];
 
 
+    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
+    pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
+
     return 0;
     return 0;
 }
 }
 
 

+ 1 - 1
hw/ide/internal.h

@@ -558,7 +558,7 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
 void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 
 
-int ide_init_drive(IDEState *s, BlockDriverState *bs,
+int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
                    const char *version, const char *serial);
                    const char *version, const char *serial);
 void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
 void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,

+ 2 - 6
hw/ide/pci.c

@@ -296,12 +296,8 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
              */
              */
             if (bm->bus->dma->aiocb) {
             if (bm->bus->dma->aiocb) {
                 qemu_aio_flush();
                 qemu_aio_flush();
-#ifdef DEBUG_IDE
-                if (bm->bus->dma->aiocb)
-                    printf("ide_dma_cancel: aiocb still pending");
-                if (bm->status & BM_STATUS_DMAING)
-                    printf("ide_dma_cancel: BM_STATUS_DMAING still pending");
-#endif
+                assert(bm->bus->dma->aiocb == NULL);
+                assert((bm->status & BM_STATUS_DMAING) == 0);
             }
             }
         } else {
         } else {
             bm->cur_addr = bm->addr;
             bm->cur_addr = bm->addr;

+ 64 - 17
hw/ide/qdev.c

@@ -98,7 +98,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
 {
 {
     DeviceState *dev;
     DeviceState *dev;
 
 
-    dev = qdev_create(&bus->qbus, "ide-drive");
+    dev = qdev_create(&bus->qbus, drive->media_cd ? "ide-cd" : "ide-hd");
     qdev_prop_set_uint32(dev, "unit", unit);
     qdev_prop_set_uint32(dev, "unit", unit);
     qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv);
     qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv);
     qdev_init_nofail(dev);
     qdev_init_nofail(dev);
@@ -118,7 +118,7 @@ typedef struct IDEDrive {
     IDEDevice dev;
     IDEDevice dev;
 } IDEDrive;
 } IDEDrive;
 
 
-static int ide_drive_initfn(IDEDevice *dev)
+static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
 {
 {
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
     IDEState *s = bus->ifs + dev->unit;
     IDEState *s = bus->ifs + dev->unit;
@@ -134,7 +134,7 @@ static int ide_drive_initfn(IDEDevice *dev)
         }
         }
     }
     }
 
 
-    if (ide_init_drive(s, dev->conf.bs, dev->version, serial) < 0) {
+    if (ide_init_drive(s, dev->conf.bs, kind, dev->version, serial) < 0) {
         return -1;
         return -1;
     }
     }
 
 
@@ -151,22 +151,69 @@ static int ide_drive_initfn(IDEDevice *dev)
     return 0;
     return 0;
 }
 }
 
 
-static IDEDeviceInfo ide_drive_info = {
-    .qdev.name  = "ide-drive",
-    .qdev.fw_name  = "drive",
-    .qdev.size  = sizeof(IDEDrive),
-    .init       = ide_drive_initfn,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1),
-        DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),
-        DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),
-        DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),
-        DEFINE_PROP_END_OF_LIST(),
+static int ide_hd_initfn(IDEDevice *dev)
+{
+    return ide_dev_initfn(dev, IDE_HD);
+}
+
+static int ide_cd_initfn(IDEDevice *dev)
+{
+    return ide_dev_initfn(dev, IDE_CD);
+}
+
+static int ide_drive_initfn(IDEDevice *dev)
+{
+    DriveInfo *dinfo = drive_get_by_blockdev(dev->conf.bs);
+
+    return ide_dev_initfn(dev, dinfo->media_cd ? IDE_CD : IDE_HD);
+}
+
+#define DEFINE_IDE_DEV_PROPERTIES()                     \
+    DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1), \
+    DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),        \
+    DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
+    DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial)
+
+static IDEDeviceInfo ide_dev_info[] = {
+    {
+        .qdev.name    = "ide-hd",
+        .qdev.fw_name = "drive",
+        .qdev.desc    = "virtual IDE disk",
+        .qdev.size    = sizeof(IDEDrive),
+        .init         = ide_hd_initfn,
+        .qdev.props   = (Property[]) {
+            DEFINE_IDE_DEV_PROPERTIES(),
+            DEFINE_PROP_END_OF_LIST(),
+        }
+    },{
+        .qdev.name    = "ide-cd",
+        .qdev.fw_name = "drive",
+        .qdev.desc    = "virtual IDE CD-ROM",
+        .qdev.size    = sizeof(IDEDrive),
+        .init         = ide_cd_initfn,
+        .qdev.props   = (Property[]) {
+            DEFINE_IDE_DEV_PROPERTIES(),
+            DEFINE_PROP_END_OF_LIST(),
+        }
+    },{
+        .qdev.name    = "ide-drive", /* legacy -device ide-drive */
+        .qdev.fw_name = "drive",
+        .qdev.desc    = "virtual IDE disk or CD-ROM (legacy)",
+        .qdev.size    = sizeof(IDEDrive),
+        .init         = ide_drive_initfn,
+        .qdev.props   = (Property[]) {
+            DEFINE_IDE_DEV_PROPERTIES(),
+            DEFINE_PROP_END_OF_LIST(),
+        }
     }
     }
 };
 };
 
 
-static void ide_drive_register(void)
+static void ide_dev_register(void)
 {
 {
-    ide_qdev_register(&ide_drive_info);
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(ide_dev_info); i++) {
+        ide_qdev_register(&ide_dev_info[i]);
+    }
 }
 }
-device_init(ide_drive_register);
+device_init(ide_dev_register);

+ 1 - 1
hw/lan9118.c

@@ -721,7 +721,7 @@ static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
             break;
             break;
         }
         }
         s->phy_control = val & 0x7980;
         s->phy_control = val & 0x7980;
-        /* Complete autonegotiation imediately.  */
+        /* Complete autonegotiation immediately.  */
         if (val & 0x1000) {
         if (val & 0x1000) {
             s->phy_status |= 0x0020;
             s->phy_status |= 0x0020;
         }
         }

+ 130 - 84
hw/lsi53c895a.c

@@ -174,6 +174,7 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0)
 #define LSI_TAG_VALID     (1 << 16)
 #define LSI_TAG_VALID     (1 << 16)
 
 
 typedef struct lsi_request {
 typedef struct lsi_request {
+    SCSIRequest *req;
     uint32_t tag;
     uint32_t tag;
     uint32_t dma_len;
     uint32_t dma_len;
     uint8_t *dma_buf;
     uint8_t *dma_buf;
@@ -189,7 +190,7 @@ typedef struct {
     uint32_t script_ram_base;
     uint32_t script_ram_base;
 
 
     int carry; /* ??? Should this be an a visible register somewhere?  */
     int carry; /* ??? Should this be an a visible register somewhere?  */
-    int sense;
+    int status;
     /* Action to take at the end of a MSG IN phase.
     /* Action to take at the end of a MSG IN phase.
        0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN.  */
        0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN.  */
     int msg_action;
     int msg_action;
@@ -567,11 +568,9 @@ static void lsi_do_dma(LSIState *s, int out)
     s->csbc += count;
     s->csbc += count;
     s->dnad += count;
     s->dnad += count;
     s->dbc -= count;
     s->dbc -= count;
-
-    if (s->current->dma_buf == NULL) {
-        s->current->dma_buf = dev->info->get_buf(dev, s->current->tag);
+     if (s->current->dma_buf == NULL) {
+        s->current->dma_buf = scsi_req_get_buf(s->current->req);
     }
     }
-
     /* ??? Set SFBR to first data byte.  */
     /* ??? Set SFBR to first data byte.  */
     if (out) {
     if (out) {
         cpu_physical_memory_read(addr, s->current->dma_buf, count);
         cpu_physical_memory_read(addr, s->current->dma_buf, count);
@@ -581,13 +580,7 @@ static void lsi_do_dma(LSIState *s, int out)
     s->current->dma_len -= count;
     s->current->dma_len -= count;
     if (s->current->dma_len == 0) {
     if (s->current->dma_len == 0) {
         s->current->dma_buf = NULL;
         s->current->dma_buf = NULL;
-        if (out) {
-            /* Write the data.  */
-            dev->info->write_data(dev, s->current->tag);
-        } else {
-            /* Request any remaining data.  */
-            dev->info->read_data(dev, s->current->tag);
-        }
+        scsi_req_continue(s->current->req);
     } else {
     } else {
         s->current->dma_buf += count;
         s->current->dma_buf += count;
         lsi_resume_script(s);
         lsi_resume_script(s);
@@ -652,82 +645,123 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
     }
     }
 }
 }
 
 
-/* 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)
+static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
 {
 {
     lsi_request *p;
     lsi_request *p;
 
 
     QTAILQ_FOREACH(p, &s->queue, next) {
     QTAILQ_FOREACH(p, &s->queue, next) {
         if (p->tag == tag) {
         if (p->tag == tag) {
-            if (p->pending) {
-                BADF("Multiple IO pending for tag %d\n", tag);
-            }
-            p->pending = arg;
-            /* Reselect if waiting for it, or if reselection triggers an IRQ
-               and the bus is free.
-               Since no interrupt stacking is implemented in the emulation, it
-               is also required that there are no pending interrupts waiting
-               for service from the device driver. */
-            if (s->waiting == 1 ||
-                (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
-                 !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
-                /* Reselect device.  */
-                lsi_reselect(s, p);
-                return 0;
-            } else {
-                DPRINTF("Queueing IO tag=0x%x\n", tag);
-                p->pending = arg;
-                return 1;
-            }
+            return p;
         }
         }
     }
     }
-    BADF("IO with unknown tag %d\n", tag);
-    return 1;
+
+    return NULL;
+}
+
+static void lsi_request_cancelled(SCSIRequest *req)
+{
+    LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
+    lsi_request *p;
+
+    if (s->current && req == s->current->req) {
+        scsi_req_unref(req);
+        qemu_free(s->current);
+        s->current = NULL;
+        return;
+    }
+
+    p = lsi_find_by_tag(s, req->tag);
+    if (p) {
+        QTAILQ_REMOVE(&s->queue, p, next);
+        scsi_req_unref(req);
+        qemu_free(p);
+    }
 }
 }
 
 
-/* Callback to indicate that the SCSI layer has completed a transfer.  */
-static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag,
-                                 uint32_t arg)
+/* 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 len)
 {
 {
-    LSIState *s = DO_UPCAST(LSIState, dev.qdev, bus->qbus.parent);
+    lsi_request *p;
+
+    p = lsi_find_by_tag(s, tag);
+    if (!p) {
+        BADF("IO with unknown tag %d\n", tag);
+        return 1;
+    }
+
+    if (p->pending) {
+        BADF("Multiple IO pending for tag %d\n", tag);
+    }
+    p->pending = len;
+    /* Reselect if waiting for it, or if reselection triggers an IRQ
+       and the bus is free.
+       Since no interrupt stacking is implemented in the emulation, it
+       is also required that there are no pending interrupts waiting
+       for service from the device driver. */
+    if (s->waiting == 1 ||
+        (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
+         !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
+        /* Reselect device.  */
+        lsi_reselect(s, p);
+        return 0;
+    } else {
+        DPRINTF("Queueing IO tag=0x%x\n", tag);
+        p->pending = len;
+        return 1;
+    }
+}
+
+ /* Callback to indicate that the SCSI layer has completed a command.  */
+static void lsi_command_complete(SCSIRequest *req, uint32_t status)
+{
+    LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
     int out;
     int out;
 
 
     out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
     out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
-    if (reason == SCSI_REASON_DONE) {
-        DPRINTF("Command complete sense=%d\n", (int)arg);
-        s->sense = arg;
-        s->command_complete = 2;
-        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);
-        }
+    DPRINTF("Command complete status=%d\n", (int)status);
+    s->status = status;
+    s->command_complete = 2;
+    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);
+    }
 
 
+    if (s->current && req == s->current->req) {
+        scsi_req_unref(s->current->req);
         qemu_free(s->current);
         qemu_free(s->current);
         s->current = NULL;
         s->current = NULL;
-
-        lsi_resume_script(s);
-        return;
     }
     }
+    lsi_resume_script(s);
+}
+
+ /* Callback to indicate that the SCSI layer has completed a transfer.  */
+static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
+{
+    LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
+    int out;
 
 
-    if (s->waiting == 1 || !s->current || tag != s->current->tag ||
+    if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
         (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
         (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
-        if (lsi_queue_tag(s, tag, arg))
+        if (lsi_queue_tag(s, req->tag, len)) {
             return;
             return;
+        }
     }
     }
 
 
+    out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
+
     /* host adapter (re)connected */
     /* host adapter (re)connected */
-    DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg);
-    s->current->dma_len = arg;
+    DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, len);
+    s->current->dma_len = len;
     s->command_complete = 1;
     s->command_complete = 1;
-    if (!s->waiting)
-        return;
-    if (s->waiting == 1 || s->dbc == 0) {
-        lsi_resume_script(s);
-    } else {
-        lsi_do_dma(s, out);
+    if (s->waiting) {
+        if (s->waiting == 1 || s->dbc == 0) {
+            lsi_resume_script(s);
+        } else {
+            lsi_do_dma(s, out);
+        }
     }
     }
 }
 }
 
 
@@ -755,16 +789,17 @@ static void lsi_do_command(LSIState *s)
     assert(s->current == NULL);
     assert(s->current == NULL);
     s->current = qemu_mallocz(sizeof(lsi_request));
     s->current = qemu_mallocz(sizeof(lsi_request));
     s->current->tag = s->select_tag;
     s->current->tag = s->select_tag;
+    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
 
 
-    n = dev->info->send_command(dev, s->current->tag, buf, s->current_lun);
-    if (n > 0) {
-        lsi_set_phase(s, PHASE_DI);
-        dev->info->read_data(dev, s->current->tag);
-    } else if (n < 0) {
-        lsi_set_phase(s, PHASE_DO);
-        dev->info->write_data(dev, s->current->tag);
+    n = scsi_req_enqueue(s->current->req, buf);
+    if (n) {
+        if (n > 0) {
+            lsi_set_phase(s, PHASE_DI);
+        } else if (n < 0) {
+            lsi_set_phase(s, PHASE_DO);
+        }
+        scsi_req_continue(s->current->req);
     }
     }
-
     if (!s->command_complete) {
     if (!s->command_complete) {
         if (n) {
         if (n) {
             /* Command did not complete immediately so disconnect.  */
             /* Command did not complete immediately so disconnect.  */
@@ -783,14 +818,14 @@ static void lsi_do_command(LSIState *s)
 
 
 static void lsi_do_status(LSIState *s)
 static void lsi_do_status(LSIState *s)
 {
 {
-    uint8_t sense;
-    DPRINTF("Get status len=%d sense=%d\n", s->dbc, s->sense);
+    uint8_t status;
+    DPRINTF("Get status len=%d status=%d\n", s->dbc, s->status);
     if (s->dbc != 1)
     if (s->dbc != 1)
         BADF("Bad Status move\n");
         BADF("Bad Status move\n");
     s->dbc = 1;
     s->dbc = 1;
-    sense = s->sense;
-    s->sfbr = sense;
-    cpu_physical_memory_write(s->dnad, &sense, 1);
+    status = s->status;
+    s->sfbr = status;
+    cpu_physical_memory_write(s->dnad, &status, 1);
     lsi_set_phase(s, PHASE_MI);
     lsi_set_phase(s, PHASE_MI);
     s->msg_action = 1;
     s->msg_action = 1;
     lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
     lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
@@ -855,13 +890,15 @@ static void lsi_do_msgout(LSIState *s)
     int len;
     int len;
     uint32_t current_tag;
     uint32_t current_tag;
     SCSIDevice *current_dev;
     SCSIDevice *current_dev;
-    lsi_request *p, *p_next;
+    lsi_request *current_req, *p, *p_next;
     int id;
     int id;
 
 
     if (s->current) {
     if (s->current) {
         current_tag = s->current->tag;
         current_tag = s->current->tag;
+        current_req = s->current;
     } else {
     } else {
         current_tag = s->select_tag;
         current_tag = s->select_tag;
+        current_req = lsi_find_by_tag(s, current_tag);
     }
     }
     id = (current_tag >> 8) & 0xf;
     id = (current_tag >> 8) & 0xf;
     current_dev = s->bus.devs[id];
     current_dev = s->bus.devs[id];
@@ -913,7 +950,9 @@ static void lsi_do_msgout(LSIState *s)
         case 0x0d:
         case 0x0d:
             /* The ABORT TAG message clears the current I/O process only. */
             /* The ABORT TAG message clears the current I/O process only. */
             DPRINTF("MSG: ABORT TAG tag=0x%x\n", current_tag);
             DPRINTF("MSG: ABORT TAG tag=0x%x\n", current_tag);
-            current_dev->info->cancel_io(current_dev, current_tag);
+            if (current_req) {
+                scsi_req_cancel(current_req->req);
+            }
             lsi_disconnect(s);
             lsi_disconnect(s);
             break;
             break;
         case 0x06:
         case 0x06:
@@ -936,7 +975,9 @@ static void lsi_do_msgout(LSIState *s)
             }
             }
 
 
             /* clear the current I/O process */
             /* clear the current I/O process */
-            current_dev->info->cancel_io(current_dev, current_tag);
+            if (s->current) {
+                scsi_req_cancel(s->current->req);
+            }
 
 
             /* As the current implemented devices scsi_disk and scsi_generic
             /* As the current implemented devices scsi_disk and scsi_generic
                only support one LUN, we don't need to keep track of LUNs.
                only support one LUN, we don't need to keep track of LUNs.
@@ -948,8 +989,7 @@ static void lsi_do_msgout(LSIState *s)
             id = current_tag & 0x0000ff00;
             id = current_tag & 0x0000ff00;
             QTAILQ_FOREACH_SAFE(p, &s->queue, next, p_next) {
             QTAILQ_FOREACH_SAFE(p, &s->queue, next, p_next) {
                 if ((p->tag & 0x0000ff00) == id) {
                 if ((p->tag & 0x0000ff00) == id) {
-                    current_dev->info->cancel_io(current_dev, p->tag);
-                    QTAILQ_REMOVE(&s->queue, p, next);
+                    scsi_req_cancel(p->req);
                 }
                 }
             }
             }
 
 
@@ -2122,7 +2162,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
         VMSTATE_PCI_DEVICE(dev, LSIState),
         VMSTATE_PCI_DEVICE(dev, LSIState),
 
 
         VMSTATE_INT32(carry, LSIState),
         VMSTATE_INT32(carry, LSIState),
-        VMSTATE_INT32(sense, LSIState),
+        VMSTATE_INT32(status, LSIState),
         VMSTATE_INT32(msg_action, LSIState),
         VMSTATE_INT32(msg_action, LSIState),
         VMSTATE_INT32(msg_len, LSIState),
         VMSTATE_INT32(msg_len, LSIState),
         VMSTATE_BUFFER(msg, LSIState),
         VMSTATE_BUFFER(msg, LSIState),
@@ -2205,6 +2245,12 @@ static int lsi_scsi_uninit(PCIDevice *d)
     return 0;
     return 0;
 }
 }
 
 
+static const struct SCSIBusOps lsi_scsi_ops = {
+    .transfer_data = lsi_transfer_data,
+    .complete = lsi_command_complete,
+    .cancel = lsi_request_cancelled
+};
+
 static int lsi_scsi_init(PCIDevice *dev)
 static int lsi_scsi_init(PCIDevice *dev)
 {
 {
     LSIState *s = DO_UPCAST(LSIState, dev, dev);
     LSIState *s = DO_UPCAST(LSIState, dev, dev);
@@ -2232,7 +2278,7 @@ static int lsi_scsi_init(PCIDevice *dev)
                            PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
                            PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
     QTAILQ_INIT(&s->queue);
     QTAILQ_INIT(&s->queue);
 
 
-    scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete);
+    scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops);
     if (!dev->qdev.hotplugged) {
     if (!dev->qdev.hotplugged) {
         return scsi_bus_legacy_handle_cmdline(&s->bus);
         return scsi_bus_legacy_handle_cmdline(&s->bus);
     }
     }

+ 1 - 1
hw/msi.c

@@ -155,7 +155,7 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
     pci_set_word(dev->wmask + msi_data_off(dev, msi64bit), 0xffff);
     pci_set_word(dev->wmask + msi_data_off(dev, msi64bit), 0xffff);
 
 
     if (msi_per_vector_mask) {
     if (msi_per_vector_mask) {
-        /* Make mask bits 0 to nr_vectors - 1 writeable. */
+        /* Make mask bits 0 to nr_vectors - 1 writable. */
         pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit),
         pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit),
                      0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));
                      0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));
     }
     }

+ 1 - 1
hw/msix.c

@@ -76,7 +76,7 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
     pci_set_long(config + PCI_MSIX_PBA, (bar_size + MSIX_PAGE_PENDING) |
     pci_set_long(config + PCI_MSIX_PBA, (bar_size + MSIX_PAGE_PENDING) |
                  bar_nr);
                  bar_nr);
     pdev->msix_cap = config_offset;
     pdev->msix_cap = config_offset;
-    /* Make flags bit writeable. */
+    /* Make flags bit writable. */
     pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
     pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
 	    MSIX_MASKALL_MASK;
 	    MSIX_MASKALL_MASK;
     return 0;
     return 0;

+ 1 - 1
hw/mst_fpga.c

@@ -154,7 +154,7 @@ mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
 	case MST_MSCRD:
 	case MST_MSCRD:
 		s->mscrd =  value;
 		s->mscrd =  value;
 		break;
 		break;
-	case MST_INTMSKENA:	/* Mask interupt */
+	case MST_INTMSKENA:	/* Mask interrupt */
 		s->intmskena = (value & 0xFEEFF);
 		s->intmskena = (value & 0xFEEFF);
 		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
 		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
 		break;
 		break;

+ 1 - 1
hw/multiboot.c

@@ -307,7 +307,7 @@ int load_multiboot(void *fw_cfg,
                                 | MULTIBOOT_FLAGS_MMAP);
                                 | MULTIBOOT_FLAGS_MMAP);
     stl_p(bootinfo + MBI_MEM_LOWER,   640);
     stl_p(bootinfo + MBI_MEM_LOWER,   640);
     stl_p(bootinfo + MBI_MEM_UPPER,   (ram_size / 1024) - 1024);
     stl_p(bootinfo + MBI_MEM_UPPER,   (ram_size / 1024) - 1024);
-    stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8001ffff); /* XXX: use the -boot switch? */
+    stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8000ffff); /* XXX: use the -boot switch? */
     stl_p(bootinfo + MBI_MMAP_ADDR,   ADDR_E820_MAP);
     stl_p(bootinfo + MBI_MMAP_ADDR,   ADDR_E820_MAP);
 
 
     mb_debug("multiboot: mh_entry_addr = %#x\n", mh_entry_addr);
     mb_debug("multiboot: mh_entry_addr = %#x\n", mh_entry_addr);

+ 20 - 17
hw/pc.c

@@ -957,29 +957,18 @@ void pc_cpus_init(const char *cpu_model)
     }
     }
 }
 }
 
 
-void pc_memory_init(ram_addr_t ram_size,
-                    const char *kernel_filename,
+void pc_memory_init(const char *kernel_filename,
                     const char *kernel_cmdline,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     const char *initrd_filename,
-                    ram_addr_t *below_4g_mem_size_p,
-                    ram_addr_t *above_4g_mem_size_p)
+                    ram_addr_t below_4g_mem_size,
+                    ram_addr_t above_4g_mem_size)
 {
 {
     char *filename;
     char *filename;
     int ret, linux_boot, i;
     int ret, linux_boot, i;
     ram_addr_t ram_addr, bios_offset, option_rom_offset;
     ram_addr_t ram_addr, bios_offset, option_rom_offset;
-    ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
     int bios_size, isa_bios_size;
     int bios_size, isa_bios_size;
     void *fw_cfg;
     void *fw_cfg;
 
 
-    if (ram_size >= 0xe0000000 ) {
-        above_4g_mem_size = ram_size - 0xe0000000;
-        below_4g_mem_size = 0xe0000000;
-    } else {
-        below_4g_mem_size = ram_size;
-    }
-    *above_4g_mem_size_p = above_4g_mem_size;
-    *below_4g_mem_size_p = below_4g_mem_size;
-
     linux_boot = (kernel_filename != NULL);
     linux_boot = (kernel_filename != NULL);
 
 
     /* allocate RAM */
     /* allocate RAM */
@@ -1081,6 +1070,15 @@ void pc_vga_init(PCIBus *pci_bus)
             isa_vga_init();
             isa_vga_init();
         }
         }
     }
     }
+
+    /*
+     * sga does not suppress normal vga output. So a machine can have both a
+     * vga card and sga manually enabled. Output will be seen on both.
+     * For nographic case, sga is enabled at all times
+     */
+    if (display_type == DT_NOGRAPHIC) {
+        isa_create_simple("sga");
+    }
 }
 }
 
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 static void cpu_request_exit(void *opaque, int irq, int level)
@@ -1093,7 +1091,8 @@ static void cpu_request_exit(void *opaque, int irq, int level)
 }
 }
 
 
 void pc_basic_device_init(qemu_irq *isa_irq,
 void pc_basic_device_init(qemu_irq *isa_irq,
-                          ISADevice **rtc_state)
+                          ISADevice **rtc_state,
+                          bool no_vmport)
 {
 {
     int i;
     int i;
     DriveInfo *fd[MAX_FD];
     DriveInfo *fd[MAX_FD];
@@ -1138,8 +1137,12 @@ void pc_basic_device_init(qemu_irq *isa_irq,
     a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
     a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
     i8042 = isa_create_simple("i8042");
     i8042 = isa_create_simple("i8042");
     i8042_setup_a20_line(i8042, &a20_line[0]);
     i8042_setup_a20_line(i8042, &a20_line[0]);
-    vmport_init();
-    vmmouse = isa_try_create("vmmouse");
+    if (!no_vmport) {
+        vmport_init();
+        vmmouse = isa_try_create("vmmouse");
+    } else {
+        vmmouse = NULL;
+    }
     if (vmmouse) {
     if (vmmouse) {
         qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042);
         qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042);
         qdev_init_nofail(&vmmouse->qdev);
         qdev_init_nofail(&vmmouse->qdev);

+ 6 - 5
hw/pc.h

@@ -129,16 +129,16 @@ void pc_cmos_set_s3_resume(void *opaque, int irq, int level);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
 
 void pc_cpus_init(const char *cpu_model);
 void pc_cpus_init(const char *cpu_model);
-void pc_memory_init(ram_addr_t ram_size,
-                    const char *kernel_filename,
+void pc_memory_init(const char *kernel_filename,
                     const char *kernel_cmdline,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     const char *initrd_filename,
-                    ram_addr_t *below_4g_mem_size_p,
-                    ram_addr_t *above_4g_mem_size_p);
+                    ram_addr_t below_4g_mem_size,
+                    ram_addr_t above_4g_mem_size);
 qemu_irq *pc_allocate_cpu_irq(void);
 qemu_irq *pc_allocate_cpu_irq(void);
 void pc_vga_init(PCIBus *pci_bus);
 void pc_vga_init(PCIBus *pci_bus);
 void pc_basic_device_init(qemu_irq *isa_irq,
 void pc_basic_device_init(qemu_irq *isa_irq,
-                          ISADevice **rtc_state);
+                          ISADevice **rtc_state,
+                          bool no_vmport);
 void pc_init_ne2k_isa(NICInfo *nd);
 void pc_init_ne2k_isa(NICInfo *nd);
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
                   const char *boot_device,
                   const char *boot_device,
@@ -176,6 +176,7 @@ struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size);
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size);
+PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
 
 /* piix4.c */
 /* piix4.c */

+ 64 - 7
hw/pc_piix.c

@@ -38,6 +38,10 @@
 #include "arch_init.h"
 #include "arch_init.h"
 #include "blockdev.h"
 #include "blockdev.h"
 #include "smbus.h"
 #include "smbus.h"
+#include "xen.h"
+#ifdef CONFIG_XEN
+#  include <xen/hvm/hvm_info_table.h>
+#endif
 
 
 #define MAX_IDE_BUS 2
 #define MAX_IDE_BUS 2
 
 
@@ -92,12 +96,26 @@ static void pc_init1(ram_addr_t ram_size,
         kvmclock_create();
         kvmclock_create();
     }
     }
 
 
+    if (ram_size >= 0xe0000000 ) {
+        above_4g_mem_size = ram_size - 0xe0000000;
+        below_4g_mem_size = 0xe0000000;
+    } else {
+        above_4g_mem_size = 0;
+        below_4g_mem_size = ram_size;
+    }
+
     /* allocate ram and load rom/bios */
     /* allocate ram and load rom/bios */
-    pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename,
-                   &below_4g_mem_size, &above_4g_mem_size);
+    if (!xen_enabled()) {
+        pc_memory_init(kernel_filename, kernel_cmdline, initrd_filename,
+                       below_4g_mem_size, above_4g_mem_size);
+    }
 
 
-    cpu_irq = pc_allocate_cpu_irq();
-    i8259 = i8259_init(cpu_irq[0]);
+    if (!xen_enabled()) {
+        cpu_irq = pc_allocate_cpu_irq();
+        i8259 = i8259_init(cpu_irq[0]);
+    } else {
+        i8259 = xen_interrupt_controller_init();
+    }
     isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
     isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
     isa_irq_state->i8259 = i8259;
     isa_irq_state->i8259 = i8259;
     if (pci_enabled) {
     if (pci_enabled) {
@@ -106,7 +124,11 @@ static void pc_init1(ram_addr_t ram_size,
     isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
     isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
 
 
     if (pci_enabled) {
     if (pci_enabled) {
-        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
+        if (!xen_enabled()) {
+            pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
+        } else {
+            pci_bus = i440fx_xen_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
+        }
     } else {
     } else {
         pci_bus = NULL;
         pci_bus = NULL;
         i440fx_state = NULL;
         i440fx_state = NULL;
@@ -119,7 +141,7 @@ static void pc_init1(ram_addr_t ram_size,
     pc_vga_init(pci_enabled? pci_bus: NULL);
     pc_vga_init(pci_enabled? pci_bus: NULL);
 
 
     /* init basic PC hardware */
     /* init basic PC hardware */
-    pc_basic_device_init(isa_irq, &rtc_state);
+    pc_basic_device_init(isa_irq, &rtc_state, xen_enabled());
 
 
     for(i = 0; i < nb_nics; i++) {
     for(i = 0; i < nb_nics; i++) {
         NICInfo *nd = &nd_table[i];
         NICInfo *nd = &nd_table[i];
@@ -157,7 +179,11 @@ static void pc_init1(ram_addr_t ram_size,
     if (pci_enabled && acpi_enabled) {
     if (pci_enabled && acpi_enabled) {
         i2c_bus *smbus;
         i2c_bus *smbus;
 
 
-        cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
+        if (!xen_enabled()) {
+            cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
+        } else {
+            cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1);
+        }
         smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         /* TODO: Populate SPD eeprom data.  */
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
@@ -213,6 +239,24 @@ static void pc_init_isa(ram_addr_t ram_size,
              initrd_filename, cpu_model, 0, 1);
              initrd_filename, cpu_model, 0, 1);
 }
 }
 
 
+#ifdef CONFIG_XEN
+static void pc_xen_hvm_init(ram_addr_t ram_size,
+                            const char *boot_device,
+                            const char *kernel_filename,
+                            const char *kernel_cmdline,
+                            const char *initrd_filename,
+                            const char *cpu_model)
+{
+    if (xen_hvm_init() != 0) {
+        hw_error("xen hardware virtual machine initialisation failed");
+    }
+    pc_init_pci_no_kvmclock(ram_size, boot_device,
+                            kernel_filename, kernel_cmdline,
+                            initrd_filename, cpu_model);
+    xen_vcpu_init();
+}
+#endif
+
 static QEMUMachine pc_machine = {
 static QEMUMachine pc_machine = {
     .name = "pc-0.14",
     .name = "pc-0.14",
     .alias = "pc",
     .alias = "pc",
@@ -425,6 +469,16 @@ static QEMUMachine isapc_machine = {
     .max_cpus = 1,
     .max_cpus = 1,
 };
 };
 
 
+#ifdef CONFIG_XEN
+static QEMUMachine xenfv_machine = {
+    .name = "xenfv",
+    .desc = "Xen Fully-virtualized PC",
+    .init = pc_xen_hvm_init,
+    .max_cpus = HVM_MAX_VCPUS,
+    .default_machine_opts = "accel=xen",
+};
+#endif
+
 static void pc_machine_init(void)
 static void pc_machine_init(void)
 {
 {
     qemu_register_machine(&pc_machine);
     qemu_register_machine(&pc_machine);
@@ -433,6 +487,9 @@ static void pc_machine_init(void)
     qemu_register_machine(&pc_machine_v0_11);
     qemu_register_machine(&pc_machine_v0_11);
     qemu_register_machine(&pc_machine_v0_10);
     qemu_register_machine(&pc_machine_v0_10);
     qemu_register_machine(&isapc_machine);
     qemu_register_machine(&isapc_machine);
+#ifdef CONFIG_XEN
+    qemu_register_machine(&xenfv_machine);
+#endif
 }
 }
 
 
 machine_init(pc_machine_init);
 machine_init(pc_machine_init);

+ 5 - 3
hw/pci.c

@@ -168,7 +168,7 @@ void pci_device_reset(PCIDevice *dev)
     dev->irq_state = 0;
     dev->irq_state = 0;
     pci_update_irq_status(dev);
     pci_update_irq_status(dev);
     pci_device_deassert_intx(dev);
     pci_device_deassert_intx(dev);
-    /* Clear all writeable bits */
+    /* Clear all writable bits */
     pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,
     pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,
                                  pci_get_word(dev->wmask + PCI_COMMAND) |
                                  pci_get_word(dev->wmask + PCI_COMMAND) |
                                  pci_get_word(dev->w1cmask + PCI_COMMAND));
                                  pci_get_word(dev->w1cmask + PCI_COMMAND));
@@ -891,7 +891,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     wmask = ~(size - 1);
     wmask = ~(size - 1);
     addr = pci_bar(pci_dev, region_num);
     addr = pci_bar(pci_dev, region_num);
     if (region_num == PCI_ROM_SLOT) {
     if (region_num == PCI_ROM_SLOT) {
-        /* ROM enable bit is writeable */
+        /* ROM enable bit is writable */
         wmask |= PCI_ROM_ADDRESS_ENABLE;
         wmask |= PCI_ROM_ADDRESS_ENABLE;
     }
     }
     pci_set_long(pci_dev->config + addr, type);
     pci_set_long(pci_dev->config + addr, type);
@@ -1940,6 +1940,8 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
         pci_patch_ids(pdev, ptr, size);
         pci_patch_ids(pdev, ptr, size);
     }
     }
 
 
+    qemu_put_ram_ptr(ptr);
+
     pci_register_bar(pdev, PCI_ROM_SLOT, size,
     pci_register_bar(pdev, PCI_ROM_SLOT, size,
                      0, pci_map_option_rom);
                      0, pci_map_option_rom);
 
 
@@ -1993,7 +1995,7 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
     if (!offset)
     if (!offset)
         return;
         return;
     pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
     pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
-    /* Make capability writeable again */
+    /* Make capability writable again */
     memset(pdev->wmask + offset, 0xff, size);
     memset(pdev->wmask + offset, 0xff, size);
     memset(pdev->w1cmask + offset, 0, size);
     memset(pdev->w1cmask + offset, 0, size);
     /* Clear cmask as device-specific registers can't be checked */
     /* Clear cmask as device-specific registers can't be checked */

+ 1 - 1
hw/pci.h

@@ -132,7 +132,7 @@ struct PCIDevice {
     /* PCI config space */
     /* PCI config space */
     uint8_t *config;
     uint8_t *config;
 
 
-    /* Used to enable config checks on load. Note that writeable bits are
+    /* Used to enable config checks on load. Note that writable bits are
      * never checked even if set in cmask. */
      * never checked even if set in cmask. */
     uint8_t *cmask;
     uint8_t *cmask;
 
 

+ 1 - 0
hw/pci_ids.h

@@ -100,6 +100,7 @@
 #define PCI_VENDOR_ID_INTEL              0x8086
 #define PCI_VENDOR_ID_INTEL              0x8086
 #define PCI_DEVICE_ID_INTEL_82441        0x1237
 #define PCI_DEVICE_ID_INTEL_82441        0x1237
 #define PCI_DEVICE_ID_INTEL_82801AA_5    0x2415
 #define PCI_DEVICE_ID_INTEL_82801AA_5    0x2415
+#define PCI_DEVICE_ID_INTEL_82801D       0x24CD
 #define PCI_DEVICE_ID_INTEL_ESB_9        0x25ab
 #define PCI_DEVICE_ID_INTEL_ESB_9        0x25ab
 #define PCI_DEVICE_ID_INTEL_82371SB_0    0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_0    0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_1    0x7010
 #define PCI_DEVICE_ID_INTEL_82371SB_1    0x7010

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio