summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--CODING_STYLE2
-rw-r--r--MAINTAINERS5
-rw-r--r--Makefile9
-rw-r--r--Makefile.objs3
-rw-r--r--Makefile.target12
-rw-r--r--QMP/qmp-spec.txt20
-rw-r--r--arch_init.c2
-rw-r--r--block-migration.c58
-rwxr-xr-xconfigure38
-rw-r--r--cpu-all.h3
-rw-r--r--cpu-exec.c1
-rw-r--r--cpus.c82
-rw-r--r--cpus.h2
-rw-r--r--def-helper.h7
-rw-r--r--default-configs/pci.mak1
-rw-r--r--default-configs/s390x-softmmu.mak1
-rw-r--r--dis-asm.h3
-rw-r--r--disas.c24
-rw-r--r--dma.h1
-rw-r--r--docs/ccid.txt2
-rw-r--r--docs/qapi-code-gen.txt4
-rw-r--r--docs/specs/ivshmem_device_spec.txt2
-rw-r--r--docs/xen-save-devices-state.txt34
-rw-r--r--elf.h37
-rw-r--r--error.c13
-rw-r--r--error.h5
-rw-r--r--exec-all.h37
-rw-r--r--exec.c25
-rw-r--r--fpu/softfloat.c12
-rw-r--r--fsdev/virtfs-proxy-helper.texi2
-rw-r--r--gdbstub.c42
-rw-r--r--hmp-commands.hx3
-rw-r--r--hmp.c74
-rw-r--r--hmp.h1
-rw-r--r--hw/blizzard.c4
-rw-r--r--hw/cirrus_vga.c4
-rw-r--r--hw/ds1338.c1
-rw-r--r--hw/ioapic.c2
-rw-r--r--hw/irq.c17
-rw-r--r--hw/irq.h5
-rw-r--r--hw/ivshmem.c2
-rw-r--r--hw/mc146818rtc.c33
-rw-r--r--hw/mc146818rtc.h3
-rw-r--r--hw/mc146818rtc_regs.h62
-rw-r--r--hw/milkymist-sysctl.c26
-rw-r--r--hw/milkymist-vgafb.c5
-rw-r--r--hw/omap1.c10
-rw-r--r--hw/omap_lcdc.c5
-rw-r--r--hw/pc.c2
-rw-r--r--hw/pc_piix.c21
-rw-r--r--hw/pci.c1
-rw-r--r--hw/piix_pci.c3
-rw-r--r--hw/pl031.c75
-rw-r--r--hw/ppc440_bamboo.c2
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/ppce500_mpc8544ds.c2
-rw-r--r--hw/ps2.c2
-rw-r--r--hw/pxa2xx.c28
-rw-r--r--hw/qdev-monitor.c16
-rw-r--r--hw/qdev.c27
-rw-r--r--hw/qdev.h2
-rw-r--r--hw/qxl-render.c13
-rw-r--r--hw/qxl.c176
-rw-r--r--hw/scsi-bus.c18
-rw-r--r--hw/scsi-disk.c49
-rw-r--r--hw/serial.c5
-rw-r--r--hw/strongarm.c10
-rw-r--r--hw/sun4m.c12
-rw-r--r--hw/sun4u.c36
-rw-r--r--hw/twl92230.c9
-rw-r--r--hw/vga.c2
-rw-r--r--hw/virtio-scsi.c2
-rw-r--r--hw/xen_console.c3
-rw-r--r--hw/xen_disk.c11
-rw-r--r--include/qemu/object.h24
-rw-r--r--libcacard/vcard_emul_nss.c36
-rw-r--r--linux-user/arm/syscall_nr.h2
-rw-r--r--linux-user/elfload.c32
-rw-r--r--linux-user/ioctls.h34
-rw-r--r--linux-user/main.c51
-rw-r--r--linux-user/mmap.c35
-rw-r--r--linux-user/qemu.h2
-rw-r--r--linux-user/syscall.c303
-rw-r--r--linux-user/syscall_defs.h26
-rw-r--r--linux-user/syscall_types.h40
-rw-r--r--lm32-dis.c361
-rw-r--r--main-loop.c147
-rw-r--r--main-loop.h1
-rw-r--r--migration-fd.c2
-rw-r--r--migration.c74
-rw-r--r--migration.h5
-rw-r--r--module.c1
-rw-r--r--monitor.c9
-rw-r--r--osdep.h2
-rw-r--r--oslib-win32.c3
-rw-r--r--pc-bios/bios.binbin131072 -> 131072 bytes
-rw-r--r--ppc-dis.c2
-rw-r--r--qapi-schema-test.json2
-rw-r--r--qapi-schema.json38
-rw-r--r--qapi/qmp-input-visitor.c120
-rw-r--r--qapi/qmp-input-visitor.h2
-rw-r--r--qapi/qmp-output-visitor.c8
-rw-r--r--qemu-common.h2
-rw-r--r--qemu-doc.texi8
-rw-r--r--qemu-nbd.texi2
-rw-r--r--qemu-options.hx33
-rw-r--r--qemu-queue.h2
-rw-r--r--qemu-timer.c2
-rw-r--r--qemu-timer.h1
-rw-r--r--qerror.c8
-rw-r--r--qerror.h6
-rw-r--r--qga/channel-win32.c4
-rw-r--r--qga/commands-posix.c111
-rw-r--r--qmp-commands.hx40
-rw-r--r--qom/container.c23
-rw-r--r--qom/object.c33
-rw-r--r--qtest.c443
-rw-r--r--qtest.h35
-rw-r--r--roms/Makefile10
-rw-r--r--roms/config.seabios1
-rwxr-xr-xroms/configure-seabios.sh5
m---------roms/seabios0
-rw-r--r--rules.mak2
-rw-r--r--savevm.c113
-rwxr-xr-xscripts/create_config6
-rwxr-xr-xscripts/gtester-cat26
-rw-r--r--scripts/qapi-commands.py16
-rw-r--r--scripts/qapi-types.py4
-rw-r--r--scripts/qapi-visit.py24
-rw-r--r--scripts/qapi.py5
-rw-r--r--scripts/qemu-gdb.py89
-rwxr-xr-xscripts/qtest5
-rwxr-xr-xscripts/texi2pod.pl9
-rwxr-xr-xscripts/tracetool26
-rw-r--r--slirp/misc.c46
-rw-r--r--slirp/sbuf.c6
-rw-r--r--slirp/slirp.h14
-rw-r--r--slirp/tcp.h21
-rw-r--r--slirp/tcp_subr.c4
-rw-r--r--sysemu.h11
-rw-r--r--target-alpha/STATUS2
-rw-r--r--target-alpha/cpu.h6
-rw-r--r--target-alpha/fpu_helper.c822
-rw-r--r--target-alpha/helper.c61
-rw-r--r--target-alpha/helper.h143
-rw-r--r--target-alpha/int_helper.c319
-rw-r--r--target-alpha/mem_helper.c151
-rw-r--r--target-alpha/op_helper.c1379
-rw-r--r--target-alpha/sys_helper.c87
-rw-r--r--target-alpha/translate.c222
-rw-r--r--target-arm/cpu-qom.h71
-rw-r--r--target-arm/cpu.c60
-rw-r--r--target-arm/cpu.h35
-rw-r--r--target-arm/helper.c23
-rw-r--r--target-arm/translate.c13
-rw-r--r--target-lm32/helper.c2
-rw-r--r--target-mips/TODO4
-rw-r--r--target-mips/cpu.h2
-rw-r--r--target-mips/helper.h4
-rw-r--r--target-mips/op_helper.c3
-rw-r--r--target-ppc/cpu.h6
-rw-r--r--target-ppc/helper.c8
-rw-r--r--target-ppc/kvm.c2
-rw-r--r--target-ppc/kvm_ppc.c2
-rw-r--r--target-ppc/translate_init.c24
-rw-r--r--target-s390x/cpu-qom.h71
-rw-r--r--target-s390x/cpu.c96
-rw-r--r--target-s390x/cpu.h5
-rw-r--r--target-s390x/helper.c41
-rw-r--r--target-sparc/cpu-qom.h75
-rw-r--r--target-sparc/cpu.c (renamed from target-sparc/cpu_init.c)68
-rw-r--r--target-sparc/cpu.h6
-rw-r--r--target-sparc/helper.h2
-rw-r--r--target-sparc/mmu_helper.c19
-rw-r--r--target-unicore32/cpu-qom.h59
-rw-r--r--target-unicore32/cpu.c104
-rw-r--r--target-unicore32/cpu.h4
-rw-r--r--target-unicore32/helper.c65
-rw-r--r--target-unicore32/helper.h3
-rw-r--r--target-unicore32/op_helper.c3
-rw-r--r--target-unicore32/translate.c3
-rw-r--r--tcg/hppa/tcg-target.c103
-rw-r--r--tcg/i386/tcg-target.c114
-rw-r--r--tcg/ppc64/tcg-target.c1
-rw-r--r--tcg/sparc/tcg-target.c63
-rw-r--r--tcg/tcg.c283
-rw-r--r--tcg/tcg.h2
-rw-r--r--tci.c35
-rw-r--r--tests/Makefile166
-rw-r--r--tests/check-qdict.c (renamed from check-qdict.c)0
-rw-r--r--tests/check-qfloat.c (renamed from check-qfloat.c)0
-rw-r--r--tests/check-qint.c (renamed from check-qint.c)0
-rw-r--r--tests/check-qjson.c (renamed from check-qjson.c)0
-rw-r--r--tests/check-qlist.c (renamed from check-qlist.c)0
-rw-r--r--tests/check-qstring.c (renamed from check-qstring.c)0
-rw-r--r--tests/libqtest.c387
-rw-r--r--tests/libqtest.h335
-rw-r--r--tests/rtc-test.c263
-rw-r--r--tests/tcg/lm32/Makefile13
-rw-r--r--tests/test-coroutine.c (renamed from test-coroutine.c)0
-rw-r--r--tests/test-qmp-commands.c (renamed from test-qmp-commands.c)3
-rw-r--r--tests/test-qmp-input-strict.c234
-rw-r--r--tests/test-qmp-input-visitor.c (renamed from test-qmp-input-visitor.c)19
-rw-r--r--tests/test-qmp-output-visitor.c (renamed from test-qmp-output-visitor.c)20
-rw-r--r--tests/test-string-input-visitor.c (renamed from test-string-input-visitor.c)0
-rw-r--r--tests/test-string-output-visitor.c (renamed from test-string-output-visitor.c)0
-rw-r--r--thunk.c28
-rw-r--r--thunk.h28
-rw-r--r--trace-events66
-rw-r--r--translate-all.c6
-rw-r--r--ui/cocoa.m2
-rw-r--r--ui/spice-core.c15
-rw-r--r--ui/spice-display.c38
-rw-r--r--ui/vnc-auth-sasl.c4
-rw-r--r--ui/vnc-auth-sasl.h4
-rw-r--r--vl.c21
-rw-r--r--vmstate.h3
-rw-r--r--xen-all.c104
-rw-r--r--xen-mapcache.c22
-rw-r--r--xen-mapcache.h9
221 files changed, 7627 insertions, 2678 deletions
diff --git a/.gitignore b/.gitignore
index 81b1510297..9859c7d746 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,6 +39,7 @@ qemu-img-cmds.texi
 qemu-img-cmds.h
 qemu-io
 qemu-ga
+qemu-bridge-helper
 qemu-monitor.texi
 QMP/qmp-commands.txt
 test-coroutine
@@ -75,9 +76,14 @@ patches
 pc-bios/bios-pq/status
 pc-bios/vgabios-pq/status
 pc-bios/optionrom/linuxboot.bin
+pc-bios/optionrom/linuxboot.raw
+pc-bios/optionrom/linuxboot.img
 pc-bios/optionrom/multiboot.bin
 pc-bios/optionrom/multiboot.raw
+pc-bios/optionrom/multiboot.img
 pc-bios/optionrom/kvmvapic.bin
+pc-bios/optionrom/kvmvapic.raw
+pc-bios/optionrom/kvmvapic.img
 .stgit-*
 cscope.*
 tags
diff --git a/CODING_STYLE b/CODING_STYLE
index 7c82d4d0af..dcbce28a27 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -1,4 +1,4 @@
-Qemu Coding Style
+QEMU Coding Style
 =================
 
 Please use the script checkpatch.pl in the scripts directory to check
diff --git a/MAINTAINERS b/MAINTAINERS
index f83d07c2c4..922945c920 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -112,6 +112,11 @@ M: Blue Swirl <blauwirbel@gmail.com>
 S: Maintained
 F: target-sparc/
 
+UniCore32
+M: Guan Xuetao <gxt@mprc.pku.edu.cn>
+S: Maintained
+F: target-unicore32/
+
 X86
 M: qemu-devel@nongnu.org
 S: Odd Fixes
diff --git a/Makefile b/Makefile
index 1bc3cb049a..35c7a2a551 100644
--- a/Makefile
+++ b/Makefile
@@ -173,6 +173,7 @@ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 $(qapi-obj-y): $(GENERATED_HEADERS)
 qapi-dir := $(BUILD_DIR)/qapi-generated
 qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
+qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
 
 gen-out-type = $(subst .,-,$(suffix $@))
 
@@ -350,25 +351,25 @@ qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx
 qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi
 	$(call quiet-command, \
 	  perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu.pod && \
-	  pod2man --section=1 --center=" " --release=" " qemu.pod > $@, \
+	  $(POD2MAN) --section=1 --center=" " --release=" " qemu.pod > $@, \
 	  "  GEN   $@")
 
 qemu-img.1: qemu-img.texi qemu-img-cmds.texi
 	$(call quiet-command, \
 	  perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu-img.pod && \
-	  pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@, \
+	  $(POD2MAN) --section=1 --center=" " --release=" " qemu-img.pod > $@, \
 	  "  GEN   $@")
 
 fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
 	$(call quiet-command, \
 	  perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< fsdev/virtfs-proxy-helper.pod && \
-	  pod2man --section=1 --center=" " --release=" " fsdev/virtfs-proxy-helper.pod > $@, \
+	  $(POD2MAN) --section=1 --center=" " --release=" " fsdev/virtfs-proxy-helper.pod > $@, \
 	  "  GEN   $@")
 
 qemu-nbd.8: qemu-nbd.texi
 	$(call quiet-command, \
 	  perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu-nbd.pod && \
-	  pod2man --section=8 --center=" " --release=" " qemu-nbd.pod > $@, \
+	  $(POD2MAN) --section=8 --center=" " --release=" " qemu-nbd.pod > $@, \
 	  "  GEN   $@")
 
 dvi: qemu-doc.dvi qemu-tech.dvi
diff --git a/Makefile.objs b/Makefile.objs
index 226b01df96..f308b574d7 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -322,6 +322,8 @@ hw-obj-$(CONFIG_DP8393X) += dp8393x.o
 hw-obj-$(CONFIG_DS1225Y) += ds1225y.o
 hw-obj-$(CONFIG_MIPSNET) += mipsnet.o
 
+hw-obj-y += qtest.o
+
 # Sound
 sound-obj-y =
 sound-obj-$(CONFIG_SB16) += sb16.o
@@ -363,6 +365,7 @@ libdis-$(CONFIG_PPC_DIS) += ppc-dis.o
 libdis-$(CONFIG_S390_DIS) += s390-dis.o
 libdis-$(CONFIG_SH4_DIS) += sh4-dis.o
 libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
+libdis-$(CONFIG_LM32_DIS) += lm32-dis.o
 
 ######################################################################
 # trace
diff --git a/Makefile.target b/Makefile.target
index 37fb7edd6d..14c8fa18fc 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -58,7 +58,7 @@ else
 TARGET_TYPE=system
 endif
 
-$(QEMU_PROG).stp:
+$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
 	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool \
 		--$(TRACE_BACKEND) \
 		--binary $(bindir)/$(QEMU_PROG) \
@@ -81,8 +81,10 @@ libobj-y += tcg/tcg.o tcg/optimize.o
 libobj-$(CONFIG_TCG_INTERPRETER) += tci.o
 libobj-y += fpu/softfloat.o
 ifneq ($(TARGET_BASE_ARCH), sparc)
+ifneq ($(TARGET_BASE_ARCH), alpha)
 libobj-y += op_helper.o
 endif
+endif
 libobj-y += helper.o
 ifeq ($(TARGET_BASE_ARCH), i386)
 libobj-y += cpuid.o
@@ -90,12 +92,16 @@ endif
 libobj-$(TARGET_SPARC64) += vis_helper.o
 libobj-$(CONFIG_NEED_MMU) += mmu.o
 libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
+libobj-$(TARGET_ARM) += cpu.o
+libobj-$(TARGET_S390X) += cpu.o
 ifeq ($(TARGET_BASE_ARCH), sparc)
 libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
-libobj-y += cpu_init.o
+libobj-y += cpu.o
 endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
+libobj-$(TARGET_UNICORE32) += cpu.o
+libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
@@ -209,7 +215,7 @@ obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o
 # need to fix this properly
 obj-$(CONFIG_NO_PCI) += pci-stub.o
 obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
-obj-$(CONFIG_VIRTIO_SCSI) += virtio-scsi.o
+obj-$(CONFIG_VIRTIO) += virtio-scsi.o
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
 obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
diff --git a/QMP/qmp-spec.txt b/QMP/qmp-spec.txt
index 9d30a8ce6e..1ba916c9f2 100644
--- a/QMP/qmp-spec.txt
+++ b/QMP/qmp-spec.txt
@@ -209,13 +209,27 @@ incompatible way are disabled by default and will be advertised by the
 capabilities array (section '2.2 Server Greeting'). Thus, Clients can check
 that array and enable the capabilities they support.
 
-Additionally, Clients must not assume any particular:
-
-- Size of json-objects or length of json-arrays
+The QMP Server performs a type check on the arguments to a command.  It
+generates an error if a value does not have the expected type for its
+key, or if it does not understand a key that the Client included.  The
+strictness of the Server catches wrong assumptions of Clients about
+the Server's schema.  Clients can assume that, when such validation
+errors occur, they will be reported before the command generated any
+side effect.
+
+However, Clients must not assume any particular:
+
+- Length of json-arrays
+- Size of json-objects; in particular, future versions of QEMU may add
+  new keys and Clients should be able to ignore them.
 - Order of json-object members or json-array elements
 - Amount of errors generated by a command, that is, new errors can be added
   to any existing command in newer versions of the Server
 
+Of course, the Server does guarantee to send valid JSON.  But apart from
+this, a Client should be "conservative in what they send, and liberal in
+what they accept".
+
 6. Downstream extension of QMP
 ------------------------------
 
diff --git a/arch_init.c b/arch_init.c
index a95ef495fe..595badf50f 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -260,7 +260,7 @@ static void sort_ram_list(void)
     g_free(blocks);
 }
 
-int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
+int ram_save_live(QEMUFile *f, int stage, void *opaque)
 {
     ram_addr_t addr;
     uint64_t bytes_transferred_last;
diff --git a/block-migration.c b/block-migration.c
index 4467468506..fd2ffff0d5 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -18,7 +18,6 @@
 #include "hw/hw.h"
 #include "qemu-queue.h"
 #include "qemu-timer.h"
-#include "monitor.h"
 #include "block-migration.h"
 #include "migration.h"
 #include "blockdev.h"
@@ -204,8 +203,7 @@ static void blk_mig_read_cb(void *opaque, int ret)
     assert(block_mig_state.submitted >= 0);
 }
 
-static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,
-                                BlkMigDevState *bmds)
+static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
 {
     int64_t total_sectors = bmds->total_sectors;
     int64_t cur_sector = bmds->cur_sector;
@@ -272,7 +270,6 @@ static void set_dirty_tracking(int enable)
 
 static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
 {
-    Monitor *mon = opaque;
     BlkMigDevState *bmds;
     int64_t sectors;
 
@@ -295,19 +292,17 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
         block_mig_state.total_sector_sum += sectors;
 
         if (bmds->shared_base) {
-            monitor_printf(mon, "Start migration for %s with shared base "
-                                "image\n",
-                           bs->device_name);
+            DPRINTF("Start migration for %s with shared base image\n",
+                    bs->device_name);
         } else {
-            monitor_printf(mon, "Start full migration for %s\n",
-                           bs->device_name);
+            DPRINTF("Start full migration for %s\n", bs->device_name);
         }
 
         QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
     }
 }
 
-static void init_blk_migration(Monitor *mon, QEMUFile *f)
+static void init_blk_migration(QEMUFile *f)
 {
     block_mig_state.submitted = 0;
     block_mig_state.read_done = 0;
@@ -318,10 +313,10 @@ static void init_blk_migration(Monitor *mon, QEMUFile *f)
     block_mig_state.total_time = 0;
     block_mig_state.reads = 0;
 
-    bdrv_iterate(init_blk_migration_it, mon);
+    bdrv_iterate(init_blk_migration_it, NULL);
 }
 
-static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f)
+static int blk_mig_save_bulked_block(QEMUFile *f)
 {
     int64_t completed_sector_sum = 0;
     BlkMigDevState *bmds;
@@ -330,7 +325,7 @@ static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f)
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
         if (bmds->bulk_completed == 0) {
-            if (mig_save_device_bulk(mon, f, bmds) == 1) {
+            if (mig_save_device_bulk(f, bmds) == 1) {
                 /* completed bulk section for this device */
                 bmds->bulk_completed = 1;
             }
@@ -352,8 +347,7 @@ static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f)
         block_mig_state.prev_progress = progress;
         qemu_put_be64(f, (progress << BDRV_SECTOR_BITS)
                          | BLK_MIG_FLAG_PROGRESS);
-        monitor_printf(mon, "Completed %d %%\r", progress);
-        monitor_flush(mon);
+        DPRINTF("Completed %d %%\r", progress);
     }
 
     return ret;
@@ -368,8 +362,8 @@ static void blk_mig_reset_dirty_cursor(void)
     }
 }
 
-static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
-                                 BlkMigDevState *bmds, int is_async)
+static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
+                                 int is_async)
 {
     BlkMigBlock *blk;
     int64_t total_sectors = bmds->total_sectors;
@@ -428,20 +422,20 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
     return (bmds->cur_dirty >= bmds->total_sectors);
 
 error:
-    monitor_printf(mon, "Error reading sector %" PRId64 "\n", sector);
+    DPRINTF("Error reading sector %" PRId64 "\n", sector);
     qemu_file_set_error(f, ret);
     g_free(blk->buf);
     g_free(blk);
     return 0;
 }
 
-static int blk_mig_save_dirty_block(Monitor *mon, QEMUFile *f, int is_async)
+static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)
 {
     BlkMigDevState *bmds;
     int ret = 0;
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
-        if (mig_save_device_dirty(mon, f, bmds, is_async) == 0) {
+        if (mig_save_device_dirty(f, bmds, is_async) == 0) {
             ret = 1;
             break;
         }
@@ -520,7 +514,7 @@ static int is_stage2_completed(void)
     return 0;
 }
 
-static void blk_mig_cleanup(Monitor *mon)
+static void blk_mig_cleanup(void)
 {
     BlkMigDevState *bmds;
     BlkMigBlock *blk;
@@ -540,11 +534,9 @@ static void blk_mig_cleanup(Monitor *mon)
         g_free(blk->buf);
         g_free(blk);
     }
-
-    monitor_printf(mon, "\n");
 }
 
-static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
+static int block_save_live(QEMUFile *f, int stage, void *opaque)
 {
     int ret;
 
@@ -552,7 +544,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
             stage, block_mig_state.submitted, block_mig_state.transferred);
 
     if (stage < 0) {
-        blk_mig_cleanup(mon);
+        blk_mig_cleanup();
         return 0;
     }
 
@@ -563,7 +555,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
     }
 
     if (stage == 1) {
-        init_blk_migration(mon, f);
+        init_blk_migration(f);
 
         /* start track dirty blocks */
         set_dirty_tracking(1);
@@ -573,7 +565,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
 
     ret = qemu_file_get_error(f);
     if (ret) {
-        blk_mig_cleanup(mon);
+        blk_mig_cleanup();
         return ret;
     }
 
@@ -586,12 +578,12 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
                qemu_file_get_rate_limit(f)) {
             if (block_mig_state.bulk_completed == 0) {
                 /* first finish the bulk phase */
-                if (blk_mig_save_bulked_block(mon, f) == 0) {
+                if (blk_mig_save_bulked_block(f) == 0) {
                     /* finished saving bulk on all devices */
                     block_mig_state.bulk_completed = 1;
                 }
             } else {
-                if (blk_mig_save_dirty_block(mon, f, 1) == 0) {
+                if (blk_mig_save_dirty_block(f, 1) == 0) {
                     /* no more dirty blocks */
                     break;
                 }
@@ -602,7 +594,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
 
         ret = qemu_file_get_error(f);
         if (ret) {
-            blk_mig_cleanup(mon);
+            blk_mig_cleanup();
             return ret;
         }
     }
@@ -612,8 +604,8 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
            all async read completed */
         assert(block_mig_state.submitted == 0);
 
-        while (blk_mig_save_dirty_block(mon, f, 0) != 0);
-        blk_mig_cleanup(mon);
+        while (blk_mig_save_dirty_block(f, 0) != 0);
+        blk_mig_cleanup();
 
         /* report completion */
         qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS);
@@ -623,7 +615,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
             return ret;
         }
 
-        monitor_printf(mon, "Block migration completed\n");
+        DPRINTF("Block migration completed\n");
     }
 
     qemu_put_be64(f, BLK_MIG_FLAG_EOS);
diff --git a/configure b/configure
index 8b4e3c1a02..671b232506 100755
--- a/configure
+++ b/configure
@@ -519,7 +519,7 @@ EOF
   if compile_prog "" "-liberty" ; then
     LIBS="-liberty $LIBS"
   fi
-  prefix="c:/Program Files/Qemu"
+  prefix="c:/Program Files/QEMU"
   mandir="\${prefix}"
   datadir="\${prefix}"
   docdir="\${prefix}"
@@ -1993,13 +1993,21 @@ fi
 
 ##########################################
 # glib support probe
-if $pkg_config --modversion gthread-2.0 > /dev/null 2>&1 ; then
+
+if test "$mingw32" = yes; then
+    # g_poll is required in order to integrate with the glib main loop.
+    glib_req_ver=2.20
+else
+    glib_req_ver=2.12
+fi
+if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1
+then
     glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
     glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
     LIBS="$glib_libs $LIBS"
     libs_qga="$glib_libs $libs_qga"
 else
-    echo "glib-2.0 required to compile QEMU"
+    echo "glib-$glib_req_ver required to compile QEMU"
     exit 1
 fi
 
@@ -2821,6 +2829,13 @@ if test "$solaris" = "no" ; then
     fi
 fi
 
+# test if pod2man has --utf8 option
+if pod2man --help | grep -q utf8; then
+    POD2MAN="pod2man --utf8"
+else
+    POD2MAN="pod2man"
+fi
+
 # Use ASLR, no-SEH and DEP if available
 if test "$mingw32" = "yes" ; then
     for flag in --dynamicbase --no-seh --nxcompat; do
@@ -3052,12 +3067,12 @@ if test "$cap_ng" = "yes" ; then
   echo "CONFIG_LIBCAP=y" >> $config_host_mak
 fi
 for card in $audio_card_list; do
-    def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'`
+    def=CONFIG_`echo $card | LC_ALL=C tr '[a-z]' '[A-Z]'`
     echo "$def=y" >> $config_host_mak
 done
 echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak
 for drv in $audio_drv_list; do
-    def=CONFIG_`echo $drv | tr '[:lower:]' '[:upper:]'`
+    def=CONFIG_`echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]'`
     echo "$def=y" >> $config_host_mak
     if test "$drv" = "fmod"; then
         echo "FMOD_CFLAGS=-I$fmod_inc" >> $config_host_mak
@@ -3358,6 +3373,7 @@ echo "LIBS+=$LIBS" >> $config_host_mak
 echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak
 echo "EXESUF=$EXESUF" >> $config_host_mak
 echo "LIBS_QGA+=$libs_qga" >> $config_host_mak
+echo "POD2MAN=$POD2MAN" >> $config_host_mak
 
 # generate list of library paths for linker script
 
@@ -3608,7 +3624,7 @@ case "$target_arch2" in
 esac
 
 case "$target_arch2" in
-  sparc*)
+  alpha | sparc*)
     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
   ;;
 esac
@@ -3618,7 +3634,7 @@ echo "TARGET_INT_ALIGNMENT=$target_int_alignment" >> $config_target_mak
 echo "TARGET_LONG_ALIGNMENT=$target_long_alignment" >> $config_target_mak
 echo "TARGET_LLONG_ALIGNMENT=$target_llong_alignment" >> $config_target_mak
 echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak
-target_arch_name="`echo $TARGET_ARCH | tr '[:lower:]' '[:upper:]'`"
+target_arch_name="`echo $TARGET_ARCH | LC_ALL=C tr '[a-z]' '[A-Z]'`"
 echo "TARGET_$target_arch_name=y" >> $config_target_mak
 echo "TARGET_ARCH2=$target_arch2" >> $config_target_mak
 # TARGET_BASE_ARCH needs to be defined after TARGET_ARCH
@@ -3762,6 +3778,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
     echo "CONFIG_IA64_DIS=y"  >> $config_target_mak
     echo "CONFIG_IA64_DIS=y"  >> $libdis_config_mak
   ;;
+  lm32)
+    echo "CONFIG_LM32_DIS=y"  >> $config_target_mak
+    echo "CONFIG_LM32_DIS=y"  >> $libdis_config_mak
+  ;;
   m68k)
     echo "CONFIG_M68K_DIS=y"  >> $config_target_mak
     echo "CONFIG_M68K_DIS=y"  >> $libdis_config_mak
@@ -3868,7 +3888,8 @@ echo "QEMU_INCLUDES+=$includes" >> $config_target_mak
 done # for target in $targets
 
 # build tree in object directory in case the source is not in the current directory
-DIRS="tests tests/tcg tests/tcg/cris slirp audio block net pc-bios/optionrom"
+DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32"
+DIRS="$DIRS slirp audio block net pc-bios/optionrom"
 DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS fsdev ui usb"
@@ -3876,6 +3897,7 @@ DIRS="$DIRS qapi qapi-generated"
 DIRS="$DIRS qga trace qom"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
+FILES="$FILES tests/tcg/lm32/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
diff --git a/cpu-all.h b/cpu-all.h
index 9621c3c92e..4512518065 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -204,7 +204,8 @@ extern unsigned long reserved_va;
 #else
 #define h2g_valid(x) ({ \
     unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
-    __guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS); \
+    (__guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) && \
+    (!RESERVED_VA || (__guest < RESERVED_VA)); \
 })
 #endif
 
diff --git a/cpu-exec.c b/cpu-exec.c
index 0fa8325b27..d153f978e1 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -21,6 +21,7 @@
 #include "disas.h"
 #include "tcg.h"
 #include "qemu-barrier.h"
+#include "qtest.h"
 
 int tb_invalidated_flag;
 
diff --git a/cpus.c b/cpus.c
index 25ba621da5..eb22bd5df1 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,6 +34,7 @@
 
 #include "qemu-thread.h"
 #include "cpus.h"
+#include "qtest.h"
 #include "main-loop.h"
 
 #ifndef _WIN32
@@ -238,6 +239,20 @@ static void icount_warp_rt(void *opaque)
     vm_clock_warp_start = -1;
 }
 
+void qtest_clock_warp(int64_t dest)
+{
+    int64_t clock = qemu_get_clock_ns(vm_clock);
+    assert(qtest_enabled());
+    while (clock < dest) {
+        int64_t deadline = qemu_clock_deadline(vm_clock);
+        int64_t warp = MIN(dest - clock, deadline);
+        qemu_icount_bias += warp;
+        qemu_run_timers(vm_clock);
+        clock = qemu_get_clock_ns(vm_clock);
+    }
+    qemu_notify_event();
+}
+
 void qemu_clock_warp(QEMUClock *clock)
 {
     int64_t deadline;
@@ -264,6 +279,11 @@ void qemu_clock_warp(QEMUClock *clock)
         return;
     }
 
+    if (qtest_enabled()) {
+        /* When testing, qtest commands advance icount.  */
+	return;
+    }
+
     vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
     deadline = qemu_clock_deadline(vm_clock);
     if (deadline > 0) {
@@ -741,6 +761,48 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     return NULL;
 }
 
+static void *qemu_dummy_cpu_thread_fn(void *arg)
+{
+#ifdef _WIN32
+    fprintf(stderr, "qtest is not supported under Windows\n");
+    exit(1);
+#else
+    CPUArchState *env = arg;
+    sigset_t waitset;
+    int r;
+
+    qemu_mutex_lock_iothread();
+    qemu_thread_get_self(env->thread);
+    env->thread_id = qemu_get_thread_id();
+
+    sigemptyset(&waitset);
+    sigaddset(&waitset, SIG_IPI);
+
+    /* signal CPU creation */
+    env->created = 1;
+    qemu_cond_signal(&qemu_cpu_cond);
+
+    cpu_single_env = env;
+    while (1) {
+        cpu_single_env = NULL;
+        qemu_mutex_unlock_iothread();
+        do {
+            int sig;
+            r = sigwait(&waitset, &sig);
+        } while (r == -1 && (errno == EAGAIN || errno == EINTR));
+        if (r == -1) {
+            perror("sigwait");
+            exit(1);
+        }
+        qemu_mutex_lock_iothread();
+        cpu_single_env = env;
+        qemu_wait_io_event_common(env);
+    }
+
+    return NULL;
+#endif
+}
+
 static void tcg_exec_all(void);
 
 static void *qemu_tcg_cpu_thread_fn(void *arg)
@@ -803,7 +865,7 @@ void qemu_cpu_kick(void *_env)
     CPUArchState *env = _env;
 
     qemu_cond_broadcast(env->halt_cond);
-    if (kvm_enabled() && !env->thread_kicked) {
+    if (!tcg_enabled() && !env->thread_kicked) {
         qemu_cpu_kick_thread(env);
         env->thread_kicked = true;
     }
@@ -832,7 +894,7 @@ int qemu_cpu_is_self(void *_env)
 
 void qemu_mutex_lock_iothread(void)
 {
-    if (kvm_enabled()) {
+    if (!tcg_enabled()) {
         qemu_mutex_lock(&qemu_global_mutex);
     } else {
         iothread_requesting_mutex = true;
@@ -947,6 +1009,18 @@ static void qemu_kvm_start_vcpu(CPUArchState *env)
     }
 }
 
+static void qemu_dummy_start_vcpu(CPUArchState *env)
+{
+    env->thread = g_malloc0(sizeof(QemuThread));
+    env->halt_cond = g_malloc0(sizeof(QemuCond));
+    qemu_cond_init(env->halt_cond);
+    qemu_thread_create(env->thread, qemu_dummy_cpu_thread_fn, env,
+                       QEMU_THREAD_JOINABLE);
+    while (env->created == 0) {
+        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
+    }
+}
+
 void qemu_init_vcpu(void *_env)
 {
     CPUArchState *env = _env;
@@ -956,8 +1030,10 @@ void qemu_init_vcpu(void *_env)
     env->stopped = 1;
     if (kvm_enabled()) {
         qemu_kvm_start_vcpu(env);
-    } else {
+    } else if (tcg_enabled()) {
         qemu_tcg_init_vcpu(env);
+    } else {
+        qemu_dummy_start_vcpu(env);
     }
 }
 
diff --git a/cpus.h b/cpus.h
index 4ea2fe2c22..81bd81773f 100644
--- a/cpus.h
+++ b/cpus.h
@@ -11,6 +11,8 @@ void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
 void cpu_synchronize_all_post_init(void);
 
+void qtest_clock_warp(int64_t dest);
+
 /* vl.c */
 extern int smp_cores;
 extern int smp_threads;
diff --git a/def-helper.h b/def-helper.h
index 0e70c31bc4..b98ff69e4e 100644
--- a/def-helper.h
+++ b/def-helper.h
@@ -39,6 +39,7 @@
 #endif
 #define dh_alias_ptr ptr
 #define dh_alias_void void
+#define dh_alias_noreturn noreturn
 #define dh_alias_env ptr
 #define dh_alias(t) glue(dh_alias_, t)
 
@@ -52,36 +53,42 @@
 #define dh_ctype_tl target_ulong
 #define dh_ctype_ptr void *
 #define dh_ctype_void void
+#define dh_ctype_noreturn void QEMU_NORETURN
 #define dh_ctype_env CPUArchState *
 #define dh_ctype(t) dh_ctype_##t
 
 /* We can't use glue() here because it falls foul of C preprocessor
    recursive expansion rules.  */
 #define dh_retvar_decl0_void void
+#define dh_retvar_decl0_noreturn void
 #define dh_retvar_decl0_i32 TCGv_i32 retval
 #define dh_retvar_decl0_i64 TCGv_i64 retval
 #define dh_retvar_decl0_ptr TCGv_ptr retval
 #define dh_retvar_decl0(t) glue(dh_retvar_decl0_, dh_alias(t))
 
 #define dh_retvar_decl_void
+#define dh_retvar_decl_noreturn
 #define dh_retvar_decl_i32 TCGv_i32 retval,
 #define dh_retvar_decl_i64 TCGv_i64 retval,
 #define dh_retvar_decl_ptr TCGv_ptr retval,
 #define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t))
 
 #define dh_retvar_void TCG_CALL_DUMMY_ARG
+#define dh_retvar_noreturn TCG_CALL_DUMMY_ARG
 #define dh_retvar_i32 GET_TCGV_i32(retval)
 #define dh_retvar_i64 GET_TCGV_i64(retval)
 #define dh_retvar_ptr GET_TCGV_ptr(retval)
 #define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
 
 #define dh_is_64bit_void 0
+#define dh_is_64bit_noreturn 0
 #define dh_is_64bit_i32 0
 #define dh_is_64bit_i64 1
 #define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
 #define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
 
 #define dh_is_signed_void 0
+#define dh_is_signed_noreturn 0
 #define dh_is_signed_i32 0
 #define dh_is_signed_s32 1
 #define dh_is_signed_i64 0
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index 21e4ccfb00..9d3e1dbda1 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -1,6 +1,5 @@
 CONFIG_PCI=y
 CONFIG_VIRTIO_PCI=y
-CONFIG_VIRTIO_SCSI=y
 CONFIG_VIRTIO=y
 CONFIG_USB_UHCI=y
 CONFIG_USB_OHCI=y
diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
index e5888037cf..3005729204 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,2 +1 @@
 CONFIG_VIRTIO=y
-CONFIG_VIRTIO_SCSI=y
diff --git a/dis-asm.h b/dis-asm.h
index 4f15fad4fa..3944b3cf7e 100644
--- a/dis-asm.h
+++ b/dis-asm.h
@@ -221,6 +221,8 @@ enum bfd_architecture
   bfd_arch_ia64,      /* HP/Intel ia64 */
 #define bfd_mach_ia64_elf64    64
 #define bfd_mach_ia64_elf32    32
+  bfd_arch_lm32,       /* Lattice Mico32 */
+#define bfd_mach_lm32 1
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -404,6 +406,7 @@ int print_insn_crisv32          (bfd_vma, disassemble_info*);
 int print_insn_crisv10          (bfd_vma, disassemble_info*);
 int print_insn_microblaze       (bfd_vma, disassemble_info*);
 int print_insn_ia64             (bfd_vma, disassemble_info*);
+int print_insn_lm32             (bfd_vma, disassemble_info*);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/disas.c b/disas.c
index 4945c44b9f..4f2c4e4cb9 100644
--- a/disas.c
+++ b/disas.c
@@ -138,7 +138,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
 /* Disassemble this for me please... (debugging). 'flags' has the following
    values:
     i386 - 1 means 16 bit code, 2 means 64 bit code
-    arm  - nonzero means thumb code
+    arm  - bit 0 = thumb, bit 1 = reverse endian
     ppc  - nonzero means little endian
     other targets - unused
  */
@@ -169,10 +169,18 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
         disasm_info.mach = bfd_mach_i386_i386;
     print_insn = print_insn_i386;
 #elif defined(TARGET_ARM)
-    if (flags)
-	print_insn = print_insn_thumb1;
-    else
-	print_insn = print_insn_arm;
+    if (flags & 1) {
+        print_insn = print_insn_thumb1;
+    } else {
+        print_insn = print_insn_arm;
+    }
+    if (flags & 2) {
+#ifdef TARGET_WORDS_BIGENDIAN
+        disasm_info.endian = BFD_ENDIAN_LITTLE;
+#else
+        disasm_info.endian = BFD_ENDIAN_BIG;
+#endif
+    }
 #elif defined(TARGET_SPARC)
     print_insn = print_insn_sparc;
 #ifdef TARGET_SPARC64
@@ -220,6 +228,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
 #elif defined(TARGET_MICROBLAZE)
     disasm_info.mach = bfd_arch_microblaze;
     print_insn = print_insn_microblaze;
+#elif defined(TARGET_LM32)
+    disasm_info.mach = bfd_mach_lm32;
+    print_insn = print_insn_lm32;
 #else
     fprintf(out, "0x" TARGET_FMT_lx
 	    ": Asm output not supported on this arch\n", code);
@@ -421,6 +432,9 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
 #elif defined(TARGET_S390X)
     disasm_info.mach = bfd_mach_s390_64;
     print_insn = print_insn_s390;
+#elif defined(TARGET_LM32)
+    disasm_info.mach = bfd_mach_lm32;
+    print_insn = print_insn_lm32;
 #else
     monitor_printf(mon, "0x" TARGET_FMT_lx
                    ": Asm output not supported on this arch\n", pc);
diff --git a/dma.h b/dma.h
index 20e86d28ee..5bd1fc836f 100644
--- a/dma.h
+++ b/dma.h
@@ -11,7 +11,6 @@
 #define DMA_H
 
 #include <stdio.h>
-//#include "cpu.h"
 #include "hw/hw.h"
 #include "block.h"
 
diff --git a/docs/ccid.txt b/docs/ccid.txt
index b8e504a3cc..450a66ad99 100644
--- a/docs/ccid.txt
+++ b/docs/ccid.txt
@@ -1,4 +1,4 @@
-Qemu CCID Device Documentation.
+QEMU CCID Device Documentation.
 
 Contents
 1. USB CCID device
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 5831e371ea..ad11767a2f 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -194,11 +194,11 @@ Example:
 
     void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp)
     {
-        GenericList *i;
+        GenericList *i, **prev = (GenericList **)obj;
 
         visit_start_list(m, name, errp);
 
-        for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, &i, errp)) {
+        for (; (i = visit_next_list(m, prev, errp)) != NULL; prev = &i) {
             UserDefOneList *native_i = (UserDefOneList *)i;
             visit_type_UserDefOne(m, &native_i->value, NULL, errp);
         }
diff --git a/docs/specs/ivshmem_device_spec.txt b/docs/specs/ivshmem_device_spec.txt
index 23dd2ba89f..667a8628f0 100644
--- a/docs/specs/ivshmem_device_spec.txt
+++ b/docs/specs/ivshmem_device_spec.txt
@@ -24,7 +24,7 @@ The device currently supports 4 registers of 32-bits each.  Registers
 are used for synchronization between guests sharing the same memory object when
 interrupts are supported (this requires using the shared memory server).
 
-The server assigns each VM an ID number and sends this ID number to the Qemu
+The server assigns each VM an ID number and sends this ID number to the QEMU
 process when the guest starts.
 
 enum ivshmem_registers {
diff --git a/docs/xen-save-devices-state.txt b/docs/xen-save-devices-state.txt
new file mode 100644
index 0000000000..92e08dbf6a
--- /dev/null
+++ b/docs/xen-save-devices-state.txt
@@ -0,0 +1,34 @@
+= Save Devices =
+
+QEMU has code to load/save the state of the guest that it is running.
+These are two complementary operations.  Saving the state just does
+that, saves the state for each device that the guest is running.
+
+These operations are normally used with migration (see migration.txt),
+however it is also possible to save the state of all devices to file,
+without saving the RAM or the block devices of the VM.
+
+This operation is called "xen-save-devices-state" (see
+QMP/qmp-commands.txt)
+
+
+The binary format used in the file is the following:
+
+
+-------------------------------------------
+
+32 bit big endian: QEMU_VM_FILE_MAGIC
+32 bit big endian: QEMU_VM_FILE_VERSION
+
+for_each_device
+{
+    8 bit:              QEMU_VM_SECTION_FULL
+    32 bit big endian:  section_id
+    8 bit:              idstr (ID string) length
+    string:             idstr (ID string)
+    32 bit big endian:  instance_id
+    32 bit big endian:  version_id
+    buffer:             device specific data
+}
+
+8 bit: QEMU_VM_EOF
diff --git a/elf.h b/elf.h
index 2e05d34620..e1422b81ee 100644
--- a/elf.h
+++ b/elf.h
@@ -216,6 +216,7 @@ typedef int64_t  Elf64_Sxword;
 
 #define ELF_ST_BIND(x)		((x) >> 4)
 #define ELF_ST_TYPE(x)		(((unsigned int) x) & 0xf)
+#define ELF_ST_INFO(bind, type) (((bind) << 4) | ((type) & 0xf))
 #define ELF32_ST_BIND(x)	ELF_ST_BIND(x)
 #define ELF32_ST_TYPE(x)	ELF_ST_TYPE(x)
 #define ELF64_ST_BIND(x)	ELF_ST_BIND(x)
@@ -345,6 +346,21 @@ typedef struct {
 #define R_MIPS_HIVENDOR		127
 
 
+/* SUN SPARC specific definitions.  */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM           3
+#define EF_SPARCV9_TSO          0
+#define EF_SPARCV9_PSO          1
+#define EF_SPARCV9_RMO          2
+#define EF_SPARC_LEDATA         0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK       0xFFFF00
+#define EF_SPARC_32PLUS         0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1        0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1         0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3        0x000800 /* Sun UltraSPARCIII extensions */
+
 /*
  * Sparc ELF relocation types
  */
@@ -522,6 +538,27 @@ typedef struct {
 #define EF_ALIGN8          0x40		/* 8-bit structure alignment is in use */
 #define EF_NEW_ABI         0x80
 #define EF_OLD_ABI         0x100
+#define EF_ARM_SOFT_FLOAT  0x200
+#define EF_ARM_VFP_FLOAT   0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+#define EF_ARM_SYMSARESORTED 0x04       /* NB conflicts with EF_INTERWORK */
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08    /* NB conflicts with EF_APCS26 */
+#define EF_ARM_MAPSYMSFIRST 0x10        /* NB conflicts with EF_APCS_FLOAT */
+#define EF_ARM_EABIMASK      0xFF000000
+
+/* Constants defined in AAELF.  */
+#define EF_ARM_BE8          0x00800000
+#define EF_ARM_LE8          0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN  0x00000000
+#define EF_ARM_EABI_VER1     0x01000000
+#define EF_ARM_EABI_VER2     0x02000000
+#define EF_ARM_EABI_VER3     0x03000000
+#define EF_ARM_EABI_VER4     0x04000000
+#define EF_ARM_EABI_VER5     0x05000000
 
 /* Additional symbol types for Thumb */
 #define STT_ARM_TFUNC      0xd
diff --git a/error.c b/error.c
index 990050f792..d3455ab9e6 100644
--- a/error.c
+++ b/error.c
@@ -43,6 +43,19 @@ void error_set(Error **errp, const char *fmt, ...)
     *errp = err;
 }
 
+Error *error_copy(const Error *err)
+{
+    Error *err_new;
+
+    err_new = g_malloc0(sizeof(*err));
+    err_new->msg = g_strdup(err->msg);
+    err_new->fmt = err->fmt;
+    err_new->obj = err->obj;
+    QINCREF(err_new->obj);
+
+    return err_new;
+}
+
 bool error_is_set(Error **errp)
 {
     return (errp && *errp);
diff --git a/error.h b/error.h
index 6361f407fd..45ff6c1ffe 100644
--- a/error.h
+++ b/error.h
@@ -35,6 +35,11 @@ void error_set(Error **err, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
 bool error_is_set(Error **err);
 
 /**
+ * Returns an exact copy of the error passed as an argument.
+ */
+Error *error_copy(const Error *err);
+
+/**
  * Get a human readable representation of an error object.
  */
 const char *error_get_pretty(Error *err);
diff --git a/exec-all.h b/exec-all.h
index 93a5b22c1c..fa7bdfecd8 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -85,15 +85,15 @@ void cpu_gen_init(void);
 int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
                  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
-                      CPUArchState *env, unsigned long searched_pc);
-void cpu_resume_from_signal(CPUArchState *env1, void *puc);
-void cpu_io_recompile(CPUArchState *env, void *retaddr);
+                      CPUArchState *env, uintptr_t searched_pc);
+void QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc);
+void QEMU_NORETURN cpu_io_recompile(CPUArchState *env, void *retaddr);
 TranslationBlock *tb_gen_code(CPUArchState *env, 
                               target_ulong pc, target_ulong cs_base, int flags,
                               int cflags);
 void cpu_exec_init(CPUArchState *env);
 void QEMU_NORETURN cpu_loop_exit(CPUArchState *env1);
-int page_unprotect(target_ulong address, unsigned long pc, void *puc);
+int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access);
 void tlb_flush_page(CPUArchState *env, target_ulong addr);
@@ -150,7 +150,7 @@ struct TranslationBlock {
 #ifdef USE_DIRECT_JUMP
     uint16_t tb_jmp_offset[2]; /* offset of jump instruction */
 #else
-    unsigned long tb_next[2]; /* address of jump generated code */
+    uintptr_t tb_next[2]; /* address of jump generated code */
 #endif
     /* list of TBs jumping to this one. This is a circular list using
        the two least significant bits of the pointers to tell what is
@@ -202,14 +202,14 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
 #define tb_set_jmp_target1 ppc_tb_set_jmp_target
 #elif defined(__i386__) || defined(__x86_64__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
+static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
     /* patch the branch destination */
     *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
     /* no need to flush icache explicitly */
 }
 #elif defined(__arm__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
+static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
 #if !QEMU_GNUC_PREREQ(4, 1)
     register unsigned long _beg __asm ("a1");
@@ -237,19 +237,17 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr
 #endif
 
 static inline void tb_set_jmp_target(TranslationBlock *tb,
-                                     int n, unsigned long addr)
+                                     int n, uintptr_t addr)
 {
-    unsigned long offset;
-
-    offset = tb->tb_jmp_offset[n];
-    tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
+    uint16_t offset = tb->tb_jmp_offset[n];
+    tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr);
 }
 
 #else
 
 /* set the jump target */
 static inline void tb_set_jmp_target(TranslationBlock *tb,
-                                     int n, unsigned long addr)
+                                     int n, uintptr_t addr)
 {
     tb->tb_next[n] = addr;
 }
@@ -262,15 +260,15 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
     /* NOTE: this test is only needed for thread safety */
     if (!tb->jmp_next[n]) {
         /* patch the native jump address */
-        tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
+        tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);
 
         /* add in TB jmp circular list */
         tb->jmp_next[n] = tb_next->jmp_first;
-        tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
+        tb_next->jmp_first = (TranslationBlock *)((uintptr_t)(tb) | (n));
     }
 }
 
-TranslationBlock *tb_find_pc(unsigned long pc_ptr);
+TranslationBlock *tb_find_pc(uintptr_t pc_ptr);
 
 #include "qemu-lock.h"
 
@@ -288,13 +286,14 @@ extern void *tci_tb_ptr;
 #  define GETPC() tci_tb_ptr
 # endif
 #elif defined(__s390__) && !defined(__s390x__)
-# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1))
+# define GETPC() \
+    ((void *)(((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1))
 #elif defined(__arm__)
 /* Thumb return addresses have the low bit set, so we need to subtract two.
    This is still safe in ARM mode because instructions are 4 bytes.  */
-# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2))
+# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 2))
 #else
-# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1))
+# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 1))
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/exec.c b/exec.c
index be392e2764..03d3a6b609 100644
--- a/exec.c
+++ b/exec.c
@@ -636,6 +636,7 @@ void tcg_exec_init(unsigned long tb_size)
     cpu_gen_init();
     code_gen_alloc(tb_size);
     code_gen_ptr = code_gen_buffer;
+    tcg_register_jit(code_gen_buffer, code_gen_buffer_size);
     page_init();
 #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
     /* There's no guest base to take into account, so go ahead and
@@ -1379,7 +1380,7 @@ void tb_link_page(TranslationBlock *tb,
 
 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
    tb[1].tc_ptr. Return NULL if not found */
-TranslationBlock *tb_find_pc(unsigned long tc_ptr)
+TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
 {
     int m_min, m_max, m;
     unsigned long v;
@@ -2031,14 +2032,19 @@ static void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
     cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG);
 }
 
+static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe)
+{
+    return (tlbe->addr_write & (TLB_INVALID_MASK|TLB_MMIO|TLB_NOTDIRTY)) == 0;
+}
+
 static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
                                          unsigned long start, unsigned long length)
 {
     unsigned long addr;
-    if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr) {
+    if (tlb_is_dirty_ram(tlb_entry)) {
         addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
         if ((addr - start) < length) {
-            tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY;
+            tlb_entry->addr_write |= TLB_NOTDIRTY;
         }
     }
 }
@@ -2091,7 +2097,7 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
     ram_addr_t ram_addr;
     void *p;
 
-    if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr) {
+    if (tlb_is_dirty_ram(tlb_entry)) {
         p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
             + tlb_entry->addend);
         ram_addr = qemu_ram_addr_from_host_nofail(p);
@@ -2496,7 +2502,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
 
 /* called from signal handler: invalidate the code and unprotect the
    page. Return TRUE if the fault was successfully handled. */
-int page_unprotect(target_ulong address, unsigned long pc, void *puc)
+int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
 {
     unsigned int prot;
     PageDesc *p;
@@ -3851,8 +3857,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                 }
             } else {
                 /* RAM case */
-                ptr = qemu_get_ram_ptr(section->mr->ram_addr)
-                    + section_addr(section, addr);
+                ptr = qemu_get_ram_ptr(section->mr->ram_addr
+                                       + section_addr(section, addr));
                 memcpy(buf, ptr, l);
                 qemu_put_ram_ptr(ptr);
             }
@@ -4478,7 +4484,7 @@ void cpu_io_recompile(CPUArchState *env, void *retaddr)
     target_ulong pc, cs_base;
     uint64_t flags;
 
-    tb = tb_find_pc((unsigned long)retaddr);
+    tb = tb_find_pc((uintptr_t)retaddr);
     if (!tb) {
         cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p", 
                   retaddr);
@@ -4604,7 +4610,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
     pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
     mr = iotlb_to_region(pd);
     if (mr != &io_mem_ram && mr != &io_mem_rom
-        && mr != &io_mem_notdirty && !mr->rom_device) {
+        && mr != &io_mem_notdirty && !mr->rom_device
+        && mr != &io_mem_watch) {
 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
         cpu_unassigned_access(env1, addr, 0, 1, 0, 4);
 #else
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 81a7d1ae09..d37090ac53 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -117,7 +117,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
     int8 roundingMode;
     flag roundNearestEven;
     int8 roundIncrement, roundBits;
-    int32 z;
+    int32_t z;
 
     roundingMode = STATUS(float_rounding_mode);
     roundNearestEven = ( roundingMode == float_round_nearest_even );
@@ -166,7 +166,7 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU
 {
     int8 roundingMode;
     flag roundNearestEven, increment;
-    int64 z;
+    int64_t z;
 
     roundingMode = STATUS(float_rounding_mode);
     roundNearestEven = ( roundingMode == float_round_nearest_even );
@@ -1378,7 +1378,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
     flag aSign;
     int16 aExp, shiftCount;
     uint32_t aSig;
-    int32 z;
+    int32_t z;
     a = float32_squash_input_denormal(a STATUS_VAR);
 
     aSig = extractFloat32Frac( a );
@@ -2762,7 +2762,7 @@ int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
     flag aSign;
     int16 aExp, shiftCount;
     uint64_t aSig, savedASig;
-    int32 z;
+    int32_t z;
     a = float64_squash_input_denormal(a STATUS_VAR);
 
     aSig = extractFloat64Frac( a );
@@ -4248,7 +4248,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
     flag aSign;
     int32 aExp, shiftCount;
     uint64_t aSig, savedASig;
-    int32 z;
+    int32_t z;
 
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
@@ -5277,7 +5277,7 @@ int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
     flag aSign;
     int32 aExp, shiftCount;
     uint64_t aSig0, aSig1, savedASig;
-    int32 z;
+    int32_t z;
 
     aSig1 = extractFloat128Frac1( a );
     aSig0 = extractFloat128Frac0( a );
diff --git a/fsdev/virtfs-proxy-helper.texi b/fsdev/virtfs-proxy-helper.texi
index faa0434480..e60e3b9465 100644
--- a/fsdev/virtfs-proxy-helper.texi
+++ b/fsdev/virtfs-proxy-helper.texi
@@ -24,7 +24,7 @@ in non-root mode, but doing privileged operations using socket IO.
 Proxy helper(a stand alone binary part of qemu) is invoked with
 root privileges. Proxy helper chroots into 9p export path and creates
 a socket pair or a named socket based on the command line parameter.
-Qemu and proxy helper communicate using this socket. QEMU proxy fs
+QEMU and proxy helper communicate using this socket. QEMU proxy fs
 driver sends filesystem request to proxy helper and receives the
 response from it.
 
diff --git a/gdbstub.c b/gdbstub.c
index f4e97f7370..6a7e2c4934 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -284,7 +284,6 @@ enum RSState {
     RS_GETLINE,
     RS_CHKSUM1,
     RS_CHKSUM2,
-    RS_SYSCALL,
 };
 typedef struct GDBState {
     CPUArchState *c_cpu; /* current CPU for step/continue ops */
@@ -304,6 +303,8 @@ typedef struct GDBState {
     CharDriverState *chr;
     CharDriverState *mon_chr;
 #endif
+    char syscall_buf[256];
+    gdb_syscall_complete_cb current_syscall_cb;
 } GDBState;
 
 /* By default use no IRQs and no timers while single stepping so as to
@@ -346,8 +347,6 @@ static int get_char(GDBState *s)
 }
 #endif
 
-static gdb_syscall_complete_cb gdb_current_syscall_cb;
-
 static enum {
     GDB_SYS_UNKNOWN,
     GDB_SYS_ENABLED,
@@ -2097,8 +2096,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             if (*p == ',')
                 p++;
             type = *p;
-            if (gdb_current_syscall_cb)
-                gdb_current_syscall_cb(s->c_cpu, ret, err);
+            if (s->current_syscall_cb) {
+                s->current_syscall_cb(s->c_cpu, ret, err);
+                s->current_syscall_cb = NULL;
+            }
             if (type == 'C') {
                 put_packet(s, "T02");
             } else {
@@ -2398,7 +2399,12 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
     const char *type;
     int ret;
 
-    if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
+    if (running || s->state == RS_INACTIVE) {
+        return;
+    }
+    /* Is there a GDB syscall waiting to be sent?  */
+    if (s->current_syscall_cb) {
+        put_packet(s, s->syscall_buf);
         return;
     }
     switch (state) {
@@ -2468,8 +2474,8 @@ send_packet:
 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
 {
     va_list va;
-    char buf[256];
     char *p;
+    char *p_end;
     target_ulong addr;
     uint64_t i64;
     GDBState *s;
@@ -2477,14 +2483,13 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
     s = gdbserver_state;
     if (!s)
         return;
-    gdb_current_syscall_cb = cb;
-    s->state = RS_SYSCALL;
+    s->current_syscall_cb = cb;
 #ifndef CONFIG_USER_ONLY
     vm_stop(RUN_STATE_DEBUG);
 #endif
-    s->state = RS_IDLE;
     va_start(va, fmt);
-    p = buf;
+    p = s->syscall_buf;
+    p_end = &s->syscall_buf[sizeof(s->syscall_buf)];
     *(p++) = 'F';
     while (*fmt) {
         if (*fmt == '%') {
@@ -2492,17 +2497,17 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
             switch (*fmt++) {
             case 'x':
                 addr = va_arg(va, target_ulong);
-                p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx, addr);
+                p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
                 break;
             case 'l':
                 if (*(fmt++) != 'x')
                     goto bad_format;
                 i64 = va_arg(va, uint64_t);
-                p += snprintf(p, &buf[sizeof(buf)] - p, "%" PRIx64, i64);
+                p += snprintf(p, p_end - p, "%" PRIx64, i64);
                 break;
             case 's':
                 addr = va_arg(va, target_ulong);
-                p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx "/%x",
+                p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
                               addr, va_arg(va, int));
                 break;
             default:
@@ -2517,10 +2522,16 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
     }
     *p = 0;
     va_end(va);
-    put_packet(s, buf);
 #ifdef CONFIG_USER_ONLY
+    put_packet(s, s->syscall_buf);
     gdb_handlesig(s->c_cpu, 0);
 #else
+    /* In this case wait to send the syscall packet until notification that
+       the CPU has stopped.  This must be done because if the packet is sent
+       now the reply from the syscall request could be received while the CPU
+       is still in the running state, which can cause packets to be dropped
+       and state transition 'T' packets to be sent while the syscall is still
+       being processed.  */
     cpu_exit(s->c_cpu);
 #endif
 }
@@ -2919,6 +2930,7 @@ int gdbserver_start(const char *device)
     s->chr = chr;
     s->state = chr ? RS_IDLE : RS_INACTIVE;
     s->mon_chr = mon_chr;
+    s->current_syscall_cb = NULL;
 
     return 0;
 }
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 6980214a1a..bd35a3eb08 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -806,8 +806,7 @@ ETEXI
 		      " full copy of disk\n\t\t\t -i for migration without "
 		      "shared storage with incremental copy of disk "
 		      "(base image shared between src and destination)",
-        .user_print = monitor_user_noop,	
-	.mhandler.cmd_new = do_migrate,
+        .mhandler.cmd = hmp_migrate,
     },
 
 
diff --git a/hmp.c b/hmp.c
index 290c43d03a..9cf2d1345b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -14,6 +14,7 @@
  */
 
 #include "hmp.h"
+#include "qemu-timer.h"
 #include "qmp-commands.h"
 
 static void hmp_handle_error(Monitor *mon, Error **errp)
@@ -860,3 +861,76 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
 
     hmp_handle_error(mon, &error);
 }
+
+typedef struct MigrationStatus
+{
+    QEMUTimer *timer;
+    Monitor *mon;
+    bool is_block_migration;
+} MigrationStatus;
+
+static void hmp_migrate_status_cb(void *opaque)
+{
+    MigrationStatus *status = opaque;
+    MigrationInfo *info;
+
+    info = qmp_query_migrate(NULL);
+    if (!info->has_status || strcmp(info->status, "active") == 0) {
+        if (info->has_disk) {
+            int progress;
+
+            if (info->disk->remaining) {
+                progress = info->disk->transferred * 100 / info->disk->total;
+            } else {
+                progress = 100;
+            }
+
+            monitor_printf(status->mon, "Completed %d %%\r", progress);
+            monitor_flush(status->mon);
+        }
+
+        qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock) + 1000);
+    } else {
+        if (status->is_block_migration) {
+            monitor_printf(status->mon, "\n");
+        }
+        monitor_resume(status->mon);
+        qemu_del_timer(status->timer);
+        g_free(status);
+    }
+
+    qapi_free_MigrationInfo(info);
+}
+
+void hmp_migrate(Monitor *mon, const QDict *qdict)
+{
+    int detach = qdict_get_try_bool(qdict, "detach", 0);
+    int blk = qdict_get_try_bool(qdict, "blk", 0);
+    int inc = qdict_get_try_bool(qdict, "inc", 0);
+    const char *uri = qdict_get_str(qdict, "uri");
+    Error *err = NULL;
+
+    qmp_migrate(uri, !!blk, blk, !!inc, inc, false, false, &err);
+    if (err) {
+        monitor_printf(mon, "migrate: %s\n", error_get_pretty(err));
+        error_free(err);
+        return;
+    }
+
+    if (!detach) {
+        MigrationStatus *status;
+
+        if (monitor_suspend(mon) < 0) {
+            monitor_printf(mon, "terminal does not allow synchronous "
+                           "migration, continuing detached\n");
+            return;
+        }
+
+        status = g_malloc0(sizeof(*status));
+        status->mon = mon;
+        status->is_block_migration = blk || inc;
+        status->timer = qemu_new_timer_ms(rt_clock, hmp_migrate_status_cb,
+                                          status);
+        qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock));
+    }
+}
diff --git a/hmp.h b/hmp.h
index 5409464954..8807853e17 100644
--- a/hmp.h
+++ b/hmp.h
@@ -59,5 +59,6 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
 void hmp_block_stream(Monitor *mon, const QDict *qdict);
 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
 void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
+void hmp_migrate(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/hw/blizzard.c b/hw/blizzard.c
index c7d844d105..29074c4fa7 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -937,9 +937,7 @@ static void blizzard_screen_dump(void *opaque, const char *filename,
 {
     BlizzardState *s = (BlizzardState *) opaque;
 
-    if (cswitch) {
-        blizzard_update_display(opaque);
-    }
+    blizzard_update_display(opaque);
     if (s && ds_get_data(s->state))
         ppm_save(filename, s->state->surface);
 }
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 4edcb94774..afedaa43d3 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2767,10 +2767,6 @@ static void cirrus_reset(void *opaque)
     }
     s->vga.cr[0x27] = s->device_id;
 
-    /* Win2K seems to assume that the pattern buffer is at 0xff
-       initially ! */
-    memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
-
     s->cirrus_hidden_dac_lockindex = 5;
     s->cirrus_hidden_dac_data = 0;
 }
diff --git a/hw/ds1338.c b/hw/ds1338.c
index 6397f0aa6f..d590d9c007 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -100,6 +100,7 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
             break;
         case 5:
             s->now.tm_mon = from_bcd(data & 0x1f) - 1;
+            break;
         case 6:
             s->now.tm_year = from_bcd(data) + 100;
             break;
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 3fee0114d9..e2e4796bb5 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -195,7 +195,7 @@ ioapic_mem_write(void *opaque, target_phys_addr_t addr, uint64_t val,
         if (size != 4) {
             break;
         }
-        DPRINTF("write: %08x = %08x\n", s->ioregsel, val);
+        DPRINTF("write: %08x = %08" PRIx64 "\n", s->ioregsel, val);
         switch (s->ioregsel) {
         case IOAPIC_REG_ID:
             s->id = (val >> IOAPIC_ID_SHIFT) & IOAPIC_ID_MASK;
diff --git a/hw/irq.c b/hw/irq.c
index 62f766eb6f..d413a0b235 100644
--- a/hw/irq.c
+++ b/hw/irq.c
@@ -104,3 +104,20 @@ qemu_irq *qemu_irq_proxy(qemu_irq **target, int n)
 {
     return qemu_allocate_irqs(proxy_irq_handler, target, n);
 }
+
+void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
+{
+    int i;
+    qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
+    for (i = 0; i < n; i++) {
+        *old_irqs[i] = *gpio_in[i];
+        gpio_in[i]->handler = handler;
+        gpio_in[i]->opaque = old_irqs;
+    }
+}
+
+void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n)
+{
+    qemu_irq *old_irqs = *gpio_out;
+    *gpio_out = qemu_allocate_irqs(handler, old_irqs, n);
+}
diff --git a/hw/irq.h b/hw/irq.h
index 64da2fd601..56c55f0c46 100644
--- a/hw/irq.h
+++ b/hw/irq.h
@@ -38,4 +38,9 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
  */
 qemu_irq *qemu_irq_proxy(qemu_irq **target, int n);
 
+/* For internal use in qtest.  Similar to qemu_irq_split, but operating
+   on an existing vector of qemu_irq.  */
+void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
+void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n);
+
 #endif
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 64e1cd968e..b80aa8f1de 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -565,7 +565,7 @@ static void ivshmem_setup_msi(IVShmemState * s) {
         msix_vector_use(&s->dev, i);
     }
 
-    /* allocate Qemu char devices for receiving interrupts */
+    /* allocate QEMU char devices for receiving interrupts */
     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
 }
 
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 2b59c36ee6..9c64e0ae25 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -47,39 +47,6 @@
 
 #define RTC_REINJECT_ON_ACK_COUNT 20
 
-#define RTC_SECONDS             0
-#define RTC_SECONDS_ALARM       1
-#define RTC_MINUTES             2
-#define RTC_MINUTES_ALARM       3
-#define RTC_HOURS               4
-#define RTC_HOURS_ALARM         5
-#define RTC_ALARM_DONT_CARE    0xC0
-
-#define RTC_DAY_OF_WEEK         6
-#define RTC_DAY_OF_MONTH        7
-#define RTC_MONTH               8
-#define RTC_YEAR                9
-
-#define RTC_REG_A               10
-#define RTC_REG_B               11
-#define RTC_REG_C               12
-#define RTC_REG_D               13
-
-#define REG_A_UIP 0x80
-
-#define REG_B_SET  0x80
-#define REG_B_PIE  0x40
-#define REG_B_AIE  0x20
-#define REG_B_UIE  0x10
-#define REG_B_SQWE 0x08
-#define REG_B_DM   0x04
-#define REG_B_24H  0x02
-
-#define REG_C_UF   0x10
-#define REG_C_IRQF 0x80
-#define REG_C_PF   0x40
-#define REG_C_AF   0x20
-
 typedef struct RTCState {
     ISADevice dev;
     MemoryRegion io;
diff --git a/hw/mc146818rtc.h b/hw/mc146818rtc.h
index f1199300a4..f286b6a12a 100644
--- a/hw/mc146818rtc.h
+++ b/hw/mc146818rtc.h
@@ -2,8 +2,7 @@
 #define MC146818RTC_H
 
 #include "isa.h"
-
-#define RTC_ISA_IRQ 8
+#include "mc146818rtc_regs.h"
 
 ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq);
 void rtc_set_memory(ISADevice *dev, int addr, int val);
diff --git a/hw/mc146818rtc_regs.h b/hw/mc146818rtc_regs.h
new file mode 100644
index 0000000000..3ab37709f0
--- /dev/null
+++ b/hw/mc146818rtc_regs.h
@@ -0,0 +1,62 @@
+/*
+ * QEMU MC146818 RTC emulation
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef RTC_REGS_H
+#define RTC_REGS_H
+
+#define RTC_ISA_IRQ 8
+
+#define RTC_SECONDS             0
+#define RTC_SECONDS_ALARM       1
+#define RTC_MINUTES             2
+#define RTC_MINUTES_ALARM       3
+#define RTC_HOURS               4
+#define RTC_HOURS_ALARM         5
+#define RTC_ALARM_DONT_CARE    0xC0
+
+#define RTC_DAY_OF_WEEK         6
+#define RTC_DAY_OF_MONTH        7
+#define RTC_MONTH               8
+#define RTC_YEAR                9
+
+#define RTC_REG_A               10
+#define RTC_REG_B               11
+#define RTC_REG_C               12
+#define RTC_REG_D               13
+
+#define REG_A_UIP 0x80
+
+#define REG_B_SET  0x80
+#define REG_B_PIE  0x40
+#define REG_B_AIE  0x20
+#define REG_B_UIE  0x10
+#define REG_B_SQWE 0x08
+#define REG_B_DM   0x04
+#define REG_B_24H  0x02
+
+#define REG_C_UF   0x10
+#define REG_C_IRQF 0x80
+#define REG_C_PF   0x40
+#define REG_C_AF   0x20
+
+#endif
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index a88548e0aa..8878d2bd17 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -1,7 +1,7 @@
 /*
  *  QEMU model of the Milkymist System Controller.
  *
- *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *  Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -39,20 +39,19 @@ enum {
 };
 
 enum {
-    R_GPIO_IN = 0,
+    R_GPIO_IN         = 0,
     R_GPIO_OUT,
     R_GPIO_INTEN,
-    R_RESERVED0,
-    R_TIMER0_CONTROL,
+    R_TIMER0_CONTROL  = 4,
     R_TIMER0_COMPARE,
     R_TIMER0_COUNTER,
-    R_RESERVED1,
-    R_TIMER1_CONTROL,
+    R_TIMER1_CONTROL  = 8,
     R_TIMER1_COMPARE,
     R_TIMER1_COUNTER,
-    R_RESERVED2,
-    R_RESERVED3,
-    R_ICAP,
+    R_ICAP = 16,
+    R_DBG_SCRATCHPAD  = 20,
+    R_DBG_WRITE_LOCK,
+    R_CLK_FREQUENCY   = 29,
     R_CAPABILITIES,
     R_SYSTEM_ID,
     R_MAX
@@ -116,6 +115,9 @@ static uint64_t sysctl_read(void *opaque, target_phys_addr_t addr,
     case R_TIMER1_CONTROL:
     case R_TIMER1_COMPARE:
     case R_ICAP:
+    case R_DBG_SCRATCHPAD:
+    case R_DBG_WRITE_LOCK:
+    case R_CLK_FREQUENCY:
     case R_CAPABILITIES:
     case R_SYSTEM_ID:
         r = s->regs[addr];
@@ -145,6 +147,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     case R_GPIO_INTEN:
     case R_TIMER0_COUNTER:
     case R_TIMER1_COUNTER:
+    case R_DBG_SCRATCHPAD:
         s->regs[addr] = value;
         break;
     case R_TIMER0_COMPARE:
@@ -182,11 +185,15 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     case R_ICAP:
         sysctl_icap_write(s, value);
         break;
+    case R_DBG_WRITE_LOCK:
+        s->regs[addr] = 1;
+        break;
     case R_SYSTEM_ID:
         qemu_system_reset_request();
         break;
 
     case R_GPIO_IN:
+    case R_CLK_FREQUENCY:
     case R_CAPABILITIES:
         error_report("milkymist_sysctl: write to read-only register 0x"
                 TARGET_FMT_plx, addr << 2);
@@ -253,6 +260,7 @@ static void milkymist_sysctl_reset(DeviceState *d)
     /* defaults */
     s->regs[R_ICAP] = ICAP_READY;
     s->regs[R_SYSTEM_ID] = s->systemid;
+    s->regs[R_CLK_FREQUENCY] = s->freq_hz;
     s->regs[R_CAPABILITIES] = s->capabilities;
     s->regs[R_GPIO_IN] = s->strappings;
 }
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 69afd72d8a..cd4365d64b 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -2,7 +2,7 @@
 /*
  *  QEMU model of the Milkymist VGA framebuffer.
  *
- *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *  Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -54,6 +54,7 @@ enum {
     R_BASEADDRESS,
     R_BASEADDRESS_ACT,
     R_BURST_COUNT,
+    R_DDC,
     R_SOURCE_CLOCK,
     R_MAX
 };
@@ -173,6 +174,7 @@ static uint64_t vgafb_read(void *opaque, target_phys_addr_t addr,
     case R_VSCAN:
     case R_BASEADDRESS:
     case R_BURST_COUNT:
+    case R_DDC:
     case R_SOURCE_CLOCK:
         r = s->regs[addr];
     break;
@@ -211,6 +213,7 @@ static void vgafb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     case R_VSYNC_END:
     case R_VSCAN:
     case R_BURST_COUNT:
+    case R_DDC:
     case R_SOURCE_CLOCK:
         s->regs[addr] = value;
         break;
diff --git a/hw/omap1.c b/hw/omap1.c
index 2a341bfe7f..80d47f0b85 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -2888,7 +2888,7 @@ static void omap_rtc_reset(struct omap_rtc_s *s)
     s->pm_am = 0;
     s->auto_comp = 0;
     s->round = 0;
-    s->tick = qemu_get_clock_ms(rt_clock);
+    s->tick = qemu_get_clock_ms(rtc_clock);
     memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
     s->alarm_tm.tm_mday = 0x01;
     s->status = 1 << 7;
@@ -2909,7 +2909,7 @@ static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
 
     s->irq = timerirq;
     s->alarm = alarmirq;
-    s->clk = qemu_new_timer_ms(rt_clock, omap_rtc_tick, s);
+    s->clk = qemu_new_timer_ms(rtc_clock, omap_rtc_tick, s);
 
     omap_rtc_reset(s);
 
@@ -3497,9 +3497,9 @@ static void omap_lpg_tick(void *opaque)
     struct omap_lpg_s *s = opaque;
 
     if (s->cycle)
-        qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->period - s->on);
+        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->period - s->on);
     else
-        qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->on);
+        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->on);
 
     s->cycle = !s->cycle;
     printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
@@ -3617,7 +3617,7 @@ static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
     struct omap_lpg_s *s = (struct omap_lpg_s *)
             g_malloc0(sizeof(struct omap_lpg_s));
 
-    s->tm = qemu_new_timer_ms(rt_clock, omap_lpg_tick, s);
+    s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
 
     omap_lpg_reset(s);
 
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index f172093876..4a08e9d002 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -267,9 +267,8 @@ static int ppm_save(const char *filename, uint8_t *data,
 static void omap_screen_dump(void *opaque, const char *filename, bool cswitch)
 {
     struct omap_lcd_panel_s *omap_lcd = opaque;
-    if (cswitch) {
-        omap_update_display(opaque);
-    }
+
+    omap_update_display(opaque);
     if (omap_lcd && ds_get_data(omap_lcd->state))
         ppm_save(filename, ds_get_data(omap_lcd->state),
                 omap_lcd->width, omap_lcd->height,
diff --git a/hw/pc.c b/hw/pc.c
index 83a1b5b32b..67f0479f40 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -776,7 +776,7 @@ static void load_linux(void *fw_cfg,
     }
 
     /* loader type */
-    /* High nybble = B reserved for Qemu; low nybble is revision number.
+    /* High nybble = B reserved for QEMU; low nybble is revision number.
        If this code is substantially changed, you may want to consider
        incrementing the revision. */
     if (protocol >= 0x200)
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 3f99f9a7c2..fadca4c710 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -107,6 +107,9 @@ static void ioapic_init(GSIState *gsi_state)
     } else {
         dev = qdev_create(NULL, "ioapic");
     }
+    /* FIXME: this should be under the piix3.  */
+    object_property_add_child(object_resolve_path("i440fx", NULL),
+                              "ioapic", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
     d = sysbus_from_qdev(dev);
     sysbus_mmio_map(d, 0, 0xfec00000);
@@ -146,7 +149,6 @@ static void pc_init1(MemoryRegion *system_memory,
     MemoryRegion *ram_memory;
     MemoryRegion *pci_memory;
     MemoryRegion *rom_memory;
-    DeviceState *dev;
 
     pc_cpus_init(cpu_model);
 
@@ -224,11 +226,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     pc_register_ferr_irq(gsi[13]);
 
-    dev = pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
-    if (dev) {
-        object_property_add_child(object_get_root(), "vga", OBJECT(dev), NULL);
-    }
-
+    pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
     if (xen_enabled()) {
         pci_create_simple(pci_bus, -1, "xen-platform");
     }
@@ -255,17 +253,6 @@ static void pc_init1(MemoryRegion *system_memory,
         }
         idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
         idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
-
-        /* FIXME there's some major spaghetti here.  Somehow we create the
-         * devices on the PIIX before we actually create it.  We create the
-         * PIIX3 deep in the recess of the i440fx creation too and then lose
-         * the DeviceState.
-         *
-         * For now, let's "fix" this by making judicious use of paths.  This
-         * is not generally the right way to do this.
-         */
-        object_property_add_child(object_resolve_path("/i440fx/piix3", NULL),
-                                  "rtc", (Object *)rtc_state, NULL);
     } else {
         for(i = 0; i < MAX_IDE_BUS; i++) {
             ISADevice *dev;
diff --git a/hw/pci.c b/hw/pci.c
index bf046bfcad..ed8ec99073 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -841,7 +841,6 @@ static int pci_unregister_device(DeviceState *dev)
 
     pci_unregister_io_regions(pci_dev);
     pci_del_option_rom(pci_dev);
-    g_free(pci_dev->romfile);
     do_pci_unregister_device(pci_dev);
     return 0;
 }
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index e0268fe053..179d9a6bb9 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -276,8 +276,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
     b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
                     address_space_io, 0);
     s->bus = b;
+    object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
-    object_property_add_child(object_get_root(), "i440fx", OBJECT(dev), NULL);
 
     d = pci_create_simple(b, 0, device_name);
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
@@ -316,7 +316,6 @@ static PCIBus *i440fx_common_init(const char *device_name,
         pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
                 PIIX_NUM_PIRQS);
     }
-    object_property_add_child(OBJECT(dev), "piix3", OBJECT(piix3), NULL);
     piix3->pic = pic;
     *isa_bus = DO_UPCAST(ISABus, qbus,
                          qdev_get_child_bus(&piix3->dev.qdev, "isa.0"));
diff --git a/hw/pl031.c b/hw/pl031.c
index 69abc4f345..9602664da6 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -13,6 +13,7 @@
 
 #include "sysbus.h"
 #include "qemu-timer.h"
+#include "sysemu.h"
 
 //#define DEBUG_PL031
 
@@ -38,6 +39,11 @@ typedef struct {
     QEMUTimer *timer;
     qemu_irq irq;
 
+    /* Needed to preserve the tick_count across migration, even if the
+     * absolute value of the rtc_clock is different on the source and
+     * destination.
+     */
+    uint32_t tick_offset_vmstate;
     uint32_t tick_offset;
 
     uint32_t mr;
@@ -47,21 +53,6 @@ typedef struct {
     uint32_t is;
 } pl031_state;
 
-static const VMStateDescription vmstate_pl031 = {
-    .name = "pl031",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(tick_offset, pl031_state),
-        VMSTATE_UINT32(mr, pl031_state),
-        VMSTATE_UINT32(lr, pl031_state),
-        VMSTATE_UINT32(cr, pl031_state),
-        VMSTATE_UINT32(im, pl031_state),
-        VMSTATE_UINT32(is, pl031_state),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 static const unsigned char pl031_id[] = {
     0x31, 0x10, 0x14, 0x00,         /* Device ID        */
     0x0d, 0xf0, 0x05, 0xb1          /* Cell ID      */
@@ -83,27 +74,23 @@ static void pl031_interrupt(void * opaque)
 
 static uint32_t pl031_get_count(pl031_state *s)
 {
-    /* This assumes qemu_get_clock_ns returns the time since the machine was
-       created.  */
-    return s->tick_offset + qemu_get_clock_ns(vm_clock) / get_ticks_per_sec();
+    int64_t now = qemu_get_clock_ns(rtc_clock);
+    return s->tick_offset + now / get_ticks_per_sec();
 }
 
 static void pl031_set_alarm(pl031_state *s)
 {
-    int64_t now;
     uint32_t ticks;
 
-    now = qemu_get_clock_ns(vm_clock);
-    ticks = s->tick_offset + now / get_ticks_per_sec();
-
     /* The timer wraps around.  This subtraction also wraps in the same way,
        and gives correct results when alarm < now_ticks.  */
-    ticks = s->mr - ticks;
+    ticks = s->mr - pl031_get_count(s);
     DPRINTF("Alarm set in %ud ticks\n", ticks);
     if (ticks == 0) {
         qemu_del_timer(s->timer);
         pl031_interrupt(s);
     } else {
+        int64_t now = qemu_get_clock_ns(rtc_clock);
         qemu_mod_timer(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
     }
 }
@@ -205,14 +192,50 @@ static int pl031_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
 
     sysbus_init_irq(dev, &s->irq);
-    /* ??? We assume vm_clock is zero at this point.  */
     qemu_get_timedate(&tm, 0);
-    s->tick_offset = mktimegm(&tm);
+    s->tick_offset = mktimegm(&tm) - qemu_get_clock_ns(rtc_clock) / get_ticks_per_sec();
+
+    s->timer = qemu_new_timer_ns(rtc_clock, pl031_interrupt, s);
+    return 0;
+}
+
+static void pl031_pre_save(void *opaque)
+{
+    pl031_state *s = opaque;
+
+    /* tick_offset is base_time - rtc_clock base time.  Instead, we want to
+     * store the base time relative to the vm_clock for backwards-compatibility.  */
+    int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+    s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
+}
+
+static int pl031_post_load(void *opaque, int version_id)
+{
+    pl031_state *s = opaque;
 
-    s->timer = qemu_new_timer_ns(vm_clock, pl031_interrupt, s);
+    int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+    s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
+    pl031_set_alarm(s);
     return 0;
 }
 
+static const VMStateDescription vmstate_pl031 = {
+    .name = "pl031",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .pre_save = pl031_pre_save,
+    .post_load = pl031_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(tick_offset_vmstate, pl031_state),
+        VMSTATE_UINT32(mr, pl031_state),
+        VMSTATE_UINT32(lr, pl031_state),
+        VMSTATE_UINT32(cr, pl031_state),
+        VMSTATE_UINT32(im, pl031_state),
+        VMSTATE_UINT32(is, pl031_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static void pl031_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 220c81d06e..f0a3ae49e6 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -1,5 +1,5 @@
 /*
- * Qemu PowerPC 440 Bamboo board emulation
+ * QEMU PowerPC 440 Bamboo board emulation
  *
  * Copyright 2007 IBM Corporation.
  * Authors:
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 06d589d97b..9d8e6592e1 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -615,8 +615,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
     sys = sysbus_from_qdev(dev);
     pcihost = DO_UPCAST(PCIHostState, busdev, sys);
     pcihost->address_space = get_system_memory();
+    object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
-    object_property_add_child(object_get_root(), "raven", OBJECT(dev), NULL);
     pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
     if (pci_bus == NULL) {
         fprintf(stderr, "Couldn't create PCI host controller.\n");
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 5ee8cb34c1..f1dfbe181c 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -1,5 +1,5 @@
 /*
- * Qemu PowerPC MPC8544DS board emualtion
+ * QEMU PowerPC MPC8544DS board emulation
  *
  * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
  *
diff --git a/hw/ps2.c b/hw/ps2.c
index b1a67bc625..f93cd24d94 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -88,7 +88,7 @@ typedef struct {
 typedef struct {
     PS2State common;
     int scan_enabled;
-    /* Qemu uses translated PC scancodes internally.  To avoid multiple
+    /* QEMU uses translated PC scancodes internally.  To avoid multiple
        conversions we do the translation (if any) in the PS/2 emulation
        not the keyboard controller.  */
     int translate;
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 1d5c35f174..ddaa846882 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -875,7 +875,7 @@ static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s)
 
 static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rt_clock);
+    int64_t rt = qemu_get_clock_ms(rtc_clock);
     s->last_rcnr += ((rt - s->last_hz) << 15) /
             (1000 * ((s->rttr & 0xffff) + 1));
     s->last_rdcr += ((rt - s->last_hz) << 15) /
@@ -885,7 +885,7 @@ static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
 
 static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rt_clock);
+    int64_t rt = qemu_get_clock_ms(rtc_clock);
     if (s->rtsr & (1 << 12))
         s->last_swcr += (rt - s->last_sw) / 10;
     s->last_sw = rt;
@@ -893,7 +893,7 @@ static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
 
 static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rt_clock);
+    int64_t rt = qemu_get_clock_ms(rtc_clock);
     if (s->rtsr & (1 << 15))
         s->last_swcr += rt - s->last_pi;
     s->last_pi = rt;
@@ -1019,16 +1019,16 @@ static uint64_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr,
     case PIAR:
         return s->piar;
     case RCNR:
-        return s->last_rcnr + ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+        return s->last_rcnr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
                 (1000 * ((s->rttr & 0xffff) + 1));
     case RDCR:
-        return s->last_rdcr + ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+        return s->last_rdcr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
                 (1000 * ((s->rttr & 0xffff) + 1));
     case RYCR:
         return s->last_rycr;
     case SWCR:
         if (s->rtsr & (1 << 12))
-            return s->last_swcr + (qemu_get_clock_ms(rt_clock) - s->last_sw) / 10;
+            return s->last_swcr + (qemu_get_clock_ms(rtc_clock) - s->last_sw) / 10;
         else
             return s->last_swcr;
     default:
@@ -1168,14 +1168,14 @@ static int pxa2xx_rtc_init(SysBusDevice *dev)
     s->last_swcr = (tm.tm_hour << 19) |
             (tm.tm_min << 13) | (tm.tm_sec << 7);
     s->last_rtcpicr = 0;
-    s->last_hz = s->last_sw = s->last_pi = qemu_get_clock_ms(rt_clock);
-
-    s->rtc_hz    = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_hz_tick,    s);
-    s->rtc_rdal1 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_rdal1_tick, s);
-    s->rtc_rdal2 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_rdal2_tick, s);
-    s->rtc_swal1 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_swal1_tick, s);
-    s->rtc_swal2 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_swal2_tick, s);
-    s->rtc_pi    = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_pi_tick,    s);
+    s->last_hz = s->last_sw = s->last_pi = qemu_get_clock_ms(rtc_clock);
+
+    s->rtc_hz    = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_hz_tick,    s);
+    s->rtc_rdal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
+    s->rtc_rdal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
+    s->rtc_swal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
+    s->rtc_swal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
+    s->rtc_pi    = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_pi_tick,    s);
 
     sysbus_init_irq(dev, &s->rtc_irq);
 
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index a310cc7b16..4783366cf4 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -180,9 +180,7 @@ static Object *qdev_get_peripheral(void)
     static Object *dev;
 
     if (dev == NULL) {
-        dev = object_new("container");
-        object_property_add_child(object_get_root(), "peripheral",
-                                  OBJECT(dev), NULL);
+        dev = container_get("/machine/peripheral");
     }
 
     return dev;
@@ -193,9 +191,7 @@ static Object *qdev_get_peripheral_anon(void)
     static Object *dev;
 
     if (dev == NULL) {
-        dev = object_new("container");
-        object_property_add_child(object_get_root(), "peripheral-anon",
-                                  OBJECT(dev), NULL);
+        dev = container_get("/machine/peripheral-anon");
     }
 
     return dev;
@@ -462,10 +458,6 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         qdev_free(qdev);
         return NULL;
     }
-    if (qdev_init(qdev) < 0) {
-        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
-        return NULL;
-    }
     if (qdev->id) {
         object_property_add_child(qdev_get_peripheral(), qdev->id,
                                   OBJECT(qdev), NULL);
@@ -476,6 +468,10 @@ DeviceState *qdev_device_add(QemuOpts *opts)
                                   OBJECT(qdev), NULL);
         g_free(name);
     }        
+    if (qdev_init(qdev) < 0) {
+        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
+        return NULL;
+    }
     qdev->opts = opts;
     return qdev;
 }
diff --git a/hw/qdev.c b/hw/qdev.c
index ee21d90e80..0d3c0fc49c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -113,14 +113,14 @@ DeviceState *qdev_create(BusState *bus, const char *name)
     return dev;
 }
 
-DeviceState *qdev_try_create(BusState *bus, const char *name)
+DeviceState *qdev_try_create(BusState *bus, const char *type)
 {
     DeviceState *dev;
 
-    if (object_class_by_name(name) == NULL) {
+    if (object_class_by_name(type) == NULL) {
         return NULL;
     }
-    dev = DEVICE(object_new(name));
+    dev = DEVICE(object_new(type));
     if (!dev) {
         return NULL;
     }
@@ -152,6 +152,16 @@ int qdev_init(DeviceState *dev)
         qdev_free(dev);
         return rc;
     }
+
+    if (!OBJECT(dev)->parent) {
+        static int unattached_count = 0;
+        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
+
+        object_property_add_child(container_get("/machine/unattached"), name,
+                                  OBJECT(dev), NULL);
+        g_free(name);
+    }
+
     if (qdev_get_vmsd(dev)) {
         vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
                                        dev->instance_id_alias,
@@ -658,6 +668,17 @@ void device_reset(DeviceState *dev)
     }
 }
 
+Object *qdev_get_machine(void)
+{
+    static Object *dev;
+
+    if (dev == NULL) {
+        dev = container_get("/machine");
+    }
+
+    return dev;
+}
+
 static TypeInfo device_type_info = {
     .name = TYPE_DEVICE,
     .parent = TYPE_OBJECT,
diff --git a/hw/qdev.h b/hw/qdev.h
index 9cc3f984b2..a8df42f6fa 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -349,6 +349,8 @@ BusInfo *qdev_get_bus_info(DeviceState *dev);
 
 Property *qdev_get_props(DeviceState *dev);
 
+Object *qdev_get_machine(void);
+
 /* FIXME: make this a link<> */
 void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
 
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 25857f6a20..28ab182226 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -31,11 +31,10 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
         return;
     }
     if (!qxl->guest_primary.data) {
-        dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__);
+        trace_qxl_render_blit_guest_primary_initialized();
         qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
     }
-    dprint(qxl, 2, "%s: stride %d, [%d, %d, %d, %d]\n", __func__,
-            qxl->guest_primary.qxl_stride,
+    trace_qxl_render_blit(qxl->guest_primary.qxl_stride,
             rect->left, rect->right, rect->top, rect->bottom);
     src = qxl->guest_primary.data;
     if (qxl->guest_primary.qxl_stride < 0) {
@@ -107,8 +106,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
         qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
         qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
         qxl->num_dirty_rects = 1;
-        dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d\n",
-               __FUNCTION__,
+        trace_qxl_render_guest_primary_resized(
                qxl->guest_primary.surface.width,
                qxl->guest_primary.surface.height,
                qxl->guest_primary.qxl_stride,
@@ -118,8 +116,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
     if (surface->width != qxl->guest_primary.surface.width ||
         surface->height != qxl->guest_primary.surface.height) {
         if (qxl->guest_primary.qxl_stride > 0) {
-            dprint(qxl, 1, "%s: using guest_primary for displaysurface\n",
-                   __func__);
             qemu_free_displaysurface(vga->ds);
             qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
                                             qxl->guest_primary.surface.height,
@@ -127,8 +123,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
                                             qxl->guest_primary.abs_stride,
                                             qxl->guest_primary.data);
         } else {
-            dprint(qxl, 1, "%s: resizing displaysurface to guest_primary\n",
-                   __func__);
             qemu_resize_displaysurface(vga->ds,
                     qxl->guest_primary.surface.width,
                     qxl->guest_primary.surface.height);
@@ -187,6 +181,7 @@ void qxl_render_update_area_bh(void *opaque)
 void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
 {
     qemu_mutex_lock(&qxl->ssd.lock);
+    trace_qxl_render_update_area_done(cookie);
     qemu_bh_schedule(qxl->update_area_bh);
     qxl->render_update_cookie_num--;
     qemu_mutex_unlock(&qxl->ssd.lock);
diff --git a/hw/qxl.c b/hw/qxl.c
index e17b0e31af..47a162e479 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -23,6 +23,7 @@
 #include "qemu-queue.h"
 #include "monitor.h"
 #include "sysemu.h"
+#include "trace.h"
 
 #include "qxl.h"
 
@@ -143,19 +144,24 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
                            uint32_t clear_dirty_region,
                            qxl_async_io async, struct QXLCookie *cookie)
 {
+    trace_qxl_spice_update_area(qxl->id, surface_id, area->left, area->right,
+                                area->top, area->bottom);
+    trace_qxl_spice_update_area_rest(qxl->id, num_dirty_rects,
+                                     clear_dirty_region);
     if (async == QXL_SYNC) {
         qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
                         dirty_rects, num_dirty_rects, clear_dirty_region);
     } else {
         assert(cookie != NULL);
         spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
-                                    clear_dirty_region, (uint64_t)cookie);
+                                    clear_dirty_region, (uintptr_t)cookie);
     }
 }
 
 static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
                                                     uint32_t id)
 {
+    trace_qxl_spice_destroy_surface_wait_complete(qxl->id, id);
     qemu_mutex_lock(&qxl->track_lock);
     qxl->guest_surfaces.cmds[id] = 0;
     qxl->guest_surfaces.count--;
@@ -167,42 +173,48 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
 {
     QXLCookie *cookie;
 
+    trace_qxl_spice_destroy_surface_wait(qxl->id, id, async);
     if (async) {
         cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                                 QXL_IO_DESTROY_SURFACE_ASYNC);
         cookie->u.surface_id = id;
-        spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uint64_t)cookie);
+        spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uintptr_t)cookie);
     } else {
         qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
-        qxl_spice_destroy_surface_wait_complete(qxl, id);
     }
 }
 
 static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
 {
+    trace_qxl_spice_flush_surfaces_async(qxl->id, qxl->guest_surfaces.count,
+                                         qxl->num_free_res);
     spice_qxl_flush_surfaces_async(&qxl->ssd.qxl,
-        (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
-                                 QXL_IO_FLUSH_SURFACES_ASYNC));
+        (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+                                  QXL_IO_FLUSH_SURFACES_ASYNC));
 }
 
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
                                uint32_t count)
 {
+    trace_qxl_spice_loadvm_commands(qxl->id, ext, count);
     qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
 }
 
 void qxl_spice_oom(PCIQXLDevice *qxl)
 {
+    trace_qxl_spice_oom(qxl->id);
     qxl->ssd.worker->oom(qxl->ssd.worker);
 }
 
 void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
 {
+    trace_qxl_spice_reset_memslots(qxl->id);
     qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
 }
 
 static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
 {
+    trace_qxl_spice_destroy_surfaces_complete(qxl->id);
     qemu_mutex_lock(&qxl->track_lock);
     memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
     qxl->guest_surfaces.count = 0;
@@ -211,10 +223,11 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
 
 static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
 {
+    trace_qxl_spice_destroy_surfaces(qxl->id, async);
     if (async) {
         spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl,
-                (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
-                                         QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
+                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+                                          QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
     } else {
         qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
         qxl_spice_destroy_surfaces_complete(qxl);
@@ -223,11 +236,13 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
 
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
 {
+    trace_qxl_spice_reset_image_cache(qxl->id);
     qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
 }
 
 void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
 {
+    trace_qxl_spice_reset_cursor(qxl->id);
     qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
     qemu_mutex_lock(&qxl->track_lock);
     qxl->guest_cursor = 0;
@@ -409,7 +424,7 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
 {
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
 
-    dprint(qxl, 1, "%s:\n", __FUNCTION__);
+    trace_qxl_interface_attach_worker(qxl->id);
     qxl->ssd.worker = qxl_worker;
 }
 
@@ -417,7 +432,7 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
 {
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
 
-    dprint(qxl, 1, "%s: %d\n", __FUNCTION__, level);
+    trace_qxl_interface_set_compression_level(qxl->id, level);
     qxl->shadow_rom.compression_level = cpu_to_le32(level);
     qxl->rom->compression_level = cpu_to_le32(level);
     qxl_rom_set_dirty(qxl);
@@ -427,6 +442,7 @@ static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
 {
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
 
+    trace_qxl_interface_set_mm_time(qxl->id, mm_time);
     qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
     qxl->rom->mm_clock = cpu_to_le32(mm_time);
     qxl_rom_set_dirty(qxl);
@@ -436,7 +452,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
 {
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
 
-    dprint(qxl, 1, "%s:\n", __FUNCTION__);
+    trace_qxl_interface_get_init_info(qxl->id);
     info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
     info->memslot_id_bits = MEMSLOT_SLOT_BITS;
     info->num_memslots = NUM_MEMSLOTS;
@@ -505,9 +521,10 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
     QXLCommand *cmd;
     int notify, ret;
 
+    trace_qxl_ring_command_check(qxl->id, qxl_mode_to_string(qxl->mode));
+
     switch (qxl->mode) {
     case QXL_MODE_VGA:
-        dprint(qxl, 2, "%s: vga\n", __FUNCTION__);
         ret = false;
         qemu_mutex_lock(&qxl->ssd.lock);
         if (qxl->ssd.update != NULL) {
@@ -518,19 +535,18 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
         }
         qemu_mutex_unlock(&qxl->ssd.lock);
         if (ret) {
-            dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
+            trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
             qxl_log_command(qxl, "vga", ext);
         }
         return ret;
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
     case QXL_MODE_UNDEFINED:
-        dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
         ring = &qxl->ram->cmd_ring;
         if (SPICE_RING_IS_EMPTY(ring)) {
             return false;
         }
-        dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
+        trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
         SPICE_RING_CONS_ITEM(ring, cmd);
         ext->cmd      = *cmd;
         ext->group_id = MEMSLOT_GROUP_GUEST;
@@ -555,6 +571,7 @@ static int interface_req_cmd_notification(QXLInstance *sin)
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
     int wait = 1;
 
+    trace_qxl_ring_command_req_notification(qxl->id);
     switch (qxl->mode) {
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
@@ -592,10 +609,11 @@ static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
     }
 
     SPICE_RING_PUSH(ring, notify);
-    dprint(d, 2, "free: push %d items, notify %s, ring %d/%d [%d,%d]\n",
-           d->num_free_res, notify ? "yes" : "no",
-           ring->prod - ring->cons, ring->num_items,
-           ring->prod, ring->cons);
+    trace_qxl_ring_res_push(d->id, qxl_mode_to_string(d->mode),
+           d->guest_surfaces.count, d->num_free_res,
+           d->last_release, notify ? "yes" : "no");
+    trace_qxl_ring_res_push_rest(d->id, ring->prod - ring->cons,
+           ring->num_items, ring->prod, ring->cons);
     if (notify) {
         qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
     }
@@ -642,7 +660,7 @@ static void interface_release_resource(QXLInstance *sin,
     }
     qxl->last_release = ext.info;
     qxl->num_free_res++;
-    dprint(qxl, 3, "%4d\r", qxl->num_free_res);
+    trace_qxl_ring_res_put(qxl->id, qxl->num_free_res);
     qxl_push_free_res(qxl, 0);
 }
 
@@ -654,6 +672,8 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
     QXLCommand *cmd;
     int notify;
 
+    trace_qxl_ring_cursor_check(qxl->id, qxl_mode_to_string(qxl->mode));
+
     switch (qxl->mode) {
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
@@ -677,6 +697,7 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
         if (qxl->id == 0) {
             qxl_render_cursor(qxl, ext);
         }
+        trace_qxl_ring_cursor_get(qxl->id, qxl_mode_to_string(qxl->mode));
         return true;
     default:
         return false;
@@ -689,6 +710,7 @@ static int interface_req_cursor_notification(QXLInstance *sin)
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
     int wait = 1;
 
+    trace_qxl_ring_cursor_req_notification(qxl->id);
     switch (qxl->mode) {
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
@@ -716,7 +738,6 @@ static int interface_flush_resources(QXLInstance *sin)
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
     int ret;
 
-    dprint(qxl, 1, "free: guest flush (have %d)\n", qxl->num_free_res);
     ret = qxl->num_free_res;
     if (ret) {
         qxl_push_free_res(qxl, 1);
@@ -736,14 +757,14 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
     qxl->current_async = QXL_UNDEFINED_IO;
     qemu_mutex_unlock(&qxl->async_lock);
 
-    dprint(qxl, 2, "async_complete: %d (%p) done\n", current_async, cookie);
+    trace_qxl_interface_async_complete_io(qxl->id, current_async, cookie);
     if (!cookie) {
         fprintf(stderr, "qxl: %s: error, cookie is NULL\n", __func__);
         return;
     }
     if (cookie && current_async != cookie->io) {
         fprintf(stderr,
-                "qxl: %s: error: current_async = %d != %ld = cookie->io\n",
+                "qxl: %s: error: current_async = %d != %" PRId64 " = cookie->io\n",
                 __func__, current_async, cookie->io);
     }
     switch (current_async) {
@@ -782,11 +803,15 @@ static void interface_update_area_complete(QXLInstance *sin,
         qemu_mutex_unlock(&qxl->ssd.lock);
         return;
     }
+    trace_qxl_interface_update_area_complete(qxl->id, surface_id, dirty->left,
+            dirty->right, dirty->top, dirty->bottom);
+    trace_qxl_interface_update_area_complete_rest(qxl->id, num_updated_rects);
     if (qxl->num_dirty_rects + num_updated_rects > QXL_NUM_DIRTY_RECTS) {
         /*
          * overflow - treat this as a full update. Not expected to be common.
          */
-        dprint(qxl, 1, "%s: overflow of dirty rects\n", __func__);
+        trace_qxl_interface_update_area_complete_overflow(qxl->id,
+                                                          QXL_NUM_DIRTY_RECTS);
         qxl->guest_primary.resized = 1;
     }
     if (qxl->guest_primary.resized) {
@@ -802,8 +827,8 @@ static void interface_update_area_complete(QXLInstance *sin,
         qxl->dirty[qxl_i++] = dirty[i];
     }
     qxl->num_dirty_rects += num_updated_rects;
-    dprint(qxl, 1, "%s: scheduling update_area_bh, #dirty %d\n",
-           __func__, qxl->num_dirty_rects);
+    trace_qxl_interface_update_area_complete_schedule_bh(qxl->id,
+                                                         qxl->num_dirty_rects);
     qemu_bh_schedule(qxl->update_area_bh);
     qemu_mutex_unlock(&qxl->ssd.lock);
 }
@@ -812,7 +837,7 @@ static void interface_update_area_complete(QXLInstance *sin,
 static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
 {
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-    QXLCookie *cookie = (QXLCookie *)cookie_token;
+    QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
 
     switch (cookie->type) {
     case QXL_COOKIE_TYPE_IO:
@@ -857,7 +882,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
     if (d->mode == QXL_MODE_VGA) {
         return;
     }
-    dprint(d, 1, "%s\n", __FUNCTION__);
+    trace_qxl_enter_vga_mode(d->id);
     qemu_spice_create_host_primary(&d->ssd);
     d->mode = QXL_MODE_VGA;
     memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
@@ -868,7 +893,7 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)
     if (d->mode != QXL_MODE_VGA) {
         return;
     }
-    dprint(d, 1, "%s\n", __FUNCTION__);
+    trace_qxl_exit_vga_mode(d->id);
     qxl_destroy_primary(d, QXL_SYNC);
 }
 
@@ -905,7 +930,7 @@ static void qxl_reset_state(PCIQXLDevice *d)
 
 static void qxl_soft_reset(PCIQXLDevice *d)
 {
-    dprint(d, 1, "%s:\n", __FUNCTION__);
+    trace_qxl_soft_reset(d->id);
     qxl_check_state(d);
 
     if (d->id == 0) {
@@ -917,8 +942,7 @@ static void qxl_soft_reset(PCIQXLDevice *d)
 
 static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
 {
-    dprint(d, 1, "%s: start%s\n", __FUNCTION__,
-           loadvm ? " (loadvm)" : "");
+    trace_qxl_hard_reset(d->id, loadvm);
 
     qxl_spice_reset_cursor(d);
     qxl_spice_reset_image_cache(d);
@@ -933,13 +957,12 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
     }
     qemu_spice_create_host_memslot(&d->ssd);
     qxl_soft_reset(d);
-
-    dprint(d, 1, "%s: done\n", __FUNCTION__);
 }
 
 static void qxl_reset_handler(DeviceState *dev)
 {
     PCIQXLDevice *d = DO_UPCAST(PCIQXLDevice, pci.qdev, dev);
+
     qxl_hard_reset(d, 0);
 }
 
@@ -948,8 +971,8 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     VGACommonState *vga = opaque;
     PCIQXLDevice *qxl = container_of(vga, PCIQXLDevice, vga);
 
+    trace_qxl_io_write_vga(qxl->id, qxl_mode_to_string(qxl->mode), addr, val);
     if (qxl->mode != QXL_MODE_VGA) {
-        dprint(qxl, 1, "%s\n", __FUNCTION__);
         qxl_destroy_primary(qxl, QXL_SYNC);
         qxl_soft_reset(qxl);
     }
@@ -990,9 +1013,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
     guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);
     guest_end   = le64_to_cpu(d->guest_slots[slot_id].slot.mem_end);
 
-    dprint(d, 1, "%s: slot %d: guest phys 0x%" PRIx64 " - 0x%" PRIx64 "\n",
-           __FUNCTION__, slot_id,
-           guest_start, guest_end);
+    trace_qxl_memslot_add_guest(d->id, slot_id, guest_start, guest_end);
 
     PANIC_ON(slot_id >= NUM_MEMSLOTS);
     PANIC_ON(guest_start > guest_end);
@@ -1039,10 +1060,6 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
     memslot.generation = d->rom->slot_generation = 0;
     qxl_rom_set_dirty(d);
 
-    dprint(d, 1, "%s: slot %d: host virt 0x%lx - 0x%lx\n",
-           __FUNCTION__, memslot.slot_id,
-           memslot.virt_start, memslot.virt_end);
-
     qemu_spice_add_memslot(&d->ssd, &memslot, async);
     d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
     d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
@@ -1052,21 +1069,19 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
 
 static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
 {
-    dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
     qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
     d->guest_slots[slot_id].active = 0;
 }
 
 static void qxl_reset_memslots(PCIQXLDevice *d)
 {
-    dprint(d, 1, "%s:\n", __FUNCTION__);
     qxl_spice_reset_memslots(d);
     memset(&d->guest_slots, 0, sizeof(d->guest_slots));
 }
 
 static void qxl_reset_surfaces(PCIQXLDevice *d)
 {
-    dprint(d, 1, "%s:\n", __FUNCTION__);
+    trace_qxl_reset_surfaces(d->id);
     d->mode = QXL_MODE_UNDEFINED;
     qxl_spice_destroy_surfaces(d, QXL_SYNC);
 }
@@ -1108,9 +1123,6 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
     assert(qxl->mode != QXL_MODE_NATIVE);
     qxl_exit_vga_mode(qxl);
 
-    dprint(qxl, 1, "%s: %dx%d\n", __FUNCTION__,
-           le32_to_cpu(sc->width), le32_to_cpu(sc->height));
-
     surface.format     = le32_to_cpu(sc->format);
     surface.height     = le32_to_cpu(sc->height);
     surface.mem        = le64_to_cpu(sc->mem);
@@ -1119,6 +1131,10 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
     surface.width      = le32_to_cpu(sc->width);
     surface.type       = le32_to_cpu(sc->type);
     surface.flags      = le32_to_cpu(sc->flags);
+    trace_qxl_create_guest_primary(qxl->id, sc->width, sc->height, sc->mem,
+                                   sc->format, sc->position);
+    trace_qxl_create_guest_primary_rest(qxl->id, sc->stride, sc->type,
+                                        sc->flags);
 
     surface.mouse_mode = true;
     surface.group_id   = MEMSLOT_GROUP_GUEST;
@@ -1142,7 +1158,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
     if (d->mode == QXL_MODE_UNDEFINED) {
         return 0;
     }
-    dprint(d, 1, "%s\n", __FUNCTION__);
+    trace_qxl_destroy_primary(d->id);
     d->mode = QXL_MODE_UNDEFINED;
     qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
     qxl_spice_reset_cursor(d);
@@ -1169,8 +1185,8 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
         .mem        = devmem + d->shadow_rom.draw_area_offset,
     };
 
-    dprint(d, 1, "%s: mode %d  [ %d x %d @ %d bpp devmem 0x%" PRIx64 " ]\n",
-           __func__, modenr, mode->x_res, mode->y_res, mode->bits, devmem);
+    trace_qxl_set_mode(d->id, modenr, mode->x_res, mode->y_res, mode->bits,
+                       devmem);
     if (!loadvm) {
         qxl_hard_reset(d, 0);
     }
@@ -1216,8 +1232,8 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
         if (d->mode != QXL_MODE_VGA) {
             break;
         }
-        dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
-            __func__, io_port, io_port_to_string(io_port));
+        trace_qxl_io_unexpected_vga_mode(d->id,
+            io_port, io_port_to_string(io_port));
         /* be nice to buggy guest drivers */
         if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
             io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
@@ -1259,11 +1275,12 @@ async_common:
         }
         d->current_async = orig_io_port;
         qemu_mutex_unlock(&d->async_lock);
-        dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val);
         break;
     default:
         break;
     }
+    trace_qxl_io_write(d->id, qxl_mode_to_string(d->mode), addr, val, size,
+                       async);
 
     switch (io_port) {
     case QXL_IO_UPDATE_AREA:
@@ -1299,7 +1316,6 @@ async_common:
         d->oom_running = 0;
         break;
     case QXL_IO_SET_MODE:
-        dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
         qxl_set_mode(d, val, 0);
         break;
     case QXL_IO_LOG:
@@ -1309,7 +1325,6 @@ async_common:
         }
         break;
     case QXL_IO_RESET:
-        dprint(d, 1, "QXL_IO_RESET\n");
         qxl_hard_reset(d, 0);
         break;
     case QXL_IO_MEMSLOT_ADD:
@@ -1337,7 +1352,6 @@ async_common:
                           async);
             goto cancel_async;
         }
-        dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);
         d->guest_primary.surface = d->ram->create_surface;
         qxl_create_guest_primary(d, 0, async);
         break;
@@ -1347,11 +1361,9 @@ async_common:
                           async);
             goto cancel_async;
         }
-        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
-               qxl_mode_to_string(d->mode));
         if (!qxl_destroy_primary(d, async)) {
-            dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
-                    qxl_mode_to_string(d->mode));
+            trace_qxl_io_destroy_primary_ignored(d->id,
+                                                 qxl_mode_to_string(d->mode));
             goto cancel_async;
         }
         break;
@@ -1371,16 +1383,9 @@ async_common:
                 ring->prod, ring->cons);
         }
         qxl_push_free_res(d, 1 /* flush */);
-        dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
-            qxl_mode_to_string(d->mode), d->guest_surfaces.count,
-            d->num_free_res, d->last_release);
         break;
     }
     case QXL_IO_FLUSH_SURFACES_ASYNC:
-        dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC"
-                     " (%"PRId64") (%s, s#=%d, res#=%d)\n",
-               val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
-               d->num_free_res);
         qxl_spice_flush_surfaces_async(d);
         break;
     case QXL_IO_DESTROY_ALL_SURFACES:
@@ -1406,7 +1411,7 @@ static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
 {
     PCIQXLDevice *d = opaque;
 
-    dprint(d, 1, "%s: unexpected\n", __FUNCTION__);
+    trace_qxl_io_read_unexpected(d->id);
     return 0xff;
 }
 
@@ -1452,16 +1457,17 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
 
 static void init_pipe_signaling(PCIQXLDevice *d)
 {
-   if (pipe(d->pipe) < 0) {
-       dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
-       return;
-   }
-   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
-   fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
-   fcntl(d->pipe[0], F_SETOWN, getpid());
+    if (pipe(d->pipe) < 0) {
+        fprintf(stderr, "%s:%s: qxl pipe creation failed\n",
+                __FILE__, __func__);
+        exit(1);
+    }
+    fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
+    fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
+    fcntl(d->pipe[0], F_SETOWN, getpid());
 
-   qemu_thread_get_self(&d->main);
-   qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
+    qemu_thread_get_self(&d->main);
+    qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
 }
 
 /* graphics console */
@@ -1556,8 +1562,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
         surface_offset -= vram_start;
         surface_size = cmd->u.surface_create.height *
                        abs(cmd->u.surface_create.stride);
-        dprint(qxl, 3, "%s: dirty surface %d, offset %d, size %d\n", __func__,
-               i, (int)surface_offset, surface_size);
+        trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
         qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
     }
 }
@@ -1791,7 +1796,7 @@ static void qxl_pre_save(void *opaque)
     PCIQXLDevice* d = opaque;
     uint8_t *ram_start = d->vga.vram_ptr;
 
-    dprint(d, 1, "%s:\n", __FUNCTION__);
+    trace_qxl_pre_save(d->id);
     if (d->last_release == NULL) {
         d->last_release_offset = 0;
     } else {
@@ -1804,10 +1809,9 @@ static int qxl_pre_load(void *opaque)
 {
     PCIQXLDevice* d = opaque;
 
-    dprint(d, 1, "%s: start\n", __FUNCTION__);
+    trace_qxl_pre_load(d->id);
     qxl_hard_reset(d, 1);
     qxl_exit_vga_mode(d);
-    dprint(d, 1, "%s: done\n", __FUNCTION__);
     return 0;
 }
 
@@ -1819,7 +1823,6 @@ static void qxl_create_memslots(PCIQXLDevice *d)
         if (!d->guest_slots[i].active) {
             continue;
         }
-        dprint(d, 1, "%s: restoring guest slot %d\n", __func__, i);
         qxl_add_memslot(d, i, 0, QXL_SYNC);
     }
 }
@@ -1831,8 +1834,6 @@ static int qxl_post_load(void *opaque, int version)
     QXLCommandExt *cmds;
     int in, out, newmode;
 
-    dprint(d, 1, "%s: start\n", __FUNCTION__);
-
     assert(d->last_release_offset < d->vga.vram_size);
     if (d->last_release_offset == 0) {
         d->last_release = NULL;
@@ -1842,8 +1843,7 @@ static int qxl_post_load(void *opaque, int version)
 
     d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
 
-    dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__,
-        qxl_mode_to_string(d->mode));
+    trace_qxl_post_load(d->id, qxl_mode_to_string(d->mode));
     newmode = d->mode;
     d->mode = QXL_MODE_UNDEFINED;
 
@@ -1885,8 +1885,6 @@ static int qxl_post_load(void *opaque, int version)
         qxl_set_mode(d, d->shadow_rom.mode, 1);
         break;
     }
-    dprint(d, 1, "%s: done\n", __FUNCTION__);
-
     return 0;
 }
 
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 2cb5a18da2..8e76c5d32c 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -7,6 +7,7 @@
 #include "trace.h"
 #include "dma.h"
 
+static char *scsibus_get_dev_path(DeviceState *dev);
 static char *scsibus_get_fw_dev_path(DeviceState *dev);
 static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
 static void scsi_req_dequeue(SCSIRequest *req);
@@ -14,6 +15,7 @@ static void scsi_req_dequeue(SCSIRequest *req);
 static struct BusInfo scsi_bus_info = {
     .name  = "SCSI",
     .size  = sizeof(SCSIBus),
+    .get_dev_path = scsibus_get_dev_path,
     .get_fw_dev_path = scsibus_get_fw_dev_path,
     .props = (Property[]) {
         DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
@@ -1423,6 +1425,22 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
     sdev->unit_attention = sense;
 }
 
+static char *scsibus_get_dev_path(DeviceState *dev)
+{
+    SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
+    DeviceState *hba = dev->parent_bus->parent;
+    char *id = NULL;
+
+    if (hba && hba->parent_bus && hba->parent_bus->info->get_dev_path) {
+        id = hba->parent_bus->info->get_dev_path(hba);
+    }
+    if (id) {
+        return g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun);
+    } else {
+        return g_strdup_printf("%d:%d:%d", d->channel, d->id, d->lun);
+    }
+}
+
 static char *scsibus_get_fw_dev_path(DeviceState *dev)
 {
     SCSIDevice *d = SCSI_DEVICE(dev);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index add399e97b..9949786e52 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -471,8 +471,9 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
 
         case 0x83: /* Device identification page, mandatory */
         {
-            int max_len = 255 - 8;
-            int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs));
+            const char *str = s->serial ?: bdrv_get_device_name(s->qdev.conf.bs);
+            int max_len = s->serial ? 20 : 255 - 8;
+            int id_len = strlen(str);
 
             if (id_len > max_len) {
                 id_len = max_len;
@@ -486,7 +487,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
             outbuf[buflen++] = 0;   // reserved
             outbuf[buflen++] = id_len; // length of data following
 
-            memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len);
+            memcpy(outbuf+buflen, str, id_len);
             buflen += id_len;
             break;
         }
@@ -1152,9 +1153,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
     outbuf = r->iov.iov_base;
     switch (req->cmd.buf[0]) {
     case TEST_UNIT_READY:
-        if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
-            goto not_ready;
-        }
+        assert(!s->tray_open && bdrv_is_inserted(s->qdev.conf.bs));
         break;
     case INQUIRY:
         buflen = scsi_disk_emulate_inquiry(req, outbuf);
@@ -1209,7 +1208,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
         memset(outbuf, 0, 8);
         bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
         if (!nb_sectors) {
-            goto not_ready;
+            scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
+            return -1;
         }
         if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
             goto illegal_request;
@@ -1269,7 +1269,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
             memset(outbuf, 0, req->cmd.xfer);
             bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
             if (!nb_sectors) {
-                goto not_ready;
+                scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
+                return -1;
             }
             if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
                 goto illegal_request;
@@ -1314,14 +1315,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
     buflen = MIN(buflen, req->cmd.xfer);
     return buflen;
 
-not_ready:
-    if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
-        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
-    } else {
-        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
-    }
-    return -1;
-
 illegal_request:
     if (r->req.status == -1) {
         scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
@@ -1356,6 +1349,30 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
 #endif
 
     switch (command) {
+    case INQUIRY:
+    case MODE_SENSE:
+    case MODE_SENSE_10:
+    case RESERVE:
+    case RESERVE_10:
+    case RELEASE:
+    case RELEASE_10:
+    case START_STOP:
+    case ALLOW_MEDIUM_REMOVAL:
+    case GET_CONFIGURATION:
+    case GET_EVENT_STATUS_NOTIFICATION:
+    case MECHANISM_STATUS:
+    case REQUEST_SENSE:
+        break;
+
+    default:
+        if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
+            scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
+            return 0;
+        }
+        break;
+    }
+
+    switch (command) {
     case TEST_UNIT_READY:
     case INQUIRY:
     case MODE_SENSE:
diff --git a/hw/serial.c b/hw/serial.c
index c0ee55d20c..a421d1e7bc 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -327,9 +327,12 @@ static void serial_xmit(void *opaque)
             s->tsr = fifo_get(s,XMIT_FIFO);
             if (!s->xmit_fifo.count)
                 s->lsr |= UART_LSR_THRE;
+        } else if ((s->lsr & UART_LSR_THRE)) {
+            return;
         } else {
             s->tsr = s->thr;
             s->lsr |= UART_LSR_THRE;
+            s->lsr &= ~UART_LSR_TEMT;
         }
     }
 
@@ -337,7 +340,7 @@ static void serial_xmit(void *opaque)
         /* in loopback mode, say that we just received a char */
         serial_receive1(s, &s->tsr, 1);
     } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
-        if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
+        if ((s->tsr_retry >= 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
             s->tsr_retry++;
             qemu_mod_timer(s->transmit_timer,  new_xmit_ts + s->char_transmit_time);
             return;
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 4d5b60fd1f..1b15f399f1 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -255,7 +255,7 @@ static inline void strongarm_rtc_int_update(StrongARMRTCState *s)
 
 static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rt_clock);
+    int64_t rt = qemu_get_clock_ms(rtc_clock);
     s->last_rcnr += ((rt - s->last_hz) << 15) /
             (1000 * ((s->rttr & 0xffff) + 1));
     s->last_hz = rt;
@@ -308,7 +308,7 @@ static uint64_t strongarm_rtc_read(void *opaque, target_phys_addr_t addr,
         return s->rtar;
     case RCNR:
         return s->last_rcnr +
-                ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+                ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
                 (1000 * ((s->rttr & 0xffff) + 1));
     default:
         printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
@@ -374,10 +374,10 @@ static int strongarm_rtc_init(SysBusDevice *dev)
     qemu_get_timedate(&tm, 0);
 
     s->last_rcnr = (uint32_t) mktimegm(&tm);
-    s->last_hz = qemu_get_clock_ms(rt_clock);
+    s->last_hz = qemu_get_clock_ms(rtc_clock);
 
-    s->rtc_alarm = qemu_new_timer_ms(rt_clock, strongarm_rtc_alarm_tick, s);
-    s->rtc_hz = qemu_new_timer_ms(rt_clock, strongarm_rtc_hz_tick, s);
+    s->rtc_alarm = qemu_new_timer_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
+    s->rtc_hz = qemu_new_timer_ms(rtc_clock, strongarm_rtc_hz_tick, s);
 
     sysbus_init_irq(dev, &s->rtc_irq);
     sysbus_init_irq(dev, &s->rtc_hz_irq);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 7bcbf37e98..34088ad185 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -932,8 +932,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],
                               display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
-    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],
               serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
 
@@ -1581,8 +1581,8 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[12],
                               display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
-    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, sbi_irq[12], sbi_irq[12],
               serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
 
@@ -1762,8 +1762,8 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[1],
                               display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
-    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, slavio_irq[1],
               slavio_irq[1], serial_hds[0], serial_hds[1],
               ESCC_CLOCK, 1);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 237e20c1bf..fe3313890d 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -248,6 +248,10 @@ void cpu_check_irqs(CPUSPARCState *env)
     uint32_t pil = env->pil_in |
                   (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
 
+    /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
+    if (env->ivec_status & 0x20) {
+        return;
+    }
     /* check if TM or SM in SOFTINT are set
        setting these also causes interrupt 14 */
     if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
@@ -275,7 +279,8 @@ void cpu_check_irqs(CPUSPARCState *env)
                 int old_interrupt = env->interrupt_index;
                 int new_interrupt = TT_EXTINT | i;
 
-                if (env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt) {
+                if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
+                  && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
                     CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
                                    "current %x >= pending %x\n",
                                    env->tl, cpu_tsptr(env)->tt, new_interrupt);
@@ -309,19 +314,22 @@ static void cpu_set_ivec_irq(void *opaque, int irq, int level)
     CPUSPARCState *env = opaque;
 
     if (level) {
-        CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
-        env->interrupt_index = TT_IVEC;
-        env->pil_in |= 1 << 5;
-        env->ivec_status |= 0x20;
-        env->ivec_data[0] = (0x1f << 6) | irq;
-        env->ivec_data[1] = 0;
-        env->ivec_data[2] = 0;
-        cpu_interrupt(env, CPU_INTERRUPT_HARD);
-      } else {
-        CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
-        env->pil_in &= ~(1 << 5);
-        env->ivec_status &= ~0x20;
-        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+        if (!(env->ivec_status & 0x20)) {
+            CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
+            env->halted = 0;
+            env->interrupt_index = TT_IVEC;
+            env->ivec_status |= 0x20;
+            env->ivec_data[0] = (0x1f << 6) | irq;
+            env->ivec_data[1] = 0;
+            env->ivec_data[2] = 0;
+            cpu_interrupt(env, CPU_INTERRUPT_HARD);
+        }
+    } else {
+        if (env->ivec_status & 0x20) {
+            CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
+            env->ivec_status &= ~0x20;
+            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+        }
     }
 }
 
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 22da6f8001..0d70d8498d 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -22,6 +22,7 @@
 #include "hw.h"
 #include "qemu-timer.h"
 #include "i2c.h"
+#include "sysemu.h"
 #include "console.h"
 
 #define VERBOSE 1
@@ -71,14 +72,14 @@ static inline void menelaus_update(MenelausState *s)
 
 static inline void menelaus_rtc_start(MenelausState *s)
 {
-    s->rtc.next += qemu_get_clock_ms(rt_clock);
+    s->rtc.next += qemu_get_clock_ms(rtc_clock);
     qemu_mod_timer(s->rtc.hz_tm, s->rtc.next);
 }
 
 static inline void menelaus_rtc_stop(MenelausState *s)
 {
     qemu_del_timer(s->rtc.hz_tm);
-    s->rtc.next -= qemu_get_clock_ms(rt_clock);
+    s->rtc.next -= qemu_get_clock_ms(rtc_clock);
     if (s->rtc.next < 1)
         s->rtc.next = 1;
 }
@@ -781,7 +782,7 @@ static void menelaus_pre_save(void *opaque)
 {
     MenelausState *s = opaque;
     /* Should be <= 1000 */
-    s->rtc_next_vmstate =  s->rtc.next - qemu_get_clock_ms(rt_clock);
+    s->rtc_next_vmstate =  s->rtc.next - qemu_get_clock_ms(rtc_clock);
 }
 
 static int menelaus_post_load(void *opaque, int version_id)
@@ -842,7 +843,7 @@ static int twl92230_init(I2CSlave *i2c)
 {
     MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
 
-    s->rtc.hz_tm = qemu_new_timer_ms(rt_clock, menelaus_rtc_hz, s);
+    s->rtc.hz_tm = qemu_new_timer_ms(rtc_clock, menelaus_rtc_hz, s);
     /* Three output pins plus one interrupt pin.  */
     qdev_init_gpio_out(&i2c->qdev, s->out, 4);
 
diff --git a/hw/vga.c b/hw/vga.c
index 6dc98f6c2a..f80860caed 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2415,7 +2415,7 @@ static void vga_screen_dump(void *opaque, const char *filename, bool cswitch)
 
     if (cswitch) {
         vga_invalidate_display(s);
-        vga_hw_update();
     }
+    vga_hw_update();
     ppm_save(filename, s->ds->surface);
 }
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index e607edc915..45d54faeb5 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -613,5 +613,7 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
 
 void virtio_scsi_exit(VirtIODevice *vdev)
 {
+    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
+    unregister_savevm(s->qdev, "virtio-scsi", s);
     virtio_cleanup(vdev);
 }
diff --git a/hw/xen_console.c b/hw/xen_console.c
index edcb31ce66..3794b1972d 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -248,6 +248,9 @@ static void con_disconnect(struct XenDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
 
+    if (!xendev->dev) {
+        return;
+    }
     if (con->chr)
         qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
     xen_be_unbind_evtchn(&con->xendev);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 68fa36a1cf..9719395b09 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -330,6 +330,9 @@ static void qemu_aio_complete(void *opaque, int ret)
     if (ioreq->aio_inflight > 0) {
         return;
     }
+    if (ioreq->postsync) {
+        bdrv_flush(ioreq->blkdev->bs);
+    }
 
     ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
     ioreq_unmap(ioreq);
@@ -376,9 +379,6 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         goto err;
     }
 
-    if (ioreq->postsync) {
-        bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
-    }
     qemu_aio_complete(ioreq, 0);
 
     return 0;
@@ -584,10 +584,10 @@ static int blk_init(struct XenDevice *xendev)
     }
 
     /* read-only ? */
+    qflags = BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
     if (strcmp(blkdev->mode, "w") == 0) {
-        qflags = BDRV_O_RDWR;
+        qflags |= BDRV_O_RDWR;
     } else {
-        qflags = 0;
         info  |= VDISK_READONLY;
     }
 
@@ -726,6 +726,7 @@ static void blk_disconnect(struct XenDevice *xendev)
         if (!blkdev->dinfo) {
             /* close/delete only if we created it ourself */
             bdrv_close(blkdev->bs);
+            bdrv_detach_dev(blkdev->bs, blkdev);
             bdrv_delete(blkdev->bs);
         }
         blkdev->bs = NULL;
diff --git a/include/qemu/object.h b/include/qemu/object.h
index e8fc1268b3..a675937da1 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -837,6 +837,18 @@ Object *object_resolve_path_type(const char *path, const char *typename,
                                  bool *ambiguous);
 
 /**
+ * object_resolve_path_component:
+ * @parent: the object in which to resolve the path
+ * @part: the component to resolve.
+ *
+ * This is similar to object_resolve_path with an absolute path, but it
+ * only resolves one element (@part) and takes the others from @parent.
+ *
+ * Returns: The resolved object or NULL on path lookup failure.
+ */
+Object *object_resolve_path_component(Object *parent, gchar *part);
+
+/**
  * object_property_add_child:
  * @obj: the object to add a property to
  * @name: the name of the property
@@ -891,4 +903,16 @@ void object_property_add_str(Object *obj, const char *name,
                              void (*set)(Object *, const char *, struct Error **),
                              struct Error **errp);
 
+/**
+ * container_get:
+ * @path: path to the container
+ *
+ * Return a container object whose path is @path.  Create more containers
+ * along the path if necessary.
+ *
+ * Returns: the container object.
+ */
+Object *container_get(const char *path);
+
+
 #endif
diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index bdc3c79462..802cae3a29 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -682,8 +682,19 @@ vcard_emul_event_thread(void *arg)
     SECMODModule *module = (SECMODModule *)arg;
 
     do {
+        /*
+         * XXX - the latency value doesn't matter one bit. you only get no
+         * blocking (flags |= CKF_DONT_BLOCK) or PKCS11_WAIT_LATENCY (==500),
+         * hard coded in coolkey.  And it isn't coolkey's fault - the timeout
+         * value we pass get's dropped on the floor before C_WaitForSlotEvent
+         * is called.
+         */
         slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500);
         if (slot == NULL) {
+            /* this could be just a no event indication */
+            if (PORT_GetError() == SEC_ERROR_NO_EVENT) {
+                continue;
+            }
             break;
         }
         vreader = vcard_emul_find_vreader_from_slot(slot);
@@ -994,10 +1005,10 @@ vcard_emul_init(const VCardEmulOptions *options)
     SECMOD_GetReadLock(module_lock);
     for (mlp = module_list; mlp; mlp = mlp->next) {
         SECMODModule *module = mlp->module;
-        PRBool has_emul_slots = PR_FALSE;
 
-        if (module == NULL) {
-                continue;
+        /* Ignore the internal module */
+        if (module == NULL || module == SECMOD_GetInternalModule()) {
+            continue;
         }
 
         for (i = 0; i < module->slotCount; i++) {
@@ -1007,15 +1018,22 @@ vcard_emul_init(const VCardEmulOptions *options)
             if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) {
                 continue;
             }
+            if (strcmp("E-Gate 0 0", PK11_GetSlotName(slot)) == 0) {
+                /*
+                 * coolkey <= 1.1.0-20 emulates this reader if it can't find
+                 * any hardware readers. This causes problems, warn user of
+                 * problems.
+                 */
+                fprintf(stderr, "known bad coolkey version - see "
+                        "https://bugzilla.redhat.com/show_bug.cgi?id=802435\n");
+                continue;
+            }
             vreader_emul = vreader_emul_new(slot, options->hw_card_type,
                                             options->hw_type_params);
             vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                   vreader_emul_delete);
             vreader_add_reader(vreader);
 
-            has_readers = PR_TRUE;
-            has_emul_slots = PR_TRUE;
-
             if (PK11_IsPresent(slot)) {
                 VCard *vcard;
                 vcard = vcard_emul_mirror_card(vreader);
@@ -1024,12 +1042,10 @@ vcard_emul_init(const VCardEmulOptions *options)
                 vcard_free(vcard);
             }
         }
-        if (has_emul_slots) {
-            vcard_emul_new_event_thread(module);
-        }
+        vcard_emul_new_event_thread(module);
     }
     SECMOD_ReleaseReadLock(module_lock);
-    nss_emul_init = has_readers;
+    nss_emul_init = PR_TRUE;
 
     return VCARD_EMUL_OK;
 }
diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index 7f05879ea3..5356395659 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -339,7 +339,7 @@
 #define TARGET_NR_fchmodat			(333)
 #define TARGET_NR_faccessat			(334)
 #define TARGET_NR_pselect6			(335)
-					/* 336 for ppoll */
+#define TARGET_NR_ppoll                         (336)
 #define TARGET_NR_unshare			(337)
 #define TARGET_NR_set_robust_list		(338)
 #define TARGET_NR_get_robust_list		(339)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e502b39007..f3b1552e9e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -375,10 +375,33 @@ bool guest_validate_base(unsigned long guest_base)
     return 1; /* All good */
 }
 
-#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF               \
-                   | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT      \
-                   | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP              \
-                   | ARM_HWCAP_ARM_NEON | ARM_HWCAP_ARM_VFPv3 )
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+    CPUARMState *e = thread_env;
+    uint32_t hwcaps = 0;
+
+    hwcaps |= ARM_HWCAP_ARM_SWP;
+    hwcaps |= ARM_HWCAP_ARM_HALF;
+    hwcaps |= ARM_HWCAP_ARM_THUMB;
+    hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
+    hwcaps |= ARM_HWCAP_ARM_FPA;
+
+    /* probe for the extra features */
+#define GET_FEATURE(feat, hwcap) \
+    do {if (arm_feature(e, feat)) { hwcaps |= hwcap; } } while (0)
+    GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
+    GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
+    GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
+    GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
+    GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
+    GET_FEATURE(ARM_FEATURE_VFP_FP16, ARM_HWCAP_ARM_VFPv3D16);
+#undef GET_FEATURE
+
+    return hwcaps;
+}
 
 #endif
 
@@ -1553,6 +1576,7 @@ static void load_elf_image(const char *image_name, int image_fd,
     info->start_data = -1;
     info->end_data = 0;
     info->brk = 0;
+    info->elf_flags = ehdr->e_flags;
 
     for (i = 0; i < ehdr->e_phnum; i++) {
         struct elf_phdr *eppnt = phdr + i;
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 6514502dc4..eb96a084c2 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -74,6 +74,8 @@
      IOCTL(BLKFLSBUF, 0, TYPE_NULL)
      IOCTL(BLKRASET, 0, TYPE_INT)
      IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
+     IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
+     IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
 #ifdef FIBMAP
      IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
 #endif
@@ -345,3 +347,35 @@
   IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
   IOCTL(VT_RELDISP, 0, TYPE_INT)
   IOCTL(VT_DISALLOCATE, 0, TYPE_INT)
+
+  IOCTL(DM_VERSION, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_REMOVE_ALL,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_LIST_DEVICES, IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_CREATE,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_REMOVE,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_RENAME,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_SUSPEND,  IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_STATUS,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_WAIT,     IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_LOAD,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_CLEAR,  IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_DEPS,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_STATUS, IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_LIST_VERSIONS,IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TARGET_MSG,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_SET_GEOMETRY, IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
diff --git a/linux-user/main.c b/linux-user/main.c
index 962677e01d..191b75060d 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -33,6 +33,7 @@
 #include "tcg.h"
 #include "qemu-timer.h"
 #include "envlist.h"
+#include "elf.h"
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
@@ -48,8 +49,19 @@ unsigned long mmap_min_addr;
 #if defined(CONFIG_USE_GUEST_BASE)
 unsigned long guest_base;
 int have_guest_base;
+#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
+/*
+ * When running 32-on-64 we should make sure we can fit all of the possible
+ * guest address space into a contiguous chunk of virtual host memory.
+ *
+ * This way we will never overlap with our own libraries or binaries or stack
+ * or anything else that QEMU maps.
+ */
+unsigned long reserved_va = 0xf7000000;
+#else
 unsigned long reserved_va;
 #endif
+#endif
 
 static void usage(void);
 
@@ -463,6 +475,22 @@ void cpu_loop(CPUX86State *env)
 
 #ifdef TARGET_ARM
 
+#define get_user_code_u32(x, gaddr, doswap)             \
+    ({ abi_long __r = get_user_u32((x), (gaddr));       \
+        if (!__r && (doswap)) {                         \
+            (x) = bswap32(x);                           \
+        }                                               \
+        __r;                                            \
+    })
+
+#define get_user_code_u16(x, gaddr, doswap)             \
+    ({ abi_long __r = get_user_u16((x), (gaddr));       \
+        if (!__r && (doswap)) {                         \
+            (x) = bswap16(x);                           \
+        }                                               \
+        __r;                                            \
+    })
+
 /*
  * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
  * Input:
@@ -696,7 +724,7 @@ void cpu_loop(CPUARMState *env)
                 /* we handle the FPU emulation here, as Linux */
                 /* we get the opcode */
                 /* FIXME - what to do if get_user() fails? */
-                get_user_u32(opcode, env->regs[15]);
+                get_user_code_u32(opcode, env->regs[15], env->bswap_code);
 
                 rc = EmulateAll(opcode, &ts->fpa, env);
                 if (rc == 0) { /* illegal instruction */
@@ -766,23 +794,25 @@ void cpu_loop(CPUARMState *env)
                 if (trapnr == EXCP_BKPT) {
                     if (env->thumb) {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u16(insn, env->regs[15]);
+                        get_user_code_u16(insn, env->regs[15], env->bswap_code);
                         n = insn & 0xff;
                         env->regs[15] += 2;
                     } else {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u32(insn, env->regs[15]);
+                        get_user_code_u32(insn, env->regs[15], env->bswap_code);
                         n = (insn & 0xf) | ((insn >> 4) & 0xff0);
                         env->regs[15] += 4;
                     }
                 } else {
                     if (env->thumb) {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u16(insn, env->regs[15] - 2);
+                        get_user_code_u16(insn, env->regs[15] - 2,
+                                          env->bswap_code);
                         n = insn & 0xff;
                     } else {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u32(insn, env->regs[15] - 4);
+                        get_user_code_u32(insn, env->regs[15] - 4,
+                                          env->bswap_code);
                         n = insn & 0xffffff;
                     }
                 }
@@ -3420,6 +3450,7 @@ int main(int argc, char **argv, char **envp)
             guest_base = HOST_PAGE_ALIGN((unsigned long)p);
         }
         qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va);
+        mmap_next_start = reserved_va;
     }
 
     if (reserved_va || have_guest_base) {
@@ -3486,11 +3517,6 @@ int main(int argc, char **argv, char **envp)
         _exit(1);
     }
 
-    for (i = 0; i < target_argc; i++) {
-        free(target_argv[i]);
-    }
-    free(target_argv);
-
     for (wrk = target_environ; *wrk; wrk++) {
         free(*wrk);
     }
@@ -3650,6 +3676,11 @@ int main(int argc, char **argv, char **envp)
         for(i = 0; i < 16; i++) {
             env->regs[i] = regs->uregs[i];
         }
+        /* Enable BE8.  */
+        if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
+            && (info->elf_flags & EF_ARM_BE8)) {
+            env->bswap_code = 1;
+        }
     }
 #elif defined(TARGET_UNICORE32)
     {
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 994c02bb77..7125d1cd4b 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -212,7 +212,7 @@ static int mmap_frag(abi_ulong real_start,
 #else
 # define TASK_UNMAPPED_BASE  0x40000000
 #endif
-static abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
+abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
 
 unsigned long last_brk;
 
@@ -222,7 +222,7 @@ unsigned long last_brk;
 static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
 {
     abi_ulong addr;
-    abi_ulong last_addr;
+    abi_ulong end_addr;
     int prot;
     int looped = 0;
 
@@ -230,25 +230,38 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
         return (abi_ulong)-1;
     }
 
-    last_addr = start;
-    for (addr = start; last_addr + size != addr; addr += qemu_host_page_size) {
-        if (last_addr + size >= RESERVED_VA
-            || (abi_ulong)(last_addr + size) < last_addr) {
+    size = HOST_PAGE_ALIGN(size);
+    end_addr = start + size;
+    if (end_addr > RESERVED_VA) {
+        end_addr = RESERVED_VA;
+    }
+    addr = end_addr - qemu_host_page_size;
+
+    while (1) {
+        if (addr > end_addr) {
             if (looped) {
                 return (abi_ulong)-1;
             }
-            last_addr = qemu_host_page_size;
-            addr = 0;
+            end_addr = RESERVED_VA;
+            addr = end_addr - qemu_host_page_size;
             looped = 1;
             continue;
         }
         prot = page_get_flags(addr);
         if (prot) {
-            last_addr = addr + qemu_host_page_size;
+            end_addr = addr;
+        }
+        if (addr + size == end_addr) {
+            break;
         }
+        addr -= qemu_host_page_size;
+    }
+
+    if (start == mmap_next_start) {
+        mmap_next_start = addr;
     }
-    mmap_next_start = addr;
-    return last_addr;
+
+    return addr;
 }
 #endif
 
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 68895671ed..7b299b7bc3 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -51,6 +51,7 @@ struct image_info {
         abi_ulong       auxv_len;
         abi_ulong       arg_start;
         abi_ulong       arg_end;
+        uint32_t        elf_flags;
 	int		personality;
 #ifdef CONFIG_USE_FDPIC
         abi_ulong       loadmap_addr;
@@ -251,6 +252,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
                        abi_ulong new_addr);
 int target_msync(abi_ulong start, abi_ulong len, int flags);
 extern unsigned long last_brk;
+extern abi_ulong mmap_next_start;
 void mmap_lock(void);
 void mmap_unlock(void);
 abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9f5e53a7fe..8a92162155 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -95,6 +95,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #endif
 #include <linux/fb.h>
 #include <linux/vt.h>
+#include <linux/dm-ioctl.h>
 #include "linux_loop.h"
 #include "cpu-uname.h"
 
@@ -3354,6 +3355,231 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
     return ret;
 }
 
+static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
+                            abi_long cmd, abi_long arg)
+{
+    void *argptr;
+    struct dm_ioctl *host_dm;
+    abi_long guest_data;
+    uint32_t guest_data_size;
+    int target_size;
+    const argtype *arg_type = ie->arg_type;
+    abi_long ret;
+    void *big_buf = NULL;
+    char *host_data;
+
+    arg_type++;
+    target_size = thunk_type_size(arg_type, 0);
+    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+    if (!argptr) {
+        ret = -TARGET_EFAULT;
+        goto out;
+    }
+    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+    unlock_user(argptr, arg, 0);
+
+    /* buf_temp is too small, so fetch things into a bigger buffer */
+    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
+    memcpy(big_buf, buf_temp, target_size);
+    buf_temp = big_buf;
+    host_dm = big_buf;
+
+    guest_data = arg + host_dm->data_start;
+    if ((guest_data - arg) < 0) {
+        ret = -EINVAL;
+        goto out;
+    }
+    guest_data_size = host_dm->data_size - host_dm->data_start;
+    host_data = (char*)host_dm + host_dm->data_start;
+
+    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
+    switch (ie->host_cmd) {
+    case DM_REMOVE_ALL:
+    case DM_LIST_DEVICES:
+    case DM_DEV_CREATE:
+    case DM_DEV_REMOVE:
+    case DM_DEV_SUSPEND:
+    case DM_DEV_STATUS:
+    case DM_DEV_WAIT:
+    case DM_TABLE_STATUS:
+    case DM_TABLE_CLEAR:
+    case DM_TABLE_DEPS:
+    case DM_LIST_VERSIONS:
+        /* no input data */
+        break;
+    case DM_DEV_RENAME:
+    case DM_DEV_SET_GEOMETRY:
+        /* data contains only strings */
+        memcpy(host_data, argptr, guest_data_size);
+        break;
+    case DM_TARGET_MSG:
+        memcpy(host_data, argptr, guest_data_size);
+        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
+        break;
+    case DM_TABLE_LOAD:
+    {
+        void *gspec = argptr;
+        void *cur_data = host_data;
+        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
+        int spec_size = thunk_type_size(arg_type, 0);
+        int i;
+
+        for (i = 0; i < host_dm->target_count; i++) {
+            struct dm_target_spec *spec = cur_data;
+            uint32_t next;
+            int slen;
+
+            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
+            slen = strlen((char*)gspec + spec_size) + 1;
+            next = spec->next;
+            spec->next = sizeof(*spec) + slen;
+            strcpy((char*)&spec[1], gspec + spec_size);
+            gspec += next;
+            cur_data += spec->next;
+        }
+        break;
+    }
+    default:
+        ret = -TARGET_EINVAL;
+        goto out;
+    }
+    unlock_user(argptr, guest_data, 0);
+
+    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
+    if (!is_error(ret)) {
+        guest_data = arg + host_dm->data_start;
+        guest_data_size = host_dm->data_size - host_dm->data_start;
+        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
+        switch (ie->host_cmd) {
+        case DM_REMOVE_ALL:
+        case DM_DEV_CREATE:
+        case DM_DEV_REMOVE:
+        case DM_DEV_RENAME:
+        case DM_DEV_SUSPEND:
+        case DM_DEV_STATUS:
+        case DM_TABLE_LOAD:
+        case DM_TABLE_CLEAR:
+        case DM_TARGET_MSG:
+        case DM_DEV_SET_GEOMETRY:
+            /* no return data */
+            break;
+        case DM_LIST_DEVICES:
+        {
+            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
+            uint32_t remaining_data = guest_data_size;
+            void *cur_data = argptr;
+            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
+            int nl_size = 12; /* can't use thunk_size due to alignment */
+
+            while (1) {
+                uint32_t next = nl->next;
+                if (next) {
+                    nl->next = nl_size + (strlen(nl->name) + 1);
+                }
+                if (remaining_data < nl->next) {
+                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
+                    break;
+                }
+                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
+                strcpy(cur_data + nl_size, nl->name);
+                cur_data += nl->next;
+                remaining_data -= nl->next;
+                if (!next) {
+                    break;
+                }
+                nl = (void*)nl + next;
+            }
+            break;
+        }
+        case DM_DEV_WAIT:
+        case DM_TABLE_STATUS:
+        {
+            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
+            void *cur_data = argptr;
+            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
+            int spec_size = thunk_type_size(arg_type, 0);
+            int i;
+
+            for (i = 0; i < host_dm->target_count; i++) {
+                uint32_t next = spec->next;
+                int slen = strlen((char*)&spec[1]) + 1;
+                spec->next = (cur_data - argptr) + spec_size + slen;
+                if (guest_data_size < spec->next) {
+                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
+                    break;
+                }
+                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
+                strcpy(cur_data + spec_size, (char*)&spec[1]);
+                cur_data = argptr + spec->next;
+                spec = (void*)host_dm + host_dm->data_start + next;
+            }
+            break;
+        }
+        case DM_TABLE_DEPS:
+        {
+            void *hdata = (void*)host_dm + host_dm->data_start;
+            int count = *(uint32_t*)hdata;
+            uint64_t *hdev = hdata + 8;
+            uint64_t *gdev = argptr + 8;
+            int i;
+
+            *(uint32_t*)argptr = tswap32(count);
+            for (i = 0; i < count; i++) {
+                *gdev = tswap64(*hdev);
+                gdev++;
+                hdev++;
+            }
+            break;
+        }
+        case DM_LIST_VERSIONS:
+        {
+            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
+            uint32_t remaining_data = guest_data_size;
+            void *cur_data = argptr;
+            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
+            int vers_size = thunk_type_size(arg_type, 0);
+
+            while (1) {
+                uint32_t next = vers->next;
+                if (next) {
+                    vers->next = vers_size + (strlen(vers->name) + 1);
+                }
+                if (remaining_data < vers->next) {
+                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
+                    break;
+                }
+                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
+                strcpy(cur_data + vers_size, vers->name);
+                cur_data += vers->next;
+                remaining_data -= vers->next;
+                if (!next) {
+                    break;
+                }
+                vers = (void*)vers + next;
+            }
+            break;
+        }
+        default:
+            ret = -TARGET_EINVAL;
+            goto out;
+        }
+        unlock_user(argptr, guest_data, guest_data_size);
+
+        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+        if (!argptr) {
+            ret = -TARGET_EFAULT;
+            goto out;
+        }
+        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
+        unlock_user(argptr, arg, target_size);
+    }
+out:
+    if (big_buf) {
+        free(big_buf);
+    }
+    return ret;
+}
+
 static IOCTLEntry ioctl_entries[] = {
 #define IOCTL(cmd, access, ...) \
     { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
@@ -4662,11 +4888,22 @@ static int open_self_stat(void *cpu_env, int fd)
       int len;
       uint64_t val = 0;
 
-      if (i == 27) {
-          /* stack bottom */
-          val = start_stack;
+      if (i == 0) {
+        /* pid */
+        val = getpid();
+        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
+      } else if (i == 1) {
+        /* app name */
+        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
+      } else if (i == 27) {
+        /* stack bottom */
+        val = start_stack;
+        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
+      } else {
+        /* for the rest, there is MasterCard */
+        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
       }
-      snprintf(buf, sizeof(buf), "%"PRId64 "%c", val, i == 43 ? '\n' : ' ');
+
       len = strlen(buf);
       if (write(fd, buf, len) != len) {
           return -1;
@@ -7005,21 +7242,46 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
     case TARGET_NR_prctl:
-        switch (arg1)
-            {
-            case PR_GET_PDEATHSIG:
-                {
-                    int deathsig;
-                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
-                    if (!is_error(ret) && arg2
-                        && put_user_ual(deathsig, arg2))
-                        goto efault;
-                }
-                break;
-            default:
-                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
-                break;
+        switch (arg1) {
+        case PR_GET_PDEATHSIG:
+        {
+            int deathsig;
+            ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
+            if (!is_error(ret) && arg2
+                && put_user_ual(deathsig, arg2)) {
+                goto efault;
             }
+            break;
+        }
+#ifdef PR_GET_NAME
+        case PR_GET_NAME:
+        {
+            void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
+            if (!name) {
+                goto efault;
+            }
+            ret = get_errno(prctl(arg1, (unsigned long)name,
+                                  arg3, arg4, arg5));
+            unlock_user(name, arg2, 16);
+            break;
+        }
+        case PR_SET_NAME:
+        {
+            void *name = lock_user(VERIFY_READ, arg2, 16, 1);
+            if (!name) {
+                goto efault;
+            }
+            ret = get_errno(prctl(arg1, (unsigned long)name,
+                                  arg3, arg4, arg5));
+            unlock_user(name, arg2, 0);
+            break;
+        }
+#endif
+        default:
+            /* Most prctl options have no pointer arguments */
+            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
+            break;
+        }
         break;
 #ifdef TARGET_NR_arch_prctl
     case TARGET_NR_arch_prctl:
@@ -8248,7 +8510,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif /* CONFIG_EVENTFD  */
 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
     case TARGET_NR_fallocate:
+#if TARGET_ABI_BITS == 32
+        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
+                                  target_offset64(arg5, arg6)));
+#else
         ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
+#endif
         break;
 #endif
 #if defined(CONFIG_SYNC_FILE_RANGE)
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 41f0ff8c7d..a79b67df49 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -832,9 +832,11 @@ struct target_pollfd {
 #define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
 #define TARGET_BLKSSZGET  TARGET_IO(0x12,104)/* get block device sector size */
 /* A jump here: 108-111 have been used for various private purposes. */
-#define TARGET_BLKBSZGET  TARGET_IOR(0x12,112,sizeof(int))
-#define TARGET_BLKBSZSET  TARGET_IOW(0x12,113,sizeof(int))
-#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */
+#define TARGET_BLKBSZGET  TARGET_IOR(0x12,112,int)
+#define TARGET_BLKBSZSET  TARGET_IOW(0x12,113,int)
+#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
+                                             /* return device size in bytes
+                                                (u64 *arg) */
 #define TARGET_FIBMAP     TARGET_IO(0x00,1)  /* bmap access */
 #define TARGET_FIGETBSZ   TARGET_IO(0x00,2)  /* get the block size used for bmap */
 #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
@@ -989,6 +991,24 @@ struct target_pollfd {
 #define TARGET_VT_RELDISP             0x5605
 #define TARGET_VT_DISALLOCATE         0x5608
 
+/* device mapper */
+#define TARGET_DM_VERSION             TARGET_IOWRU(0xfd, 0x00)
+#define TARGET_DM_REMOVE_ALL          TARGET_IOWRU(0xfd, 0x01)
+#define TARGET_DM_LIST_DEVICES        TARGET_IOWRU(0xfd, 0x02)
+#define TARGET_DM_DEV_CREATE          TARGET_IOWRU(0xfd, 0x03)
+#define TARGET_DM_DEV_REMOVE          TARGET_IOWRU(0xfd, 0x04)
+#define TARGET_DM_DEV_RENAME          TARGET_IOWRU(0xfd, 0x05)
+#define TARGET_DM_DEV_SUSPEND         TARGET_IOWRU(0xfd, 0x06)
+#define TARGET_DM_DEV_STATUS          TARGET_IOWRU(0xfd, 0x07)
+#define TARGET_DM_DEV_WAIT            TARGET_IOWRU(0xfd, 0x08)
+#define TARGET_DM_TABLE_LOAD          TARGET_IOWRU(0xfd, 0x09)
+#define TARGET_DM_TABLE_CLEAR         TARGET_IOWRU(0xfd, 0x0a)
+#define TARGET_DM_TABLE_DEPS          TARGET_IOWRU(0xfd, 0x0b)
+#define TARGET_DM_TABLE_STATUS        TARGET_IOWRU(0xfd, 0x0c)
+#define TARGET_DM_LIST_VERSIONS       TARGET_IOWRU(0xfd, 0x0d)
+#define TARGET_DM_TARGET_MSG          TARGET_IOWRU(0xfd, 0x0e)
+#define TARGET_DM_DEV_SET_GEOMETRY    TARGET_IOWRU(0xfd, 0x0f)
+
 /* from asm/termbits.h */
 
 #define TARGET_NCC 8
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index c370125170..601618df98 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -83,9 +83,9 @@ STRUCT(mixer_info,
 /* loop device ioctls */
 STRUCT(loop_info,
        TYPE_INT,                 /* lo_number */
-       TYPE_SHORT,               /* lo_device */
+       TYPE_OLDDEVT,             /* lo_device */
        TYPE_ULONG,               /* lo_inode */
-       TYPE_SHORT,               /* lo_rdevice */
+       TYPE_OLDDEVT,             /* lo_rdevice */
        TYPE_INT,                 /* lo_offset */
        TYPE_INT,                 /* lo_encrypt_type */
        TYPE_INT,                 /* lo_encrypt_key_size */
@@ -186,6 +186,42 @@ STRUCT(vt_mode,
        TYPE_SHORT, /* acqsig */
        TYPE_SHORT) /* frsig  */
 
+STRUCT(dm_ioctl,
+       MK_ARRAY(TYPE_INT, 3), /* version */
+       TYPE_INT, /* data_size */
+       TYPE_INT, /* data_start */
+       TYPE_INT, /* target_count*/
+       TYPE_INT, /* open_count */
+       TYPE_INT, /* flags */
+       TYPE_INT, /* event_nr */
+       TYPE_INT, /* padding */
+       TYPE_ULONGLONG, /* dev */
+       MK_ARRAY(TYPE_CHAR, 128), /* name */
+       MK_ARRAY(TYPE_CHAR, 129), /* uuid */
+       MK_ARRAY(TYPE_CHAR, 7)) /* data */
+
+STRUCT(dm_target_spec,
+       TYPE_ULONGLONG, /* sector_start */
+       TYPE_ULONGLONG, /* length */
+       TYPE_INT, /* status */
+       TYPE_INT, /* next */
+       MK_ARRAY(TYPE_CHAR, 16)) /* target_type */
+
+STRUCT(dm_target_deps,
+       TYPE_INT, /* count */
+       TYPE_INT) /* padding */
+
+STRUCT(dm_name_list,
+       TYPE_ULONGLONG, /* dev */
+       TYPE_INT) /* next */
+
+STRUCT(dm_target_versions,
+       TYPE_INT, /* next */
+       MK_ARRAY(TYPE_INT, 3)) /* version*/
+
+STRUCT(dm_target_msg,
+       TYPE_ULONGLONG) /* sector */
+
 STRUCT(fiemap_extent,
        TYPE_ULONGLONG, /* fe_logical */
        TYPE_ULONGLONG, /* fe_physical */
diff --git a/lm32-dis.c b/lm32-dis.c
new file mode 100644
index 0000000000..709ed3215c
--- /dev/null
+++ b/lm32-dis.c
@@ -0,0 +1,361 @@
+/*
+ *  Simple LatticeMico32 disassembler.
+ *
+ *  Copyright (c) 2012 Michael Walle <michael@walle.cc>
+ *
+ * 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 <stdio.h>
+#include "dis-asm.h"
+
+typedef enum {
+    LM32_OP_SRUI = 0, LM32_OP_NORI, LM32_OP_MULI, LM32_OP_SH, LM32_OP_LB,
+    LM32_OP_SRI, LM32_OP_XORI, LM32_OP_LH, LM32_OP_ANDI, LM32_OP_XNORI,
+    LM32_OP_LW, LM32_OP_LHU, LM32_OP_SB, LM32_OP_ADDI, LM32_OP_ORI,
+    LM32_OP_SLI, LM32_OP_LBU, LM32_OP_BE, LM32_OP_BG, LM32_OP_BGE,
+    LM32_OP_BGEU, LM32_OP_BGU, LM32_OP_SW, LM32_OP_BNE, LM32_OP_ANDHI,
+    LM32_OP_CMPEI, LM32_OP_CMPGI, LM32_OP_CMPGEI, LM32_OP_CMPGEUI,
+    LM32_OP_CMPGUI, LM32_OP_ORHI, LM32_OP_CMPNEI, LM32_OP_SRU, LM32_OP_NOR,
+    LM32_OP_MUL, LM32_OP_DIVU, LM32_OP_RCSR, LM32_OP_SR, LM32_OP_XOR,
+    LM32_OP_ILL0, LM32_OP_AND, LM32_OP_XNOR, LM32_OP_ILL1, LM32_OP_SCALL,
+    LM32_OP_SEXTB, LM32_OP_ADD, LM32_OP_OR, LM32_OP_SL, LM32_OP_B,
+    LM32_OP_MODU, LM32_OP_SUB, LM32_OP_ILL2, LM32_OP_WCSR, LM32_OP_ILL3,
+    LM32_OP_CALL, LM32_OP_SEXTH, LM32_OP_BI, LM32_OP_CMPE, LM32_OP_CMPG,
+    LM32_OP_CMPGE, LM32_OP_CMPGEU, LM32_OP_CMPGU, LM32_OP_CALLI, LM32_OP_CMPNE,
+} Lm32Opcode;
+
+typedef enum {
+    FMT_INVALID = 0, FMT_RRI5, FMT_RRI16, FMT_IMM26, FMT_LOAD, FMT_STORE,
+    FMT_RRR, FMT_R, FMT_RNR, FMT_CRN, FMT_CNR, FMT_BREAK,
+} Lm32OpcodeFmt;
+
+typedef enum {
+    LM32_CSR_IE = 0, LM32_CSR_IM, LM32_CSR_IP, LM32_CSR_ICC, LM32_CSR_DCC,
+    LM32_CSR_CC, LM32_CSR_CFG, LM32_CSR_EBA, LM32_CSR_DC, LM32_CSR_DEBA,
+    LM32_CSR_CFG2, LM32_CSR_JTX = 0xe, LM32_CSR_JRX, LM32_CSR_BP0,
+    LM32_CSR_BP1, LM32_CSR_BP2, LM32_CSR_BP3, LM32_CSR_WP0 = 0x18,
+    LM32_CSR_WP1, LM32_CSR_WP2, LM32_CSR_WP3,
+} Lm32CsrNum;
+
+typedef struct {
+    int csr;
+    const char *name;
+} Lm32CsrInfo;
+
+static const Lm32CsrInfo lm32_csr_info[] = {
+    {LM32_CSR_IE,   "ie", },
+    {LM32_CSR_IM,   "im", },
+    {LM32_CSR_IP,   "ip", },
+    {LM32_CSR_ICC,  "icc", },
+    {LM32_CSR_DCC,  "dcc", },
+    {LM32_CSR_CC,   "cc", },
+    {LM32_CSR_CFG,  "cfg", },
+    {LM32_CSR_EBA,  "eba", },
+    {LM32_CSR_DC,   "dc", },
+    {LM32_CSR_DEBA, "deba", },
+    {LM32_CSR_CFG2, "cfg2", },
+    {LM32_CSR_JTX,  "jtx", },
+    {LM32_CSR_JRX,  "jrx", },
+    {LM32_CSR_BP0,  "bp0", },
+    {LM32_CSR_BP1,  "bp1", },
+    {LM32_CSR_BP2,  "bp2", },
+    {LM32_CSR_BP3,  "bp3", },
+    {LM32_CSR_WP0,  "wp0", },
+    {LM32_CSR_WP1,  "wp1", },
+    {LM32_CSR_WP2,  "wp2", },
+    {LM32_CSR_WP3,  "wp3", },
+};
+
+static const Lm32CsrInfo *find_csr_info(int csr)
+{
+    const Lm32CsrInfo *info;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(lm32_csr_info); i++) {
+        info = &lm32_csr_info[i];
+        if (csr == info->csr) {
+            return info;
+        }
+    }
+
+    return NULL;
+}
+
+typedef struct {
+    int reg;
+    const char *name;
+} Lm32RegInfo;
+
+typedef enum {
+    LM32_REG_R0 = 0, LM32_REG_R1, LM32_REG_R2, LM32_REG_R3, LM32_REG_R4,
+    LM32_REG_R5, LM32_REG_R6, LM32_REG_R7, LM32_REG_R8, LM32_REG_R9,
+    LM32_REG_R10, LM32_REG_R11, LM32_REG_R12, LM32_REG_R13, LM32_REG_R14,
+    LM32_REG_R15, LM32_REG_R16, LM32_REG_R17, LM32_REG_R18, LM32_REG_R19,
+    LM32_REG_R20, LM32_REG_R21, LM32_REG_R22, LM32_REG_R23, LM32_REG_R24,
+    LM32_REG_R25, LM32_REG_GP, LM32_REG_FP, LM32_REG_SP, LM32_REG_RA,
+    LM32_REG_EA, LM32_REG_BA,
+} Lm32RegNum;
+
+static const Lm32RegInfo lm32_reg_info[] = {
+    {LM32_REG_R0,  "r0", },
+    {LM32_REG_R1,  "r1", },
+    {LM32_REG_R2,  "r2", },
+    {LM32_REG_R3,  "r3", },
+    {LM32_REG_R4,  "r4", },
+    {LM32_REG_R5,  "r5", },
+    {LM32_REG_R6,  "r6", },
+    {LM32_REG_R7,  "r7", },
+    {LM32_REG_R8,  "r8", },
+    {LM32_REG_R9,  "r9", },
+    {LM32_REG_R10, "r10", },
+    {LM32_REG_R11, "r11", },
+    {LM32_REG_R12, "r12", },
+    {LM32_REG_R13, "r13", },
+    {LM32_REG_R14, "r14", },
+    {LM32_REG_R15, "r15", },
+    {LM32_REG_R16, "r16", },
+    {LM32_REG_R17, "r17", },
+    {LM32_REG_R18, "r18", },
+    {LM32_REG_R19, "r19", },
+    {LM32_REG_R20, "r20", },
+    {LM32_REG_R21, "r21", },
+    {LM32_REG_R22, "r22", },
+    {LM32_REG_R23, "r23", },
+    {LM32_REG_R24, "r24", },
+    {LM32_REG_R25, "r25", },
+    {LM32_REG_GP,  "gp", },
+    {LM32_REG_FP,  "fp", },
+    {LM32_REG_SP,  "sp", },
+    {LM32_REG_RA,  "ra", },
+    {LM32_REG_EA,  "ea", },
+    {LM32_REG_BA,  "ba", },
+};
+
+static const Lm32RegInfo *find_reg_info(int reg)
+{
+    assert(ARRAY_SIZE(lm32_reg_info) == 32);
+    return &lm32_reg_info[reg & 0x1f];
+}
+
+typedef struct {
+    struct {
+        uint32_t code;
+        uint32_t mask;
+    } op;
+    const char *name;
+    const char *args_fmt;
+} Lm32OpcodeInfo;
+
+static const Lm32OpcodeInfo lm32_opcode_info[] = {
+    /* pseudo instructions */
+    {{0x34000000, 0xffffffff}, "nop",   NULL},
+    {{0xac000002, 0xffffffff}, "break", NULL},
+    {{0xac000003, 0xffffffff}, "scall", NULL},
+    {{0xc3e00000, 0xffffffff}, "bret",  NULL},
+    {{0xc3c00000, 0xffffffff}, "eret",  NULL},
+    {{0xc3a00000, 0xffffffff}, "ret",   NULL},
+    {{0xa4000000, 0xfc1f07ff}, "not",   "%2, %0"},
+    {{0xb8000000, 0xfc1f07ff}, "mv",    "%2, %0"},
+    {{0x71e00000, 0xffe00000}, "mvhi",  "%1, %u"},
+    {{0x34000000, 0xffe00000}, "mvi",   "%1, %s"},
+
+#define _O(op) {op << 26, 0x3f << 26}
+    /* regular opcodes */
+    {_O(LM32_OP_ADD),     "add",     "%2, %0, %1"  },
+    {_O(LM32_OP_ADDI),    "addi",    "%1, %0, %s"  },
+    {_O(LM32_OP_AND),     "and",     "%2, %0, %1"  },
+    {_O(LM32_OP_ANDHI),   "andhi",   "%1, %0, %u"  },
+    {_O(LM32_OP_ANDI),    "andi",    "%1, %0, %u"  },
+    {_O(LM32_OP_B),       "b",       "%0",         },
+    {_O(LM32_OP_BE),      "be",      "%1, %0, %r"  },
+    {_O(LM32_OP_BG),      "bg",      "%1, %0, %r"  },
+    {_O(LM32_OP_BGE),     "bge",     "%1, %0, %r"  },
+    {_O(LM32_OP_BGEU),    "bgeu",    "%1, %0, %r"  },
+    {_O(LM32_OP_BGU),     "bgu",     "%1, %0, %r"  },
+    {_O(LM32_OP_BI),      "bi",      "%R",         },
+    {_O(LM32_OP_BNE),     "bne",     "%1, %0, %r"  },
+    {_O(LM32_OP_CALL),    "call",    "%0",         },
+    {_O(LM32_OP_CALLI),   "calli",   "%R",         },
+    {_O(LM32_OP_CMPE),    "cmpe",    "%2, %0, %1"  },
+    {_O(LM32_OP_CMPEI),   "cmpei",   "%1, %0, %s"  },
+    {_O(LM32_OP_CMPG),    "cmpg",    "%2, %0, %1"  },
+    {_O(LM32_OP_CMPGE),   "cmpge",   "%2, %0, %1"  },
+    {_O(LM32_OP_CMPGEI),  "cmpgei",  "%1, %0, %s"  },
+    {_O(LM32_OP_CMPGEU),  "cmpgeu",  "%2, %0, %1"  },
+    {_O(LM32_OP_CMPGEUI), "cmpgeui", "%1, %0, %s"  },
+    {_O(LM32_OP_CMPGI),   "cmpgi",   "%1, %0, %s"  },
+    {_O(LM32_OP_CMPGU),   "cmpgu",   "%2, %0, %1"  },
+    {_O(LM32_OP_CMPGUI),  "cmpgui",  "%1, %0, %s"  },
+    {_O(LM32_OP_CMPNE),   "cmpne",   "%2, %0, %1"  },
+    {_O(LM32_OP_CMPNEI),  "cmpnei",  "%1, %0, %s"  },
+    {_O(LM32_OP_DIVU),    "divu",    "%2, %0, %1"  },
+    {_O(LM32_OP_LB),      "lb",      "%1, (%0+%s)" },
+    {_O(LM32_OP_LBU),     "lbu",     "%1, (%0+%s)" },
+    {_O(LM32_OP_LH),      "lh",      "%1, (%0+%s)" },
+    {_O(LM32_OP_LHU),     "lhu",     "%1, (%0+%s)" },
+    {_O(LM32_OP_LW),      "lw",      "%1, (%0+%s)" },
+    {_O(LM32_OP_MODU),    "modu",    "%2, %0, %1"  },
+    {_O(LM32_OP_MULI),    "muli",    "%1, %0, %s"  },
+    {_O(LM32_OP_MUL),     "mul",     "%2, %0, %1"  },
+    {_O(LM32_OP_NORI),    "nori",    "%1, %0, %u"  },
+    {_O(LM32_OP_NOR),     "nor",     "%2, %0, %1"  },
+    {_O(LM32_OP_ORHI),    "orhi",    "%1, %0, %u"  },
+    {_O(LM32_OP_ORI),     "ori",     "%1, %0, %u"  },
+    {_O(LM32_OP_OR),      "or",      "%2, %0, %1"  },
+    {_O(LM32_OP_RCSR),    "rcsr",    "%2, %c",     },
+    {_O(LM32_OP_SB),      "sb",      "(%0+%s), %1" },
+    {_O(LM32_OP_SEXTB),   "sextb",   "%2, %0",     },
+    {_O(LM32_OP_SEXTH),   "sexth",   "%2, %0",     },
+    {_O(LM32_OP_SH),      "sh",      "(%0+%s), %1" },
+    {_O(LM32_OP_SLI),     "sli",     "%1, %0, %h"  },
+    {_O(LM32_OP_SL),      "sl",      "%2, %0, %1"  },
+    {_O(LM32_OP_SRI),     "sri",     "%1, %0, %h"  },
+    {_O(LM32_OP_SR),      "sr",      "%2, %0, %1"  },
+    {_O(LM32_OP_SRUI),    "srui",    "%1, %0, %d"  },
+    {_O(LM32_OP_SRU),     "sru",     "%2, %0, %s"  },
+    {_O(LM32_OP_SUB),     "sub",     "%2, %0, %s"  },
+    {_O(LM32_OP_SW),      "sw",      "(%0+%s), %1" },
+    {_O(LM32_OP_WCSR),    "wcsr",    "%c, %1",     },
+    {_O(LM32_OP_XNORI),   "xnori",   "%1, %0, %u"  },
+    {_O(LM32_OP_XNOR),    "xnor",    "%2, %0, %1"  },
+    {_O(LM32_OP_XORI),    "xori",    "%1, %0, %u"  },
+    {_O(LM32_OP_XOR),     "xor",     "%2, %0, %1"  },
+#undef _O
+};
+
+static const Lm32OpcodeInfo *find_opcode_info(uint32_t opcode)
+{
+    const Lm32OpcodeInfo *info;
+    int i;
+    for (i = 0; i < ARRAY_SIZE(lm32_opcode_info); i++) {
+        info = &lm32_opcode_info[i];
+        if ((opcode & info->op.mask) == info->op.code) {
+            return info;
+        }
+    }
+
+    return NULL;
+}
+
+int print_insn_lm32(bfd_vma memaddr, struct disassemble_info *info)
+{
+    fprintf_function fprintf_fn = info->fprintf_func;
+    void *stream = info->stream;
+    int rc;
+    uint8_t insn[4];
+    const Lm32OpcodeInfo *opc_info;
+    uint32_t op;
+    const char *args_fmt;
+
+    rc = info->read_memory_func(memaddr, insn, 4, info);
+    if (rc != 0) {
+        info->memory_error_func(rc, memaddr, info);
+        return -1;
+    }
+
+    fprintf_fn(stream, "%02x %02x %02x %02x    ",
+            insn[0], insn[1], insn[2], insn[3]);
+
+    op = bfd_getb32(insn);
+    opc_info = find_opcode_info(op);
+    if (opc_info) {
+        fprintf_fn(stream, "%-8s ", opc_info->name);
+        args_fmt = opc_info->args_fmt;
+        while (args_fmt && *args_fmt) {
+            if (*args_fmt == '%') {
+                switch (*(++args_fmt)) {
+                case '0': {
+                    uint8_t r0;
+                    const char *r0_name;
+                    r0 = (op >> 21) & 0x1f;
+                    r0_name = find_reg_info(r0)->name;
+                    fprintf_fn(stream, "%s", r0_name);
+                    break;
+                }
+                case '1': {
+                    uint8_t r1;
+                    const char *r1_name;
+                    r1 = (op >> 16) & 0x1f;
+                    r1_name = find_reg_info(r1)->name;
+                    fprintf_fn(stream, "%s", r1_name);
+                    break;
+                }
+                case '2': {
+                    uint8_t r2;
+                    const char *r2_name;
+                    r2 = (op >> 11) & 0x1f;
+                    r2_name = find_reg_info(r2)->name;
+                    fprintf_fn(stream, "%s", r2_name);
+                    break;
+                }
+                case 'c': {
+                    uint8_t csr;
+                    const char *csr_name;
+                    csr = (op >> 21) & 0x1f;
+                    csr_name = find_csr_info(csr)->name;
+                    if (csr_name) {
+                        fprintf_fn(stream, "%s", csr_name);
+                    } else {
+                        fprintf_fn(stream, "0x%x", csr);
+                    }
+                    break;
+                }
+                case 'u': {
+                    uint16_t u16;
+                    u16 = op & 0xffff;
+                    fprintf_fn(stream, "0x%x", u16);
+                    break;
+                }
+                case 's': {
+                    int16_t s16;
+                    s16 = (int16_t)(op & 0xffff);
+                    fprintf_fn(stream, "%d", s16);
+                    break;
+                }
+                case 'r': {
+                    uint32_t rela;
+                    rela = memaddr + (((int16_t)(op & 0xffff)) << 2);
+                    fprintf_fn(stream, "%x", rela);
+                    break;
+                }
+                case 'R': {
+                    uint32_t rela;
+                    int32_t imm26;
+                    imm26 = (int32_t)((op & 0x3ffffff) << 6) >> 4;
+                    rela = memaddr + imm26;
+                    fprintf_fn(stream, "%x", rela);
+                    break;
+                }
+                case 'h': {
+                    uint8_t u5;
+                    u5 = (op & 0x1f);
+                    fprintf_fn(stream, "%d", u5);
+                    break;
+                }
+                default:
+                    break;
+                }
+            } else {
+                fprintf_fn(stream, "%c", *args_fmt);
+            }
+            args_fmt++;
+        }
+    } else {
+        fprintf_fn(stream, ".word 0x%x", op);
+    }
+
+    return 4;
+}
diff --git a/main-loop.c b/main-loop.c
index db23de0497..7e163f9428 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -218,17 +218,19 @@ int main_loop_init(void)
     return 0;
 }
 
-
+static fd_set rfds, wfds, xfds;
+static int nfds;
 static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
 static int n_poll_fds;
 static int max_priority;
 
+#ifndef _WIN32
 static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
-                             fd_set *xfds, struct timeval *tv)
+                             fd_set *xfds, int *cur_timeout)
 {
     GMainContext *context = g_main_context_default();
     int i;
-    int timeout = 0, cur_timeout;
+    int timeout = 0;
 
     g_main_context_prepare(context, &max_priority);
 
@@ -253,10 +255,8 @@ static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
         }
     }
 
-    cur_timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 500) / 1000);
-    if (timeout >= 0 && timeout < cur_timeout) {
-        tv->tv_sec = timeout / 1000;
-        tv->tv_usec = (timeout % 1000) * 1000;
+    if (timeout >= 0 && timeout < *cur_timeout) {
+        *cur_timeout = timeout;
     }
 }
 
@@ -288,7 +288,29 @@ static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
     }
 }
 
-#ifdef _WIN32
+static int os_host_main_loop_wait(int timeout)
+{
+    struct timeval tv;
+    int ret;
+
+    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout);
+
+    if (timeout > 0) {
+        qemu_mutex_unlock_iothread();
+    }
+
+    tv.tv_sec = timeout / 1000;
+    tv.tv_usec = (timeout % 1000) * 1000;
+    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+
+    if (timeout > 0) {
+        qemu_mutex_lock_iothread();
+    }
+
+    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    return ret;
+}
+#else
 /***********************************************************/
 /* Polling handling */
 
@@ -328,6 +350,7 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque)
 /* Wait objects support */
 typedef struct WaitObjects {
     int num;
+    int revents[MAXIMUM_WAIT_OBJECTS + 1];
     HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
     WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
     void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
@@ -344,6 +367,7 @@ int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
     w->events[w->num] = handle;
     w->func[w->num] = func;
     w->opaque[w->num] = opaque;
+    w->revents[w->num] = 0;
     w->num++;
     return 0;
 }
@@ -362,6 +386,7 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
             w->events[i] = w->events[i + 1];
             w->func[i] = w->func[i + 1];
             w->opaque[i] = w->opaque[i + 1];
+            w->revents[i] = w->revents[i + 1];
         }
     }
     if (found) {
@@ -369,61 +394,76 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
     }
 }
 
-static void os_host_main_loop_wait(int *timeout)
+void qemu_fd_register(int fd)
 {
-    int ret, ret2, i;
+    WSAEventSelect(fd, qemu_event_handle, FD_READ | FD_ACCEPT | FD_CLOSE |
+                   FD_CONNECT | FD_WRITE | FD_OOB);
+}
+
+static int os_host_main_loop_wait(int timeout)
+{
+    GMainContext *context = g_main_context_default();
+    int ret, i;
     PollingEntry *pe;
+    WaitObjects *w = &wait_objects;
+    static struct timeval tv0;
 
     /* XXX: need to suppress polling by better using win32 events */
     ret = 0;
     for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
         ret |= pe->func(pe->opaque);
     }
-    if (ret == 0) {
-        int err;
-        WaitObjects *w = &wait_objects;
+    if (ret != 0) {
+        return ret;
+    }
 
-        qemu_mutex_unlock_iothread();
-        ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
-        qemu_mutex_lock_iothread();
-        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
-            if (w->func[ret - WAIT_OBJECT_0]) {
-                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
-            }
+    if (nfds >= 0) {
+        ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
+        if (ret != 0) {
+            timeout = 0;
+        }
+    }
+
+    g_main_context_prepare(context, &max_priority);
+    n_poll_fds = g_main_context_query(context, max_priority, &timeout,
+                                      poll_fds, ARRAY_SIZE(poll_fds));
+    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
 
-            /* Check for additional signaled events */
-            for (i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
-                /* Check if event is signaled */
-                ret2 = WaitForSingleObject(w->events[i], 0);
-                if (ret2 == WAIT_OBJECT_0) {
-                    if (w->func[i]) {
-                        w->func[i](w->opaque[i]);
-                    }
-                } else if (ret2 != WAIT_TIMEOUT) {
-                    err = GetLastError();
-                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
-                }
+    for (i = 0; i < w->num; i++) {
+        poll_fds[n_poll_fds + i].fd = (DWORD) w->events[i];
+        poll_fds[n_poll_fds + i].events = G_IO_IN;
+    }
+
+    qemu_mutex_unlock_iothread();
+    ret = g_poll(poll_fds, n_poll_fds + w->num, timeout);
+    qemu_mutex_lock_iothread();
+    if (ret > 0) {
+        for (i = 0; i < w->num; i++) {
+            w->revents[i] = poll_fds[n_poll_fds + i].revents;
+        }
+        for (i = 0; i < w->num; i++) {
+            if (w->revents[i] && w->func[i]) {
+                w->func[i](w->opaque[i]);
             }
-        } else if (ret != WAIT_TIMEOUT) {
-            err = GetLastError();
-            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
         }
     }
 
-    *timeout = 0;
-}
-#else
-static inline void os_host_main_loop_wait(int *timeout)
-{
+    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
+        g_main_context_dispatch(context);
+    }
+
+    /* If an edge-triggered socket event occurred, select will return a
+     * positive result on the next iteration.  We do not need to do anything
+     * here.
+     */
+
+    return ret;
 }
 #endif
 
 int main_loop_wait(int nonblocking)
 {
-    fd_set rfds, wfds, xfds;
-    int ret, nfds;
-    struct timeval tv;
-    int timeout;
+    int ret, timeout;
 
     if (nonblocking) {
         timeout = 0;
@@ -432,11 +472,6 @@ int main_loop_wait(int nonblocking)
         qemu_bh_update_timeout(&timeout);
     }
 
-    os_host_main_loop_wait(&timeout);
-
-    tv.tv_sec = timeout / 1000;
-    tv.tv_usec = (timeout % 1000) * 1000;
-
     /* poll any events */
     /* XXX: separate device handlers from system ones */
     nfds = -1;
@@ -448,19 +483,7 @@ int main_loop_wait(int nonblocking)
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 #endif
     qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
-    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &tv);
-
-    if (timeout > 0) {
-        qemu_mutex_unlock_iothread();
-    }
-
-    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
-
-    if (timeout > 0) {
-        qemu_mutex_lock_iothread();
-    }
-
-    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    ret = os_host_main_loop_wait(timeout);
     qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
 #ifdef CONFIG_SLIRP
     slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
diff --git a/main-loop.h b/main-loop.h
index 4987041ce7..e743aa0cf6 100644
--- a/main-loop.h
+++ b/main-loop.h
@@ -359,6 +359,7 @@ void qemu_mutex_unlock_iothread(void);
 
 /* internal interfaces */
 
+void qemu_fd_register(int fd);
 void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds);
 void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int rc);
 
diff --git a/migration-fd.c b/migration-fd.c
index 5a068c632a..50138edb34 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -75,7 +75,7 @@ static int fd_close(MigrationState *s)
 
 int fd_start_outgoing_migration(MigrationState *s, const char *fdname)
 {
-    s->fd = monitor_get_fd(s->mon, fdname);
+    s->fd = monitor_get_fd(cur_mon, fdname);
     if (s->fd == -1) {
         DPRINTF("fd_migration: invalid file descriptor identifier\n");
         goto err_after_get_fd;
diff --git a/migration.c b/migration.c
index 00fa1e3f72..8c119ba8ff 100644
--- a/migration.c
+++ b/migration.c
@@ -158,16 +158,6 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 
 /* shared migration helpers */
 
-static void migrate_fd_monitor_suspend(MigrationState *s, Monitor *mon)
-{
-    if (monitor_suspend(mon) == 0) {
-        DPRINTF("suspending monitor\n");
-    } else {
-        monitor_printf(mon, "terminal does not allow synchronous "
-                       "migration, continuing detached\n");
-    }
-}
-
 static int migrate_fd_cleanup(MigrationState *s)
 {
     int ret = 0;
@@ -178,10 +168,6 @@ static int migrate_fd_cleanup(MigrationState *s)
         DPRINTF("closing file\n");
         ret = qemu_fclose(s->file);
         s->file = NULL;
-    } else {
-        if (s->mon) {
-            monitor_resume(s->mon);
-        }
     }
 
     if (s->fd != -1) {
@@ -258,7 +244,7 @@ static void migrate_fd_put_ready(void *opaque)
     }
 
     DPRINTF("iterate\n");
-    ret = qemu_savevm_state_iterate(s->mon, s->file);
+    ret = qemu_savevm_state_iterate(s->file);
     if (ret < 0) {
         migrate_fd_error(s);
     } else if (ret == 1) {
@@ -267,7 +253,7 @@ static void migrate_fd_put_ready(void *opaque)
         DPRINTF("done iterating\n");
         vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
 
-        if (qemu_savevm_state_complete(s->mon, s->file) < 0) {
+        if (qemu_savevm_state_complete(s->file) < 0) {
             migrate_fd_error(s);
         } else {
             migrate_fd_completed(s);
@@ -289,7 +275,7 @@ static void migrate_fd_cancel(MigrationState *s)
 
     s->state = MIG_STATE_CANCELLED;
     notifier_list_notify(&migration_state_notifiers, s);
-    qemu_savevm_state_cancel(s->mon, s->file);
+    qemu_savevm_state_cancel(s->file);
 
     migrate_fd_cleanup(s);
 }
@@ -321,9 +307,6 @@ static int migrate_fd_close(void *opaque)
 {
     MigrationState *s = opaque;
 
-    if (s->mon) {
-        monitor_resume(s->mon);
-    }
     qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
     return s->close(s);
 }
@@ -367,7 +350,7 @@ void migrate_fd_connect(MigrationState *s)
                                       migrate_fd_close);
 
     DPRINTF("beginning savevm\n");
-    ret = qemu_savevm_state_begin(s->mon, s->file, s->blk, s->shared);
+    ret = qemu_savevm_state_begin(s->file, s->blk, s->shared);
     if (ret < 0) {
         DPRINTF("failed, %d\n", ret);
         migrate_fd_error(s);
@@ -376,7 +359,7 @@ void migrate_fd_connect(MigrationState *s)
     migrate_fd_put_ready(s);
 }
 
-static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc)
+static MigrationState *migrate_init(int blk, int inc)
 {
     MigrationState *s = migrate_get_current();
     int64_t bandwidth_limit = s->bandwidth_limit;
@@ -386,18 +369,9 @@ static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc)
     s->blk = blk;
     s->shared = inc;
 
-    /* s->mon is used for two things:
-       - pass fd in fd migration
-       - suspend/resume monitor for not detached migration
-    */
-    s->mon = mon;
     s->bandwidth_limit = bandwidth_limit;
     s->state = MIG_STATE_SETUP;
 
-    if (!detach) {
-        migrate_fd_monitor_suspend(s, mon);
-    }
-
     return s;
 }
 
@@ -413,32 +387,29 @@ void migrate_del_blocker(Error *reason)
     migration_blockers = g_slist_remove(migration_blockers, reason);
 }
 
-int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void qmp_migrate(const char *uri, bool has_blk, bool blk,
+                 bool has_inc, bool inc, bool has_detach, bool detach,
+                 Error **errp)
 {
     MigrationState *s = migrate_get_current();
     const char *p;
-    int detach = qdict_get_try_bool(qdict, "detach", 0);
-    int blk = qdict_get_try_bool(qdict, "blk", 0);
-    int inc = qdict_get_try_bool(qdict, "inc", 0);
-    const char *uri = qdict_get_str(qdict, "uri");
     int ret;
 
     if (s->state == MIG_STATE_ACTIVE) {
-        monitor_printf(mon, "migration already in progress\n");
-        return -1;
+        error_set(errp, QERR_MIGRATION_ACTIVE);
+        return;
     }
 
-    if (qemu_savevm_state_blocked(mon)) {
-        return -1;
+    if (qemu_savevm_state_blocked(errp)) {
+        return;
     }
 
     if (migration_blockers) {
-        Error *err = migration_blockers->data;
-        qerror_report_err(err);
-        return -1;
+        *errp = error_copy(migration_blockers->data);
+        return;
     }
 
-    s = migrate_init(mon, detach, blk, inc);
+    s = migrate_init(blk, inc);
 
     if (strstart(uri, "tcp:", &p)) {
         ret = tcp_start_outgoing_migration(s, p);
@@ -451,21 +422,18 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
         ret = fd_start_outgoing_migration(s, p);
 #endif
     } else {
-        monitor_printf(mon, "unknown migration protocol: %s\n", uri);
-        ret  = -EINVAL;
+        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol");
+        return;
     }
 
     if (ret < 0) {
-        monitor_printf(mon, "migration failed: %s\n", strerror(-ret));
-        return ret;
-    }
-
-    if (detach) {
-        s->mon = NULL;
+        DPRINTF("migration failed: %s\n", strerror(-ret));
+        /* FIXME: we should return meaningful errors */
+        error_set(errp, QERR_UNDEFINED_ERROR);
+        return;
     }
 
     notifier_list_notify(&migration_state_notifiers, s);
-    return 0;
 }
 
 void qmp_migrate_cancel(Error **errp)
diff --git a/migration.h b/migration.h
index 372b066b48..691b367389 100644
--- a/migration.h
+++ b/migration.h
@@ -26,7 +26,6 @@ struct MigrationState
     int64_t bandwidth_limit;
     QEMUFile *file;
     int fd;
-    Monitor *mon;
     int state;
     int (*get_error)(MigrationState *s);
     int (*close)(MigrationState *s);
@@ -40,8 +39,6 @@ void process_incoming_migration(QEMUFile *f);
 
 int qemu_start_incoming_migration(const char *uri);
 
-int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
-
 uint64_t migrate_max_downtime(void);
 
 void do_info_migrate_print(Monitor *mon, const QObject *data);
@@ -78,7 +75,7 @@ uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_transferred(void);
 uint64_t ram_bytes_total(void);
 
-int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
+int ram_save_live(QEMUFile *f, int stage, void *opaque);
 int ram_load(QEMUFile *f, void *opaque, int version_id);
 
 /**
diff --git a/module.c b/module.c
index 106a969449..c3a6da7a86 100644
--- a/module.c
+++ b/module.c
@@ -19,7 +19,6 @@
 
 typedef struct ModuleEntry
 {
-    module_init_type type;
     void (*init)(void);
     QTAILQ_ENTRY(ModuleEntry) node;
 } ModuleEntry;
diff --git a/monitor.c b/monitor.c
index d57e7bf61d..8946a100c0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -128,7 +128,6 @@ typedef struct mon_cmd_t {
         int  (*cmd_async)(Monitor *mon, const QDict *params,
                           MonitorCompletion *cb, void *opaque);
     } mhandler;
-    bool qapi;
     int flags;
 } mon_cmd_t;
 
@@ -880,6 +879,11 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict,
             return -1;
         }
 
+        if (port == -1 && tls_port == -1) {
+            qerror_report(QERR_MISSING_PARAMETER, "port/tls-port");
+            return -1;
+        }
+
         ret = qemu_spice_migrate_info(hostname, port, tls_port, subject,
                                       cb, opaque);
         if (ret != 0) {
@@ -4153,6 +4157,9 @@ static int check_client_args_type(const QDict *client_args,
         case 'O':
             assert(flags & QMP_ACCEPT_UNKNOWNS);
             break;
+        case 'q':
+            /* Any QObject can be passed.  */
+            break;
         case '/':
         case '.':
             /*
diff --git a/osdep.h b/osdep.h
index 156666e0ee..428285c7e0 100644
--- a/osdep.h
+++ b/osdep.h
@@ -140,4 +140,6 @@ static inline void qemu_timersub(const struct timeval *val1,
 #define qemu_timersub timersub
 #endif
 
+void qemu_set_cloexec(int fd);
+
 #endif
diff --git a/oslib-win32.c b/oslib-win32.c
index ce3021e6c7..ffbc6d0c9f 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -28,6 +28,7 @@
 #include <windows.h>
 #include "config-host.h"
 #include "sysemu.h"
+#include "main-loop.h"
 #include "trace.h"
 #include "qemu_socket.h"
 
@@ -76,6 +77,7 @@ void qemu_vfree(void *ptr)
 void socket_set_block(int fd)
 {
     unsigned long opt = 0;
+    WSAEventSelect(fd, NULL, 0);
     ioctlsocket(fd, FIONBIO, &opt);
 }
 
@@ -83,6 +85,7 @@ void socket_set_nonblock(int fd)
 {
     unsigned long opt = 1;
     ioctlsocket(fd, FIONBIO, &opt);
+    qemu_fd_register(fd);
 }
 
 int inet_aton(const char *cp, struct in_addr *ia)
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index 41e2b38ea2..e1f3923681 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differdiff --git a/ppc-dis.c b/ppc-dis.c
index ffdbec18db..bc98cbe655 100644
--- a/ppc-dis.c
+++ b/ppc-dis.c
@@ -5152,7 +5152,7 @@ powerpc_dialect (struct disassemble_info *info)
   return dialect;
 }
 
-/* Qemu default */
+/* QEMU default */
 int
 print_insn_ppc (bfd_vma memaddr, struct disassemble_info *info)
 {
diff --git a/qapi-schema-test.json b/qapi-schema-test.json
index 8c7f9f79f4..9eae3501d7 100644
--- a/qapi-schema-test.json
+++ b/qapi-schema-test.json
@@ -8,7 +8,7 @@
 
 # for testing nested structs
 { 'type': 'UserDefOne',
-  'data': { 'integer': 'int', 'string': 'str' } }
+  'data': { 'integer': 'int', 'string': 'str', '*enum1': 'EnumOne' } }
 
 { 'type': 'UserDefTwo',
   'data': { 'string': 'str',
diff --git a/qapi-schema.json b/qapi-schema.json
index 04fa84fbde..0d11d6eb14 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1663,3 +1663,41 @@
 { 'command': 'qom-list-types',
   'data': { '*implements': 'str', '*abstract': 'bool' },
   'returns': [ 'ObjectTypeInfo' ] }
+
+##
+# @migrate
+#
+# Migrates the current running guest to another Virtual Machine.
+#
+# @uri: the Uniform Resource Identifier of the destination VM
+#
+# @blk: #optional do block migration (full disk copy)
+#
+# @inc: #optional incremental disk copy migration
+#
+# @detach: this argument exists only for compatibility reasons and
+#          is ignored by QEMU
+#
+# Returns: nothing on success
+#
+# Since: 0.14.0
+##
+{ 'command': 'migrate',
+  'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool', '*detach': 'bool' } }
+
+# @xen-save-devices-state:
+#
+# Save the state of all devices to file. The RAM and the block devices
+# of the VM are not saved by this command.
+#
+# @filename: the file to save the state of the devices to as binary
+# data. See xen-save-devices-state.txt for a description of the binary
+# format.
+#
+# Returns: Nothing on success
+#          If @filename cannot be opened, OpenFileFailed
+#          If an I/O error occurs while writing the file, IOError
+#
+# Since: 1.1
+##
+{ 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index e6b6152e08..74386b9b1b 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -22,16 +22,17 @@
 
 typedef struct StackObject
 {
-    const QObject *obj;
-    const  QListEntry *entry;
+    QObject *obj;
+    const QListEntry *entry;
+    GHashTable *h;
 } StackObject;
 
 struct QmpInputVisitor
 {
     Visitor visitor;
-    QObject *obj;
     StackObject stack[QIV_STACK_SIZE];
     int nb_stack;
+    bool strict;
 };
 
 static QmpInputVisitor *to_qiv(Visitor *v)
@@ -39,21 +40,18 @@ static QmpInputVisitor *to_qiv(Visitor *v)
     return container_of(v, QmpInputVisitor, visitor);
 }
 
-static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
-                                           const char *name)
+static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
+                                     const char *name)
 {
-    const QObject *qobj;
-
-    if (qiv->nb_stack == 0) {
-        qobj = qiv->obj;
-    } else {
-        qobj = qiv->stack[qiv->nb_stack - 1].obj;
-    }
+    QObject *qobj = qiv->stack[qiv->nb_stack - 1].obj;
 
     if (qobj) {
         if (name && qobject_type(qobj) == QTYPE_QDICT) {
+            if (qiv->stack[qiv->nb_stack - 1].h) {
+                g_hash_table_remove(qiv->stack[qiv->nb_stack - 1].h, name);
+            }
             return qdict_get(qobject_to_qdict(qobj), name);
-        } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
+        } else if (qiv->stack[qiv->nb_stack - 1].entry) {
             return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
         }
     }
@@ -61,34 +59,57 @@ static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
     return qobj;
 }
 
-static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp)
+static void qdict_add_key(const char *key, QObject *obj, void *opaque)
 {
-    qiv->stack[qiv->nb_stack].obj = obj;
-    if (qobject_type(obj) == QTYPE_QLIST) {
-        qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj));
-    }
-    qiv->nb_stack++;
+    GHashTable *h = opaque;
+    g_hash_table_insert(h, (gpointer) key, NULL);
+}
+
+static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)
+{
+    GHashTable *h;
 
     if (qiv->nb_stack >= QIV_STACK_SIZE) {
         error_set(errp, QERR_BUFFER_OVERRUN);
         return;
     }
+
+    qiv->stack[qiv->nb_stack].obj = obj;
+    qiv->stack[qiv->nb_stack].entry = NULL;
+    qiv->stack[qiv->nb_stack].h = NULL;
+
+    if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
+        h = g_hash_table_new(g_str_hash, g_str_equal);
+        qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
+        qiv->stack[qiv->nb_stack].h = h;
+    }
+
+    qiv->nb_stack++;
 }
 
 static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
 {
-    qiv->nb_stack--;
-    if (qiv->nb_stack < 0) {
-        error_set(errp, QERR_BUFFER_OVERRUN);
-        return;
+    GHashTableIter iter;
+    gpointer key;
+
+    if (qiv->strict && qiv->stack[qiv->nb_stack - 1].h) {
+        g_hash_table_iter_init(&iter, qiv->stack[qiv->nb_stack - 1].h);
+        if (g_hash_table_iter_next(&iter, &key, NULL)) {
+            error_set(errp, QERR_QMP_EXTRA_MEMBER, (char *) key);
+        }
+        g_hash_table_unref(qiv->stack[qiv->nb_stack - 1].h);
     }
+
+    assert(qiv->nb_stack > 0);
+    qiv->nb_stack--;
 }
 
 static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind,
                                    const char *name, size_t size, Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    const QObject *qobj = qmp_input_get_object(qiv, name);
+    QObject *qobj = qmp_input_get_object(qiv, name);
+    Error *err = NULL;
 
     if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
@@ -96,8 +117,9 @@ static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind,
         return;
     }
 
-    qmp_input_push(qiv, qobj, errp);
-    if (error_is_set(errp)) {
+    qmp_input_push(qiv, qobj, &err);
+    if (err) {
+        error_propagate(errp, err);
         return;
     }
 
@@ -116,7 +138,7 @@ static void qmp_input_end_struct(Visitor *v, Error **errp)
 static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    const QObject *qobj = qmp_input_get_object(qiv, name);
+    QObject *qobj = qmp_input_get_object(qiv, name);
 
     if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
@@ -133,18 +155,24 @@ static GenericList *qmp_input_next_list(Visitor *v, GenericList **list,
     QmpInputVisitor *qiv = to_qiv(v);
     GenericList *entry;
     StackObject *so = &qiv->stack[qiv->nb_stack - 1];
+    bool first;
+
+    if (so->entry == NULL) {
+        so->entry = qlist_first(qobject_to_qlist(so->obj));
+        first = true;
+    } else {
+        so->entry = qlist_next(so->entry);
+        first = false;
+    }
 
     if (so->entry == NULL) {
         return NULL;
     }
 
     entry = g_malloc0(sizeof(*entry));
-    if (*list) {
-        so->entry = qlist_next(so->entry);
-        if (so->entry == NULL) {
-            g_free(entry);
-            return NULL;
-        }
+    if (first) {
+        *list = entry;
+    } else {
         (*list)->next = entry;
     }
 
@@ -162,7 +190,7 @@ static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name,
                                Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    const QObject *qobj = qmp_input_get_object(qiv, name);
+    QObject *qobj = qmp_input_get_object(qiv, name);
 
     if (!qobj || qobject_type(qobj) != QTYPE_QINT) {
         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
@@ -177,7 +205,7 @@ static void qmp_input_type_bool(Visitor *v, bool *obj, const char *name,
                                 Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    const QObject *qobj = qmp_input_get_object(qiv, name);
+    QObject *qobj = qmp_input_get_object(qiv, name);
 
     if (!qobj || qobject_type(qobj) != QTYPE_QBOOL) {
         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
@@ -192,7 +220,7 @@ static void qmp_input_type_str(Visitor *v, char **obj, const char *name,
                                Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    const QObject *qobj = qmp_input_get_object(qiv, name);
+    QObject *qobj = qmp_input_get_object(qiv, name);
 
     if (!qobj || qobject_type(qobj) != QTYPE_QSTRING) {
         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
@@ -207,7 +235,7 @@ static void qmp_input_type_number(Visitor *v, double *obj, const char *name,
                                   Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    const QObject *qobj = qmp_input_get_object(qiv, name);
+    QObject *qobj = qmp_input_get_object(qiv, name);
 
     if (!qobj || qobject_type(qobj) != QTYPE_QFLOAT) {
         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
@@ -222,7 +250,7 @@ static void qmp_input_start_optional(Visitor *v, bool *present,
                                      const char *name, Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    const QObject *qobj = qmp_input_get_object(qiv, name);
+    QObject *qobj = qmp_input_get_object(qiv, name);
 
     if (!qobj) {
         *present = false;
@@ -239,7 +267,7 @@ Visitor *qmp_input_get_visitor(QmpInputVisitor *v)
 
 void qmp_input_visitor_cleanup(QmpInputVisitor *v)
 {
-    qobject_decref(v->obj);
+    qobject_decref(v->stack[0].obj);
     g_free(v);
 }
 
@@ -261,8 +289,18 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
     v->visitor.type_number = qmp_input_type_number;
     v->visitor.start_optional = qmp_input_start_optional;
 
-    v->obj = obj;
-    qobject_incref(v->obj);
+    qmp_input_push(v, obj, NULL);
+    qobject_incref(obj);
+
+    return v;
+}
+
+QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj)
+{
+    QmpInputVisitor *v;
+
+    v = qmp_input_visitor_new(obj);
+    v->strict = true;
 
     return v;
 }
diff --git a/qapi/qmp-input-visitor.h b/qapi/qmp-input-visitor.h
index 3f798f0335..e0a48a5f3b 100644
--- a/qapi/qmp-input-visitor.h
+++ b/qapi/qmp-input-visitor.h
@@ -20,6 +20,8 @@
 typedef struct QmpInputVisitor QmpInputVisitor;
 
 QmpInputVisitor *qmp_input_visitor_new(QObject *obj);
+QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj);
+
 void qmp_input_visitor_cleanup(QmpInputVisitor *v);
 
 Visitor *qmp_input_get_visitor(QmpInputVisitor *v);
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index e0697b0d0f..2bce9d5db1 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -199,14 +199,16 @@ void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
 {
     QStackEntry *e, *tmp;
 
+    /* The bottom QStackEntry, if any, owns the root QObject. See the
+     * qmp_output_push_obj() invocations in qmp_output_add_obj(). */
+    QObject *root = QTAILQ_EMPTY(&v->stack) ? NULL : qmp_output_first(v);
+
     QTAILQ_FOREACH_SAFE(e, &v->stack, node, tmp) {
         QTAILQ_REMOVE(&v->stack, e, node);
-        if (e->value) {
-            qobject_decref(e->value);
-        }
         g_free(e);
     }
 
+    qobject_decref(root);
     g_free(v);
 }
 
diff --git a/qemu-common.h b/qemu-common.h
index b0fdf5c2b4..4647dd96e9 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -190,7 +190,6 @@ ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
     QEMU_WARN_UNUSED_RESULT;
 ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
     QEMU_WARN_UNUSED_RESULT;
-void qemu_set_cloexec(int fd);
 
 #ifndef _WIN32
 int qemu_eventfd(int pipefd[2]);
@@ -236,7 +235,6 @@ typedef struct MACAddr MACAddr;
 typedef struct VLANState VLANState;
 typedef struct VLANClientState VLANClientState;
 typedef struct i2c_bus i2c_bus;
-typedef struct i2c_slave i2c_slave;
 typedef struct ISABus ISABus;
 typedef struct SMBusDevice SMBusDevice;
 typedef struct PCIHostState PCIHostState;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 83b2ad5237..9e07ba6c1b 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -968,7 +968,7 @@ monitor (@pxref{pcsys_keys}).
 
 QEMU emulates a PCI UHCI USB controller. You can virtually plug
 virtual USB devices or real host USB devices (experimental, works only
-on Linux hosts).  Qemu will automatically create and connect virtual USB hubs
+on Linux hosts).  QEMU will automatically create and connect virtual USB hubs
 as necessary to connect multiple USB devices.
 
 @menu
@@ -2709,9 +2709,9 @@ MinGW's default header and linker search paths.
 @file{make}.  If you have problems using SDL, verify that
 @file{sdl-config} can be launched from the MSYS command line.
 
-@item You can install QEMU in @file{Program Files/Qemu} by typing
+@item You can install QEMU in @file{Program Files/QEMU} by typing
 @file{make install}. Don't forget to copy @file{SDL.dll} in
-@file{Program Files/Qemu}.
+@file{Program Files/QEMU}.
 
 @end itemize
 
@@ -2745,7 +2745,7 @@ The example assumes @file{sdl-config} is installed under @file{/usr/i686-pc-ming
 MinGW cross compilation tools have names like @file{i686-pc-mingw32-gcc} and @file{i686-pc-mingw32-strip}.
 We set the @code{PATH} environment variable to ensure the MinGW version of @file{sdl-config} is used and
 use --cross-prefix to specify the name of the cross compiler.
-You can also use --prefix to set the Win32 install path which defaults to @file{c:/Program Files/Qemu}.
+You can also use --prefix to set the Win32 install path which defaults to @file{c:/Program Files/QEMU}.
 
 Under Fedora Linux, you can run:
 @example
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
index 44996cc650..6955d90327 100644
--- a/qemu-nbd.texi
+++ b/qemu-nbd.texi
@@ -6,7 +6,7 @@ usage: qemu-nbd [OPTION]...  @var{filename}
 
 @c man begin DESCRIPTION
 
-Export Qemu disk image using NBD protocol.
+Export QEMU disk image using NBD protocol.
 
 @c man end
 
diff --git a/qemu-options.hx b/qemu-options.hx
index daefce3038..a169792f07 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -288,13 +288,21 @@ TODO
 ETEXI
 
 DEF("global", HAS_ARG, QEMU_OPTION_global,
-    "-global driver.property=value\n"
+    "-global driver.prop=value\n"
     "                set a global default for a driver property\n",
     QEMU_ARCH_ALL)
 STEXI
-@item -global
+@item -global @var{driver}.@var{prop}=@var{value}
 @findex -global
-TODO
+Set default value of @var{driver}'s property @var{prop} to @var{value}, e.g.:
+
+@example
+qemu -global ide-drive.physical_block_size=4096 -drive file=file,if=ide,index=0,media=disk
+@end example
+
+In particular, you can use this to set driver properties for devices which are 
+created automatically by the machine model. To create a device which is not 
+created automatically and set properties on it, use -@option{device}.
 ETEXI
 
 DEF("mtdblock", HAS_ARG, QEMU_OPTION_mtdblock,
@@ -1302,7 +1310,7 @@ and a @var{name} can be assigned for use in monitor commands.
 Optionally, for PCI cards, you can specify the number @var{v} of MSI-X vectors
 that the card should have; this option currently only affects virtio cards; set
 @var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single
-NIC is created.  Qemu can emulate several different models of network card.
+NIC is created.  QEMU can emulate several different models of network card.
 Valid values for @var{type} are
 @code{virtio}, @code{i82551}, @code{i82557b}, @code{i82559er},
 @code{ne2k_pci}, @code{ne2k_isa}, @code{pcnet}, @code{rtl8139},
@@ -2125,7 +2133,7 @@ activates telnet remote echo and single char transfer, then you can
 use the following options to step up a netcat redirector to allow
 telnet on port 5555 to access the qemu port.
 @table @code
-@item Qemu Options:
+@item QEMU Options:
 -serial udp::4555@@:4556
 @item netcat options:
 -u -P 4555 -L 0.0.0.0:4556 -t -p 5555 -I -T
@@ -2445,7 +2453,7 @@ DEF("localtime", 0, QEMU_OPTION_localtime, "", QEMU_ARCH_ALL)
 DEF("startdate", HAS_ARG, QEMU_OPTION_startdate, "", QEMU_ARCH_ALL)
 
 DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \
-    "-rtc [base=utc|localtime|date][,clock=host|vm][,driftfix=none|slew]\n" \
+    "-rtc [base=utc|localtime|date][,clock=host|rt|vm][,driftfix=none|slew]\n" \
     "                set the RTC base and clock, enable drift fix for clock ticks (x86 only)\n",
     QEMU_ARCH_ALL)
 
@@ -2461,8 +2469,9 @@ format @code{2006-06-17T16:01:21} or @code{2006-06-17}. The default base is UTC.
 By default the RTC is driven by the host system time. This allows to use the
 RTC as accurate reference clock inside the guest, specifically if the host
 time is smoothly following an accurate external reference clock, e.g. via NTP.
-If you want to isolate the guest time from the host, even prevent it from
-progressing during suspension, you can set @option{clock} to @code{vm} instead.
+If you want to isolate the guest time from the host, you can set @option{clock}
+to @code{rt} instead.  To even prevent it from progressing during suspension,
+you can set it to @code{vm}.
 
 Enable @option{driftfix} (i386 targets only) if you experience time drift problems,
 specifically with Windows' ACPI HAL. This option will try to figure out how
@@ -2707,6 +2716,14 @@ the @var{simple} tracing backend.
 @end table
 ETEXI
 
+DEF("qtest", HAS_ARG, QEMU_OPTION_qtest,
+    "-qtest CHR      specify tracing options\n",
+    QEMU_ARCH_ALL)
+
+DEF("qtest-log", HAS_ARG, QEMU_OPTION_qtest_log,
+    "-qtest-log LOG  specify tracing options\n",
+    QEMU_ARCH_ALL)
+
 HXCOMM This is the last statement. Insert new options before this line!
 STEXI
 @end table
diff --git a/qemu-queue.h b/qemu-queue.h
index 74d7122e4d..9288cd8e82 100644
--- a/qemu-queue.h
+++ b/qemu-queue.h
@@ -1,7 +1,7 @@
 /*      $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
 
 /*
- * Qemu version: Copy from netbsd, removed debug code, removed some of
+ * QEMU version: Copy from netbsd, removed debug code, removed some of
  * the implementations.  Left in singly-linked lists, lists, simple
  * queues, and tail queues.
  */
diff --git a/qemu-timer.c b/qemu-timer.c
index d7f56e55f9..80bcc563e0 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -397,7 +397,7 @@ int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
     return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
 }
 
-static void qemu_run_timers(QEMUClock *clock)
+void qemu_run_timers(QEMUClock *clock)
 {
     QEMUTimer **ptimer_head, *ts;
     int64_t current_time;
diff --git a/qemu-timer.h b/qemu-timer.h
index de17f3b1a1..661bbe76b2 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -59,6 +59,7 @@ int qemu_timer_pending(QEMUTimer *ts);
 int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
 uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts);
 
+void qemu_run_timers(QEMUClock *clock);
 void qemu_run_all_timers(void);
 int qemu_alarm_pending(void);
 void configure_alarms(char const *opt);
diff --git a/qerror.c b/qerror.c
index f55d435d11..41c729a01f 100644
--- a/qerror.c
+++ b/qerror.c
@@ -193,6 +193,14 @@ static const QErrorStringTable qerror_table[] = {
         .desc      = "Using KVM without %(capability), %(feature) unavailable",
     },
     {
+        .error_fmt = QERR_MIGRATION_ACTIVE,
+        .desc      = "There's a migration process in progress",
+    },
+    {
+        .error_fmt = QERR_MIGRATION_NOT_SUPPORTED,
+        .desc      = "State blocked by non-migratable device '%(device)'",
+    },
+    {
         .error_fmt = QERR_MIGRATION_EXPECTED,
         .desc      = "An incoming migration is expected before this command can be executed",
     },
diff --git a/qerror.h b/qerror.h
index e26c63598d..e16f9c27e1 100644
--- a/qerror.h
+++ b/qerror.h
@@ -166,6 +166,12 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_KVM_MISSING_CAP \
     "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }"
 
+#define QERR_MIGRATION_ACTIVE \
+    "{ 'class': 'MigrationActive', 'data': {} }"
+
+#define QERR_MIGRATION_NOT_SUPPORTED \
+    "{ 'class': 'MigrationNotSupported', 'data': {'device': %s} }"
+
 #define QERR_MIGRATION_EXPECTED \
     "{ 'class': 'MigrationExpected', 'data': {} }"
 
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index 190251bb57..16bf44a376 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -259,6 +259,10 @@ static GIOStatus ga_channel_write(GAChannel *c, const char *buf, size_t size,
         *count = written;
     }
 
+    if (ov.hEvent) {
+        CloseHandle(ov.hEvent);
+        ov.hEvent = NULL;
+    }
     return status;
 }
 
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 7b2be2f936..faf970dff3 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -12,29 +12,30 @@
  */
 
 #include <glib.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include "qga/guest-agent-core.h"
+#include "qga-qmp-commands.h"
+#include "qerror.h"
+#include "qemu-queue.h"
+#include "host-utils.h"
 
 #if defined(__linux__)
 #include <mntent.h>
 #include <linux/fs.h>
-
-#if defined(__linux__) && defined(FIFREEZE)
-#define CONFIG_FSFREEZE
-#endif
-#endif
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
 #include <ifaddrs.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <net/if.h>
 #include <sys/wait.h>
-#include "qga/guest-agent-core.h"
-#include "qga-qmp-commands.h"
-#include "qerror.h"
-#include "qemu-queue.h"
-#include "host-utils.h"
 
+#if defined(__linux__) && defined(FIFREEZE)
+#define CONFIG_FSFREEZE
+#endif
+#endif
+
+#if defined(__linux__)
+/* TODO: use this in place of all post-fork() fclose(std*) callers */
 static void reopen_fd_to_null(int fd)
 {
     int nullfd;
@@ -50,6 +51,7 @@ static void reopen_fd_to_null(int fd)
         close(nullfd);
     }
 }
+#endif /* defined(__linux__) */
 
 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
 {
@@ -309,7 +311,11 @@ static void guest_file_init(void)
     QTAILQ_INIT(&guest_file_state.filehandles);
 }
 
+/* linux-specific implementations. avoid this if at all possible. */
+#if defined(__linux__)
+
 #if defined(CONFIG_FSFREEZE)
+
 static void disable_logging(void)
 {
     ga_disable_logging(ga_state);
@@ -505,38 +511,7 @@ static void guest_fsfreeze_cleanup(void)
         }
     }
 }
-#else
-/*
- * Return status of freeze/thaw
- */
-GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
-{
-    error_set(err, QERR_UNSUPPORTED);
-
-    return 0;
-}
-
-/*
- * Walk list of mounted file systems in the guest, and freeze the ones which
- * are real local file systems.
- */
-int64_t qmp_guest_fsfreeze_freeze(Error **err)
-{
-    error_set(err, QERR_UNSUPPORTED);
-
-    return 0;
-}
-
-/*
- * Walk list of frozen file systems in the guest, and thaw them.
- */
-int64_t qmp_guest_fsfreeze_thaw(Error **err)
-{
-    error_set(err, QERR_UNSUPPORTED);
-
-    return 0;
-}
-#endif
+#endif /* CONFIG_FSFREEZE */
 
 #define LINUX_SYS_STATE_FILE "/sys/power/state"
 #define SUSPEND_SUPPORTED 0
@@ -904,6 +879,52 @@ error:
     return NULL;
 }
 
+#else /* defined(__linux__) */
+
+GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
+{
+    error_set(err, QERR_UNSUPPORTED);
+
+    return 0;
+}
+
+int64_t qmp_guest_fsfreeze_freeze(Error **err)
+{
+    error_set(err, QERR_UNSUPPORTED);
+
+    return 0;
+}
+
+int64_t qmp_guest_fsfreeze_thaw(Error **err)
+{
+    error_set(err, QERR_UNSUPPORTED);
+
+    return 0;
+}
+
+void qmp_guest_suspend_disk(Error **err)
+{
+    error_set(err, QERR_UNSUPPORTED);
+}
+
+void qmp_guest_suspend_ram(Error **err)
+{
+    error_set(err, QERR_UNSUPPORTED);
+}
+
+void qmp_guest_suspend_hybrid(Error **err)
+{
+    error_set(err, QERR_UNSUPPORTED);
+}
+
+GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
+
+#endif
+
 /* register init/cleanup routines for stateful command groups */
 void ga_command_state_init(GAState *s, GACommandState *cs)
 {
diff --git a/qmp-commands.hx b/qmp-commands.hx
index dfe8a5b40b..944787161f 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -444,16 +444,36 @@ Note: inject-nmi is only supported for x86 guest currently, it will
 EQMP
 
     {
+        .name       = "xen-save-devices-state",
+        .args_type  = "filename:F",
+    .mhandler.cmd_new = qmp_marshal_input_xen_save_devices_state,
+    },
+
+SQMP
+xen-save-devices-state
+-------
+
+Save the state of all devices to file. The RAM and the block devices
+of the VM are not saved by this command.
+
+Arguments:
+
+- "filename": the file to save the state of the devices to as binary
+data. See xen-save-devices-state.txt for a description of the binary
+format.
+
+Example:
+
+-> { "execute": "xen-save-devices-state",
+     "arguments": { "filename": "/tmp/save" } }
+<- { "return": {} }
+
+EQMP
+
+    {
         .name       = "migrate",
         .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
-        .params     = "[-d] [-b] [-i] uri",
-        .help       = "migrate to URI (using -d to not wait for completion)"
-		      "\n\t\t\t -b for migration without shared storage with"
-		      " full copy of disk\n\t\t\t -i for migration without "
-		      "shared storage with incremental copy of disk "
-		      "(base image shared between src and destination)",
-        .user_print = monitor_user_noop,	
-	.mhandler.cmd_new = do_migrate,
+        .mhandler.cmd_new = qmp_marshal_input_migrate,
     },
 
 SQMP
@@ -688,7 +708,7 @@ EQMP
     },
     {
         .name       = "transaction",
-        .args_type  = "actions:O",
+        .args_type  = "actions:q",
         .mhandler.cmd_new = qmp_marshal_input_transaction,
     },
 
@@ -2105,7 +2125,7 @@ EQMP
 
     {
         .name       = "qom-set",
-	.args_type  = "path:s,property:s,opts:O",
+	.args_type  = "path:s,property:s,value:q",
 	.mhandler.cmd_new = qmp_qom_set,
     },
 
diff --git a/qom/container.c b/qom/container.c
index f107208867..67e9e8a6f8 100644
--- a/qom/container.c
+++ b/qom/container.c
@@ -12,6 +12,7 @@
 
 #include "qemu/object.h"
 #include "module.h"
+#include <assert.h>
 
 static TypeInfo container_info = {
     .name          = "container",
@@ -24,4 +25,26 @@ static void container_register_types(void)
     type_register_static(&container_info);
 }
 
+Object *container_get(const char *path)
+{
+    Object *obj, *child;
+    gchar **parts;
+    int i;
+
+    parts = g_strsplit(path, "/", 0);
+    assert(parts != NULL && parts[0] != NULL && !parts[0][0]);
+    obj = object_get_root();
+
+    for (i = 1; parts[i] != NULL; i++, obj = child) {
+        child = object_resolve_path_component(obj, parts[i]);
+        if (!child) {
+            child = object_new("container");
+            object_property_add_child(obj, parts[i], child, NULL);
+        }
+    }
+
+    return obj;
+}
+
+
 type_init(container_register_types)
diff --git a/qom/object.c b/qom/object.c
index 9cd9506eb5..e721fc28fb 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1022,12 +1022,27 @@ gchar *object_get_canonical_path(Object *obj)
     return newpath;
 }
 
+Object *object_resolve_path_component(Object *parent, gchar *part)
+{
+    ObjectProperty *prop = object_property_find(parent, part);
+    if (prop == NULL) {
+        return NULL;
+    }
+
+    if (strstart(prop->type, "link<", NULL)) {
+        return *(Object **)prop->opaque;
+    } else if (strstart(prop->type, "child<", NULL)) {
+        return prop->opaque;
+    } else {
+        return NULL;
+    }
+}
+
 static Object *object_resolve_abs_path(Object *parent,
                                           gchar **parts,
                                           const char *typename,
                                           int index)
 {
-    ObjectProperty *prop;
     Object *child;
 
     if (parts[index] == NULL) {
@@ -1038,21 +1053,7 @@ static Object *object_resolve_abs_path(Object *parent,
         return object_resolve_abs_path(parent, parts, typename, index + 1);
     }
 
-    prop = object_property_find(parent, parts[index]);
-    if (prop == NULL) {
-        return NULL;
-    }
-
-    child = NULL;
-    if (strstart(prop->type, "link<", NULL)) {
-        Object **pchild = prop->opaque;
-        if (*pchild) {
-            child = *pchild;
-        }
-    } else if (strstart(prop->type, "child<", NULL)) {
-        child = prop->opaque;
-    }
-
+    child = object_resolve_path_component(parent, parts[index]);
     if (!child) {
         return NULL;
     }
diff --git a/qtest.c b/qtest.c
new file mode 100644
index 0000000000..daeabb7c25
--- /dev/null
+++ b/qtest.c
@@ -0,0 +1,443 @@
+/*
+ * Test Server
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qtest.h"
+#include "hw/qdev.h"
+#include "qemu-char.h"
+#include "ioport.h"
+#include "memory.h"
+#include "hw/irq.h"
+#include "sysemu.h"
+#include "cpus.h"
+
+#define MAX_IRQ 256
+
+const char *qtest_chrdev;
+const char *qtest_log;
+int qtest_allowed = 0;
+
+static DeviceState *irq_intercept_dev;
+static FILE *qtest_log_fp;
+static CharDriverState *qtest_chr;
+static GString *inbuf;
+static int irq_levels[MAX_IRQ];
+static qemu_timeval start_time;
+static bool qtest_opened;
+
+#define FMT_timeval "%ld.%06ld"
+
+/**
+ * QTest Protocol
+ *
+ * Line based protocol, request/response based.  Server can send async messages
+ * so clients should always handle many async messages before the response
+ * comes in.
+ *
+ * Valid requests
+ *
+ * Clock management:
+ *
+ * The qtest client is completely in charge of the vm_clock.  qtest commands
+ * let you adjust the value of the clock (monotonically).  All the commands
+ * return the current value of the clock in nanoseconds.
+ *
+ *  > clock_step
+ *  < OK VALUE
+ *
+ *     Advance the clock to the next deadline.  Useful when waiting for
+ *     asynchronous events.
+ *
+ *  > clock_step NS
+ *  < OK VALUE
+ *
+ *     Advance the clock by NS nanoseconds.
+ *
+ *  > clock_set NS
+ *  < OK VALUE
+ *
+ *     Advance the clock to NS nanoseconds (do nothing if it's already past).
+ *
+ * PIO and memory access:
+ *
+ *  > outb ADDR VALUE
+ *  < OK
+ *
+ *  > outw ADDR VALUE
+ *  < OK
+ *
+ *  > outl ADDR VALUE
+ *  < OK
+ *
+ *  > inb ADDR
+ *  < OK VALUE
+ *
+ *  > inw ADDR
+ *  < OK VALUE
+ *
+ *  > inl ADDR
+ *  < OK VALUE
+ *
+ *  > read ADDR SIZE
+ *  < OK DATA
+ *
+ *  > write ADDR SIZE DATA
+ *  < OK
+ *
+ * ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
+ *
+ * DATA is an arbitrarily long hex number prefixed with '0x'.  If it's smaller
+ * than the expected size, the value will be zero filled at the end of the data
+ * sequence.
+ *
+ * IRQ management:
+ *
+ *  > irq_intercept_in QOM-PATH
+ *  < OK
+ *
+ *  > irq_intercept_out QOM-PATH
+ *  < OK
+ *
+ * Attach to the gpio-in (resp. gpio-out) pins exported by the device at
+ * QOM-PATH.  When the pin is triggered, one of the following async messages
+ * will be printed to the qtest stream:
+ *
+ *  IRQ raise NUM
+ *  IRQ lower NUM
+ *
+ * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
+ * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
+ * NUM=0 even though it is remapped to GSI 2).
+ */
+
+static int hex2nib(char ch)
+{
+    if (ch >= '0' && ch <= '9') {
+        return ch - '0';
+    } else if (ch >= 'a' && ch <= 'f') {
+        return 10 + (ch - 'a');
+    } else if (ch >= 'A' && ch <= 'F') {
+        return 10 + (ch - 'a');
+    } else {
+        return -1;
+    }
+}
+
+static void qtest_get_time(qemu_timeval *tv)
+{
+    qemu_gettimeofday(tv);
+    tv->tv_sec -= start_time.tv_sec;
+    tv->tv_usec -= start_time.tv_usec;
+    if (tv->tv_usec < 0) {
+        tv->tv_usec += 1000000;
+        tv->tv_sec -= 1;
+    }
+}
+
+static void qtest_send_prefix(CharDriverState *chr)
+{
+    qemu_timeval tv;
+
+    if (!qtest_log_fp || !qtest_opened) {
+        return;
+    }
+
+    qtest_get_time(&tv);
+    fprintf(qtest_log_fp, "[S +" FMT_timeval "] ",
+            tv.tv_sec, tv.tv_usec);
+}
+
+static void qtest_send(CharDriverState *chr, const char *fmt, ...)
+{
+    va_list ap;
+    char buffer[1024];
+    size_t len;
+
+    va_start(ap, fmt);
+    len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
+    va_end(ap);
+
+    qemu_chr_fe_write(chr, (uint8_t *)buffer, len);
+    if (qtest_log_fp && qtest_opened) {
+        fprintf(qtest_log_fp, "%s", buffer);
+    }
+}
+
+static void qtest_irq_handler(void *opaque, int n, int level)
+{
+    qemu_irq *old_irqs = opaque;
+    qemu_set_irq(old_irqs[n], level);
+
+    if (irq_levels[n] != level) {
+        CharDriverState *chr = qtest_chr;
+        irq_levels[n] = level;
+        qtest_send_prefix(chr);
+        qtest_send(chr, "IRQ %s %d\n",
+                   level ? "raise" : "lower", n);
+    }
+}
+
+static void qtest_process_command(CharDriverState *chr, gchar **words)
+{
+    const gchar *command;
+
+    g_assert(words);
+
+    command = words[0];
+
+    if (qtest_log_fp) {
+        qemu_timeval tv;
+        int i;
+
+        qtest_get_time(&tv);
+        fprintf(qtest_log_fp, "[R +" FMT_timeval "]",
+                tv.tv_sec, tv.tv_usec);
+        for (i = 0; words[i]; i++) {
+            fprintf(qtest_log_fp, " %s", words[i]);
+        }
+        fprintf(qtest_log_fp, "\n");
+    }
+
+    g_assert(command);
+    if (strcmp(words[0], "irq_intercept_out") == 0
+        || strcmp(words[0], "irq_intercept_in") == 0) {
+	DeviceState *dev;
+
+        g_assert(words[1]);
+        dev = DEVICE(object_resolve_path(words[1], NULL));
+        if (!dev) {
+            qtest_send_prefix(chr);
+            qtest_send(chr, "FAIL Unknown device\n");
+	    return;
+        }
+
+        if (irq_intercept_dev) {
+            qtest_send_prefix(chr);
+            if (irq_intercept_dev != dev) {
+                qtest_send(chr, "FAIL IRQ intercept already enabled\n");
+            } else {
+                qtest_send(chr, "OK\n");
+            }
+	    return;
+        }
+
+        if (words[0][14] == 'o') {
+            qemu_irq_intercept_out(&dev->gpio_out, qtest_irq_handler, dev->num_gpio_out);
+        } else {
+            qemu_irq_intercept_in(dev->gpio_in, qtest_irq_handler, dev->num_gpio_in);
+        }
+        irq_intercept_dev = dev;
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK\n");
+
+    } else if (strcmp(words[0], "outb") == 0 ||
+               strcmp(words[0], "outw") == 0 ||
+               strcmp(words[0], "outl") == 0) {
+        uint16_t addr;
+        uint32_t value;
+
+        g_assert(words[1] && words[2]);
+        addr = strtol(words[1], NULL, 0);
+        value = strtol(words[2], NULL, 0);
+
+        if (words[0][3] == 'b') {
+            cpu_outb(addr, value);
+        } else if (words[0][3] == 'w') {
+            cpu_outw(addr, value);
+        } else if (words[0][3] == 'l') {
+            cpu_outl(addr, value);
+        }
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK\n");
+    } else if (strcmp(words[0], "inb") == 0 ||
+        strcmp(words[0], "inw") == 0 ||
+        strcmp(words[0], "inl") == 0) {
+        uint16_t addr;
+        uint32_t value = -1U;
+
+        g_assert(words[1]);
+        addr = strtol(words[1], NULL, 0);
+
+        if (words[0][2] == 'b') {
+            value = cpu_inb(addr);
+        } else if (words[0][2] == 'w') {
+            value = cpu_inw(addr);
+        } else if (words[0][2] == 'l') {
+            value = cpu_inl(addr);
+        }
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK 0x%04x\n", value);
+    } else if (strcmp(words[0], "read") == 0) {
+        uint64_t addr, len, i;
+        uint8_t *data;
+
+        g_assert(words[1] && words[2]);
+        addr = strtoul(words[1], NULL, 0);
+        len = strtoul(words[2], NULL, 0);
+
+        data = g_malloc(len);
+        cpu_physical_memory_read(addr, data, len);
+
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK 0x");
+        for (i = 0; i < len; i++) {
+            qtest_send(chr, "%02x", data[i]);
+        }
+        qtest_send(chr, "\n");
+
+        g_free(data);
+    } else if (strcmp(words[0], "write") == 0) {
+        uint64_t addr, len, i;
+        uint8_t *data;
+        size_t data_len;
+
+        g_assert(words[1] && words[2] && words[3]);
+        addr = strtoul(words[1], NULL, 0);
+        len = strtoul(words[2], NULL, 0);
+
+        data_len = strlen(words[3]);
+        if (data_len < 3) {
+            qtest_send(chr, "ERR invalid argument size\n");
+            return;
+        }
+
+        data = g_malloc(len);
+        for (i = 0; i < len; i++) {
+            if ((i * 2 + 4) <= data_len) {
+                data[i] = hex2nib(words[3][i * 2 + 2]) << 4;
+                data[i] |= hex2nib(words[3][i * 2 + 3]);
+            } else {
+                data[i] = 0;
+            }
+        }
+        cpu_physical_memory_write(addr, data, len);
+        g_free(data);
+
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK\n");
+    } else if (strcmp(words[0], "clock_step") == 0) {
+        int64_t ns;
+
+        if (words[1]) {
+            ns = strtoll(words[1], NULL, 0);
+        } else {
+            ns = qemu_clock_deadline(vm_clock);
+        }
+        qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+    } else if (strcmp(words[0], "clock_set") == 0) {
+        int64_t ns;
+
+        g_assert(words[1]);
+        ns = strtoll(words[1], NULL, 0);
+        qtest_clock_warp(ns);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+    } else {
+        qtest_send_prefix(chr);
+        qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
+    }
+}
+
+static void qtest_process_inbuf(CharDriverState *chr, GString *inbuf)
+{
+    char *end;
+
+    while ((end = strchr(inbuf->str, '\n')) != NULL) {
+        size_t offset;
+        GString *cmd;
+        gchar **words;
+
+        offset = end - inbuf->str;
+
+        cmd = g_string_new_len(inbuf->str, offset);
+        g_string_erase(inbuf, 0, offset + 1);
+
+        words = g_strsplit(cmd->str, " ", 0);
+        qtest_process_command(chr, words);
+        g_strfreev(words);
+
+        g_string_free(cmd, TRUE);
+    }
+}
+
+static void qtest_read(void *opaque, const uint8_t *buf, int size)
+{
+    CharDriverState *chr = opaque;
+
+    g_string_append_len(inbuf, (const gchar *)buf, size);
+    qtest_process_inbuf(chr, inbuf);
+}
+
+static int qtest_can_read(void *opaque)
+{
+    return 1024;
+}
+
+static void qtest_event(void *opaque, int event)
+{
+    int i;
+
+    switch (event) {
+    case CHR_EVENT_OPENED:
+        qemu_system_reset(false);
+        for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
+            irq_levels[i] = 0;
+        }
+        qemu_gettimeofday(&start_time);
+        qtest_opened = true;
+        if (qtest_log_fp) {
+            fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n",
+                    start_time.tv_sec, start_time.tv_usec);
+        }
+        break;
+    case CHR_EVENT_CLOSED:
+        qtest_opened = false;
+        if (qtest_log_fp) {
+            qemu_timeval tv;
+            qtest_get_time(&tv);
+            fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n",
+                    tv.tv_sec, tv.tv_usec);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+int qtest_init(void)
+{
+    CharDriverState *chr;
+
+    g_assert(qtest_chrdev != NULL);
+
+    configure_icount("0");
+    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
+
+    qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
+    qemu_chr_fe_set_echo(chr, true);
+
+    inbuf = g_string_new("");
+
+    if (qtest_log) {
+        if (strcmp(qtest_log, "none") != 0) {
+            qtest_log_fp = fopen(qtest_log, "w+");
+        }
+    } else {
+        qtest_log_fp = stderr;
+    }
+
+    qtest_chr = chr;
+
+    return 0;
+}
diff --git a/qtest.h b/qtest.h
new file mode 100644
index 0000000000..1478343ff0
--- /dev/null
+++ b/qtest.h
@@ -0,0 +1,35 @@
+/*
+ * Test Server
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QTEST_H
+#define QTEST_H
+
+#include "qemu-common.h"
+
+extern int qtest_allowed;
+extern const char *qtest_chrdev;
+extern const char *qtest_log;
+
+static inline bool qtest_enabled(void)
+{
+    return qtest_allowed;
+}
+
+static inline int qtest_available(void)
+{
+    return 1;
+}
+
+int qtest_init(void);
+
+#endif
diff --git a/roms/Makefile b/roms/Makefile
new file mode 100644
index 0000000000..0114e6f33f
--- /dev/null
+++ b/roms/Makefile
@@ -0,0 +1,10 @@
+
+default:
+	@echo "nothing is build by default"
+	@echo "available build targets:"
+	@echo "  bios           -- update bios.bin (seabios)"
+
+bios: config.seabios
+	sh configure-seabios.sh $<
+	make -C seabios out/bios.bin
+	cp seabios/out/bios.bin ../pc-bios/bios.bin
diff --git a/roms/config.seabios b/roms/config.seabios
new file mode 100644
index 0000000000..c373b87a98
--- /dev/null
+++ b/roms/config.seabios
@@ -0,0 +1 @@
+# empty, default config works for us
diff --git a/roms/configure-seabios.sh b/roms/configure-seabios.sh
new file mode 100755
index 0000000000..98f59a24ba
--- /dev/null
+++ b/roms/configure-seabios.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+config="$1"
+make -C seabios clean distclean
+cp "$config" seabios/.config
+make -C seabios oldnoconfig
diff --git a/roms/seabios b/roms/seabios
-Subproject 80d11e8577bf03e98f2eb1b0cb3a281ab2879c9
+Subproject 2e8bd611ce4e1e36b5a80c9ca6e256e23802f09
diff --git a/rules.mak b/rules.mak
index 04a91983ec..c30093c116 100644
--- a/rules.mak
+++ b/rules.mak
@@ -47,7 +47,7 @@ quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1))
 cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
               >/dev/null 2>&1 && echo OK), $2, $3)
 
-VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi
+VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi %.sh
 set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
 
 # find-in-path
diff --git a/savevm.c b/savevm.c
index 694eaa4f85..12fb20954f 100644
--- a/savevm.c
+++ b/savevm.c
@@ -84,6 +84,7 @@
 #include "qemu-timer.h"
 #include "cpus.h"
 #include "memory.h"
+#include "qmp-commands.h"
 
 #define SELF_ANNOUNCE_ROUNDS 5
 
@@ -1177,6 +1178,7 @@ typedef struct SaveStateEntry {
     void *opaque;
     CompatEntry *compat;
     int no_migrate;
+    int is_ram;
 } SaveStateEntry;
 
 
@@ -1241,6 +1243,10 @@ int register_savevm_live(DeviceState *dev,
     se->opaque = opaque;
     se->vmsd = NULL;
     se->no_migrate = 0;
+    /* if this is a live_savem then set is_ram */
+    if (save_live_state != NULL) {
+        se->is_ram = 1;
+    }
 
     if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
         char *id = dev->parent_bus->info->get_dev_path(dev);
@@ -1542,22 +1548,20 @@ static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
 #define QEMU_VM_SECTION_FULL         0x04
 #define QEMU_VM_SUBSECTION           0x05
 
-bool qemu_savevm_state_blocked(Monitor *mon)
+bool qemu_savevm_state_blocked(Error **errp)
 {
     SaveStateEntry *se;
 
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {
         if (se->no_migrate) {
-            monitor_printf(mon, "state blocked by non-migratable device '%s'\n",
-                           se->idstr);
+            error_set(errp, QERR_MIGRATION_NOT_SUPPORTED, se->idstr);
             return true;
         }
     }
     return false;
 }
 
-int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
-                            int shared)
+int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared)
 {
     SaveStateEntry *se;
     int ret;
@@ -1590,15 +1594,15 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
         qemu_put_be32(f, se->instance_id);
         qemu_put_be32(f, se->version_id);
 
-        ret = se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
+        ret = se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
         if (ret < 0) {
-            qemu_savevm_state_cancel(mon, f);
+            qemu_savevm_state_cancel(f);
             return ret;
         }
     }
     ret = qemu_file_get_error(f);
     if (ret != 0) {
-        qemu_savevm_state_cancel(mon, f);
+        qemu_savevm_state_cancel(f);
     }
 
     return ret;
@@ -1611,7 +1615,7 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
  *   0 : We haven't finished, caller have to go again
  *   1 : We have finished, we can go to complete phase
  */
-int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
+int qemu_savevm_state_iterate(QEMUFile *f)
 {
     SaveStateEntry *se;
     int ret = 1;
@@ -1624,7 +1628,7 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
         qemu_put_byte(f, QEMU_VM_SECTION_PART);
         qemu_put_be32(f, se->section_id);
 
-        ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);
+        ret = se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
         if (ret <= 0) {
             /* Do not proceed to the next vmstate before this one reported
                completion of the current stage. This serializes the migration
@@ -1638,12 +1642,12 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
     }
     ret = qemu_file_get_error(f);
     if (ret != 0) {
-        qemu_savevm_state_cancel(mon, f);
+        qemu_savevm_state_cancel(f);
     }
     return ret;
 }
 
-int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
+int qemu_savevm_state_complete(QEMUFile *f)
 {
     SaveStateEntry *se;
     int ret;
@@ -1658,7 +1662,7 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
         qemu_put_byte(f, QEMU_VM_SECTION_END);
         qemu_put_be32(f, se->section_id);
 
-        ret = se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
+        ret = se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
         if (ret < 0) {
             return ret;
         }
@@ -1690,37 +1694,37 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
     return qemu_file_get_error(f);
 }
 
-void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f)
+void qemu_savevm_state_cancel(QEMUFile *f)
 {
     SaveStateEntry *se;
 
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {
         if (se->save_live_state) {
-            se->save_live_state(mon, f, -1, se->opaque);
+            se->save_live_state(f, -1, se->opaque);
         }
     }
 }
 
-static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
+static int qemu_savevm_state(QEMUFile *f)
 {
     int ret;
 
-    if (qemu_savevm_state_blocked(mon)) {
+    if (qemu_savevm_state_blocked(NULL)) {
         ret = -EINVAL;
         goto out;
     }
 
-    ret = qemu_savevm_state_begin(mon, f, 0, 0);
+    ret = qemu_savevm_state_begin(f, 0, 0);
     if (ret < 0)
         goto out;
 
     do {
-        ret = qemu_savevm_state_iterate(mon, f);
+        ret = qemu_savevm_state_iterate(f);
         if (ret < 0)
             goto out;
     } while (ret == 0);
 
-    ret = qemu_savevm_state_complete(mon, f);
+    ret = qemu_savevm_state_complete(f);
 
 out:
     if (ret == 0) {
@@ -1730,6 +1734,45 @@ out:
     return ret;
 }
 
+static int qemu_save_device_state(QEMUFile *f)
+{
+    SaveStateEntry *se;
+
+    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+    cpu_synchronize_all_states();
+
+    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+        int len;
+
+        if (se->is_ram) {
+            continue;
+        }
+        if (se->save_state == NULL && se->vmsd == NULL) {
+            continue;
+        }
+
+        /* Section type */
+        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
+        qemu_put_be32(f, se->section_id);
+
+        /* ID string */
+        len = strlen(se->idstr);
+        qemu_put_byte(f, len);
+        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
+
+        qemu_put_be32(f, se->instance_id);
+        qemu_put_be32(f, se->version_id);
+
+        vmstate_save(f, se);
+    }
+
+    qemu_put_byte(f, QEMU_VM_EOF);
+
+    return qemu_file_get_error(f);
+}
+
 static SaveStateEntry *find_se(const char *idstr, int instance_id)
 {
     SaveStateEntry *se;
@@ -1839,7 +1882,7 @@ int qemu_loadvm_state(QEMUFile *f)
     unsigned int v;
     int ret;
 
-    if (qemu_savevm_state_blocked(default_mon)) {
+    if (qemu_savevm_state_blocked(NULL)) {
         return -EINVAL;
     }
 
@@ -2083,7 +2126,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, "Could not open VM state file\n");
         goto the_end;
     }
-    ret = qemu_savevm_state(mon, f);
+    ret = qemu_savevm_state(f);
     vm_state_size = qemu_ftell(f);
     qemu_fclose(f);
     if (ret < 0) {
@@ -2111,6 +2154,32 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         vm_start();
 }
 
+void qmp_xen_save_devices_state(const char *filename, Error **errp)
+{
+    QEMUFile *f;
+    int saved_vm_running;
+    int ret;
+
+    saved_vm_running = runstate_is_running();
+    vm_stop(RUN_STATE_SAVE_VM);
+
+    f = qemu_fopen(filename, "wb");
+    if (!f) {
+        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
+        goto the_end;
+    }
+    ret = qemu_save_device_state(f);
+    qemu_fclose(f);
+    if (ret < 0) {
+        error_set(errp, QERR_IO_ERROR);
+    }
+
+ the_end:
+    if (saved_vm_running)
+        vm_start();
+    return;
+}
+
 int load_vmstate(const char *name)
 {
     BlockDriverState *bs, *bs_vm_state;
diff --git a/scripts/create_config b/scripts/create_config
index 0098e683e2..470e05e397 100755
--- a/scripts/create_config
+++ b/scripts/create_config
@@ -16,7 +16,7 @@ case $line in
  prefix=* | [a-z]*dir=*) # directory configuration
     name=${line%=*}
     value=${line#*=}
-    define_name=`echo $name | tr '[:lower:]' '[:upper:]'`
+    define_name=`echo $name | LC_ALL=C tr '[a-z]' '[A-Z]'`
     eval "define_value=\"$value\""
     echo "#define CONFIG_QEMU_$define_name \"$define_value\""
     # save for the next definitions
@@ -48,7 +48,7 @@ case $line in
     ;;
  ARCH=*) # configuration
     arch=${line#*=}
-    arch_name=`echo $arch | tr '[:lower:]' '[:upper:]'`
+    arch_name=`echo $arch | LC_ALL=C tr '[a-z]' '[A-Z]'`
     echo "#define HOST_$arch_name 1"
     ;;
  HOST_USB=*)
@@ -73,7 +73,7 @@ case $line in
  TARGET_BASE_ARCH=*) # configuration
     target_base_arch=${line#*=}
     if [ "$target_base_arch" != "$target_arch" ]; then
-      base_arch_name=`echo $target_base_arch | tr '[:lower:]' '[:upper:]'`
+      base_arch_name=`echo $target_base_arch | LC_ALL=C tr '[a-z]' '[A-Z]'`
       echo "#define TARGET_$base_arch_name 1"
     fi
     ;;
diff --git a/scripts/gtester-cat b/scripts/gtester-cat
new file mode 100755
index 0000000000..061a952cad
--- /dev/null
+++ b/scripts/gtester-cat
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# Copyright IBM, Corp. 2012
+#
+# Authors:
+#  Anthony Liguori <aliguori@us.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPLv2 or later.
+# See the COPYING file in the top-level directory.
+
+cat <<EOF
+<?xml version="1.0"?>
+<gtester>
+ <info>
+  <package>qemu</package>
+  <version>0.0</version>
+  <revision>rev</revision>
+ </info>
+EOF
+
+sed \
+  -e '/<?xml/d' \
+  -e '/^<gtester>$/d' \
+  -e '/<info>/,/<\/info>/d' \
+  -e '$b' \
+  -e '/^<\/gtester>$/d' "$@"
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 3aabf61491..0b4f0a0fe1 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -42,7 +42,7 @@ def generate_command_decl(name, args, ret_type):
     return mcgen('''
 %(ret_type)s qmp_%(name)s(%(args)sError **errp);
 ''',
-                 ret_type=c_type(ret_type), name=c_var(name), args=arglist).strip()
+                 ret_type=c_type(ret_type), name=c_fun(name), args=arglist).strip()
 
 def gen_sync_call(name, args, ret_type, indent=0):
     ret = ""
@@ -59,7 +59,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
 %(retval)sqmp_%(name)s(%(args)serrp);
 
 ''',
-                name=c_var(name), args=arglist, retval=retval).rstrip()
+                name=c_fun(name), args=arglist, retval=retval).rstrip()
     if ret_type:
         ret += "\n" + mcgen(''''
 if (!error_is_set(errp)) {
@@ -74,7 +74,7 @@ if (!error_is_set(errp)) {
 def gen_marshal_output_call(name, ret_type):
     if not ret_type:
         return ""
-    return "qmp_marshal_output_%s(retval, ret, errp);" % c_var(name)
+    return "qmp_marshal_output_%s(retval, ret, errp);" % c_fun(name)
 
 def gen_visitor_output_containers_decl(ret_type):
     ret = ""
@@ -140,7 +140,7 @@ v = qapi_dealloc_get_visitor(md);
 ''')
     else:
         ret += mcgen('''
-mi = qmp_input_visitor_new(%(obj)s);
+mi = qmp_input_visitor_new_strict(%(obj)s);
 v = qmp_input_get_visitor(mi);
 ''',
                      obj=obj)
@@ -198,16 +198,16 @@ static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_o
     qapi_dealloc_visitor_cleanup(md);
 }
 ''',
-                c_ret_type=c_type(ret_type), c_name=c_var(name),
+                c_ret_type=c_type(ret_type), c_name=c_fun(name),
                 visitor=type_visitor(ret_type))
 
     return ret
 
 def gen_marshal_input_decl(name, args, ret_type, middle_mode):
     if middle_mode:
-        return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_var(name)
+        return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_fun(name)
     else:
-        return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_var(name)
+        return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_fun(name)
 
 
 
@@ -298,7 +298,7 @@ def gen_registry(commands):
         registry += mcgen('''
 qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s);
 ''',
-                     name=cmd['command'], c_name=c_var(cmd['command']))
+                     name=cmd['command'], c_name=c_fun(cmd['command']))
     pop_indent()
     ret = mcgen('''
 static void qmp_init_marshal(void)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 727fb77266..4a734f58d5 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -100,7 +100,7 @@ typedef enum %(name)s
     %(abbrev)s_%(value)s = %(i)d,
 ''',
                      abbrev=de_camel_case(name).upper(),
-                     value=c_var(value).upper(),
+                     value=c_fun(value).upper(),
                      i=i)
         i += 1
 
@@ -126,7 +126,7 @@ struct %(name)s
         %(c_type)s %(c_name)s;
 ''',
                      c_type=c_type(typeinfo[key]),
-                     c_name=c_var(key))
+                     c_name=c_fun(key))
 
     ret += mcgen('''
     };
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 54117d4d2b..8d4e94a45f 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -61,7 +61,13 @@ def generate_visit_struct(name, members):
 
 void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
 {
+    if (error_is_set(errp)) {
+        return;
+    }
     visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), errp);
+    if (obj && !*obj) {
+        goto end;
+    }
 ''',
                 name=name)
     push_indent()
@@ -69,6 +75,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
     pop_indent()
 
     ret += mcgen('''
+end:
     visit_end_struct(m, errp);
 }
 ''')
@@ -79,11 +86,14 @@ def generate_visit_list(name, members):
 
 void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
 {
-    GenericList *i, **head = (GenericList **)obj;
+    GenericList *i, **prev = (GenericList **)obj;
 
+    if (error_is_set(errp)) {
+        return;
+    }
     visit_start_list(m, name, errp);
 
-    for (*head = i = visit_next_list(m, head, errp); i; i = visit_next_list(m, &i, errp)) {
+    for (; (i = visit_next_list(m, prev, errp)) != NULL; prev = &i) {
         %(name)sList *native_i = (%(name)sList *)i;
         visit_type_%(name)s(m, &native_i->value, NULL, errp);
     }
@@ -112,7 +122,13 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
 {
     Error *err = NULL;
 
+    if (error_is_set(errp)) {
+        return;
+    }
     visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
+    if (obj && !*obj) {
+        goto end;
+    }
     visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err);
     if (err) {
         error_propagate(errp, err);
@@ -129,9 +145,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
         break;
 ''',
                 abbrev = de_camel_case(name).upper(),
-                enum = de_camel_case(key).upper(),
+                enum = c_fun(de_camel_case(key)).upper(),
                 c_type=members[key],
-                c_name=c_var(key))
+                c_name=c_fun(key))
 
     ret += mcgen('''
     default:
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 6e05469e6d..e06233666b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -131,7 +131,10 @@ def camel_case(name):
     return new_name
 
 def c_var(name):
-    return '_'.join(name.split('-')).lstrip("*")
+    return name.replace('-', '_').lstrip("*")
+
+def c_fun(name):
+    return c_var(name).replace('.', '_')
 
 def c_list_type(name):
     return '%sList' % name
diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
new file mode 100644
index 0000000000..8a0f30534f
--- /dev/null
+++ b/scripts/qemu-gdb.py
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+
+# GDB debugging support
+#
+# Copyright 2012 Red Hat, Inc. and/or its affiliates
+#
+# Authors:
+#  Avi Kivity <avi@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2.  See
+# the COPYING file in the top-level directory.
+#
+# Contributions after 2012-01-13 are licensed under the terms of the
+# GNU GPL, version 2 or (at your option) any later version.
+
+
+import gdb
+
+def isnull(ptr):
+    return ptr == gdb.Value(0).cast(ptr.type)
+
+def int128(p):
+    return long(p['lo']) + (long(p['hi']) << 64)
+
+class QemuCommand(gdb.Command):
+    '''Prefix for QEMU debug support commands'''
+    def __init__(self):
+        gdb.Command.__init__(self, 'qemu', gdb.COMMAND_DATA,
+                             gdb.COMPLETE_NONE, True)
+
+class MtreeCommand(gdb.Command):
+    '''Display the memory tree hierarchy'''
+    def __init__(self):
+        gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
+                             gdb.COMPLETE_NONE)
+        self.queue = []
+    def invoke(self, arg, from_tty):
+        self.seen = set()
+        self.queue_root('address_space_memory')
+        self.queue_root('address_space_io')
+        self.process_queue()
+    def queue_root(self, varname):
+        ptr = gdb.parse_and_eval(varname)['root']
+        self.queue.append(ptr)
+    def process_queue(self):
+        while self.queue:
+            ptr = self.queue.pop(0)
+            if long(ptr) in self.seen:
+                continue
+            self.print_item(ptr)
+    def print_item(self, ptr, offset = gdb.Value(0), level = 0):
+        self.seen.add(long(ptr))
+        addr = ptr['addr']
+        addr += offset
+        size = int128(ptr['size'])
+        alias = ptr['alias']
+        klass = ''
+        if not isnull(alias):
+            klass = ' (alias)'
+        elif not isnull(ptr['ops']):
+            klass = ' (I/O)'
+        elif bool(ptr['ram']):
+            klass = ' (RAM)'
+        gdb.write('%s%016x-%016x %s%s (@ %s)\n'
+                  % ('  ' * level,
+                     long(addr),
+                     long(addr + (size - 1)),
+                     ptr['name'].string(),
+                     klass,
+                     ptr,
+                     ),
+                  gdb.STDOUT)
+        if not isnull(alias):
+            gdb.write('%s    alias: %s@%016x (@ %s)\n' %
+                      ('  ' * level,
+                       alias['name'].string(),
+                       ptr['alias_offset'],
+                       alias,
+                       ),
+                      gdb.STDOUT)
+            self.queue.append(alias)
+        subregion = ptr['subregions']['tqh_first']
+        level += 1
+        while not isnull(subregion):
+            self.print_item(subregion, addr, level)
+            subregion = subregion['subregions_link']['tqe_next']
+
+QemuCommand()
+MtreeCommand()
diff --git a/scripts/qtest b/scripts/qtest
new file mode 100755
index 0000000000..4ef6c1c500
--- /dev/null
+++ b/scripts/qtest
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+export QTEST_QEMU_BINARY=$1
+shift
+"$@"
diff --git a/scripts/texi2pod.pl b/scripts/texi2pod.pl
index 9ed056ad1c..94097fb065 100755
--- a/scripts/texi2pod.pl
+++ b/scripts/texi2pod.pl
@@ -36,6 +36,7 @@ $fnno = 1;
 $inf = "";
 $ibase = "";
 @ipath = ();
+$encoding = undef;
 
 while ($_ = shift) {
     if (/^-D(.*)$/) {
@@ -97,6 +98,12 @@ while(<$inf>) {
     /^\@setfilename\s+([^.]+)/ and $fn = $1, next;
     /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next;
 
+    # Look for document encoding
+    /^\@documentencoding\s+([^.]+)/ and do {
+        $encoding = $1 unless defined $encoding;
+        next;
+    };
+
     # Identify a man title but keep only the one we are interested in.
     /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do {
 	if (exists $defs{$1}) {
@@ -336,6 +343,8 @@ $inf = pop @instack;
 
 die "No filename or title\n" unless defined $fn && defined $tl;
 
+print "=encoding $encoding\n\n" if defined $encoding;
+
 $sects{NAME} = "$fn \- $tl\n";
 $sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
 
diff --git a/scripts/tracetool b/scripts/tracetool
index 65bd0a1b4c..47389b62ea 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -161,6 +161,18 @@ linetoc_nop()
     return
 }
 
+linetod_nop()
+{
+    # Used when "disabled" events are processed
+    return
+}
+
+linetostap_nop()
+{
+    # Used when "disabled" events are processed
+    return
+}
+
 linetoc_end_nop()
 {
     return
@@ -410,7 +422,7 @@ linetoh_dtrace()
     args=$(get_args "$1")
     argnames=$(get_argnames "$1", ",")
 
-    nameupper=`echo $name | tr '[:lower:]' '[:upper:]'`
+    nameupper=`echo $name | LC_ALL=C tr '[a-z]' '[A-Z]'`
 
     # Define an empty function for the trace event
     cat <<EOF
@@ -494,10 +506,12 @@ EOF
     i=1
     for arg in $arglist
     do
-        # 'limit' is a reserved keyword
-        if [ "$arg" = "limit" ]; then
-          arg="_limit"
-        fi
+        # postfix reserved words with '_'
+        case "$arg" in
+            limit|in|next|self)
+                arg="${arg}_"
+                ;;
+        esac
         cat <<EOF
   $arg = \$arg$i;
 EOF
@@ -539,7 +553,7 @@ convert()
         fi
         if [ "$1" = "h" ]; then
             name=$(get_name "$str")
-            NAME=$(echo $name | tr '[:lower:]' '[:upper:]')
+            NAME=$(echo $name | LC_ALL=C tr '[a-z]' '[A-Z]')
             echo "#define TRACE_${NAME}_ENABLED ${enabled}"
         fi
     done
diff --git a/slirp/misc.c b/slirp/misc.c
index 0308a62fac..0bee864337 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -215,7 +215,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
                 setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
                 opt = 1;
                 setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
-		fd_nonblock(so->s);
+		socket_set_nonblock(so->s);
 
 		/* Append the telnet options now */
                 if (so->so_m != NULL && do_pty == 1)  {
@@ -267,50 +267,6 @@ u_sleep(int usec)
 	select(0, &fdset, &fdset, &fdset, &t);
 }
 
-/*
- * Set fd blocking and non-blocking
- */
-
-void
-fd_nonblock(int fd)
-{
-#ifdef FIONBIO
-#ifdef _WIN32
-        unsigned long opt = 1;
-#else
-        int opt = 1;
-#endif
-
-	ioctlsocket(fd, FIONBIO, &opt);
-#else
-	int opt;
-
-	opt = fcntl(fd, F_GETFL, 0);
-	opt |= O_NONBLOCK;
-	fcntl(fd, F_SETFL, opt);
-#endif
-}
-
-void
-fd_block(int fd)
-{
-#ifdef FIONBIO
-#ifdef _WIN32
-        unsigned long opt = 0;
-#else
-	int opt = 0;
-#endif
-
-	ioctlsocket(fd, FIONBIO, &opt);
-#else
-	int opt;
-
-	opt = fcntl(fd, F_GETFL, 0);
-	opt &= ~O_NONBLOCK;
-	fcntl(fd, F_SETFL, opt);
-#endif
-}
-
 void slirp_connection_info(Slirp *slirp, Monitor *mon)
 {
     const char * const tcpstates[] = {
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index 5a1ccbfadf..637f8fea3d 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -6,6 +6,7 @@
  */
 
 #include <slirp.h>
+#include <main-loop.h>
 
 static void sbappendsb(struct sbuf *sb, struct mbuf *m);
 
@@ -18,6 +19,8 @@ sbfree(struct sbuf *sb)
 void
 sbdrop(struct sbuf *sb, int num)
 {
+    int limit = sb->sb_datalen / 2;
+
 	/*
 	 * We can only drop how much we have
 	 * This should never succeed
@@ -29,6 +32,9 @@ sbdrop(struct sbuf *sb, int num)
 	if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
 		sb->sb_rptr -= sb->sb_datalen;
 
+    if (sb->sb_cc < limit && sb->sb_cc + num >= limit) {
+        qemu_notify_event();
+    }
 }
 
 void
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 5033ee3118..46bfe4636d 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -15,6 +15,12 @@ typedef char *caddr_t;
 # include <sys/timeb.h>
 # include <iphlpapi.h>
 
+# undef EWOULDBLOCK
+# undef EINPROGRESS
+# undef ENOTCONN
+# undef EHOSTUNREACH
+# undef ENETUNREACH
+# undef ECONNREFUSED
 # define EWOULDBLOCK WSAEWOULDBLOCK
 # define EINPROGRESS WSAEINPROGRESS
 # define ENOTCONN WSAENOTCONN
@@ -88,10 +94,6 @@ void *malloc(size_t arg);
 void free(void *ptr);
 #endif
 
-#ifndef HAVE_INET_ATON
-int inet_aton(const char *cp, struct in_addr *ia);
-#endif
-
 #include <fcntl.h>
 #ifndef NO_UNIX_SOCKETS
 #include <sys/un.h>
@@ -144,6 +146,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #include "debug.h"
 
 #include "qemu-queue.h"
+#include "qemu_socket.h"
 
 #include "libslirp.h"
 #include "ip.h"
@@ -167,9 +170,6 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #include "bootp.h"
 #include "tftp.h"
 
-/* osdep.c */
-int qemu_socket(int domain, int type, int protocol);
-
 #define ETH_ALEN 6
 #define ETH_HLEN 14
 
diff --git a/slirp/tcp.h b/slirp/tcp.h
index b3817cb13c..82996031e0 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -45,6 +45,7 @@ typedef	uint32_t tcp_seq;
  * TCP header.
  * Per RFC 793, September, 1981.
  */
+#define tcphdr slirp_tcphdr
 struct tcphdr {
 	uint16_t th_sport;              /* source port */
 	uint16_t th_dport;              /* destination port */
@@ -58,12 +59,6 @@ struct tcphdr {
 		th_off:4;		/* data offset */
 #endif
 	uint8_t th_flags;
-#define	TH_FIN	0x01
-#define	TH_SYN	0x02
-#define	TH_RST	0x04
-#define	TH_PUSH	0x08
-#define	TH_ACK	0x10
-#define	TH_URG	0x20
 	uint16_t th_win;                /* window */
 	uint16_t th_sum;                /* checksum */
 	uint16_t th_urp;                /* urgent pointer */
@@ -71,6 +66,16 @@ struct tcphdr {
 
 #include "tcp_var.h"
 
+#ifndef TH_FIN
+#define	TH_FIN	0x01
+#define	TH_SYN	0x02
+#define	TH_RST	0x04
+#define	TH_PUSH	0x08
+#define	TH_ACK	0x10
+#define	TH_URG	0x20
+#endif
+
+#ifndef TCPOPT_EOL
 #define	TCPOPT_EOL		0
 #define	TCPOPT_NOP		1
 #define	TCPOPT_MAXSEG		2
@@ -86,6 +91,7 @@ struct tcphdr {
 
 #define TCPOPT_TSTAMP_HDR	\
     (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+#endif
 
 /*
  * Default maximum segment size for TCP.
@@ -95,10 +101,13 @@ struct tcphdr {
  *
  * We make this 1460 because we only care about Ethernet in the qemu context.
  */
+#undef TCP_MSS
 #define	TCP_MSS	1460
 
+#undef TCP_MAXWIN
 #define	TCP_MAXWIN	65535	/* largest value for (unscaled) window */
 
+#undef TCP_MAX_WINSHIFT
 #define TCP_MAX_WINSHIFT	14	/* maximum window shift */
 
 /*
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 6f6585a10f..0a545c41e7 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -336,7 +336,7 @@ int tcp_fconnect(struct socket *so)
     int opt, s=so->s;
     struct sockaddr_in addr;
 
-    fd_nonblock(s);
+    socket_set_nonblock(s);
     opt = 1;
     setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt ));
     opt = 1;
@@ -424,7 +424,7 @@ tcp_connect(struct socket *inso)
 		tcp_close(sototcpcb(so)); /* This will sofree() as well */
 		return;
 	}
-	fd_nonblock(s);
+	socket_set_nonblock(s);
 	opt = 1;
 	setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
 	opt = 1;
diff --git a/sysemu.h b/sysemu.h
index 98118cc478..bc2c788921 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -76,12 +76,11 @@ void do_info_snapshots(Monitor *mon);
 
 void qemu_announce_self(void);
 
-bool qemu_savevm_state_blocked(Monitor *mon);
-int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
-                            int shared);
-int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f);
-int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f);
-void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f);
+bool qemu_savevm_state_blocked(Error **errp);
+int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared);
+int qemu_savevm_state_iterate(QEMUFile *f);
+int qemu_savevm_state_complete(QEMUFile *f);
+void qemu_savevm_state_cancel(QEMUFile *f);
 int qemu_loadvm_state(QEMUFile *f);
 
 /* SLIRP */
diff --git a/target-alpha/STATUS b/target-alpha/STATUS
index 742e370b90..6c9744569e 100644
--- a/target-alpha/STATUS
+++ b/target-alpha/STATUS
@@ -4,7 +4,7 @@ Alpha emulation structure:
 cpu.h           : CPU definitions globally exported
 exec.h          : CPU definitions used only for translated code execution
 helper.c        : helpers that can be called either by the translated code
-                  or the Qemu core, including the exception handler.
+                  or the QEMU core, including the exception handler.
 op_helper.c     : helpers that can be called only from TCG
 helper.h        : TCG helpers prototypes
 translate.c     : Alpha instructions to micro-operations translator
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 48c0fdc188..74bf7f7ff4 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -234,7 +234,6 @@ struct CPUAlphaState {
     uint8_t fpcr_exc_mask;
     uint8_t fpcr_dyn_round;
     uint8_t fpcr_flush_to_zero;
-    uint8_t fpcr_dnz;
     uint8_t fpcr_dnod;
     uint8_t fpcr_undz;
 
@@ -277,7 +276,7 @@ struct CPUAlphaState {
     target_ulong t0, t1;
 #endif
 
-    /* Those resources are used only in Qemu core */
+    /* Those resources are used only in QEMU core */
     CPU_COMMON
 
     int error_code;
@@ -434,6 +433,9 @@ int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
                                 int mmu_idx);
 #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
 void do_interrupt (CPUAlphaState *env);
+void do_restore_state(CPUAlphaState *, void *retaddr);
+void QEMU_NORETURN dynamic_excp(CPUAlphaState *, void *, int, int);
+void QEMU_NORETURN arith_excp(CPUAlphaState *, void *, int, uint64_t);
 
 uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
 void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c
new file mode 100644
index 0000000000..dda110352e
--- /dev/null
+++ b/target-alpha/fpu_helper.c
@@ -0,0 +1,822 @@
+/*
+ *  Helpers for floating point instructions.
+ *
+ *  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 "cpu.h"
+#include "helper.h"
+#include "softfloat.h"
+
+#define FP_STATUS (env->fp_status)
+
+
+void helper_setroundmode(CPUAlphaState *env, uint32_t val)
+{
+    set_float_rounding_mode(val, &FP_STATUS);
+}
+
+void helper_setflushzero(CPUAlphaState *env, uint32_t val)
+{
+    set_flush_to_zero(val, &FP_STATUS);
+}
+
+void helper_fp_exc_clear(CPUAlphaState *env)
+{
+    set_float_exception_flags(0, &FP_STATUS);
+}
+
+uint32_t helper_fp_exc_get(CPUAlphaState *env)
+{
+    return get_float_exception_flags(&FP_STATUS);
+}
+
+static inline void inline_fp_exc_raise(CPUAlphaState *env, void *retaddr,
+                                       uint32_t exc, uint32_t regno)
+{
+    if (exc) {
+        uint32_t hw_exc = 0;
+
+        if (exc & float_flag_invalid) {
+            hw_exc |= EXC_M_INV;
+        }
+        if (exc & float_flag_divbyzero) {
+            hw_exc |= EXC_M_DZE;
+        }
+        if (exc & float_flag_overflow) {
+            hw_exc |= EXC_M_FOV;
+        }
+        if (exc & float_flag_underflow) {
+            hw_exc |= EXC_M_UNF;
+        }
+        if (exc & float_flag_inexact) {
+            hw_exc |= EXC_M_INE;
+        }
+
+        arith_excp(env, retaddr, hw_exc, 1ull << regno);
+    }
+}
+
+/* Raise exceptions for ieee fp insns without software completion.
+   In that case there are no exceptions that don't trap; the mask
+   doesn't apply.  */
+void helper_fp_exc_raise(CPUAlphaState *env, uint32_t exc, uint32_t regno)
+{
+    inline_fp_exc_raise(env, GETPC(), exc, regno);
+}
+
+/* Raise exceptions for ieee fp insns with software completion.  */
+void helper_fp_exc_raise_s(CPUAlphaState *env, uint32_t exc, uint32_t regno)
+{
+    if (exc) {
+        env->fpcr_exc_status |= exc;
+        exc &= ~env->fpcr_exc_mask;
+        inline_fp_exc_raise(env, GETPC(), exc, regno);
+    }
+}
+
+/* Input handing without software completion.  Trap for all
+   non-finite numbers.  */
+void helper_ieee_input(CPUAlphaState *env, uint64_t val)
+{
+    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
+    uint64_t frac = val & 0xfffffffffffffull;
+
+    if (exp == 0) {
+        /* Denormals without DNZ set raise an exception.  */
+        if (frac != 0 && !env->fp_status.flush_inputs_to_zero) {
+            arith_excp(env, GETPC(), EXC_M_UNF, 0);
+        }
+    } else if (exp == 0x7ff) {
+        /* Infinity or NaN.  */
+        /* ??? I'm not sure these exception bit flags are correct.  I do
+           know that the Linux kernel, at least, doesn't rely on them and
+           just emulates the insn to figure out what exception to use.  */
+        arith_excp(env, GETPC(), frac ? EXC_M_INV : EXC_M_FOV, 0);
+    }
+}
+
+/* Similar, but does not trap for infinities.  Used for comparisons.  */
+void helper_ieee_input_cmp(CPUAlphaState *env, uint64_t val)
+{
+    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
+    uint64_t frac = val & 0xfffffffffffffull;
+
+    if (exp == 0) {
+        /* Denormals without DNZ set raise an exception.  */
+        if (frac != 0 && !env->fp_status.flush_inputs_to_zero) {
+            arith_excp(env, GETPC(), EXC_M_UNF, 0);
+        }
+    } else if (exp == 0x7ff && frac) {
+        /* NaN.  */
+        arith_excp(env, GETPC(), EXC_M_INV, 0);
+    }
+}
+
+/* F floating (VAX) */
+static uint64_t float32_to_f(float32 fa)
+{
+    uint64_t r, exp, mant, sig;
+    CPU_FloatU a;
+
+    a.f = fa;
+    sig = ((uint64_t)a.l & 0x80000000) << 32;
+    exp = (a.l >> 23) & 0xff;
+    mant = ((uint64_t)a.l & 0x007fffff) << 29;
+
+    if (exp == 255) {
+        /* NaN or infinity */
+        r = 1; /* VAX dirty zero */
+    } else if (exp == 0) {
+        if (mant == 0) {
+            /* Zero */
+            r = 0;
+        } else {
+            /* Denormalized */
+            r = sig | ((exp + 1) << 52) | mant;
+        }
+    } else {
+        if (exp >= 253) {
+            /* Overflow */
+            r = 1; /* VAX dirty zero */
+        } else {
+            r = sig | ((exp + 2) << 52);
+        }
+    }
+
+    return r;
+}
+
+static float32 f_to_float32(CPUAlphaState *env, void *retaddr, uint64_t a)
+{
+    uint32_t exp, mant_sig;
+    CPU_FloatU r;
+
+    exp = ((a >> 55) & 0x80) | ((a >> 52) & 0x7f);
+    mant_sig = ((a >> 32) & 0x80000000) | ((a >> 29) & 0x007fffff);
+
+    if (unlikely(!exp && mant_sig)) {
+        /* Reserved operands / Dirty zero */
+        dynamic_excp(env, retaddr, EXCP_OPCDEC, 0);
+    }
+
+    if (exp < 3) {
+        /* Underflow */
+        r.l = 0;
+    } else {
+        r.l = ((exp - 2) << 23) | mant_sig;
+    }
+
+    return r.f;
+}
+
+uint32_t helper_f_to_memory(uint64_t a)
+{
+    uint32_t r;
+    r =  (a & 0x00001fffe0000000ull) >> 13;
+    r |= (a & 0x07ffe00000000000ull) >> 45;
+    r |= (a & 0xc000000000000000ull) >> 48;
+    return r;
+}
+
+uint64_t helper_memory_to_f(uint32_t a)
+{
+    uint64_t r;
+    r =  ((uint64_t)(a & 0x0000c000)) << 48;
+    r |= ((uint64_t)(a & 0x003fffff)) << 45;
+    r |= ((uint64_t)(a & 0xffff0000)) << 13;
+    if (!(a & 0x00004000)) {
+        r |= 0x7ll << 59;
+    }
+    return r;
+}
+
+/* ??? Emulating VAX arithmetic with IEEE arithmetic is wrong.  We should
+   either implement VAX arithmetic properly or just signal invalid opcode.  */
+
+uint64_t helper_addf(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = f_to_float32(env, GETPC(), a);
+    fb = f_to_float32(env, GETPC(), b);
+    fr = float32_add(fa, fb, &FP_STATUS);
+    return float32_to_f(fr);
+}
+
+uint64_t helper_subf(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = f_to_float32(env, GETPC(), a);
+    fb = f_to_float32(env, GETPC(), b);
+    fr = float32_sub(fa, fb, &FP_STATUS);
+    return float32_to_f(fr);
+}
+
+uint64_t helper_mulf(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = f_to_float32(env, GETPC(), a);
+    fb = f_to_float32(env, GETPC(), b);
+    fr = float32_mul(fa, fb, &FP_STATUS);
+    return float32_to_f(fr);
+}
+
+uint64_t helper_divf(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = f_to_float32(env, GETPC(), a);
+    fb = f_to_float32(env, GETPC(), b);
+    fr = float32_div(fa, fb, &FP_STATUS);
+    return float32_to_f(fr);
+}
+
+uint64_t helper_sqrtf(CPUAlphaState *env, uint64_t t)
+{
+    float32 ft, fr;
+
+    ft = f_to_float32(env, GETPC(), t);
+    fr = float32_sqrt(ft, &FP_STATUS);
+    return float32_to_f(fr);
+}
+
+
+/* G floating (VAX) */
+static uint64_t float64_to_g(float64 fa)
+{
+    uint64_t r, exp, mant, sig;
+    CPU_DoubleU a;
+
+    a.d = fa;
+    sig = a.ll & 0x8000000000000000ull;
+    exp = (a.ll >> 52) & 0x7ff;
+    mant = a.ll & 0x000fffffffffffffull;
+
+    if (exp == 2047) {
+        /* NaN or infinity */
+        r = 1; /* VAX dirty zero */
+    } else if (exp == 0) {
+        if (mant == 0) {
+            /* Zero */
+            r = 0;
+        } else {
+            /* Denormalized */
+            r = sig | ((exp + 1) << 52) | mant;
+        }
+    } else {
+        if (exp >= 2045) {
+            /* Overflow */
+            r = 1; /* VAX dirty zero */
+        } else {
+            r = sig | ((exp + 2) << 52);
+        }
+    }
+
+    return r;
+}
+
+static float64 g_to_float64(CPUAlphaState *env, void *retaddr, uint64_t a)
+{
+    uint64_t exp, mant_sig;
+    CPU_DoubleU r;
+
+    exp = (a >> 52) & 0x7ff;
+    mant_sig = a & 0x800fffffffffffffull;
+
+    if (!exp && mant_sig) {
+        /* Reserved operands / Dirty zero */
+        dynamic_excp(env, retaddr, EXCP_OPCDEC, 0);
+    }
+
+    if (exp < 3) {
+        /* Underflow */
+        r.ll = 0;
+    } else {
+        r.ll = ((exp - 2) << 52) | mant_sig;
+    }
+
+    return r.d;
+}
+
+uint64_t helper_g_to_memory(uint64_t a)
+{
+    uint64_t r;
+    r =  (a & 0x000000000000ffffull) << 48;
+    r |= (a & 0x00000000ffff0000ull) << 16;
+    r |= (a & 0x0000ffff00000000ull) >> 16;
+    r |= (a & 0xffff000000000000ull) >> 48;
+    return r;
+}
+
+uint64_t helper_memory_to_g(uint64_t a)
+{
+    uint64_t r;
+    r =  (a & 0x000000000000ffffull) << 48;
+    r |= (a & 0x00000000ffff0000ull) << 16;
+    r |= (a & 0x0000ffff00000000ull) >> 16;
+    r |= (a & 0xffff000000000000ull) >> 48;
+    return r;
+}
+
+uint64_t helper_addg(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fb = g_to_float64(env, GETPC(), b);
+    fr = float64_add(fa, fb, &FP_STATUS);
+    return float64_to_g(fr);
+}
+
+uint64_t helper_subg(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fb = g_to_float64(env, GETPC(), b);
+    fr = float64_sub(fa, fb, &FP_STATUS);
+    return float64_to_g(fr);
+}
+
+uint64_t helper_mulg(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fb = g_to_float64(env, GETPC(), b);
+    fr = float64_mul(fa, fb, &FP_STATUS);
+    return float64_to_g(fr);
+}
+
+uint64_t helper_divg(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fb = g_to_float64(env, GETPC(), b);
+    fr = float64_div(fa, fb, &FP_STATUS);
+    return float64_to_g(fr);
+}
+
+uint64_t helper_sqrtg(CPUAlphaState *env, uint64_t a)
+{
+    float64 fa, fr;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fr = float64_sqrt(fa, &FP_STATUS);
+    return float64_to_g(fr);
+}
+
+
+/* S floating (single) */
+
+/* Taken from linux/arch/alpha/kernel/traps.c, s_mem_to_reg.  */
+static inline uint64_t float32_to_s_int(uint32_t fi)
+{
+    uint32_t frac = fi & 0x7fffff;
+    uint32_t sign = fi >> 31;
+    uint32_t exp_msb = (fi >> 30) & 1;
+    uint32_t exp_low = (fi >> 23) & 0x7f;
+    uint32_t exp;
+
+    exp = (exp_msb << 10) | exp_low;
+    if (exp_msb) {
+        if (exp_low == 0x7f) {
+            exp = 0x7ff;
+        }
+    } else {
+        if (exp_low != 0x00) {
+            exp |= 0x380;
+        }
+    }
+
+    return (((uint64_t)sign << 63)
+            | ((uint64_t)exp << 52)
+            | ((uint64_t)frac << 29));
+}
+
+static inline uint64_t float32_to_s(float32 fa)
+{
+    CPU_FloatU a;
+    a.f = fa;
+    return float32_to_s_int(a.l);
+}
+
+static inline uint32_t s_to_float32_int(uint64_t a)
+{
+    return ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
+}
+
+static inline float32 s_to_float32(uint64_t a)
+{
+    CPU_FloatU r;
+    r.l = s_to_float32_int(a);
+    return r.f;
+}
+
+uint32_t helper_s_to_memory(uint64_t a)
+{
+    return s_to_float32_int(a);
+}
+
+uint64_t helper_memory_to_s(uint32_t a)
+{
+    return float32_to_s_int(a);
+}
+
+uint64_t helper_adds(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = s_to_float32(a);
+    fb = s_to_float32(b);
+    fr = float32_add(fa, fb, &FP_STATUS);
+    return float32_to_s(fr);
+}
+
+uint64_t helper_subs(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = s_to_float32(a);
+    fb = s_to_float32(b);
+    fr = float32_sub(fa, fb, &FP_STATUS);
+    return float32_to_s(fr);
+}
+
+uint64_t helper_muls(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = s_to_float32(a);
+    fb = s_to_float32(b);
+    fr = float32_mul(fa, fb, &FP_STATUS);
+    return float32_to_s(fr);
+}
+
+uint64_t helper_divs(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float32 fa, fb, fr;
+
+    fa = s_to_float32(a);
+    fb = s_to_float32(b);
+    fr = float32_div(fa, fb, &FP_STATUS);
+    return float32_to_s(fr);
+}
+
+uint64_t helper_sqrts(CPUAlphaState *env, uint64_t a)
+{
+    float32 fa, fr;
+
+    fa = s_to_float32(a);
+    fr = float32_sqrt(fa, &FP_STATUS);
+    return float32_to_s(fr);
+}
+
+
+/* T floating (double) */
+static inline float64 t_to_float64(uint64_t a)
+{
+    /* Memory format is the same as float64 */
+    CPU_DoubleU r;
+    r.ll = a;
+    return r.d;
+}
+
+static inline uint64_t float64_to_t(float64 fa)
+{
+    /* Memory format is the same as float64 */
+    CPU_DoubleU r;
+    r.d = fa;
+    return r.ll;
+}
+
+uint64_t helper_addt(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+    fr = float64_add(fa, fb, &FP_STATUS);
+    return float64_to_t(fr);
+}
+
+uint64_t helper_subt(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+    fr = float64_sub(fa, fb, &FP_STATUS);
+    return float64_to_t(fr);
+}
+
+uint64_t helper_mult(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+    fr = float64_mul(fa, fb, &FP_STATUS);
+    return float64_to_t(fr);
+}
+
+uint64_t helper_divt(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb, fr;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+    fr = float64_div(fa, fb, &FP_STATUS);
+    return float64_to_t(fr);
+}
+
+uint64_t helper_sqrtt(CPUAlphaState *env, uint64_t a)
+{
+    float64 fa, fr;
+
+    fa = t_to_float64(a);
+    fr = float64_sqrt(fa, &FP_STATUS);
+    return float64_to_t(fr);
+}
+
+/* Comparisons */
+uint64_t helper_cmptun(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+
+    if (float64_unordered_quiet(fa, fb, &FP_STATUS)) {
+        return 0x4000000000000000ULL;
+    } else {
+        return 0;
+    }
+}
+
+uint64_t helper_cmpteq(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+
+    if (float64_eq_quiet(fa, fb, &FP_STATUS)) {
+        return 0x4000000000000000ULL;
+    } else {
+        return 0;
+    }
+}
+
+uint64_t helper_cmptle(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+
+    if (float64_le(fa, fb, &FP_STATUS)) {
+        return 0x4000000000000000ULL;
+    } else {
+        return 0;
+    }
+}
+
+uint64_t helper_cmptlt(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb;
+
+    fa = t_to_float64(a);
+    fb = t_to_float64(b);
+
+    if (float64_lt(fa, fb, &FP_STATUS)) {
+        return 0x4000000000000000ULL;
+    } else {
+        return 0;
+    }
+}
+
+uint64_t helper_cmpgeq(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fb = g_to_float64(env, GETPC(), b);
+
+    if (float64_eq_quiet(fa, fb, &FP_STATUS)) {
+        return 0x4000000000000000ULL;
+    } else {
+        return 0;
+    }
+}
+
+uint64_t helper_cmpgle(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fb = g_to_float64(env, GETPC(), b);
+
+    if (float64_le(fa, fb, &FP_STATUS)) {
+        return 0x4000000000000000ULL;
+    } else {
+        return 0;
+    }
+}
+
+uint64_t helper_cmpglt(CPUAlphaState *env, uint64_t a, uint64_t b)
+{
+    float64 fa, fb;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fb = g_to_float64(env, GETPC(), b);
+
+    if (float64_lt(fa, fb, &FP_STATUS)) {
+        return 0x4000000000000000ULL;
+    } else {
+        return 0;
+    }
+}
+
+/* Floating point format conversion */
+uint64_t helper_cvtts(CPUAlphaState *env, uint64_t a)
+{
+    float64 fa;
+    float32 fr;
+
+    fa = t_to_float64(a);
+    fr = float64_to_float32(fa, &FP_STATUS);
+    return float32_to_s(fr);
+}
+
+uint64_t helper_cvtst(CPUAlphaState *env, uint64_t a)
+{
+    float32 fa;
+    float64 fr;
+
+    fa = s_to_float32(a);
+    fr = float32_to_float64(fa, &FP_STATUS);
+    return float64_to_t(fr);
+}
+
+uint64_t helper_cvtqs(CPUAlphaState *env, uint64_t a)
+{
+    float32 fr = int64_to_float32(a, &FP_STATUS);
+    return float32_to_s(fr);
+}
+
+/* Implement float64 to uint64 conversion without saturation -- we must
+   supply the truncated result.  This behaviour is used by the compiler
+   to get unsigned conversion for free with the same instruction.
+
+   The VI flag is set when overflow or inexact exceptions should be raised.  */
+
+static inline uint64_t inline_cvttq(CPUAlphaState *env, uint64_t a,
+                                    int roundmode, int VI)
+{
+    uint64_t frac, ret = 0;
+    uint32_t exp, sign, exc = 0;
+    int shift;
+
+    sign = (a >> 63);
+    exp = (uint32_t)(a >> 52) & 0x7ff;
+    frac = a & 0xfffffffffffffull;
+
+    if (exp == 0) {
+        if (unlikely(frac != 0)) {
+            goto do_underflow;
+        }
+    } else if (exp == 0x7ff) {
+        exc = (frac ? float_flag_invalid : VI ? float_flag_overflow : 0);
+    } else {
+        /* Restore implicit bit.  */
+        frac |= 0x10000000000000ull;
+
+        shift = exp - 1023 - 52;
+        if (shift >= 0) {
+            /* In this case the number is so large that we must shift
+               the fraction left.  There is no rounding to do.  */
+            if (shift < 63) {
+                ret = frac << shift;
+                if (VI && (ret >> shift) != frac) {
+                    exc = float_flag_overflow;
+                }
+            }
+        } else {
+            uint64_t round;
+
+            /* In this case the number is smaller than the fraction as
+               represented by the 52 bit number.  Here we must think
+               about rounding the result.  Handle this by shifting the
+               fractional part of the number into the high bits of ROUND.
+               This will let us efficiently handle round-to-nearest.  */
+            shift = -shift;
+            if (shift < 63) {
+                ret = frac >> shift;
+                round = frac << (64 - shift);
+            } else {
+                /* The exponent is so small we shift out everything.
+                   Leave a sticky bit for proper rounding below.  */
+            do_underflow:
+                round = 1;
+            }
+
+            if (round) {
+                exc = (VI ? float_flag_inexact : 0);
+                switch (roundmode) {
+                case float_round_nearest_even:
+                    if (round == (1ull << 63)) {
+                        /* Fraction is exactly 0.5; round to even.  */
+                        ret += (ret & 1);
+                    } else if (round > (1ull << 63)) {
+                        ret += 1;
+                    }
+                    break;
+                case float_round_to_zero:
+                    break;
+                case float_round_up:
+                    ret += 1 - sign;
+                    break;
+                case float_round_down:
+                    ret += sign;
+                    break;
+                }
+            }
+        }
+        if (sign) {
+            ret = -ret;
+        }
+    }
+    if (unlikely(exc)) {
+        float_raise(exc, &FP_STATUS);
+    }
+
+    return ret;
+}
+
+uint64_t helper_cvttq(CPUAlphaState *env, uint64_t a)
+{
+    return inline_cvttq(env, a, FP_STATUS.float_rounding_mode, 1);
+}
+
+uint64_t helper_cvttq_c(CPUAlphaState *env, uint64_t a)
+{
+    return inline_cvttq(env, a, float_round_to_zero, 0);
+}
+
+uint64_t helper_cvttq_svic(CPUAlphaState *env, uint64_t a)
+{
+    return inline_cvttq(env, a, float_round_to_zero, 1);
+}
+
+uint64_t helper_cvtqt(CPUAlphaState *env, uint64_t a)
+{
+    float64 fr = int64_to_float64(a, &FP_STATUS);
+    return float64_to_t(fr);
+}
+
+uint64_t helper_cvtqf(CPUAlphaState *env, uint64_t a)
+{
+    float32 fr = int64_to_float32(a, &FP_STATUS);
+    return float32_to_f(fr);
+}
+
+uint64_t helper_cvtgf(CPUAlphaState *env, uint64_t a)
+{
+    float64 fa;
+    float32 fr;
+
+    fa = g_to_float64(env, GETPC(), a);
+    fr = float64_to_float32(fa, &FP_STATUS);
+    return float32_to_f(fr);
+}
+
+uint64_t helper_cvtgq(CPUAlphaState *env, uint64_t a)
+{
+    float64 fa = g_to_float64(env, GETPC(), a);
+    return float64_to_int64_round_to_zero(fa, &FP_STATUS);
+}
+
+uint64_t helper_cvtqg(CPUAlphaState *env, uint64_t a)
+{
+    float64 fr;
+    fr = int64_to_float64(a, &FP_STATUS);
+    return float64_to_g(fr);
+}
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 3f2e7c383d..765e650002 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -23,6 +23,7 @@
 
 #include "cpu.h"
 #include "softfloat.h"
+#include "helper.h"
 
 uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env)
 {
@@ -81,7 +82,7 @@ uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env)
         break;
     }
 
-    if (env->fpcr_dnz) {
+    if (env->fp_status.flush_inputs_to_zero) {
         r |= FPCR_DNZ;
     }
     if (env->fpcr_dnod) {
@@ -150,17 +151,25 @@ void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val)
     }
     env->fpcr_dyn_round = t;
 
-    env->fpcr_flush_to_zero
-      = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD);
-
-    env->fpcr_dnz = (val & FPCR_DNZ) != 0;
     env->fpcr_dnod = (val & FPCR_DNOD) != 0;
     env->fpcr_undz = (val & FPCR_UNDZ) != 0;
+    env->fpcr_flush_to_zero = env->fpcr_dnod & env->fpcr_undz;
+    env->fp_status.flush_inputs_to_zero = (val & FPCR_DNZ) != 0;
+}
+
+uint64_t helper_load_fpcr(CPUAlphaState *env)
+{
+    return cpu_alpha_load_fpcr(env);
+}
+
+void helper_store_fpcr(CPUAlphaState *env, uint64_t val)
+{
+    cpu_alpha_store_fpcr(env, val);
 }
 
 #if defined(CONFIG_USER_ONLY)
-int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, target_ulong address, int rw,
-                                int mmu_idx)
+int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong address,
+                               int rw, int mmu_idx)
 {
     env->exception_index = EXCP_MMFAULT;
     env->trap_arg0 = address;
@@ -484,3 +493,41 @@ void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf,
     }
     cpu_fprintf(f, "\n");
 }
+
+void do_restore_state(CPUAlphaState *env, void *retaddr)
+{
+    uintptr_t pc = (uintptr_t)retaddr;
+    if (pc) {
+        TranslationBlock *tb = tb_find_pc(pc);
+        if (tb) {
+            cpu_restore_state(tb, env, pc);
+        }
+    }
+}
+
+/* This should only be called from translate, via gen_excp.
+   We expect that ENV->PC has already been updated.  */
+void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error)
+{
+    env->exception_index = excp;
+    env->error_code = error;
+    cpu_loop_exit(env);
+}
+
+/* This may be called from any of the helpers to set up EXCEPTION_INDEX.  */
+void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, void *retaddr,
+                                int excp, int error)
+{
+    env->exception_index = excp;
+    env->error_code = error;
+    do_restore_state(env, retaddr);
+    cpu_loop_exit(env);
+}
+
+void QEMU_NORETURN arith_excp(CPUAlphaState *env, void *retaddr,
+                              int exc, uint64_t mask)
+{
+    env->trap_arg0 = exc;
+    env->trap_arg1 = mask;
+    dynamic_excp(env, retaddr, EXCP_ARITH, 0);
+}
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index b693ceea97..a184def3e9 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -1,14 +1,14 @@
 #include "def-helper.h"
 
-DEF_HELPER_2(excp, void, int, int)
-DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64)
-
-DEF_HELPER_2(addqv, i64, i64, i64)
-DEF_HELPER_2(addlv, i64, i64, i64)
-DEF_HELPER_2(subqv, i64, i64, i64)
-DEF_HELPER_2(sublv, i64, i64, i64)
-DEF_HELPER_2(mullv, i64, i64, i64)
-DEF_HELPER_2(mulqv, i64, i64, i64)
+DEF_HELPER_3(excp, noreturn, env, int, int)
+DEF_HELPER_FLAGS_1(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64, env)
+
+DEF_HELPER_3(addqv, i64, env, i64, i64)
+DEF_HELPER_3(addlv, i64, env, i64, i64)
+DEF_HELPER_3(subqv, i64, env, i64, i64)
+DEF_HELPER_3(sublv, i64, env, i64, i64)
+DEF_HELPER_3(mullv, i64, env, i64, i64)
+DEF_HELPER_3(mulqv, i64, env, i64, i64)
 DEF_HELPER_FLAGS_2(umulh, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
 
 DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
@@ -34,90 +34,89 @@ DEF_HELPER_FLAGS_1(pkwb, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
 DEF_HELPER_FLAGS_1(unpkbl, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
 DEF_HELPER_FLAGS_1(unpkbw, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
 
-DEF_HELPER_FLAGS_0(load_fpcr, TCG_CALL_CONST | TCG_CALL_PURE, i64)
-DEF_HELPER_FLAGS_1(store_fpcr, TCG_CALL_CONST, void, i64)
+DEF_HELPER_FLAGS_1(load_fpcr, TCG_CALL_CONST | TCG_CALL_PURE, i64, env)
+DEF_HELPER_FLAGS_2(store_fpcr, TCG_CALL_CONST, void, env, i64)
 
 DEF_HELPER_FLAGS_1(f_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64)
 DEF_HELPER_FLAGS_1(memory_to_f, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32)
-DEF_HELPER_FLAGS_2(addf, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(subf, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(mulf, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(divf, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_1(sqrtf, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_3(addf, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(subf, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(mulf, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(divf, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_2(sqrtf, TCG_CALL_CONST, i64, env, i64)
 
 DEF_HELPER_FLAGS_1(g_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
 DEF_HELPER_FLAGS_1(memory_to_g, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
-DEF_HELPER_FLAGS_2(addg, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(subg, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(mulg, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(divg, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_1(sqrtg, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_3(addg, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(subg, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(mulg, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(divg, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_2(sqrtg, TCG_CALL_CONST, i64, env, i64)
 
 DEF_HELPER_FLAGS_1(s_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64)
 DEF_HELPER_FLAGS_1(memory_to_s, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32)
-DEF_HELPER_FLAGS_2(adds, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(subs, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(muls, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(divs, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_1(sqrts, TCG_CALL_CONST, i64, i64)
-
-DEF_HELPER_FLAGS_2(addt, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(subt, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(mult, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_2(divt, TCG_CALL_CONST, i64, i64, i64)
-DEF_HELPER_FLAGS_1(sqrtt, TCG_CALL_CONST, i64, i64)
-
-DEF_HELPER_FLAGS_2(cmptun, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(cmpteq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(cmptle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(cmptlt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(cmpgeq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(cmpgle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(cmpglt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_1(cvtts, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvtst, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvtqs, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvtqt, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvtqf, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvtgf, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvtgq, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvtqg, TCG_CALL_CONST, i64, i64)
-
-DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvttq_c, TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_1(cvttq_svic, TCG_CALL_CONST, i64, i64)
-
-DEF_HELPER_FLAGS_1(setroundmode, TCG_CALL_CONST, void, i32)
-DEF_HELPER_FLAGS_1(setflushzero, TCG_CALL_CONST, void, i32)
-DEF_HELPER_FLAGS_0(fp_exc_clear, TCG_CALL_CONST, void)
-DEF_HELPER_FLAGS_0(fp_exc_get, TCG_CALL_CONST | TCG_CALL_PURE, i32)
-DEF_HELPER_2(fp_exc_raise, void, i32, i32)
-DEF_HELPER_2(fp_exc_raise_s, void, i32, i32)
-
-DEF_HELPER_1(ieee_input, i64, i64)
-DEF_HELPER_1(ieee_input_cmp, i64, i64)
-DEF_HELPER_1(ieee_input_s, i64, i64)
+DEF_HELPER_FLAGS_3(adds, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(subs, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(muls, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(divs, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_2(sqrts, TCG_CALL_CONST, i64, env, i64)
+
+DEF_HELPER_FLAGS_3(addt, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(subt, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(mult, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(divt, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_2(sqrtt, TCG_CALL_CONST, i64, env, i64)
+
+DEF_HELPER_FLAGS_3(cmptun, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(cmpteq, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(cmptle, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(cmptlt, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(cmpgeq, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(cmpgle, TCG_CALL_CONST, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(cmpglt, TCG_CALL_CONST, i64, env, i64, i64)
+
+DEF_HELPER_FLAGS_2(cvtts, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtst, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtqs, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtqt, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtqf, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtgf, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtgq, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtqg, TCG_CALL_CONST, i64, env, i64)
+
+DEF_HELPER_FLAGS_2(cvttq, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvttq_c, TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvttq_svic, TCG_CALL_CONST, i64, env, i64)
+
+DEF_HELPER_FLAGS_2(setroundmode, TCG_CALL_CONST, void, env, i32)
+DEF_HELPER_FLAGS_2(setflushzero, TCG_CALL_CONST, void, env, i32)
+DEF_HELPER_FLAGS_1(fp_exc_clear, TCG_CALL_CONST, void, env)
+DEF_HELPER_FLAGS_1(fp_exc_get, TCG_CALL_CONST | TCG_CALL_PURE, i32, env)
+DEF_HELPER_3(fp_exc_raise, void, env, i32, i32)
+DEF_HELPER_3(fp_exc_raise_s, void, env, i32, i32)
+
+DEF_HELPER_2(ieee_input, void, env, i64)
+DEF_HELPER_2(ieee_input_cmp, void, env, i64)
 
 #if !defined (CONFIG_USER_ONLY)
-DEF_HELPER_1(hw_ret, void, i64)
+DEF_HELPER_2(hw_ret, void, env, i64)
 
 DEF_HELPER_1(ldl_phys, i64, i64)
 DEF_HELPER_1(ldq_phys, i64, i64)
-DEF_HELPER_1(ldl_l_phys, i64, i64)
-DEF_HELPER_1(ldq_l_phys, i64, i64)
+DEF_HELPER_2(ldl_l_phys, i64, env, i64)
+DEF_HELPER_2(ldq_l_phys, i64, env, i64)
 DEF_HELPER_2(stl_phys, void, i64, i64)
 DEF_HELPER_2(stq_phys, void, i64, i64)
-DEF_HELPER_2(stl_c_phys, i64, i64, i64)
-DEF_HELPER_2(stq_c_phys, i64, i64, i64)
+DEF_HELPER_3(stl_c_phys, i64, env, i64, i64)
+DEF_HELPER_3(stq_c_phys, i64, env, i64, i64)
 
-DEF_HELPER_FLAGS_0(tbia, TCG_CALL_CONST, void)
-DEF_HELPER_FLAGS_1(tbis, TCG_CALL_CONST, void, i64)
+DEF_HELPER_FLAGS_1(tbia, TCG_CALL_CONST, void, env)
+DEF_HELPER_FLAGS_2(tbis, TCG_CALL_CONST, void, env, i64)
 
 DEF_HELPER_1(halt, void, i64);
 
 DEF_HELPER_FLAGS_0(get_time, TCG_CALL_CONST, i64)
-DEF_HELPER_FLAGS_1(set_alarm, TCG_CALL_CONST, void, i64)
+DEF_HELPER_FLAGS_2(set_alarm, TCG_CALL_CONST, void, env, i64)
 #endif
 
 #include "def-helper.h"
diff --git a/target-alpha/int_helper.c b/target-alpha/int_helper.c
new file mode 100644
index 0000000000..1d832f0b57
--- /dev/null
+++ b/target-alpha/int_helper.c
@@ -0,0 +1,319 @@
+/*
+ *  Helpers for integer and multimedia instructions.
+ *
+ *  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 "cpu.h"
+#include "helper.h"
+#include "host-utils.h"
+
+
+uint64_t helper_umulh(uint64_t op1, uint64_t op2)
+{
+    uint64_t tl, th;
+    mulu64(&tl, &th, op1, op2);
+    return th;
+}
+
+uint64_t helper_ctpop(uint64_t arg)
+{
+    return ctpop64(arg);
+}
+
+uint64_t helper_ctlz(uint64_t arg)
+{
+    return clz64(arg);
+}
+
+uint64_t helper_cttz(uint64_t arg)
+{
+    return ctz64(arg);
+}
+
+static inline uint64_t byte_zap(uint64_t op, uint8_t mskb)
+{
+    uint64_t mask;
+
+    mask = 0;
+    mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL;
+    mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL;
+    mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL;
+    mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL;
+    mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL;
+    mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL;
+    mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL;
+    mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL;
+
+    return op & ~mask;
+}
+
+uint64_t helper_zap(uint64_t val, uint64_t mask)
+{
+    return byte_zap(val, mask);
+}
+
+uint64_t helper_zapnot(uint64_t val, uint64_t mask)
+{
+    return byte_zap(val, ~mask);
+}
+
+uint64_t helper_cmpbge(uint64_t op1, uint64_t op2)
+{
+    uint8_t opa, opb, res;
+    int i;
+
+    res = 0;
+    for (i = 0; i < 8; i++) {
+        opa = op1 >> (i * 8);
+        opb = op2 >> (i * 8);
+        if (opa >= opb) {
+            res |= 1 << i;
+        }
+    }
+    return res;
+}
+
+uint64_t helper_minub8(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    uint8_t opa, opb, opr;
+    int i;
+
+    for (i = 0; i < 8; ++i) {
+        opa = op1 >> (i * 8);
+        opb = op2 >> (i * 8);
+        opr = opa < opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 8);
+    }
+    return res;
+}
+
+uint64_t helper_minsb8(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    int8_t opa, opb;
+    uint8_t opr;
+    int i;
+
+    for (i = 0; i < 8; ++i) {
+        opa = op1 >> (i * 8);
+        opb = op2 >> (i * 8);
+        opr = opa < opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 8);
+    }
+    return res;
+}
+
+uint64_t helper_minuw4(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    uint16_t opa, opb, opr;
+    int i;
+
+    for (i = 0; i < 4; ++i) {
+        opa = op1 >> (i * 16);
+        opb = op2 >> (i * 16);
+        opr = opa < opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 16);
+    }
+    return res;
+}
+
+uint64_t helper_minsw4(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    int16_t opa, opb;
+    uint16_t opr;
+    int i;
+
+    for (i = 0; i < 4; ++i) {
+        opa = op1 >> (i * 16);
+        opb = op2 >> (i * 16);
+        opr = opa < opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 16);
+    }
+    return res;
+}
+
+uint64_t helper_maxub8(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    uint8_t opa, opb, opr;
+    int i;
+
+    for (i = 0; i < 8; ++i) {
+        opa = op1 >> (i * 8);
+        opb = op2 >> (i * 8);
+        opr = opa > opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 8);
+    }
+    return res;
+}
+
+uint64_t helper_maxsb8(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    int8_t opa, opb;
+    uint8_t opr;
+    int i;
+
+    for (i = 0; i < 8; ++i) {
+        opa = op1 >> (i * 8);
+        opb = op2 >> (i * 8);
+        opr = opa > opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 8);
+    }
+    return res;
+}
+
+uint64_t helper_maxuw4(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    uint16_t opa, opb, opr;
+    int i;
+
+    for (i = 0; i < 4; ++i) {
+        opa = op1 >> (i * 16);
+        opb = op2 >> (i * 16);
+        opr = opa > opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 16);
+    }
+    return res;
+}
+
+uint64_t helper_maxsw4(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    int16_t opa, opb;
+    uint16_t opr;
+    int i;
+
+    for (i = 0; i < 4; ++i) {
+        opa = op1 >> (i * 16);
+        opb = op2 >> (i * 16);
+        opr = opa > opb ? opa : opb;
+        res |= (uint64_t)opr << (i * 16);
+    }
+    return res;
+}
+
+uint64_t helper_perr(uint64_t op1, uint64_t op2)
+{
+    uint64_t res = 0;
+    uint8_t opa, opb, opr;
+    int i;
+
+    for (i = 0; i < 8; ++i) {
+        opa = op1 >> (i * 8);
+        opb = op2 >> (i * 8);
+        if (opa >= opb) {
+            opr = opa - opb;
+        } else {
+            opr = opb - opa;
+        }
+        res += opr;
+    }
+    return res;
+}
+
+uint64_t helper_pklb(uint64_t op1)
+{
+    return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
+}
+
+uint64_t helper_pkwb(uint64_t op1)
+{
+    return ((op1 & 0xff)
+            | ((op1 >> 8) & 0xff00)
+            | ((op1 >> 16) & 0xff0000)
+            | ((op1 >> 24) & 0xff000000));
+}
+
+uint64_t helper_unpkbl(uint64_t op1)
+{
+    return (op1 & 0xff) | ((op1 & 0xff00) << 24);
+}
+
+uint64_t helper_unpkbw(uint64_t op1)
+{
+    return ((op1 & 0xff)
+            | ((op1 & 0xff00) << 8)
+            | ((op1 & 0xff0000) << 16)
+            | ((op1 & 0xff000000) << 24));
+}
+
+uint64_t helper_addqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
+{
+    uint64_t tmp = op1;
+    op1 += op2;
+    if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
+        arith_excp(env, GETPC(), EXC_M_IOV, 0);
+    }
+    return op1;
+}
+
+uint64_t helper_addlv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
+{
+    uint64_t tmp = op1;
+    op1 = (uint32_t)(op1 + op2);
+    if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
+        arith_excp(env, GETPC(), EXC_M_IOV, 0);
+    }
+    return op1;
+}
+
+uint64_t helper_subqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
+{
+    uint64_t res;
+    res = op1 - op2;
+    if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
+        arith_excp(env, GETPC(), EXC_M_IOV, 0);
+    }
+    return res;
+}
+
+uint64_t helper_sublv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
+{
+    uint32_t res;
+    res = op1 - op2;
+    if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
+        arith_excp(env, GETPC(), EXC_M_IOV, 0);
+    }
+    return res;
+}
+
+uint64_t helper_mullv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
+{
+    int64_t res = (int64_t)op1 * (int64_t)op2;
+
+    if (unlikely((int32_t)res != res)) {
+        arith_excp(env, GETPC(), EXC_M_IOV, 0);
+    }
+    return (int64_t)((int32_t)res);
+}
+
+uint64_t helper_mulqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
+{
+    uint64_t tl, th;
+
+    muls64(&tl, &th, op1, op2);
+    /* If th != 0 && th != -1, then we had an overflow */
+    if (unlikely((th + 1) > 1)) {
+        arith_excp(env, GETPC(), EXC_M_IOV, 0);
+    }
+    return tl;
+}
diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
new file mode 100644
index 0000000000..dd5ca4933a
--- /dev/null
+++ b/target-alpha/mem_helper.c
@@ -0,0 +1,151 @@
+/*
+ *  Helpers for loads and stores
+ *
+ *  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 "cpu.h"
+#include "helper.h"
+
+
+/* Softmmu support */
+#ifndef CONFIG_USER_ONLY
+
+uint64_t helper_ldl_phys(uint64_t p)
+{
+    return (int32_t)ldl_phys(p);
+}
+
+uint64_t helper_ldq_phys(uint64_t p)
+{
+    return ldq_phys(p);
+}
+
+uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p)
+{
+    env->lock_addr = p;
+    return env->lock_value = (int32_t)ldl_phys(p);
+}
+
+uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p)
+{
+    env->lock_addr = p;
+    return env->lock_value = ldq_phys(p);
+}
+
+void helper_stl_phys(uint64_t p, uint64_t v)
+{
+    stl_phys(p, v);
+}
+
+void helper_stq_phys(uint64_t p, uint64_t v)
+{
+    stq_phys(p, v);
+}
+
+uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
+{
+    uint64_t ret = 0;
+
+    if (p == env->lock_addr) {
+        int32_t old = ldl_phys(p);
+        if (old == (int32_t)env->lock_value) {
+            stl_phys(p, v);
+            ret = 1;
+        }
+    }
+    env->lock_addr = -1;
+
+    return ret;
+}
+
+uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
+{
+    uint64_t ret = 0;
+
+    if (p == env->lock_addr) {
+        uint64_t old = ldq_phys(p);
+        if (old == env->lock_value) {
+            stq_phys(p, v);
+            ret = 1;
+        }
+    }
+    env->lock_addr = -1;
+
+    return ret;
+}
+
+static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
+                                int is_write, int is_user, void *retaddr)
+{
+    uint64_t pc;
+    uint32_t insn;
+
+    do_restore_state(env, retaddr);
+
+    pc = env->pc;
+    insn = cpu_ldl_code(env, pc);
+
+    env->trap_arg0 = addr;
+    env->trap_arg1 = insn >> 26;                /* opcode */
+    env->trap_arg2 = (insn >> 21) & 31;         /* dest regno */
+    env->exception_index = EXCP_UNALIGN;
+    env->error_code = 0;
+    cpu_loop_exit(env);
+}
+
+void cpu_unassigned_access(CPUAlphaState *env, target_phys_addr_t addr,
+                           int is_write, int is_exec, int unused, int size)
+{
+    env->trap_arg0 = addr;
+    env->trap_arg1 = is_write;
+    dynamic_excp(env, NULL, EXCP_MCHK, 0);
+}
+
+#include "softmmu_exec.h"
+
+#define MMUSUFFIX _mmu
+#define ALIGNED_ONLY
+
+#define SHIFT 0
+#include "softmmu_template.h"
+
+#define SHIFT 1
+#include "softmmu_template.h"
+
+#define SHIFT 2
+#include "softmmu_template.h"
+
+#define SHIFT 3
+#include "softmmu_template.h"
+
+/* try to fill the TLB and return an exception if error. If retaddr is
+   NULL, it means that the function was called in C code (i.e. not
+   from generated code or from helper.c) */
+/* XXX: fix it to restore all registers */
+void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write,
+              int mmu_idx, void *retaddr)
+{
+    int ret;
+
+    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    if (unlikely(ret != 0)) {
+        do_restore_state(env, retaddr);
+        /* Exception index and error code are already set */
+        cpu_loop_exit(env);
+    }
+}
+#endif /* CONFIG_USER_ONLY */
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
deleted file mode 100644
index c77f009b79..0000000000
--- a/target-alpha/op_helper.c
+++ /dev/null
@@ -1,1379 +0,0 @@
-/*
- *  Alpha emulation cpu micro-operations helpers 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 "cpu.h"
-#include "dyngen-exec.h"
-#include "host-utils.h"
-#include "softfloat.h"
-#include "helper.h"
-#include "sysemu.h"
-#include "qemu-timer.h"
-
-#define FP_STATUS (env->fp_status)
-
-/*****************************************************************************/
-/* Exceptions processing helpers */
-
-/* This should only be called from translate, via gen_excp.
-   We expect that ENV->PC has already been updated.  */
-void QEMU_NORETURN helper_excp(int excp, int error)
-{
-    env->exception_index = excp;
-    env->error_code = error;
-    cpu_loop_exit(env);
-}
-
-static void do_restore_state(void *retaddr)
-{
-    unsigned long pc = (unsigned long)retaddr;
-
-    if (pc) {
-        TranslationBlock *tb = tb_find_pc(pc);
-        if (tb) {
-            cpu_restore_state(tb, env, pc);
-        }
-    }
-}
-
-/* This may be called from any of the helpers to set up EXCEPTION_INDEX.  */
-static void QEMU_NORETURN dynamic_excp(int excp, int error)
-{
-    env->exception_index = excp;
-    env->error_code = error;
-    do_restore_state(GETPC());
-    cpu_loop_exit(env);
-}
-
-static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
-{
-    env->trap_arg0 = exc;
-    env->trap_arg1 = mask;
-    dynamic_excp(EXCP_ARITH, 0);
-}
-
-uint64_t helper_load_pcc (void)
-{
-#ifndef CONFIG_USER_ONLY
-    /* In system mode we have access to a decent high-resolution clock.
-       In order to make OS-level time accounting work with the RPCC,
-       present it with a well-timed clock fixed at 250MHz.  */
-    return (((uint64_t)env->pcc_ofs << 32)
-            | (uint32_t)(qemu_get_clock_ns(vm_clock) >> 2));
-#else
-    /* In user-mode, vm_clock doesn't exist.  Just pass through the host cpu
-       clock ticks.  Also, don't bother taking PCC_OFS into account.  */
-    return (uint32_t)cpu_get_real_ticks();
-#endif
-}
-
-uint64_t helper_load_fpcr (void)
-{
-    return cpu_alpha_load_fpcr (env);
-}
-
-void helper_store_fpcr (uint64_t val)
-{
-    cpu_alpha_store_fpcr (env, val);
-}
-
-uint64_t helper_addqv (uint64_t op1, uint64_t op2)
-{
-    uint64_t tmp = op1;
-    op1 += op2;
-    if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
-        arith_excp(EXC_M_IOV, 0);
-    }
-    return op1;
-}
-
-uint64_t helper_addlv (uint64_t op1, uint64_t op2)
-{
-    uint64_t tmp = op1;
-    op1 = (uint32_t)(op1 + op2);
-    if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
-        arith_excp(EXC_M_IOV, 0);
-    }
-    return op1;
-}
-
-uint64_t helper_subqv (uint64_t op1, uint64_t op2)
-{
-    uint64_t res;
-    res = op1 - op2;
-    if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
-        arith_excp(EXC_M_IOV, 0);
-    }
-    return res;
-}
-
-uint64_t helper_sublv (uint64_t op1, uint64_t op2)
-{
-    uint32_t res;
-    res = op1 - op2;
-    if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
-        arith_excp(EXC_M_IOV, 0);
-    }
-    return res;
-}
-
-uint64_t helper_mullv (uint64_t op1, uint64_t op2)
-{
-    int64_t res = (int64_t)op1 * (int64_t)op2;
-
-    if (unlikely((int32_t)res != res)) {
-        arith_excp(EXC_M_IOV, 0);
-    }
-    return (int64_t)((int32_t)res);
-}
-
-uint64_t helper_mulqv (uint64_t op1, uint64_t op2)
-{
-    uint64_t tl, th;
-
-    muls64(&tl, &th, op1, op2);
-    /* If th != 0 && th != -1, then we had an overflow */
-    if (unlikely((th + 1) > 1)) {
-        arith_excp(EXC_M_IOV, 0);
-    }
-    return tl;
-}
-
-uint64_t helper_umulh (uint64_t op1, uint64_t op2)
-{
-    uint64_t tl, th;
-
-    mulu64(&tl, &th, op1, op2);
-    return th;
-}
-
-uint64_t helper_ctpop (uint64_t arg)
-{
-    return ctpop64(arg);
-}
-
-uint64_t helper_ctlz (uint64_t arg)
-{
-    return clz64(arg);
-}
-
-uint64_t helper_cttz (uint64_t arg)
-{
-    return ctz64(arg);
-}
-
-static inline uint64_t byte_zap(uint64_t op, uint8_t mskb)
-{
-    uint64_t mask;
-
-    mask = 0;
-    mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL;
-    mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL;
-    mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL;
-    mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL;
-    mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL;
-    mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL;
-    mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL;
-    mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL;
-
-    return op & ~mask;
-}
-
-uint64_t helper_zap(uint64_t val, uint64_t mask)
-{
-    return byte_zap(val, mask);
-}
-
-uint64_t helper_zapnot(uint64_t val, uint64_t mask)
-{
-    return byte_zap(val, ~mask);
-}
-
-uint64_t helper_cmpbge (uint64_t op1, uint64_t op2)
-{
-    uint8_t opa, opb, res;
-    int i;
-
-    res = 0;
-    for (i = 0; i < 8; i++) {
-        opa = op1 >> (i * 8);
-        opb = op2 >> (i * 8);
-        if (opa >= opb)
-            res |= 1 << i;
-    }
-    return res;
-}
-
-uint64_t helper_minub8 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    uint8_t opa, opb, opr;
-    int i;
-
-    for (i = 0; i < 8; ++i) {
-        opa = op1 >> (i * 8);
-        opb = op2 >> (i * 8);
-        opr = opa < opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 8);
-    }
-    return res;
-}
-
-uint64_t helper_minsb8 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    int8_t opa, opb;
-    uint8_t opr;
-    int i;
-
-    for (i = 0; i < 8; ++i) {
-        opa = op1 >> (i * 8);
-        opb = op2 >> (i * 8);
-        opr = opa < opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 8);
-    }
-    return res;
-}
-
-uint64_t helper_minuw4 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    uint16_t opa, opb, opr;
-    int i;
-
-    for (i = 0; i < 4; ++i) {
-        opa = op1 >> (i * 16);
-        opb = op2 >> (i * 16);
-        opr = opa < opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 16);
-    }
-    return res;
-}
-
-uint64_t helper_minsw4 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    int16_t opa, opb;
-    uint16_t opr;
-    int i;
-
-    for (i = 0; i < 4; ++i) {
-        opa = op1 >> (i * 16);
-        opb = op2 >> (i * 16);
-        opr = opa < opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 16);
-    }
-    return res;
-}
-
-uint64_t helper_maxub8 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    uint8_t opa, opb, opr;
-    int i;
-
-    for (i = 0; i < 8; ++i) {
-        opa = op1 >> (i * 8);
-        opb = op2 >> (i * 8);
-        opr = opa > opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 8);
-    }
-    return res;
-}
-
-uint64_t helper_maxsb8 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    int8_t opa, opb;
-    uint8_t opr;
-    int i;
-
-    for (i = 0; i < 8; ++i) {
-        opa = op1 >> (i * 8);
-        opb = op2 >> (i * 8);
-        opr = opa > opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 8);
-    }
-    return res;
-}
-
-uint64_t helper_maxuw4 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    uint16_t opa, opb, opr;
-    int i;
-
-    for (i = 0; i < 4; ++i) {
-        opa = op1 >> (i * 16);
-        opb = op2 >> (i * 16);
-        opr = opa > opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 16);
-    }
-    return res;
-}
-
-uint64_t helper_maxsw4 (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    int16_t opa, opb;
-    uint16_t opr;
-    int i;
-
-    for (i = 0; i < 4; ++i) {
-        opa = op1 >> (i * 16);
-        opb = op2 >> (i * 16);
-        opr = opa > opb ? opa : opb;
-        res |= (uint64_t)opr << (i * 16);
-    }
-    return res;
-}
-
-uint64_t helper_perr (uint64_t op1, uint64_t op2)
-{
-    uint64_t res = 0;
-    uint8_t opa, opb, opr;
-    int i;
-
-    for (i = 0; i < 8; ++i) {
-        opa = op1 >> (i * 8);
-        opb = op2 >> (i * 8);
-        if (opa >= opb)
-            opr = opa - opb;
-        else
-            opr = opb - opa;
-        res += opr;
-    }
-    return res;
-}
-
-uint64_t helper_pklb (uint64_t op1)
-{
-    return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
-}
-
-uint64_t helper_pkwb (uint64_t op1)
-{
-    return ((op1 & 0xff)
-            | ((op1 >> 8) & 0xff00)
-            | ((op1 >> 16) & 0xff0000)
-            | ((op1 >> 24) & 0xff000000));
-}
-
-uint64_t helper_unpkbl (uint64_t op1)
-{
-    return (op1 & 0xff) | ((op1 & 0xff00) << 24);
-}
-
-uint64_t helper_unpkbw (uint64_t op1)
-{
-    return ((op1 & 0xff)
-            | ((op1 & 0xff00) << 8)
-            | ((op1 & 0xff0000) << 16)
-            | ((op1 & 0xff000000) << 24));
-}
-
-/* Floating point helpers */
-
-void helper_setroundmode (uint32_t val)
-{
-    set_float_rounding_mode(val, &FP_STATUS);
-}
-
-void helper_setflushzero (uint32_t val)
-{
-    set_flush_to_zero(val, &FP_STATUS);
-}
-
-void helper_fp_exc_clear (void)
-{
-    set_float_exception_flags(0, &FP_STATUS);
-}
-
-uint32_t helper_fp_exc_get (void)
-{
-    return get_float_exception_flags(&FP_STATUS);
-}
-
-/* Raise exceptions for ieee fp insns without software completion.
-   In that case there are no exceptions that don't trap; the mask
-   doesn't apply.  */
-void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
-{
-    if (exc) {
-        uint32_t hw_exc = 0;
-
-        if (exc & float_flag_invalid) {
-            hw_exc |= EXC_M_INV;
-        }
-        if (exc & float_flag_divbyzero) {
-            hw_exc |= EXC_M_DZE;
-        }
-        if (exc & float_flag_overflow) {
-            hw_exc |= EXC_M_FOV;
-        }
-        if (exc & float_flag_underflow) {
-            hw_exc |= EXC_M_UNF;
-        }
-        if (exc & float_flag_inexact) {
-            hw_exc |= EXC_M_INE;
-        }
-
-        arith_excp(hw_exc, 1ull << regno);
-    }
-}
-
-/* Raise exceptions for ieee fp insns with software completion.  */
-void helper_fp_exc_raise_s(uint32_t exc, uint32_t regno)
-{
-    if (exc) {
-        env->fpcr_exc_status |= exc;
-
-        exc &= ~env->fpcr_exc_mask;
-        if (exc) {
-            helper_fp_exc_raise(exc, regno);
-        }
-    }
-}
-
-/* Input remapping without software completion.  Handle denormal-map-to-zero
-   and trap for all other non-finite numbers.  */
-uint64_t helper_ieee_input(uint64_t val)
-{
-    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
-    uint64_t frac = val & 0xfffffffffffffull;
-
-    if (exp == 0) {
-        if (frac != 0) {
-            /* If DNZ is set flush denormals to zero on input.  */
-            if (env->fpcr_dnz) {
-                val &= 1ull << 63;
-            } else {
-                arith_excp(EXC_M_UNF, 0);
-            }
-        }
-    } else if (exp == 0x7ff) {
-        /* Infinity or NaN.  */
-        /* ??? I'm not sure these exception bit flags are correct.  I do
-           know that the Linux kernel, at least, doesn't rely on them and
-           just emulates the insn to figure out what exception to use.  */
-        arith_excp(frac ? EXC_M_INV : EXC_M_FOV, 0);
-    }
-    return val;
-}
-
-/* Similar, but does not trap for infinities.  Used for comparisons.  */
-uint64_t helper_ieee_input_cmp(uint64_t val)
-{
-    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
-    uint64_t frac = val & 0xfffffffffffffull;
-
-    if (exp == 0) {
-        if (frac != 0) {
-            /* If DNZ is set flush denormals to zero on input.  */
-            if (env->fpcr_dnz) {
-                val &= 1ull << 63;
-            } else {
-                arith_excp(EXC_M_UNF, 0);
-            }
-        }
-    } else if (exp == 0x7ff && frac) {
-        /* NaN.  */
-        arith_excp(EXC_M_INV, 0);
-    }
-    return val;
-}
-
-/* Input remapping with software completion enabled.  All we have to do
-   is handle denormal-map-to-zero; all other inputs get exceptions as
-   needed from the actual operation.  */
-uint64_t helper_ieee_input_s(uint64_t val)
-{
-    if (env->fpcr_dnz) {
-        uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
-        if (exp == 0) {
-            val &= 1ull << 63;
-        }
-    }
-    return val;
-}
-
-/* F floating (VAX) */
-static inline uint64_t float32_to_f(float32 fa)
-{
-    uint64_t r, exp, mant, sig;
-    CPU_FloatU a;
-
-    a.f = fa;
-    sig = ((uint64_t)a.l & 0x80000000) << 32;
-    exp = (a.l >> 23) & 0xff;
-    mant = ((uint64_t)a.l & 0x007fffff) << 29;
-
-    if (exp == 255) {
-        /* NaN or infinity */
-        r = 1; /* VAX dirty zero */
-    } else if (exp == 0) {
-        if (mant == 0) {
-            /* Zero */
-            r = 0;
-        } else {
-            /* Denormalized */
-            r = sig | ((exp + 1) << 52) | mant;
-        }
-    } else {
-        if (exp >= 253) {
-            /* Overflow */
-            r = 1; /* VAX dirty zero */
-        } else {
-            r = sig | ((exp + 2) << 52);
-        }
-    }
-
-    return r;
-}
-
-static inline float32 f_to_float32(uint64_t a)
-{
-    uint32_t exp, mant_sig;
-    CPU_FloatU r;
-
-    exp = ((a >> 55) & 0x80) | ((a >> 52) & 0x7f);
-    mant_sig = ((a >> 32) & 0x80000000) | ((a >> 29) & 0x007fffff);
-
-    if (unlikely(!exp && mant_sig)) {
-        /* Reserved operands / Dirty zero */
-        dynamic_excp(EXCP_OPCDEC, 0);
-    }
-
-    if (exp < 3) {
-        /* Underflow */
-        r.l = 0;
-    } else {
-        r.l = ((exp - 2) << 23) | mant_sig;
-    }
-
-    return r.f;
-}
-
-uint32_t helper_f_to_memory (uint64_t a)
-{
-    uint32_t r;
-    r =  (a & 0x00001fffe0000000ull) >> 13;
-    r |= (a & 0x07ffe00000000000ull) >> 45;
-    r |= (a & 0xc000000000000000ull) >> 48;
-    return r;
-}
-
-uint64_t helper_memory_to_f (uint32_t a)
-{
-    uint64_t r;
-    r =  ((uint64_t)(a & 0x0000c000)) << 48;
-    r |= ((uint64_t)(a & 0x003fffff)) << 45;
-    r |= ((uint64_t)(a & 0xffff0000)) << 13;
-    if (!(a & 0x00004000))
-        r |= 0x7ll << 59;
-    return r;
-}
-
-/* ??? Emulating VAX arithmetic with IEEE arithmetic is wrong.  We should
-   either implement VAX arithmetic properly or just signal invalid opcode.  */
-
-uint64_t helper_addf (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = f_to_float32(a);
-    fb = f_to_float32(b);
-    fr = float32_add(fa, fb, &FP_STATUS);
-    return float32_to_f(fr);
-}
-
-uint64_t helper_subf (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = f_to_float32(a);
-    fb = f_to_float32(b);
-    fr = float32_sub(fa, fb, &FP_STATUS);
-    return float32_to_f(fr);
-}
-
-uint64_t helper_mulf (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = f_to_float32(a);
-    fb = f_to_float32(b);
-    fr = float32_mul(fa, fb, &FP_STATUS);
-    return float32_to_f(fr);
-}
-
-uint64_t helper_divf (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = f_to_float32(a);
-    fb = f_to_float32(b);
-    fr = float32_div(fa, fb, &FP_STATUS);
-    return float32_to_f(fr);
-}
-
-uint64_t helper_sqrtf (uint64_t t)
-{
-    float32 ft, fr;
-
-    ft = f_to_float32(t);
-    fr = float32_sqrt(ft, &FP_STATUS);
-    return float32_to_f(fr);
-}
-
-
-/* G floating (VAX) */
-static inline uint64_t float64_to_g(float64 fa)
-{
-    uint64_t r, exp, mant, sig;
-    CPU_DoubleU a;
-
-    a.d = fa;
-    sig = a.ll & 0x8000000000000000ull;
-    exp = (a.ll >> 52) & 0x7ff;
-    mant = a.ll & 0x000fffffffffffffull;
-
-    if (exp == 2047) {
-        /* NaN or infinity */
-        r = 1; /* VAX dirty zero */
-    } else if (exp == 0) {
-        if (mant == 0) {
-            /* Zero */
-            r = 0;
-        } else {
-            /* Denormalized */
-            r = sig | ((exp + 1) << 52) | mant;
-        }
-    } else {
-        if (exp >= 2045) {
-            /* Overflow */
-            r = 1; /* VAX dirty zero */
-        } else {
-            r = sig | ((exp + 2) << 52);
-        }
-    }
-
-    return r;
-}
-
-static inline float64 g_to_float64(uint64_t a)
-{
-    uint64_t exp, mant_sig;
-    CPU_DoubleU r;
-
-    exp = (a >> 52) & 0x7ff;
-    mant_sig = a & 0x800fffffffffffffull;
-
-    if (!exp && mant_sig) {
-        /* Reserved operands / Dirty zero */
-        dynamic_excp(EXCP_OPCDEC, 0);
-    }
-
-    if (exp < 3) {
-        /* Underflow */
-        r.ll = 0;
-    } else {
-        r.ll = ((exp - 2) << 52) | mant_sig;
-    }
-
-    return r.d;
-}
-
-uint64_t helper_g_to_memory (uint64_t a)
-{
-    uint64_t r;
-    r =  (a & 0x000000000000ffffull) << 48;
-    r |= (a & 0x00000000ffff0000ull) << 16;
-    r |= (a & 0x0000ffff00000000ull) >> 16;
-    r |= (a & 0xffff000000000000ull) >> 48;
-    return r;
-}
-
-uint64_t helper_memory_to_g (uint64_t a)
-{
-    uint64_t r;
-    r =  (a & 0x000000000000ffffull) << 48;
-    r |= (a & 0x00000000ffff0000ull) << 16;
-    r |= (a & 0x0000ffff00000000ull) >> 16;
-    r |= (a & 0xffff000000000000ull) >> 48;
-    return r;
-}
-
-uint64_t helper_addg (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = g_to_float64(a);
-    fb = g_to_float64(b);
-    fr = float64_add(fa, fb, &FP_STATUS);
-    return float64_to_g(fr);
-}
-
-uint64_t helper_subg (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = g_to_float64(a);
-    fb = g_to_float64(b);
-    fr = float64_sub(fa, fb, &FP_STATUS);
-    return float64_to_g(fr);
-}
-
-uint64_t helper_mulg (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = g_to_float64(a);
-    fb = g_to_float64(b);
-    fr = float64_mul(fa, fb, &FP_STATUS);
-    return float64_to_g(fr);
-}
-
-uint64_t helper_divg (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = g_to_float64(a);
-    fb = g_to_float64(b);
-    fr = float64_div(fa, fb, &FP_STATUS);
-    return float64_to_g(fr);
-}
-
-uint64_t helper_sqrtg (uint64_t a)
-{
-    float64 fa, fr;
-
-    fa = g_to_float64(a);
-    fr = float64_sqrt(fa, &FP_STATUS);
-    return float64_to_g(fr);
-}
-
-
-/* S floating (single) */
-
-/* Taken from linux/arch/alpha/kernel/traps.c, s_mem_to_reg.  */
-static inline uint64_t float32_to_s_int(uint32_t fi)
-{
-    uint32_t frac = fi & 0x7fffff;
-    uint32_t sign = fi >> 31;
-    uint32_t exp_msb = (fi >> 30) & 1;
-    uint32_t exp_low = (fi >> 23) & 0x7f;
-    uint32_t exp;
-
-    exp = (exp_msb << 10) | exp_low;
-    if (exp_msb) {
-        if (exp_low == 0x7f)
-            exp = 0x7ff;
-    } else {
-        if (exp_low != 0x00)
-            exp |= 0x380;
-    }
-
-    return (((uint64_t)sign << 63)
-            | ((uint64_t)exp << 52)
-            | ((uint64_t)frac << 29));
-}
-
-static inline uint64_t float32_to_s(float32 fa)
-{
-    CPU_FloatU a;
-    a.f = fa;
-    return float32_to_s_int(a.l);
-}
-
-static inline uint32_t s_to_float32_int(uint64_t a)
-{
-    return ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
-}
-
-static inline float32 s_to_float32(uint64_t a)
-{
-    CPU_FloatU r;
-    r.l = s_to_float32_int(a);
-    return r.f;
-}
-
-uint32_t helper_s_to_memory (uint64_t a)
-{
-    return s_to_float32_int(a);
-}
-
-uint64_t helper_memory_to_s (uint32_t a)
-{
-    return float32_to_s_int(a);
-}
-
-uint64_t helper_adds (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = s_to_float32(a);
-    fb = s_to_float32(b);
-    fr = float32_add(fa, fb, &FP_STATUS);
-    return float32_to_s(fr);
-}
-
-uint64_t helper_subs (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = s_to_float32(a);
-    fb = s_to_float32(b);
-    fr = float32_sub(fa, fb, &FP_STATUS);
-    return float32_to_s(fr);
-}
-
-uint64_t helper_muls (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = s_to_float32(a);
-    fb = s_to_float32(b);
-    fr = float32_mul(fa, fb, &FP_STATUS);
-    return float32_to_s(fr);
-}
-
-uint64_t helper_divs (uint64_t a, uint64_t b)
-{
-    float32 fa, fb, fr;
-
-    fa = s_to_float32(a);
-    fb = s_to_float32(b);
-    fr = float32_div(fa, fb, &FP_STATUS);
-    return float32_to_s(fr);
-}
-
-uint64_t helper_sqrts (uint64_t a)
-{
-    float32 fa, fr;
-
-    fa = s_to_float32(a);
-    fr = float32_sqrt(fa, &FP_STATUS);
-    return float32_to_s(fr);
-}
-
-
-/* T floating (double) */
-static inline float64 t_to_float64(uint64_t a)
-{
-    /* Memory format is the same as float64 */
-    CPU_DoubleU r;
-    r.ll = a;
-    return r.d;
-}
-
-static inline uint64_t float64_to_t(float64 fa)
-{
-    /* Memory format is the same as float64 */
-    CPU_DoubleU r;
-    r.d = fa;
-    return r.ll;
-}
-
-uint64_t helper_addt (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-    fr = float64_add(fa, fb, &FP_STATUS);
-    return float64_to_t(fr);
-}
-
-uint64_t helper_subt (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-    fr = float64_sub(fa, fb, &FP_STATUS);
-    return float64_to_t(fr);
-}
-
-uint64_t helper_mult (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-    fr = float64_mul(fa, fb, &FP_STATUS);
-    return float64_to_t(fr);
-}
-
-uint64_t helper_divt (uint64_t a, uint64_t b)
-{
-    float64 fa, fb, fr;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-    fr = float64_div(fa, fb, &FP_STATUS);
-    return float64_to_t(fr);
-}
-
-uint64_t helper_sqrtt (uint64_t a)
-{
-    float64 fa, fr;
-
-    fa = t_to_float64(a);
-    fr = float64_sqrt(fa, &FP_STATUS);
-    return float64_to_t(fr);
-}
-
-/* Comparisons */
-uint64_t helper_cmptun (uint64_t a, uint64_t b)
-{
-    float64 fa, fb;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-
-    if (float64_unordered_quiet(fa, fb, &FP_STATUS)) {
-        return 0x4000000000000000ULL;
-    } else {
-        return 0;
-    }
-}
-
-uint64_t helper_cmpteq(uint64_t a, uint64_t b)
-{
-    float64 fa, fb;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-
-    if (float64_eq_quiet(fa, fb, &FP_STATUS))
-        return 0x4000000000000000ULL;
-    else
-        return 0;
-}
-
-uint64_t helper_cmptle(uint64_t a, uint64_t b)
-{
-    float64 fa, fb;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-
-    if (float64_le(fa, fb, &FP_STATUS))
-        return 0x4000000000000000ULL;
-    else
-        return 0;
-}
-
-uint64_t helper_cmptlt(uint64_t a, uint64_t b)
-{
-    float64 fa, fb;
-
-    fa = t_to_float64(a);
-    fb = t_to_float64(b);
-
-    if (float64_lt(fa, fb, &FP_STATUS))
-        return 0x4000000000000000ULL;
-    else
-        return 0;
-}
-
-uint64_t helper_cmpgeq(uint64_t a, uint64_t b)
-{
-    float64 fa, fb;
-
-    fa = g_to_float64(a);
-    fb = g_to_float64(b);
-
-    if (float64_eq_quiet(fa, fb, &FP_STATUS))
-        return 0x4000000000000000ULL;
-    else
-        return 0;
-}
-
-uint64_t helper_cmpgle(uint64_t a, uint64_t b)
-{
-    float64 fa, fb;
-
-    fa = g_to_float64(a);
-    fb = g_to_float64(b);
-
-    if (float64_le(fa, fb, &FP_STATUS))
-        return 0x4000000000000000ULL;
-    else
-        return 0;
-}
-
-uint64_t helper_cmpglt(uint64_t a, uint64_t b)
-{
-    float64 fa, fb;
-
-    fa = g_to_float64(a);
-    fb = g_to_float64(b);
-
-    if (float64_lt(fa, fb, &FP_STATUS))
-        return 0x4000000000000000ULL;
-    else
-        return 0;
-}
-
-/* Floating point format conversion */
-uint64_t helper_cvtts (uint64_t a)
-{
-    float64 fa;
-    float32 fr;
-
-    fa = t_to_float64(a);
-    fr = float64_to_float32(fa, &FP_STATUS);
-    return float32_to_s(fr);
-}
-
-uint64_t helper_cvtst (uint64_t a)
-{
-    float32 fa;
-    float64 fr;
-
-    fa = s_to_float32(a);
-    fr = float32_to_float64(fa, &FP_STATUS);
-    return float64_to_t(fr);
-}
-
-uint64_t helper_cvtqs (uint64_t a)
-{
-    float32 fr = int64_to_float32(a, &FP_STATUS);
-    return float32_to_s(fr);
-}
-
-/* Implement float64 to uint64 conversion without saturation -- we must
-   supply the truncated result.  This behaviour is used by the compiler
-   to get unsigned conversion for free with the same instruction.
-
-   The VI flag is set when overflow or inexact exceptions should be raised.  */
-
-static inline uint64_t helper_cvttq_internal(uint64_t a, int roundmode, int VI)
-{
-    uint64_t frac, ret = 0;
-    uint32_t exp, sign, exc = 0;
-    int shift;
-
-    sign = (a >> 63);
-    exp = (uint32_t)(a >> 52) & 0x7ff;
-    frac = a & 0xfffffffffffffull;
-
-    if (exp == 0) {
-        if (unlikely(frac != 0)) {
-            goto do_underflow;
-        }
-    } else if (exp == 0x7ff) {
-        exc = (frac ? float_flag_invalid : VI ? float_flag_overflow : 0);
-    } else {
-        /* Restore implicit bit.  */
-        frac |= 0x10000000000000ull;
-
-        shift = exp - 1023 - 52;
-        if (shift >= 0) {
-            /* In this case the number is so large that we must shift
-               the fraction left.  There is no rounding to do.  */
-            if (shift < 63) {
-                ret = frac << shift;
-                if (VI && (ret >> shift) != frac) {
-                    exc = float_flag_overflow;
-                }
-            }
-        } else {
-            uint64_t round;
-
-            /* In this case the number is smaller than the fraction as
-               represented by the 52 bit number.  Here we must think
-               about rounding the result.  Handle this by shifting the
-               fractional part of the number into the high bits of ROUND.
-               This will let us efficiently handle round-to-nearest.  */
-            shift = -shift;
-            if (shift < 63) {
-                ret = frac >> shift;
-                round = frac << (64 - shift);
-            } else {
-                /* The exponent is so small we shift out everything.
-                   Leave a sticky bit for proper rounding below.  */
-            do_underflow:
-                round = 1;
-            }
-
-            if (round) {
-                exc = (VI ? float_flag_inexact : 0);
-                switch (roundmode) {
-                case float_round_nearest_even:
-                    if (round == (1ull << 63)) {
-                        /* Fraction is exactly 0.5; round to even.  */
-                        ret += (ret & 1);
-                    } else if (round > (1ull << 63)) {
-                        ret += 1;
-                    }
-                    break;
-                case float_round_to_zero:
-                    break;
-                case float_round_up:
-                    ret += 1 - sign;
-                    break;
-                case float_round_down:
-                    ret += sign;
-                    break;
-                }
-            }
-        }
-        if (sign) {
-            ret = -ret;
-        }
-    }
-    if (unlikely(exc)) {
-        float_raise(exc, &FP_STATUS);
-    }
-
-    return ret;
-}
-
-uint64_t helper_cvttq(uint64_t a)
-{
-    return helper_cvttq_internal(a, FP_STATUS.float_rounding_mode, 1);
-}
-
-uint64_t helper_cvttq_c(uint64_t a)
-{
-    return helper_cvttq_internal(a, float_round_to_zero, 0);
-}
-
-uint64_t helper_cvttq_svic(uint64_t a)
-{
-    return helper_cvttq_internal(a, float_round_to_zero, 1);
-}
-
-uint64_t helper_cvtqt (uint64_t a)
-{
-    float64 fr = int64_to_float64(a, &FP_STATUS);
-    return float64_to_t(fr);
-}
-
-uint64_t helper_cvtqf (uint64_t a)
-{
-    float32 fr = int64_to_float32(a, &FP_STATUS);
-    return float32_to_f(fr);
-}
-
-uint64_t helper_cvtgf (uint64_t a)
-{
-    float64 fa;
-    float32 fr;
-
-    fa = g_to_float64(a);
-    fr = float64_to_float32(fa, &FP_STATUS);
-    return float32_to_f(fr);
-}
-
-uint64_t helper_cvtgq (uint64_t a)
-{
-    float64 fa = g_to_float64(a);
-    return float64_to_int64_round_to_zero(fa, &FP_STATUS);
-}
-
-uint64_t helper_cvtqg (uint64_t a)
-{
-    float64 fr;
-    fr = int64_to_float64(a, &FP_STATUS);
-    return float64_to_g(fr);
-}
-
-/* PALcode support special instructions */
-#if !defined (CONFIG_USER_ONLY)
-void helper_hw_ret (uint64_t a)
-{
-    env->pc = a & ~3;
-    env->intr_flag = 0;
-    env->lock_addr = -1;
-    if ((a & 1) == 0) {
-        env->pal_mode = 0;
-        swap_shadow_regs(env);
-    }
-}
-
-void helper_tbia(void)
-{
-    tlb_flush(env, 1);
-}
-
-void helper_tbis(uint64_t p)
-{
-    tlb_flush_page(env, p);
-}
-
-void helper_halt(uint64_t restart)
-{
-    if (restart) {
-        qemu_system_reset_request();
-    } else {
-        qemu_system_shutdown_request();
-    }
-}
-
-uint64_t helper_get_time(void)
-{
-    return qemu_get_clock_ns(rtc_clock);
-}
-
-void helper_set_alarm(uint64_t expire)
-{
-    if (expire) {
-        env->alarm_expire = expire;
-        qemu_mod_timer(env->alarm_timer, expire);
-    } else {
-        qemu_del_timer(env->alarm_timer);
-    }
-}
-#endif
-
-/*****************************************************************************/
-/* Softmmu support */
-#if !defined (CONFIG_USER_ONLY)
-uint64_t helper_ldl_phys(uint64_t p)
-{
-    return (int32_t)ldl_phys(p);
-}
-
-uint64_t helper_ldq_phys(uint64_t p)
-{
-    return ldq_phys(p);
-}
-
-uint64_t helper_ldl_l_phys(uint64_t p)
-{
-    env->lock_addr = p;
-    return env->lock_value = (int32_t)ldl_phys(p);
-}
-
-uint64_t helper_ldq_l_phys(uint64_t p)
-{
-    env->lock_addr = p;
-    return env->lock_value = ldl_phys(p);
-}
-
-void helper_stl_phys(uint64_t p, uint64_t v)
-{
-    stl_phys(p, v);
-}
-
-void helper_stq_phys(uint64_t p, uint64_t v)
-{
-    stq_phys(p, v);
-}
-
-uint64_t helper_stl_c_phys(uint64_t p, uint64_t v)
-{
-    uint64_t ret = 0;
-
-    if (p == env->lock_addr) {
-        int32_t old = ldl_phys(p);
-        if (old == (int32_t)env->lock_value) {
-            stl_phys(p, v);
-            ret = 1;
-        }
-    }
-    env->lock_addr = -1;
-
-    return ret;
-}
-
-uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
-{
-    uint64_t ret = 0;
-
-    if (p == env->lock_addr) {
-        uint64_t old = ldq_phys(p);
-        if (old == env->lock_value) {
-            stq_phys(p, v);
-            ret = 1;
-        }
-    }
-    env->lock_addr = -1;
-
-    return ret;
-}
-
-static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
-                                              int is_user, void *retaddr)
-{
-    uint64_t pc;
-    uint32_t insn;
-
-    do_restore_state(retaddr);
-
-    pc = env->pc;
-    insn = ldl_code(pc);
-
-    env->trap_arg0 = addr;
-    env->trap_arg1 = insn >> 26;                /* opcode */
-    env->trap_arg2 = (insn >> 21) & 31;         /* dest regno */
-    helper_excp(EXCP_UNALIGN, 0);
-}
-
-void QEMU_NORETURN cpu_unassigned_access(CPUAlphaState *env1,
-                                         target_phys_addr_t addr, int is_write,
-                                         int is_exec, int unused, int size)
-{
-    env = env1;
-    env->trap_arg0 = addr;
-    env->trap_arg1 = is_write;
-    dynamic_excp(EXCP_MCHK, 0);
-}
-
-#include "softmmu_exec.h"
-
-#define MMUSUFFIX _mmu
-#define ALIGNED_ONLY
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
-/* try to fill the TLB and return an exception if error. If retaddr is
-   NULL, it means that the function was called in C code (i.e. not
-   from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill(CPUAlphaState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
-{
-    CPUAlphaState *saved_env;
-    int ret;
-
-    saved_env = env;
-    env = env1;
-    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx);
-    if (unlikely(ret != 0)) {
-        do_restore_state(retaddr);
-        /* Exception index and error code are already set */
-        cpu_loop_exit(env);
-    }
-    env = saved_env;
-}
-#endif
diff --git a/target-alpha/sys_helper.c b/target-alpha/sys_helper.c
new file mode 100644
index 0000000000..40ca49c883
--- /dev/null
+++ b/target-alpha/sys_helper.c
@@ -0,0 +1,87 @@
+/*
+ *  Helpers for system instructions.
+ *
+ *  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 "cpu.h"
+#include "helper.h"
+#include "sysemu.h"
+#include "qemu-timer.h"
+
+
+uint64_t helper_load_pcc(CPUAlphaState *env)
+{
+#ifndef CONFIG_USER_ONLY
+    /* In system mode we have access to a decent high-resolution clock.
+       In order to make OS-level time accounting work with the RPCC,
+       present it with a well-timed clock fixed at 250MHz.  */
+    return (((uint64_t)env->pcc_ofs << 32)
+            | (uint32_t)(qemu_get_clock_ns(vm_clock) >> 2));
+#else
+    /* In user-mode, vm_clock doesn't exist.  Just pass through the host cpu
+       clock ticks.  Also, don't bother taking PCC_OFS into account.  */
+    return (uint32_t)cpu_get_real_ticks();
+#endif
+}
+
+/* PALcode support special instructions */
+#ifndef CONFIG_USER_ONLY
+void helper_hw_ret(CPUAlphaState *env, uint64_t a)
+{
+    env->pc = a & ~3;
+    env->intr_flag = 0;
+    env->lock_addr = -1;
+    if ((a & 1) == 0) {
+        env->pal_mode = 0;
+        swap_shadow_regs(env);
+    }
+}
+
+void helper_tbia(CPUAlphaState *env)
+{
+    tlb_flush(env, 1);
+}
+
+void helper_tbis(CPUAlphaState *env, uint64_t p)
+{
+    tlb_flush_page(env, p);
+}
+
+void helper_halt(uint64_t restart)
+{
+    if (restart) {
+        qemu_system_reset_request();
+    } else {
+        qemu_system_shutdown_request();
+    }
+}
+
+uint64_t helper_get_time(void)
+{
+    return qemu_get_clock_ns(rtc_clock);
+}
+
+void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
+{
+    if (expire) {
+        env->alarm_expire = expire;
+        qemu_mod_timer(env->alarm_timer, expire);
+    } else {
+        qemu_del_timer(env->alarm_timer);
+    }
+}
+#endif /* CONFIG_USER_ONLY */
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index b51fe5c8da..1f4565d794 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -149,7 +149,7 @@ static void gen_excp_1(int exception, int error_code)
 
     tmp1 = tcg_const_i32(exception);
     tmp2 = tcg_const_i32(error_code);
-    gen_helper_excp(tmp1, tmp2);
+    gen_helper_excp(cpu_env, tmp1, tmp2);
     tcg_temp_free_i32(tmp2);
     tcg_temp_free_i32(tmp1);
 }
@@ -611,7 +611,8 @@ static void gen_qual_roundmode(DisasContext *ctx, int fn11)
         tcg_gen_movi_i32(tmp, float_round_down);
         break;
     case QUAL_RM_D:
-        tcg_gen_ld8u_i32(tmp, cpu_env, offsetof(CPUAlphaState, fpcr_dyn_round));
+        tcg_gen_ld8u_i32(tmp, cpu_env,
+                         offsetof(CPUAlphaState, fpcr_dyn_round));
         break;
     }
 
@@ -641,7 +642,8 @@ static void gen_qual_flushzero(DisasContext *ctx, int fn11)
     tmp = tcg_temp_new_i32();
     if (fn11) {
         /* Underflow is enabled, use the FPCR setting.  */
-        tcg_gen_ld8u_i32(tmp, cpu_env, offsetof(CPUAlphaState, fpcr_flush_to_zero));
+        tcg_gen_ld8u_i32(tmp, cpu_env,
+                         offsetof(CPUAlphaState, fpcr_flush_to_zero));
     } else {
         /* Underflow is disabled, force flush-to-zero.  */
         tcg_gen_movi_i32(tmp, 1);
@@ -659,15 +661,19 @@ static void gen_qual_flushzero(DisasContext *ctx, int fn11)
 
 static TCGv gen_ieee_input(int reg, int fn11, int is_cmp)
 {
-    TCGv val = tcg_temp_new();
+    TCGv val;
     if (reg == 31) {
-        tcg_gen_movi_i64(val, 0);
-    } else if (fn11 & QUAL_S) {
-        gen_helper_ieee_input_s(val, cpu_fir[reg]);
-    } else if (is_cmp) {
-        gen_helper_ieee_input_cmp(val, cpu_fir[reg]);
+        val = tcg_const_i64(0);
     } else {
-        gen_helper_ieee_input(val, cpu_fir[reg]);
+        if ((fn11 & QUAL_S) == 0) {
+            if (is_cmp) {
+                gen_helper_ieee_input_cmp(cpu_env, cpu_fir[reg]);
+            } else {
+                gen_helper_ieee_input(cpu_env, cpu_fir[reg]);
+            }
+        }
+        val = tcg_temp_new();
+        tcg_gen_mov_i64(val, cpu_fir[reg]);
     }
     return val;
 }
@@ -680,7 +686,7 @@ static void gen_fp_exc_clear(void)
                     offsetof(CPUAlphaState, fp_status.float_exception_flags));
     tcg_temp_free_i32(zero);
 #else
-    gen_helper_fp_exc_clear();
+    gen_helper_fp_exc_clear(cpu_env);
 #endif
 }
 
@@ -698,7 +704,7 @@ static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
     tcg_gen_ld8u_i32(exc, cpu_env,
                      offsetof(CPUAlphaState, fp_status.float_exception_flags));
 #else
-    gen_helper_fp_exc_get(exc);
+    gen_helper_fp_exc_get(exc, cpu_env);
 #endif
 
     if (ignore) {
@@ -713,9 +719,9 @@ static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
     reg = tcg_const_i32(rc + 32);
 
     if (fn11 & QUAL_S) {
-        gen_helper_fp_exc_raise_s(exc, reg);
+        gen_helper_fp_exc_raise_s(cpu_env, exc, reg);
     } else {
-        gen_helper_fp_exc_raise(exc, reg);
+        gen_helper_fp_exc_raise(cpu_env, exc, reg);
     }
 
     tcg_temp_free_i32(reg);
@@ -784,20 +790,20 @@ static void gen_fcvtql_v(DisasContext *ctx, int rb, int rc)
     gen_fcvtql(rb, rc);
 }
 
-#define FARITH2(name)                                   \
-static inline void glue(gen_f, name)(int rb, int rc)    \
-{                                                       \
-    if (unlikely(rc == 31)) {                           \
-        return;                                         \
-    }                                                   \
-    if (rb != 31) {                                     \
-        gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]); \
-    } else {						\
-        TCGv tmp = tcg_const_i64(0);                    \
-        gen_helper_ ## name (cpu_fir[rc], tmp);         \
-        tcg_temp_free(tmp);                             \
-    }                                                   \
-}
+#define FARITH2(name)                                                   \
+    static inline void glue(gen_f, name)(int rb, int rc)                \
+    {                                                                   \
+        if (unlikely(rc == 31)) {                                       \
+            return;                                                     \
+        }                                                               \
+        if (rb != 31) {                                                 \
+            gen_helper_ ## name(cpu_fir[rc], cpu_env, cpu_fir[rb]);     \
+        } else {                                                        \
+            TCGv tmp = tcg_const_i64(0);                                \
+            gen_helper_ ## name(cpu_fir[rc], cpu_env, tmp);             \
+            tcg_temp_free(tmp);                                         \
+        }                                                               \
+    }
 
 /* ??? VAX instruction qualifiers ignored.  */
 FARITH2(sqrtf)
@@ -807,7 +813,8 @@ FARITH2(cvtgq)
 FARITH2(cvtqf)
 FARITH2(cvtqg)
 
-static void gen_ieee_arith2(DisasContext *ctx, void (*helper)(TCGv, TCGv),
+static void gen_ieee_arith2(DisasContext *ctx,
+                            void (*helper)(TCGv, TCGv_ptr, TCGv),
                             int rb, int rc, int fn11)
 {
     TCGv vb;
@@ -823,7 +830,7 @@ static void gen_ieee_arith2(DisasContext *ctx, void (*helper)(TCGv, TCGv),
     gen_fp_exc_clear();
 
     vb = gen_ieee_input(rb, fn11, 0);
-    helper(cpu_fir[rc], vb);
+    helper(cpu_fir[rc], cpu_env, vb);
     tcg_temp_free(vb);
 
     gen_fp_exc_raise(rc, fn11);
@@ -859,18 +866,18 @@ static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
        also do not have integer overflow enabled.  Special case that.  */
     switch (fn11) {
     case QUAL_RM_C:
-        gen_helper_cvttq_c(cpu_fir[rc], vb);
+        gen_helper_cvttq_c(cpu_fir[rc], cpu_env, vb);
         break;
     case QUAL_V | QUAL_RM_C:
     case QUAL_S | QUAL_V | QUAL_RM_C:
         ignore = float_flag_inexact;
         /* FALLTHRU */
     case QUAL_S | QUAL_V | QUAL_I | QUAL_RM_C:
-        gen_helper_cvttq_svic(cpu_fir[rc], vb);
+        gen_helper_cvttq_svic(cpu_fir[rc], cpu_env, vb);
         break;
     default:
         gen_qual_roundmode(ctx, fn11);
-        gen_helper_cvttq(cpu_fir[rc], vb);
+        gen_helper_cvttq(cpu_fir[rc], cpu_env, vb);
         ignore |= (fn11 & QUAL_V ? 0 : float_flag_overflow);
         ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact);
         break;
@@ -880,7 +887,8 @@ static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
     gen_fp_exc_raise_ignore(rc, fn11, ignore);
 }
 
-static void gen_ieee_intcvt(DisasContext *ctx, void (*helper)(TCGv, TCGv),
+static void gen_ieee_intcvt(DisasContext *ctx,
+                            void (*helper)(TCGv, TCGv_ptr, TCGv),
 			    int rb, int rc, int fn11)
 {
     TCGv vb;
@@ -904,10 +912,10 @@ static void gen_ieee_intcvt(DisasContext *ctx, void (*helper)(TCGv, TCGv),
        inexact handling is requested.  */
     if (fn11 & QUAL_I) {
         gen_fp_exc_clear();
-        helper(cpu_fir[rc], vb);
+        helper(cpu_fir[rc], cpu_env, vb);
         gen_fp_exc_raise(rc, fn11);
     } else {
-        helper(cpu_fir[rc], vb);
+        helper(cpu_fir[rc], cpu_env, vb);
     }
 
     if (rb == 31) {
@@ -999,34 +1007,34 @@ static inline void gen_fcpyse(int ra, int rb, int rc)
     gen_cpys_internal(ra, rb, rc, 0, 0xFFF0000000000000ULL);
 }
 
-#define FARITH3(name)                                           \
-static inline void glue(gen_f, name)(int ra, int rb, int rc)    \
-{                                                               \
-    TCGv va, vb;                                                \
-                                                                \
-    if (unlikely(rc == 31)) {                                   \
-        return;                                                 \
-    }                                                           \
-    if (ra == 31) {                                             \
-        va = tcg_const_i64(0);                                  \
-    } else {                                                    \
-        va = cpu_fir[ra];                                       \
-    }                                                           \
-    if (rb == 31) {                                             \
-        vb = tcg_const_i64(0);                                  \
-    } else {                                                    \
-        vb = cpu_fir[rb];                                       \
-    }                                                           \
-                                                                \
-    gen_helper_ ## name (cpu_fir[rc], va, vb);                  \
-                                                                \
-    if (ra == 31) {                                             \
-        tcg_temp_free(va);                                      \
-    }                                                           \
-    if (rb == 31) {                                             \
-        tcg_temp_free(vb);                                      \
-    }                                                           \
-}
+#define FARITH3(name)                                                   \
+    static inline void glue(gen_f, name)(int ra, int rb, int rc)        \
+    {                                                                   \
+        TCGv va, vb;                                                    \
+                                                                        \
+        if (unlikely(rc == 31)) {                                       \
+            return;                                                     \
+        }                                                               \
+        if (ra == 31) {                                                 \
+            va = tcg_const_i64(0);                                      \
+        } else {                                                        \
+            va = cpu_fir[ra];                                           \
+        }                                                               \
+        if (rb == 31) {                                                 \
+            vb = tcg_const_i64(0);                                      \
+        } else {                                                        \
+            vb = cpu_fir[rb];                                           \
+        }                                                               \
+                                                                        \
+        gen_helper_ ## name(cpu_fir[rc], cpu_env, va, vb);              \
+                                                                        \
+        if (ra == 31) {                                                 \
+            tcg_temp_free(va);                                          \
+        }                                                               \
+        if (rb == 31) {                                                 \
+            tcg_temp_free(vb);                                          \
+        }                                                               \
+    }
 
 /* ??? VAX instruction qualifiers ignored.  */
 FARITH3(addf)
@@ -1042,7 +1050,7 @@ FARITH3(cmpglt)
 FARITH3(cmpgle)
 
 static void gen_ieee_arith3(DisasContext *ctx,
-                            void (*helper)(TCGv, TCGv, TCGv),
+                            void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
                             int ra, int rb, int rc, int fn11)
 {
     TCGv va, vb;
@@ -1059,7 +1067,7 @@ static void gen_ieee_arith3(DisasContext *ctx,
 
     va = gen_ieee_input(ra, fn11, 0);
     vb = gen_ieee_input(rb, fn11, 0);
-    helper(cpu_fir[rc], va, vb);
+    helper(cpu_fir[rc], cpu_env, va, vb);
     tcg_temp_free(va);
     tcg_temp_free(vb);
 
@@ -1082,7 +1090,7 @@ IEEE_ARITH3(mult)
 IEEE_ARITH3(divt)
 
 static void gen_ieee_compare(DisasContext *ctx,
-                             void (*helper)(TCGv, TCGv, TCGv),
+                             void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
                              int ra, int rb, int rc, int fn11)
 {
     TCGv va, vb;
@@ -1097,7 +1105,7 @@ static void gen_ieee_compare(DisasContext *ctx,
 
     va = gen_ieee_input(ra, fn11, 1);
     vb = gen_ieee_input(rb, fn11, 1);
-    helper(cpu_fir[rc], va, vb);
+    helper(cpu_fir[rc], cpu_env, va, vb);
     tcg_temp_free(va);
     tcg_temp_free(vb);
 
@@ -1388,14 +1396,8 @@ static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
         tcg_temp_free(tmp1);                                          \
     }                                                                 \
 }
-ARITH3(cmpbge)
-ARITH3(addlv)
-ARITH3(sublv)
-ARITH3(addqv)
-ARITH3(subqv)
 ARITH3(umulh)
-ARITH3(mullv)
-ARITH3(mulqv)
+ARITH3(cmpbge)
 ARITH3(minub8)
 ARITH3(minsb8)
 ARITH3(minuw4)
@@ -1406,6 +1408,43 @@ ARITH3(maxuw4)
 ARITH3(maxsw4)
 ARITH3(perr)
 
+/* Code to call arith3 helpers */
+#define ARITH3_EX(name)                                                 \
+    static inline void glue(gen_, name)(int ra, int rb, int rc,         \
+                                        int islit, uint8_t lit)         \
+    {                                                                   \
+        if (unlikely(rc == 31)) {                                       \
+            return;                                                     \
+        }                                                               \
+        if (ra != 31) {                                                 \
+            if (islit) {                                                \
+                TCGv tmp = tcg_const_i64(lit);                          \
+                gen_helper_ ## name(cpu_ir[rc], cpu_env,                \
+                                    cpu_ir[ra], tmp);                   \
+                tcg_temp_free(tmp);                                     \
+            } else {                                                    \
+                gen_helper_ ## name(cpu_ir[rc], cpu_env,                \
+                                    cpu_ir[ra], cpu_ir[rb]);            \
+            }                                                           \
+        } else {                                                        \
+            TCGv tmp1 = tcg_const_i64(0);                               \
+            if (islit) {                                                \
+                TCGv tmp2 = tcg_const_i64(lit);                         \
+                gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, tmp2);   \
+                tcg_temp_free(tmp2);                                    \
+            } else {                                                    \
+                gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, cpu_ir[rb]); \
+            }                                                           \
+            tcg_temp_free(tmp1);                                        \
+        }                                                               \
+    }
+ARITH3_EX(addlv)
+ARITH3_EX(sublv)
+ARITH3_EX(addqv)
+ARITH3_EX(subqv)
+ARITH3_EX(mullv)
+ARITH3_EX(mulqv)
+
 #define MVIOP2(name)                                    \
 static inline void glue(gen_, name)(int rb, int rc)     \
 {                                                       \
@@ -1643,12 +1682,12 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
     switch (regno) {
     case 255:
         /* TBIA */
-        gen_helper_tbia();
+        gen_helper_tbia(cpu_env);
         break;
 
     case 254:
         /* TBIS */
-        gen_helper_tbis(tmp);
+        gen_helper_tbis(cpu_env, tmp);
         break;
 
     case 253:
@@ -1664,7 +1703,7 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
 
     case 251:
         /* ALARM */
-        gen_helper_set_alarm(tmp);
+        gen_helper_set_alarm(cpu_env, tmp);
         break;
 
     default:
@@ -2674,17 +2713,17 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         case 0x024:
             /* MT_FPCR */
             if (likely(ra != 31))
-                gen_helper_store_fpcr(cpu_fir[ra]);
+                gen_helper_store_fpcr(cpu_env, cpu_fir[ra]);
             else {
                 TCGv tmp = tcg_const_i64(0);
-                gen_helper_store_fpcr(tmp);
+                gen_helper_store_fpcr(cpu_env, tmp);
                 tcg_temp_free(tmp);
             }
             break;
         case 0x025:
             /* MF_FPCR */
             if (likely(ra != 31))
-                gen_helper_load_fpcr(cpu_fir[ra]);
+                gen_helper_load_fpcr(cpu_fir[ra], cpu_env);
             break;
         case 0x02A:
             /* FCMOVEQ */
@@ -2758,11 +2797,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             if (ra != 31) {
                 if (use_icount) {
                     gen_io_start();
-                    gen_helper_load_pcc(cpu_ir[ra]);
+                    gen_helper_load_pcc(cpu_ir[ra], cpu_env);
                     gen_io_end();
                     ret = EXIT_PC_STALE;
                 } else {
-                    gen_helper_load_pcc(cpu_ir[ra]);
+                    gen_helper_load_pcc(cpu_ir[ra], cpu_env);
                 }
             }
             break;
@@ -2832,11 +2871,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 break;
             case 0x2:
                 /* Longword physical access with lock (hw_ldl_l/p) */
-                gen_helper_ldl_l_phys(cpu_ir[ra], addr);
+                gen_helper_ldl_l_phys(cpu_ir[ra], cpu_env, addr);
                 break;
             case 0x3:
                 /* Quadword physical access with lock (hw_ldq_l/p) */
-                gen_helper_ldq_l_phys(cpu_ir[ra], addr);
+                gen_helper_ldq_l_phys(cpu_ir[ra], cpu_env, addr);
                 break;
             case 0x4:
                 /* Longword virtual PTE fetch (hw_ldl/v) */
@@ -3108,10 +3147,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                    emulation PALcode, so continue to accept it.  */
                 TCGv tmp = tcg_temp_new();
                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr));
-                gen_helper_hw_ret(tmp);
+                gen_helper_hw_ret(cpu_env, tmp);
                 tcg_temp_free(tmp);
             } else {
-                gen_helper_hw_ret(cpu_ir[rb]);
+                gen_helper_hw_ret(cpu_env, cpu_ir[rb]);
             }
             ret = EXIT_PC_UPDATED;
             break;
@@ -3145,11 +3184,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 break;
             case 0x2:
                 /* Longword physical access with lock */
-                gen_helper_stl_c_phys(val, addr, val);
+                gen_helper_stl_c_phys(val, cpu_env, addr, val);
                 break;
             case 0x3:
                 /* Quadword physical access with lock */
-                gen_helper_stq_c_phys(val, addr, val);
+                gen_helper_stq_c_phys(val, cpu_env, addr, val);
                 break;
             case 0x4:
                 /* Longword virtual access */
@@ -3385,7 +3424,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
-        insn = ldl_code(ctx.pc);
+        insn = cpu_ldl_code(env, ctx.pc);
         num_insns++;
 
 	if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
@@ -3513,7 +3552,8 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
 #if defined (CONFIG_USER_ONLY)
     env->ps = PS_USER_MODE;
     cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
-                               | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
+                               | FPCR_UNFD | FPCR_INED | FPCR_DNOD
+                               | FPCR_DYN_NORMAL));
 #endif
     env->lock_addr = -1;
     env->fen = 1;
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
new file mode 100644
index 0000000000..42d2a6b63b
--- /dev/null
+++ b/target-arm/cpu-qom.h
@@ -0,0 +1,71 @@
+/*
+ * QEMU ARM CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+#ifndef QEMU_ARM_CPU_QOM_H
+#define QEMU_ARM_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#define TYPE_ARM_CPU "arm-cpu"
+
+#define ARM_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)
+#define ARM_CPU(obj) \
+    OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU)
+#define ARM_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
+
+/**
+ * ARMCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An ARM CPU model.
+ */
+typedef struct ARMCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} ARMCPUClass;
+
+/**
+ * ARMCPU:
+ * @env: #CPUARMState
+ *
+ * An ARM CPU core.
+ */
+typedef struct ARMCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUARMState env;
+} ARMCPU;
+
+static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
+{
+    return ARM_CPU(container_of(env, ARMCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
+
+
+#endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
new file mode 100644
index 0000000000..c3ed45b0bc
--- /dev/null
+++ b/target-arm/cpu.c
@@ -0,0 +1,60 @@
+/*
+ * QEMU ARM CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+
+/* CPUClass::reset() */
+static void arm_cpu_reset(CPUState *s)
+{
+    ARMCPU *cpu = ARM_CPU(s);
+    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
+
+    acc->parent_reset(s);
+
+    /* TODO Inline the current contents of cpu_state_reset(),
+            once cpu_reset_model_id() is eliminated. */
+    cpu_state_reset(&cpu->env);
+}
+
+static void arm_cpu_class_init(ObjectClass *oc, void *data)
+{
+    ARMCPUClass *acc = ARM_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(acc);
+
+    acc->parent_reset = cc->reset;
+    cc->reset = arm_cpu_reset;
+}
+
+static const TypeInfo arm_cpu_type_info = {
+    .name = TYPE_ARM_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(ARMCPU),
+    .abstract = false,
+    .class_size = sizeof(ARMCPUClass),
+    .class_init = arm_cpu_class_init,
+};
+
+static void arm_cpu_register_types(void)
+{
+    type_register_static(&arm_cpu_type_info);
+}
+
+type_init(arm_cpu_register_types)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 26c114b6e5..c208c804aa 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -216,6 +216,9 @@ typedef struct CPUARMState {
         uint32_t cregs[16];
     } iwmmxt;
 
+    /* For mixed endian mode.  */
+    bool bswap_code;
+
 #if defined(CONFIG_USER_ONLY)
     /* For usermode syscall translation.  */
     int eabi;
@@ -238,7 +241,6 @@ typedef struct CPUARMState {
 CPUARMState *cpu_arm_init(const char *cpu_model);
 void arm_translate_init(void);
 int cpu_arm_exec(CPUARMState *s);
-void cpu_arm_close(CPUARMState *s);
 void do_interrupt(CPUARMState *);
 void switch_mode(CPUARMState *, int);
 uint32_t do_arm_semihosting(CPUARMState *env);
@@ -383,6 +385,7 @@ enum arm_features {
     ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
     ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
     ARM_FEATURE_GENERIC_TIMER,
+    ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
@@ -476,6 +479,7 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
 #endif
 
 #include "cpu-all.h"
+#include "cpu-qom.h"
 
 /* Bit usage in the TB flags field: */
 #define ARM_TBFLAG_THUMB_SHIFT      0
@@ -490,7 +494,9 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
 #define ARM_TBFLAG_VFPEN_MASK       (1 << ARM_TBFLAG_VFPEN_SHIFT)
 #define ARM_TBFLAG_CONDEXEC_SHIFT   8
 #define ARM_TBFLAG_CONDEXEC_MASK    (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
-/* Bits 31..16 are currently unused. */
+#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
+#define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
+/* Bits 31..17 are currently unused. */
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_THUMB(F) \
@@ -505,6 +511,8 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
     (((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT)
 #define ARM_TBFLAG_CONDEXEC(F) \
     (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
+#define ARM_TBFLAG_BSWAP_CODE(F) \
+    (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT)
 
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
@@ -515,7 +523,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
         | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
         | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
-        | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT);
+        | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
+        | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
     if (arm_feature(env, ARM_FEATURE_M)) {
         privmode = !((env->v7m.exception == 0) && (env->v7m.control & 1));
     } else {
@@ -542,4 +551,24 @@ static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
     env->regs[15] = tb->pc;
 }
 
+/* Load an instruction and return it in the standard little-endian order */
+static inline uint32_t arm_ldl_code(uint32_t addr, bool do_swap)
+{
+    uint32_t insn = ldl_code(addr);
+    if (do_swap) {
+        return bswap32(insn);
+    }
+    return insn;
+}
+
+/* Ditto, for a halfword (Thumb) instruction */
+static inline uint16_t arm_lduw_code(uint32_t addr, bool do_swap)
+{
+    uint16_t insn = lduw_code(addr);
+    if (do_swap) {
+        return bswap16(insn);
+    }
+    return insn;
+}
+
 #endif
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1314f23d59..28f127baf8 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -254,6 +254,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
     }
     if (arm_feature(env, ARM_FEATURE_V6K)) {
         set_feature(env, ARM_FEATURE_V6);
+        set_feature(env, ARM_FEATURE_MVFR);
     }
     if (arm_feature(env, ARM_FEATURE_V6)) {
         set_feature(env, ARM_FEATURE_V5);
@@ -278,6 +279,10 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
     }
 }
 
+/* TODO Move contents into arm_cpu_reset() in cpu.c,
+ *      once cpu_reset_model_id() is eliminated,
+ *      and then forward to cpu_reset() here.
+ */
 void cpu_state_reset(CPUARMState *env)
 {
     uint32_t id;
@@ -400,6 +405,7 @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
 
 CPUARMState *cpu_arm_init(const char *cpu_model)
 {
+    ARMCPU *cpu;
     CPUARMState *env;
     uint32_t id;
     static int inited = 0;
@@ -407,7 +413,8 @@ CPUARMState *cpu_arm_init(const char *cpu_model)
     id = cpu_arm_find_by_name(cpu_model);
     if (id == 0)
         return NULL;
-    env = g_malloc0(sizeof(CPUARMState));
+    cpu = ARM_CPU(object_new(TYPE_ARM_CPU));
+    env = &cpu->env;
     cpu_exec_init(env);
     if (tcg_enabled() && !inited) {
         inited = 1;
@@ -493,11 +500,6 @@ static uint32_t cpu_arm_find_by_name(const char *name)
     return id;
 }
 
-void cpu_arm_close(CPUARMState *env)
-{
-    g_free(env);
-}
-
 static int bad_mode_switch(CPUARMState *env, int mode)
 {
     /* Return true if it is not valid for us to switch to
@@ -840,7 +842,7 @@ static void do_interrupt_v7m(CPUARMState *env)
     case EXCP_BKPT:
         if (semihosting_enabled) {
             int nr;
-            nr = lduw_code(env->regs[15]) & 0xff;
+            nr = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
             if (nr == 0xab) {
                 env->regs[15] += 2;
                 env->regs[0] = do_arm_semihosting(env);
@@ -912,9 +914,10 @@ void do_interrupt(CPUARMState *env)
         if (semihosting_enabled) {
             /* Check for semihosting interrupt.  */
             if (env->thumb) {
-                mask = lduw_code(env->regs[15] - 2) & 0xff;
+                mask = arm_lduw_code(env->regs[15] - 2, env->bswap_code) & 0xff;
             } else {
-                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
+                mask = arm_ldl_code(env->regs[15] - 4, env->bswap_code)
+                    & 0xffffff;
             }
             /* Only intercept calls from privileged modes, to provide some
                semblance of security.  */
@@ -934,7 +937,7 @@ void do_interrupt(CPUARMState *env)
     case EXCP_BKPT:
         /* See if this is a semihosting syscall.  */
         if (env->thumb && semihosting_enabled) {
-            mask = lduw_code(env->regs[15]) & 0xff;
+            mask = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
             if (mask == 0xab
                   && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
                 env->regs[15] += 2;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 81725d1687..7a3c7d650c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -59,6 +59,7 @@ typedef struct DisasContext {
     struct TranslationBlock *tb;
     int singlestep_enabled;
     int thumb;
+    int bswap_code;
 #if !defined(CONFIG_USER_ONLY)
     int user;
 #endif
@@ -2906,7 +2907,7 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                         case ARM_VFP_MVFR0:
                         case ARM_VFP_MVFR1:
                             if (IS_USER(s)
-                                || !arm_feature(env, ARM_FEATURE_VFP3))
+                                || !arm_feature(env, ARM_FEATURE_MVFR))
                                 return 1;
                             tmp = load_cpu_field(vfp.xregs[rn]);
                             break;
@@ -6705,7 +6706,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
     TCGv addr;
     TCGv_i64 tmp64;
 
-    insn = ldl_code(s->pc);
+    insn = arm_ldl_code(s->pc, s->bswap_code);
     s->pc += 4;
 
     /* M variants do not implement ARM mode.  */
@@ -8133,7 +8134,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
         /* Fall through to 32-bit decode.  */
     }
 
-    insn = lduw_code(s->pc);
+    insn = arm_lduw_code(s->pc, s->bswap_code);
     s->pc += 2;
     insn |= (uint32_t)insn_hw1 << 16;
 
@@ -9163,7 +9164,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         }
     }
 
-    insn = lduw_code(s->pc);
+    insn = arm_lduw_code(s->pc, s->bswap_code);
     s->pc += 2;
 
     switch (insn >> 12) {
@@ -9872,6 +9873,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
     dc->singlestep_enabled = env->singlestep_enabled;
     dc->condjmp = 0;
     dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
+    dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
     dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
     dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
 #if !defined(CONFIG_USER_ONLY)
@@ -10105,7 +10107,8 @@ done_generating:
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
+        log_target_disas(pc_start, dc->pc - pc_start,
+                         dc->thumb | (dc->bswap_code << 1));
         qemu_log("\n");
     }
 #endif
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 5db8f8d60f..78076e4603 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -215,7 +215,7 @@ CPULM32State *cpu_lm32_init(const char *cpu_model)
     cpu_state_reset(env);
     qemu_init_vcpu(env);
 
-    if (!tcg_initialized) {
+    if (tcg_enabled() && !tcg_initialized) {
         tcg_initialized = 1;
         lm32_translate_init();
     }
diff --git a/target-mips/TODO b/target-mips/TODO
index 9101881a97..2a3546f624 100644
--- a/target-mips/TODO
+++ b/target-mips/TODO
@@ -16,7 +16,7 @@ General
   Existing documentation is x86-centric.
 - Reverse endianness bit not implemented
 - The TLB emulation is very inefficient:
-  Qemu's softmmu implements a x86-style MMU, with separate entries
+  QEMU's softmmu implements a x86-style MMU, with separate entries
   for read/write/execute, a TLB index which is just a modulo of the
   virtual address, and a set of TLBs for each user/kernel/supervisor
   MMU mode.
@@ -25,7 +25,7 @@ General
   up to 256 ASID tags as additional matching criterion (which roughly
   equates to 256 MMU modes). It also has a global flag which causes
   entries to match regardless of ASID.
-  To cope with these differences, Qemu currently flushes the TLB at
+  To cope with these differences, QEMU currently flushes the TLB at
   each ASID change. Using the MMU modes to implement ASIDs hinges on
   implementing the global bit efficiently.
 - save/restore of the CPU state is not implemented (see machine.c).
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 7430aa5086..257c4c462b 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -418,7 +418,7 @@ struct CPUMIPSState {
     /* We waste some space so we can handle shadow registers like TCs. */
     TCState tcs[MIPS_SHADOW_SET_MAX];
     CPUMIPSFPUContext fpus[MIPS_FPU_MAX];
-    /* Qemu */
+    /* QEMU */
     int error_code;
     uint32_t hflags;    /* CPU State */
     /* TMASK defines different execution modes */
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 442f684697..76fb451e77 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -1,7 +1,7 @@
 #include "def-helper.h"
 
-DEF_HELPER_2(raise_exception_err, void, i32, int)
-DEF_HELPER_1(raise_exception, void, i32)
+DEF_HELPER_2(raise_exception_err, noreturn, i32, int)
+DEF_HELPER_1(raise_exception, noreturn, i32)
 
 #ifdef TARGET_MIPS64
 DEF_HELPER_3(ldl, tl, tl, tl, int)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 3a207312a4..ce01225e6c 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2292,7 +2292,8 @@ void helper_wait (void)
 
 #if !defined(CONFIG_USER_ONLY)
 
-static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr);
+static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
+                                              int is_user, void *retaddr);
 
 #define MMUSUFFIX _mmu
 #define ALIGNED_ONLY
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index ca6f1cb58c..e7fb3641a7 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -233,10 +233,10 @@ enum {
     POWERPC_EXCP_DTLBE    = 93, /* Data TLB error                            */
     /* EOL                                                                   */
     POWERPC_EXCP_NB       = 96,
-    /* Qemu exceptions: used internally during code translation              */
+    /* QEMU exceptions: used internally during code translation              */
     POWERPC_EXCP_STOP         = 0x200, /* stop translation                   */
     POWERPC_EXCP_BRANCH       = 0x201, /* branch instruction                 */
-    /* Qemu exceptions: special cases we want to stop translation            */
+    /* QEMU exceptions: special cases we want to stop translation            */
     POWERPC_EXCP_SYNC         = 0x202, /* context synchronizing instruction  */
     POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only      */
     POWERPC_EXCP_STCX         = 0x204 /* Conditional stores in user mode     */
@@ -1041,7 +1041,7 @@ struct CPUPPCState {
     /* opcode handlers */
     opc_handler_t *opcodes[0x40];
 
-    /* Those resources are used only in Qemu core */
+    /* Those resources are used only in QEMU core */
     target_ulong hflags;      /* hflags is a MSR & HFLAGS_MASK         */
     target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
     int mmu_idx;         /* precomputed MMU index to speed up mem accesses */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 39dcc273e5..e13b74993d 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -365,7 +365,7 @@ void ppc6xx_tlb_store (CPUPPCState *env, target_ulong EPN, int way, int is_code,
     tlb = &env->tlb.tlb6[nr];
     LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
               " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
-    /* Invalidate any pending reference in Qemu for this virtual address */
+    /* Invalidate any pending reference in QEMU for this virtual address */
     __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
     tlb->pte0 = pte0;
     tlb->pte1 = pte1;
@@ -729,7 +729,7 @@ void ppc_slb_invalidate_all (CPUPPCState *env)
             slb->esid &= ~SLB_ESID_V;
             /* XXX: given the fact that segment size is 256 MB or 1TB,
              *      and we still don't have a tlb_flush_mask(env, n, mask)
-             *      in Qemu, we just invalidate all TLBs
+             *      in QEMU, we just invalidate all TLBs
              */
             do_invalidate = 1;
         }
@@ -752,7 +752,7 @@ void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
 
         /* XXX: given the fact that segment size is 256 MB or 1TB,
          *      and we still don't have a tlb_flush_mask(env, n, mask)
-         *      in Qemu, we just invalidate all TLBs
+         *      in QEMU, we just invalidate all TLBs
          */
         tlb_flush(env, 1);
     }
@@ -2319,7 +2319,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
     case POWERPC_MMU_2_06:
         /* tlbie invalidate TLBs for all segments */
         /* XXX: given the fact that there are too many segments to invalidate,
-         *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
+         *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
          *      we just invalidate all TLBs
          */
         tlb_flush(env, 1);
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 724f4c7815..d929213a04 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -470,7 +470,7 @@ void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
     int r;
     unsigned irq;
 
-    /* PowerPC Qemu tracks the various core input pins (interrupt, critical
+    /* PowerPC QEMU tracks the various core input pins (interrupt, critical
      * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
     if (!cap_interrupt_level &&
         run->ready_for_interrupt_injection &&
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 24fc6bce3b..a2e49cd423 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -31,7 +31,7 @@ void kvmppc_init(void)
 {
     /* XXX The only reason KVM yields control back to qemu is device IO. Since
      * an idle guest does no IO, qemu's device model will never get a chance to
-     * run. So, until Qemu gains IO threads, we create this timer to ensure
+     * run. So, until QEMU gains IO threads, we create this timer to ensure
      * that the device model gets a chance to run. */
     kvmppc_timer_rate = get_ticks_per_sec() / 10;
     kvmppc_timer = qemu_new_timer_ns(vm_clock, &kvmppc_timer_hack, NULL);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 367eefaf9e..b1f87854a0 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -1796,17 +1796,17 @@ static void gen_spr_440 (CPUPPCState *env)
 static void gen_spr_40x (CPUPPCState *env)
 {
     /* Cache */
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCCR, "DCCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_ICCR, "ICCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, SPR_NOACCESS,
@@ -1974,7 +1974,7 @@ static void gen_spr_401_403 (CPUPPCState *env)
                  SPR_NOACCESS, &spr_write_tbu,
                  0x00000000);
     /* Debug */
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_403_CDBCR, "CDBCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -2012,12 +2012,12 @@ static void gen_spr_401 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_40x_sler,
                  0x00000000);
-    /* not emulated, as Qemu never does speculative access */
+    /* not emulated, as QEMU never does speculative access */
     spr_register(env, SPR_40x_SGR, "SGR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFFFFFFF);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCWR, "DCWR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -3436,12 +3436,12 @@ static void init_proc_403GCX (CPUPPCState *env)
     gen_spr_403_real(env);
     gen_spr_403_mmu(env);
     /* Bus access control */
-    /* not emulated, as Qemu never does speculative access */
+    /* not emulated, as QEMU never does speculative access */
     spr_register(env, SPR_40x_SGR, "SGR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFFFFFFF);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCWR, "DCWR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -3488,12 +3488,12 @@ static void init_proc_405 (CPUPPCState *env)
     gen_spr_40x(env);
     gen_spr_405(env);
     /* Bus access control */
-    /* not emulated, as Qemu never does speculative access */
+    /* not emulated, as QEMU never does speculative access */
     spr_register(env, SPR_40x_SGR, "SGR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFFFFFFF);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCWR, "DCWR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -9442,13 +9442,13 @@ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def)
     }
     if (env->irq_inputs == NULL) {
         fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
-                " Attempt Qemu to crash very soon !\n");
+                " Attempt QEMU to crash very soon !\n");
     }
 #endif
     if (env->check_pow == NULL) {
         fprintf(stderr, "WARNING: no power management check handler "
                 "registered.\n"
-                " Attempt Qemu to crash very soon !\n");
+                " Attempt QEMU to crash very soon !\n");
     }
 }
 
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
new file mode 100644
index 0000000000..6fa55a80a5
--- /dev/null
+++ b/target-s390x/cpu-qom.h
@@ -0,0 +1,71 @@
+/*
+ * QEMU S/390 CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_S390_CPU_QOM_H
+#define QEMU_S390_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#define TYPE_S390_CPU "s390-cpu"
+
+#define S390_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(S390CPUClass, (klass), TYPE_S390_CPU)
+#define S390_CPU(obj) \
+    OBJECT_CHECK(S390CPU, (obj), TYPE_S390_CPU)
+#define S390_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(S390CPUClass, (obj), TYPE_S390_CPU)
+
+/**
+ * S390CPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An S/390 CPU model.
+ */
+typedef struct S390CPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} S390CPUClass;
+
+/**
+ * S390CPU:
+ * @env: #CPUS390XState.
+ *
+ * An S/390 CPU.
+ */
+typedef struct S390CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUS390XState env;
+} S390CPU;
+
+static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
+{
+    return S390_CPU(container_of(env, S390CPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
+
+
+#endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
new file mode 100644
index 0000000000..f183213eab
--- /dev/null
+++ b/target-s390x/cpu.c
@@ -0,0 +1,96 @@
+/*
+ * QEMU S/390 CPU
+ *
+ * Copyright (c) 2009 Ulrich Hecht
+ * Copyright (c) 2011 Alexander Graf
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+#include "qemu-timer.h"
+
+
+/* CPUClass::reset() */
+static void s390_cpu_reset(CPUState *s)
+{
+    S390CPU *cpu = S390_CPU(s);
+    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
+    CPUS390XState *env = &cpu->env;
+
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
+
+    scc->parent_reset(s);
+
+    memset(env, 0, offsetof(CPUS390XState, breakpoints));
+    /* FIXME: reset vector? */
+    tlb_flush(env, 1);
+    s390_add_running_cpu(env);
+}
+
+static void s390_cpu_initfn(Object *obj)
+{
+    S390CPU *cpu = S390_CPU(obj);
+    CPUS390XState *env = &cpu->env;
+    static int cpu_num = 0;
+#if !defined(CONFIG_USER_ONLY)
+    struct tm tm;
+#endif
+
+    cpu_exec_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    qemu_get_timedate(&tm, 0);
+    env->tod_offset = TOD_UNIX_EPOCH +
+                      (time2tod(mktimegm(&tm)) * 1000000000ULL);
+    env->tod_basetime = 0;
+    env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu);
+    env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu);
+#endif
+    env->cpu_num = cpu_num++;
+    env->ext_index = -1;
+
+    cpu_reset(CPU(cpu));
+}
+
+static void s390_cpu_class_init(ObjectClass *oc, void *data)
+{
+    S390CPUClass *scc = S390_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(scc);
+
+    scc->parent_reset = cc->reset;
+    cc->reset = s390_cpu_reset;
+}
+
+static const TypeInfo s390_cpu_type_info = {
+    .name = TYPE_S390_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(S390CPU),
+    .instance_init = s390_cpu_initfn,
+    .abstract = false,
+    .class_size = sizeof(S390CPUClass),
+    .class_init = s390_cpu_class_init,
+};
+
+static void s390_cpu_register_types(void)
+{
+    type_register_static(&s390_cpu_type_info);
+}
+
+type_init(s390_cpu_register_types)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index ea849fca1e..2f3f3942c0 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -288,6 +288,9 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
 
 
 #ifndef CONFIG_USER_ONLY
+void s390x_tod_timer(void *opaque);
+void s390x_cpu_timer(void *opaque);
+
 int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall);
 
 #ifdef CONFIG_KVM
@@ -991,4 +994,6 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
     env->psw.addr = tb->pc;
 }
 
+#include "cpu-qom.h"
+
 #endif
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 44d50484d5..209a69603c 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -51,17 +51,19 @@
 #endif
 
 #ifndef CONFIG_USER_ONLY
-static void s390x_tod_timer(void *opaque)
+void s390x_tod_timer(void *opaque)
 {
-    CPUS390XState *env = opaque;
+    S390CPU *cpu = opaque;
+    CPUS390XState *env = &cpu->env;
 
     env->pending_int |= INTERRUPT_TOD;
     cpu_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
-static void s390x_cpu_timer(void *opaque)
+void s390x_cpu_timer(void *opaque)
 {
-    CPUS390XState *env = opaque;
+    S390CPU *cpu = opaque;
+    CPUS390XState *env = &cpu->env;
 
     env->pending_int |= INTERRUPT_CPUTIMER;
     cpu_interrupt(env, CPU_INTERRUPT_HARD);
@@ -70,32 +72,19 @@ static void s390x_cpu_timer(void *opaque)
 
 CPUS390XState *cpu_s390x_init(const char *cpu_model)
 {
+    S390CPU *cpu;
     CPUS390XState *env;
-#if !defined (CONFIG_USER_ONLY)
-    struct tm tm;
-#endif
     static int inited = 0;
-    static int cpu_num = 0;
 
-    env = g_malloc0(sizeof(CPUS390XState));
-    cpu_exec_init(env);
+    cpu = S390_CPU(object_new(TYPE_S390_CPU));
+    env = &cpu->env;
+
     if (tcg_enabled() && !inited) {
         inited = 1;
         s390x_translate_init();
     }
 
-#if !defined(CONFIG_USER_ONLY)
-    qemu_get_timedate(&tm, 0);
-    env->tod_offset = TOD_UNIX_EPOCH +
-                      (time2tod(mktimegm(&tm)) * 1000000000ULL);
-    env->tod_basetime = 0;
-    env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env);
-    env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env);
-#endif
     env->cpu_model_str = cpu_model;
-    env->cpu_num = cpu_num++;
-    env->ext_index = -1;
-    cpu_state_reset(env);
     qemu_init_vcpu(env);
     return env;
 }
@@ -121,15 +110,7 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
 
 void cpu_state_reset(CPUS390XState *env)
 {
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
-
-    memset(env, 0, offsetof(CPUS390XState, breakpoints));
-    /* FIXME: reset vector? */
-    tlb_flush(env, 1);
-    s390_add_running_cpu(env);
+    cpu_reset(ENV_GET_CPU(env));
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
new file mode 100644
index 0000000000..3d3ac0fcef
--- /dev/null
+++ b/target-sparc/cpu-qom.h
@@ -0,0 +1,75 @@
+/*
+ * QEMU SPARC CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_SPARC_CPU_QOM_H
+#define QEMU_SPARC_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#ifdef TARGET_SPARC64
+#define TYPE_SPARC_CPU "sparc64-cpu"
+#else
+#define TYPE_SPARC_CPU "sparc-cpu"
+#endif
+
+#define SPARC_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(SPARCCPUClass, (klass), TYPE_SPARC_CPU)
+#define SPARC_CPU(obj) \
+    OBJECT_CHECK(SPARCCPU, (obj), TYPE_SPARC_CPU)
+#define SPARC_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(SPARCCPUClass, (obj), TYPE_SPARC_CPU)
+
+/**
+ * SPARCCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A SPARC CPU model.
+ */
+typedef struct SPARCCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} SPARCCPUClass;
+
+/**
+ * SPARCCPU:
+ * @env: #CPUSPARCState
+ *
+ * A SPARC CPU.
+ */
+typedef struct SPARCCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUSPARCState env;
+} SPARCCPU;
+
+static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
+{
+    return SPARC_CPU(container_of(env, SPARCCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))
+
+
+#endif
diff --git a/target-sparc/cpu_init.c b/target-sparc/cpu.c
index 5c03f0b893..24f90f1ded 100644
--- a/target-sparc/cpu_init.c
+++ b/target-sparc/cpu.c
@@ -25,11 +25,23 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
 
 void cpu_state_reset(CPUSPARCState *env)
 {
+    cpu_reset(ENV_GET_CPU(env));
+}
+
+/* CPUClass::reset() */
+static void sparc_cpu_reset(CPUState *s)
+{
+    SPARCCPU *cpu = SPARC_CPU(s);
+    SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
+    CPUSPARCState *env = &cpu->env;
+
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
         log_cpu_state(env, 0);
     }
 
+    scc->parent_reset(s);
+
     memset(env, 0, offsetof(CPUSPARCState, breakpoints));
     tlb_flush(env, 1);
     env->cwp = 0;
@@ -99,23 +111,18 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
     return 0;
 }
 
-static void cpu_sparc_close(CPUSPARCState *env)
-{
-    g_free(env->def);
-    g_free(env);
-}
-
 CPUSPARCState *cpu_sparc_init(const char *cpu_model)
 {
+    SPARCCPU *cpu;
     CPUSPARCState *env;
 
-    env = g_new0(CPUSPARCState, 1);
-    cpu_exec_init(env);
+    cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
+    env = &cpu->env;
 
     gen_intermediate_code_init(env);
 
     if (cpu_sparc_register(env, cpu_model) < 0) {
-        cpu_sparc_close(env);
+        object_delete(OBJECT(cpu));
         return NULL;
     }
     qemu_init_vcpu(env);
@@ -847,3 +854,46 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
                 env->fsr, env->y);
 #endif
 }
+
+static void sparc_cpu_initfn(Object *obj)
+{
+    SPARCCPU *cpu = SPARC_CPU(obj);
+    CPUSPARCState *env = &cpu->env;
+
+    cpu_exec_init(env);
+}
+
+static void sparc_cpu_uninitfn(Object *obj)
+{
+    SPARCCPU *cpu = SPARC_CPU(obj);
+    CPUSPARCState *env = &cpu->env;
+
+    g_free(env->def);
+}
+
+static void sparc_cpu_class_init(ObjectClass *oc, void *data)
+{
+    SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+
+    scc->parent_reset = cc->reset;
+    cc->reset = sparc_cpu_reset;
+}
+
+static const TypeInfo sparc_cpu_type_info = {
+    .name = TYPE_SPARC_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(SPARCCPU),
+    .instance_init = sparc_cpu_initfn,
+    .instance_finalize = sparc_cpu_uninitfn,
+    .abstract = false,
+    .class_size = sizeof(SPARCCPUClass),
+    .class_init = sparc_cpu_class_init,
+};
+
+static void sparc_cpu_register_types(void)
+{
+    type_register_static(&sparc_cpu_type_info);
+}
+
+type_init(sparc_cpu_register_types)
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 1025752e8f..865288cc94 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -691,6 +691,7 @@ static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
 #endif
 
 #include "cpu-all.h"
+#include "cpu-qom.h"
 
 #ifdef TARGET_SPARC64
 /* sun4u.c */
@@ -699,8 +700,9 @@ uint64_t cpu_tick_get_count(CPUTimer *timer);
 void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
 trap_state* cpu_tsptr(CPUSPARCState* env);
 #endif
-void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write,
-                         int is_user, void *retaddr);
+void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env, target_ulong addr,
+                                       int is_write, int is_user,
+                                       void *retaddr);
 
 #define TB_FLAG_FPU_ENABLED (1 << 4)
 #define TB_FLAG_AM_ENABLED (1 << 5)
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index c4d6225102..e3c7fddbe8 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -78,7 +78,7 @@ DEF_HELPER_1(fcmpeq_fcc1, void, env)
 DEF_HELPER_1(fcmpeq_fcc2, void, env)
 DEF_HELPER_1(fcmpeq_fcc3, void, env)
 #endif
-DEF_HELPER_2(raise_exception, void, env, int)
+DEF_HELPER_2(raise_exception, noreturn, env, int)
 #define F_HELPER_0_1(name) DEF_HELPER_1(f ## name, void, env)
 
 DEF_HELPER_3(faddd, f64, env, f64, f64)
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 11fb9f5de6..cb73c449f0 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -150,18 +150,17 @@ static int get_physical_address(CPUSPARCState *env, target_phys_addr_t *physical
                 case 3: /* Reserved */
                     return (3 << 8) | (4 << 2);
                 case 2: /* L3 PTE */
-                    page_offset = (address & TARGET_PAGE_MASK) &
-                        (TARGET_PAGE_SIZE - 1);
+                    page_offset = 0;
                 }
                 *page_size = TARGET_PAGE_SIZE;
                 break;
             case 2: /* L2 PTE */
-                page_offset = address & 0x3ffff;
+                page_offset = address & 0x3f000;
                 *page_size = 0x40000;
             }
             break;
         case 2: /* L1 PTE */
-            page_offset = address & 0xffffff;
+            page_offset = address & 0xfff000;
             *page_size = 0x1000000;
         }
     }
@@ -206,11 +205,11 @@ int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
     target_ulong page_size;
     int error_code = 0, prot, access_index;
 
+    address &= TARGET_PAGE_MASK;
     error_code = get_physical_address(env, &paddr, &prot, &access_index,
                                       address, rw, mmu_idx, &page_size);
+    vaddr = address;
     if (error_code == 0) {
-        vaddr = address & TARGET_PAGE_MASK;
-        paddr &= TARGET_PAGE_MASK;
 #ifdef DEBUG_MMU
         printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
                TARGET_FMT_lx "\n", address, paddr, vaddr);
@@ -230,7 +229,6 @@ int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
            permissions. If no mapping is available, redirect accesses to
            neverland. Fake/overridden mappings will be flushed when
            switching to normal mode. */
-        vaddr = address & TARGET_PAGE_MASK;
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         tlb_set_page(env, vaddr, paddr, prot, mmu_idx, TARGET_PAGE_SIZE);
         return 0;
@@ -704,17 +702,16 @@ static int get_physical_address(CPUSPARCState *env, target_phys_addr_t *physical
 int cpu_sparc_handle_mmu_fault(CPUSPARCState *env, target_ulong address, int rw,
                                int mmu_idx)
 {
-    target_ulong virt_addr, vaddr;
+    target_ulong vaddr;
     target_phys_addr_t paddr;
     target_ulong page_size;
     int error_code = 0, prot, access_index;
 
+    address &= TARGET_PAGE_MASK;
     error_code = get_physical_address(env, &paddr, &prot, &access_index,
                                       address, rw, mmu_idx, &page_size);
     if (error_code == 0) {
-        virt_addr = address & TARGET_PAGE_MASK;
-        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
-                             (TARGET_PAGE_SIZE - 1));
+        vaddr = address;
 
         trace_mmu_helper_mmu_fault(address, paddr, mmu_idx, env->tl,
                                    env->dmmu.mmu_primary_context,
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
new file mode 100644
index 0000000000..342d85e39b
--- /dev/null
+++ b/target-unicore32/cpu-qom.h
@@ -0,0 +1,59 @@
+/*
+ * QEMU UniCore32 CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_UC32_CPU_QOM_H
+#define QEMU_UC32_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#define TYPE_UNICORE32_CPU "unicore32-cpu"
+
+#define UNICORE32_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(UniCore32CPUClass, (klass), TYPE_UNICORE32_CPU)
+#define UNICORE32_CPU(obj) \
+    OBJECT_CHECK(UniCore32CPU, (obj), TYPE_UNICORE32_CPU)
+#define UNICORE32_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(UniCore32CPUClass, (obj), TYPE_UNICORE32_CPU)
+
+/**
+ * UniCore32CPUClass:
+ *
+ * A UniCore32 CPU model.
+ */
+typedef struct UniCore32CPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+} UniCore32CPUClass;
+
+/**
+ * UniCore32CPU:
+ * @env: #CPUUniCore32State
+ *
+ * A UniCore32 CPU.
+ */
+typedef struct UniCore32CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUUniCore32State env;
+} UniCore32CPU;
+
+static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
+{
+    return UNICORE32_CPU(container_of(env, UniCore32CPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(uc32_env_get_cpu(e))
+
+
+#endif
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
new file mode 100644
index 0000000000..de63f58dda
--- /dev/null
+++ b/target-unicore32/cpu.c
@@ -0,0 +1,104 @@
+/*
+ * QEMU UniCore32 CPU
+ *
+ * Copyright (c) 2010-2011 GUAN Xue-tao
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Contributions from 2012-04-01 on are considered under GPL version 2,
+ * or (at your option) any later version.
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+
+static inline void set_feature(CPUUniCore32State *env, int feature)
+{
+    env->features |= feature;
+}
+
+/* CPU models */
+
+typedef struct UniCore32CPUInfo {
+    const char *name;
+    void (*instance_init)(Object *obj);
+} UniCore32CPUInfo;
+
+static void unicore_ii_cpu_initfn(Object *obj)
+{
+    UniCore32CPU *cpu = UNICORE32_CPU(obj);
+    CPUUniCore32State *env = &cpu->env;
+
+    env->cp0.c0_cpuid = 0x40010863;
+
+    set_feature(env, UC32_HWCAP_CMOV);
+    set_feature(env, UC32_HWCAP_UCF64);
+    env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
+    env->cp0.c0_cachetype = 0x1dd20d2;
+    env->cp0.c1_sys = 0x00090078;
+}
+
+static void uc32_any_cpu_initfn(Object *obj)
+{
+    UniCore32CPU *cpu = UNICORE32_CPU(obj);
+    CPUUniCore32State *env = &cpu->env;
+
+    env->cp0.c0_cpuid = 0xffffffff;
+
+    set_feature(env, UC32_HWCAP_CMOV);
+    set_feature(env, UC32_HWCAP_UCF64);
+}
+
+static const UniCore32CPUInfo uc32_cpus[] = {
+    { .name = "UniCore-II", .instance_init = unicore_ii_cpu_initfn },
+    { .name = "any",        .instance_init = uc32_any_cpu_initfn },
+};
+
+static void uc32_cpu_initfn(Object *obj)
+{
+    UniCore32CPU *cpu = UNICORE32_CPU(obj);
+    CPUUniCore32State *env = &cpu->env;
+
+    cpu_exec_init(env);
+    env->cpu_model_str = object_get_typename(obj);
+
+    env->uncached_asr = ASR_MODE_USER;
+    env->regs[31] = 0;
+
+    tlb_flush(env, 1);
+}
+
+static void uc32_register_cpu_type(const UniCore32CPUInfo *info)
+{
+    TypeInfo type_info = {
+        .name = info->name,
+        .parent = TYPE_UNICORE32_CPU,
+        .instance_init = info->instance_init,
+    };
+
+    type_register_static(&type_info);
+}
+
+static const TypeInfo uc32_cpu_type_info = {
+    .name = TYPE_UNICORE32_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(UniCore32CPU),
+    .instance_init = uc32_cpu_initfn,
+    .abstract = true,
+    .class_size = sizeof(UniCore32CPUClass),
+};
+
+static void uc32_cpu_register_types(void)
+{
+    int i;
+
+    type_register_static(&uc32_cpu_type_info);
+    for (i = 0; i < ARRAY_SIZE(uc32_cpus); i++) {
+        uc32_register_cpu_type(&uc32_cpus[i]);
+    }
+}
+
+type_init(uc32_cpu_register_types)
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index a3f8589205..81c14ffd77 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -5,7 +5,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
  */
 #ifndef __CPU_UC32_H__
 #define __CPU_UC32_H__
@@ -159,6 +160,7 @@ static inline void cpu_set_tls(CPUUniCore32State *env, target_ulong newtls)
 }
 
 #include "cpu-all.h"
+#include "cpu-qom.h"
 #include "exec-all.h"
 
 static inline void cpu_pc_from_tb(CPUUniCore32State *env, TranslationBlock *tb)
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index 6af492daf5..9fe4a375e4 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -4,6 +4,9 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
+ *
+ * Contributions from 2012-04-01 on are considered under GPL version 2,
+ * or (at your option) any later version.
  */
 
 #include "cpu.h"
@@ -11,75 +14,23 @@
 #include "helper.h"
 #include "host-utils.h"
 
-static inline void set_feature(CPUUniCore32State *env, int feature)
-{
-    env->features |= feature;
-}
-
-struct uc32_cpu_t {
-    uint32_t id;
-    const char *name;
-};
-
-static const struct uc32_cpu_t uc32_cpu_names[] = {
-    { UC32_CPUID_UCV2, "UniCore-II"},
-    { UC32_CPUID_ANY, "any"},
-    { 0, NULL}
-};
-
-/* return 0 if not found */
-static uint32_t uc32_cpu_find_by_name(const char *name)
-{
-    int i;
-    uint32_t id;
-
-    id = 0;
-    for (i = 0; uc32_cpu_names[i].name; i++) {
-        if (strcmp(name, uc32_cpu_names[i].name) == 0) {
-            id = uc32_cpu_names[i].id;
-            break;
-        }
-    }
-    return id;
-}
-
 CPUUniCore32State *uc32_cpu_init(const char *cpu_model)
 {
+    UniCore32CPU *cpu;
     CPUUniCore32State *env;
-    uint32_t id;
     static int inited = 1;
 
-    env = g_malloc0(sizeof(CPUUniCore32State));
-    cpu_exec_init(env);
-
-    id = uc32_cpu_find_by_name(cpu_model);
-    switch (id) {
-    case UC32_CPUID_UCV2:
-        set_feature(env, UC32_HWCAP_CMOV);
-        set_feature(env, UC32_HWCAP_UCF64);
-        env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
-        env->cp0.c0_cachetype = 0x1dd20d2;
-        env->cp0.c1_sys = 0x00090078;
-        break;
-    case UC32_CPUID_ANY: /* For userspace emulation.  */
-        set_feature(env, UC32_HWCAP_CMOV);
-        set_feature(env, UC32_HWCAP_UCF64);
-        break;
-    default:
-        cpu_abort(env, "Bad CPU ID: %x\n", id);
+    if (object_class_by_name(cpu_model) == NULL) {
+        return NULL;
     }
-
-    env->cpu_model_str = cpu_model;
-    env->cp0.c0_cpuid = id;
-    env->uncached_asr = ASR_MODE_USER;
-    env->regs[31] = 0;
+    cpu = UNICORE32_CPU(object_new(cpu_model));
+    env = &cpu->env;
 
     if (inited) {
         inited = 0;
         uc32_translate_init();
     }
 
-    tlb_flush(env, 1);
     qemu_init_vcpu(env);
     return env;
 }
diff --git a/target-unicore32/helper.h b/target-unicore32/helper.h
index 615de2add9..5a3b8a41ea 100644
--- a/target-unicore32/helper.h
+++ b/target-unicore32/helper.h
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
  */
 #include "def-helper.h"
 
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
index 638a02097d..b954c30a84 100644
--- a/target-unicore32/op_helper.c
+++ b/target-unicore32/op_helper.c
@@ -5,7 +5,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
  */
 #include "cpu.h"
 #include "dyngen-exec.h"
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 3b3ba163a6..9793d14c1b 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -5,7 +5,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
  */
 #include <stdarg.h>
 #include <stdlib.h>
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index e579ef06a1..2885212e3a 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -336,7 +336,7 @@ static int tcg_target_const_match(tcg_target_long val,
 #define INSN_COMIBF     (INSN_OP(0x23))
 
 /* supplied by libgcc */
-extern void *__canonicalize_funcptr_for_compare(void *);
+extern void *__canonicalize_funcptr_for_compare(const void *);
 
 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
 {
@@ -628,7 +628,7 @@ static void tcg_out_bswap32(TCGContext *s, int ret, int arg, int temp)
     tcg_out_shd(s, ret, arg, temp, 8);    /* ret =  DCBA */
 }
 
-static void tcg_out_call(TCGContext *s, void *func)
+static void tcg_out_call(TCGContext *s, const void *func)
 {
     tcg_target_long val, hi, lo, disp;
 
@@ -1661,23 +1661,18 @@ static int tcg_target_callee_save_regs[] = {
     TCG_REG_R18
 };
 
+#define FRAME_SIZE ((-TCG_TARGET_CALL_STACK_OFFSET \
+                     + TCG_TARGET_STATIC_CALL_ARGS_SIZE \
+                     + ARRAY_SIZE(tcg_target_callee_save_regs) * 4 \
+                     + CPU_TEMP_BUF_NLONGS * sizeof(long) \
+                     + TCG_TARGET_STACK_ALIGN - 1) \
+                    & -TCG_TARGET_STACK_ALIGN)
+
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
     int frame_size, i;
 
-    /* Allocate space for the fixed frame marker.  */
-    frame_size = -TCG_TARGET_CALL_STACK_OFFSET;
-    frame_size += TCG_TARGET_STATIC_CALL_ARGS_SIZE;
-
-    /* Allocate space for the saved registers.  */
-    frame_size += ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
-
-    /* Allocate space for the TCG temps. */
-    frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long);
-
-    /* Align the allocated space.  */
-    frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
-                  & -TCG_TARGET_STACK_ALIGN);
+    frame_size = FRAME_SIZE;
 
     /* The return address is stored in the caller's frame.  */
     tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_CALL_STACK, -20);
@@ -1752,3 +1747,81 @@ static void tcg_target_init(TCGContext *s)
 
     tcg_add_target_add_op_defs(hppa_op_defs);
 }
+
+typedef struct {
+    uint32_t len __attribute__((aligned((sizeof(void *)))));
+    uint32_t id;
+    uint8_t version;
+    char augmentation[1];
+    uint8_t code_align;
+    uint8_t data_align;
+    uint8_t return_column;
+} DebugFrameCIE;
+
+typedef struct {
+    uint32_t len __attribute__((aligned((sizeof(void *)))));
+    uint32_t cie_offset;
+    tcg_target_long func_start __attribute__((packed));
+    tcg_target_long func_len __attribute__((packed));
+    uint8_t def_cfa[4];
+    uint8_t ret_ofs[3];
+    uint8_t reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
+} DebugFrameFDE;
+
+typedef struct {
+    DebugFrameCIE cie;
+    DebugFrameFDE fde;
+} DebugFrame;
+
+#define ELF_HOST_MACHINE  EM_PARISC
+#define ELF_HOST_FLAGS    EFA_PARISC_1_1
+
+/* ??? BFD (and thus GDB) wants very much to distinguish between HPUX
+   and other extensions.  We don't really care, but if we don't set this
+   to *something* then the object file won't be properly matched.  */
+#define ELF_OSABI         ELFOSABI_LINUX
+
+static DebugFrame debug_frame = {
+    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+    .cie.id = -1,
+    .cie.version = 1,
+    .cie.code_align = 1,
+    .cie.data_align = 1,
+    .cie.return_column = 2,
+
+    .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
+    .fde.def_cfa = {
+        0x12, 30,                       /* DW_CFA_def_cfa_sf sp, ... */
+        (-FRAME_SIZE & 0x7f) | 0x80,     /* ... sleb128 -FRAME_SIZE */
+        (-FRAME_SIZE >> 7) & 0x7f
+    },
+    .fde.ret_ofs = {
+        0x11, 2, (-20 / 4) & 0x7f       /* DW_CFA_offset_extended_sf r2, 20 */
+    },
+    .fde.reg_ofs = {
+        /* This must match the ordering in tcg_target_callee_save_regs.  */
+        0x80 + 4, 0,                    /* DW_CFA_offset r4, 0 */
+        0x80 + 5, 4,                    /* DW_CFA_offset r5, 4 */
+        0x80 + 6, 8,                    /* DW_CFA_offset r6, 8 */
+        0x80 + 7, 12,                    /* ... */
+        0x80 + 8, 16,
+        0x80 + 9, 20,
+        0x80 + 10, 24,
+        0x80 + 11, 28,
+        0x80 + 12, 32,
+        0x80 + 13, 36,
+        0x80 + 14, 40,
+        0x80 + 15, 44,
+        0x80 + 16, 48,
+        0x80 + 17, 52,
+        0x80 + 18, 56,
+    }
+};
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+    debug_frame.fde.func_start = (tcg_target_long) buf;
+    debug_frame.fde.func_len = buf_size;
+
+    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+}
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 43a51a1c54..871a7e74f5 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1989,22 +1989,29 @@ static int tcg_target_callee_save_regs[] = {
 #endif
 };
 
+/* Compute frame size via macros, to share between tcg_target_qemu_prologue
+   and tcg_register_jit.  */
+
+#define PUSH_SIZE \
+    ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
+     * (TCG_TARGET_REG_BITS / 8))
+
+#define FRAME_SIZE \
+    ((PUSH_SIZE \
+      + TCG_STATIC_CALL_ARGS_SIZE \
+      + CPU_TEMP_BUF_NLONGS * sizeof(long) \
+      + TCG_TARGET_STACK_ALIGN - 1) \
+     & ~(TCG_TARGET_STACK_ALIGN - 1))
+
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
-    int i, frame_size, push_size, stack_addend;
+    int i, stack_addend;
 
     /* TB prologue */
 
     /* Reserve some stack space, also for TCG temps.  */
-    push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs);
-    push_size *= TCG_TARGET_REG_BITS / 8;
-
-    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE +
-        CPU_TEMP_BUF_NLONGS * sizeof(long);
-    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
-        ~(TCG_TARGET_STACK_ALIGN - 1);
-    stack_addend = frame_size - push_size;
+    stack_addend = FRAME_SIZE - PUSH_SIZE;
     tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
                   CPU_TEMP_BUF_NLONGS * sizeof(long));
 
@@ -2070,3 +2077,92 @@ static void tcg_target_init(TCGContext *s)
 
     tcg_add_target_add_op_defs(x86_op_defs);
 }
+
+typedef struct {
+    uint32_t len __attribute__((aligned((sizeof(void *)))));
+    uint32_t id;
+    uint8_t version;
+    char augmentation[1];
+    uint8_t code_align;
+    uint8_t data_align;
+    uint8_t return_column;
+} DebugFrameCIE;
+
+typedef struct {
+    uint32_t len __attribute__((aligned((sizeof(void *)))));
+    uint32_t cie_offset;
+    tcg_target_long func_start __attribute__((packed));
+    tcg_target_long func_len __attribute__((packed));
+    uint8_t def_cfa[4];
+    uint8_t reg_ofs[14];
+} DebugFrameFDE;
+
+typedef struct {
+    DebugFrameCIE cie;
+    DebugFrameFDE fde;
+} DebugFrame;
+
+#if TCG_TARGET_REG_BITS == 64
+#define ELF_HOST_MACHINE EM_X86_64
+static DebugFrame debug_frame = {
+    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+    .cie.id = -1,
+    .cie.version = 1,
+    .cie.code_align = 1,
+    .cie.data_align = 0x78,             /* sleb128 -8 */
+    .cie.return_column = 16,
+
+    .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
+    .fde.def_cfa = {
+        12, 7,                          /* DW_CFA_def_cfa %rsp, ... */
+        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
+        (FRAME_SIZE >> 7)
+    },
+    .fde.reg_ofs = {
+        0x90, 1,                        /* DW_CFA_offset, %rip, -8 */
+        /* The following ordering must match tcg_target_callee_save_regs.  */
+        0x86, 2,                        /* DW_CFA_offset, %rbp, -16 */
+        0x83, 3,                        /* DW_CFA_offset, %rbx, -24 */
+        0x8c, 4,                        /* DW_CFA_offset, %r12, -32 */
+        0x8d, 5,                        /* DW_CFA_offset, %r13, -40 */
+        0x8e, 6,                        /* DW_CFA_offset, %r14, -48 */
+        0x8f, 7,                        /* DW_CFA_offset, %r15, -56 */
+    }
+};
+#else
+#define ELF_HOST_MACHINE EM_386
+static DebugFrame debug_frame = {
+    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+    .cie.id = -1,
+    .cie.version = 1,
+    .cie.code_align = 1,
+    .cie.data_align = 0x7c,             /* sleb128 -4 */
+    .cie.return_column = 8,
+
+    .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
+    .fde.def_cfa = {
+        12, 4,                          /* DW_CFA_def_cfa %esp, ... */
+        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
+        (FRAME_SIZE >> 7)
+    },
+    .fde.reg_ofs = {
+        0x88, 1,                        /* DW_CFA_offset, %eip, -4 */
+        /* The following ordering must match tcg_target_callee_save_regs.  */
+        0x85, 2,                        /* DW_CFA_offset, %ebp, -8 */
+        0x83, 3,                        /* DW_CFA_offset, %ebx, -12 */
+        0x86, 4,                        /* DW_CFA_offset, %esi, -16 */
+        0x87, 5,                        /* DW_CFA_offset, %edi, -20 */
+    }
+};
+#endif
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+    /* We're expecting a 2 byte uleb128 encoded value.  */
+    assert(FRAME_SIZE >> 14 == 0);
+
+    debug_frame.fde.func_start = (tcg_target_long) buf;
+    debug_frame.fde.func_len = buf_size;
+
+    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+}
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 409a1ac1ce..f2ad9e3d85 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -1656,7 +1656,6 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_ld16s_i64, { "r", "r" } },
     { INDEX_op_ld32u_i64, { "r", "r" } },
     { INDEX_op_ld32s_i64, { "r", "r" } },
-    { INDEX_op_ld_i64, { "r", "r" } },
 
     { INDEX_op_add_i32, { "r", "r", "ri" } },
     { INDEX_op_mul_i32, { "r", "r", "ri" } },
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 491c9797d3..247a27814a 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1624,3 +1624,66 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
     tcg_add_target_add_op_defs(sparc_op_defs);
 }
+
+#if TCG_TARGET_REG_BITS == 64
+# define ELF_HOST_MACHINE  EM_SPARCV9
+#elif defined(__sparc_v8plus__)
+# define ELF_HOST_MACHINE  EM_SPARC32PLUS
+# define ELF_HOST_FLAGS    EF_SPARC_32PLUS
+#else
+# define ELF_HOST_MACHINE  EM_SPARC
+#endif
+
+typedef struct {
+    uint32_t len __attribute__((aligned((sizeof(void *)))));
+    uint32_t id;
+    uint8_t version;
+    char augmentation[1];
+    uint8_t code_align;
+    uint8_t data_align;
+    uint8_t return_column;
+} DebugFrameCIE;
+
+typedef struct {
+    uint32_t len __attribute__((aligned((sizeof(void *)))));
+    uint32_t cie_offset;
+    tcg_target_long func_start __attribute__((packed));
+    tcg_target_long func_len __attribute__((packed));
+    uint8_t def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
+    uint8_t win_save;
+    uint8_t ret_save[3];
+} DebugFrameFDE;
+
+typedef struct {
+    DebugFrameCIE cie;
+    DebugFrameFDE fde;
+} DebugFrame;
+
+static DebugFrame debug_frame = {
+    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+    .cie.id = -1,
+    .cie.version = 1,
+    .cie.code_align = 1,
+    .cie.data_align = -sizeof(void *) & 0x7f,
+    .cie.return_column = 15,            /* o7 */
+
+    .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
+    .fde.def_cfa = {
+#if TCG_TARGET_REG_BITS == 64
+        12, 30,                         /* DW_CFA_def_cfa i6, 2047 */
+        (2047 & 0x7f) | 0x80, (2047 >> 7)
+#else
+        13, 30                          /* DW_CFA_def_cfa_register i6 */
+#endif
+    },
+    .fde.win_save = 0x2d,               /* DW_CFA_GNU_window_save */
+    .fde.ret_save = { 9, 15, 31 },      /* DW_CFA_register o7, i7 */
+};
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+    debug_frame.fde.func_start = (tcg_target_long) buf;
+    debug_frame.fde.func_len = buf_size;
+
+    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+}
diff --git a/tcg/tcg.c b/tcg/tcg.c
index ccfcd1abe1..ab589c7ad2 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -28,6 +28,9 @@
 
 #include "config.h"
 
+/* Define to jump the ELF file used to communicate with GDB.  */
+#undef DEBUG_JIT
+
 #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
 /* define it to suppress various consistency checks (faster) */
 #define NDEBUG
@@ -45,6 +48,18 @@
 #include "cpu.h"
 
 #include "tcg-op.h"
+
+#if TCG_TARGET_REG_BITS == 64
+# define ELF_CLASS  ELFCLASS64
+#else
+# define ELF_CLASS  ELFCLASS32
+#endif
+#ifdef HOST_WORDS_BIGENDIAN
+# define ELF_DATA   ELFDATA2MSB
+#else
+# define ELF_DATA   ELFDATA2LSB
+#endif
+
 #include "elf.h"
 
 #if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
@@ -57,6 +72,10 @@ static void tcg_target_qemu_prologue(TCGContext *s);
 static void patch_reloc(uint8_t *code_ptr, int type, 
                         tcg_target_long value, tcg_target_long addend);
 
+static void tcg_register_jit_int(void *buf, size_t size,
+                                 void *debug_frame, size_t debug_frame_size)
+    __attribute__((unused));
+
 /* Forward declarations for functions declared and used in tcg-target.c. */
 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
@@ -2231,3 +2250,267 @@ void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
     cpu_fprintf(f, "[TCG profiler not compiled]\n");
 }
 #endif
+
+#ifdef ELF_HOST_MACHINE
+/* In order to use this feature, the backend needs to do three things:
+
+   (1) Define ELF_HOST_MACHINE to indicate both what value to
+       put into the ELF image and to indicate support for the feature.
+
+   (2) Define tcg_register_jit.  This should create a buffer containing
+       the contents of a .debug_frame section that describes the post-
+       prologue unwind info for the tcg machine.
+
+   (3) Call tcg_register_jit_int, with the constructed .debug_frame.
+*/
+
+/* Begin GDB interface.  THE FOLLOWING MUST MATCH GDB DOCS.  */
+typedef enum {
+    JIT_NOACTION = 0,
+    JIT_REGISTER_FN,
+    JIT_UNREGISTER_FN
+} jit_actions_t;
+
+struct jit_code_entry {
+    struct jit_code_entry *next_entry;
+    struct jit_code_entry *prev_entry;
+    const void *symfile_addr;
+    uint64_t symfile_size;
+};
+
+struct jit_descriptor {
+    uint32_t version;
+    uint32_t action_flag;
+    struct jit_code_entry *relevant_entry;
+    struct jit_code_entry *first_entry;
+};
+
+void __jit_debug_register_code(void) __attribute__((noinline));
+void __jit_debug_register_code(void)
+{
+    asm("");
+}
+
+/* Must statically initialize the version, because GDB may check
+   the version before we can set it.  */
+struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
+
+/* End GDB interface.  */
+
+static int find_string(const char *strtab, const char *str)
+{
+    const char *p = strtab + 1;
+
+    while (1) {
+        if (strcmp(p, str) == 0) {
+            return p - strtab;
+        }
+        p += strlen(p) + 1;
+    }
+}
+
+static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
+                                 void *debug_frame, size_t debug_frame_size)
+{
+    struct __attribute__((packed)) DebugInfo {
+        uint32_t  len;
+        uint16_t  version;
+        uint32_t  abbrev;
+        uint8_t   ptr_size;
+        uint8_t   cu_die;
+        uint16_t  cu_lang;
+        uintptr_t cu_low_pc;
+        uintptr_t cu_high_pc;
+        uint8_t   fn_die;
+        char      fn_name[16];
+        uintptr_t fn_low_pc;
+        uintptr_t fn_high_pc;
+        uint8_t   cu_eoc;
+    };
+
+    struct ElfImage {
+        ElfW(Ehdr) ehdr;
+        ElfW(Phdr) phdr;
+        ElfW(Shdr) shdr[7];
+        ElfW(Sym)  sym[2];
+        struct DebugInfo di;
+        uint8_t    da[24];
+        char       str[80];
+    };
+
+    struct ElfImage *img;
+
+    static const struct ElfImage img_template = {
+        .ehdr = {
+            .e_ident[EI_MAG0] = ELFMAG0,
+            .e_ident[EI_MAG1] = ELFMAG1,
+            .e_ident[EI_MAG2] = ELFMAG2,
+            .e_ident[EI_MAG3] = ELFMAG3,
+            .e_ident[EI_CLASS] = ELF_CLASS,
+            .e_ident[EI_DATA] = ELF_DATA,
+            .e_ident[EI_VERSION] = EV_CURRENT,
+            .e_type = ET_EXEC,
+            .e_machine = ELF_HOST_MACHINE,
+            .e_version = EV_CURRENT,
+            .e_phoff = offsetof(struct ElfImage, phdr),
+            .e_shoff = offsetof(struct ElfImage, shdr),
+            .e_ehsize = sizeof(ElfW(Shdr)),
+            .e_phentsize = sizeof(ElfW(Phdr)),
+            .e_phnum = 1,
+            .e_shentsize = sizeof(ElfW(Shdr)),
+            .e_shnum = ARRAY_SIZE(img->shdr),
+            .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
+#ifdef ELF_HOST_FLAGS
+            .e_flags = ELF_HOST_FLAGS,
+#endif
+#ifdef ELF_OSABI
+            .e_ident[EI_OSABI] = ELF_OSABI,
+#endif
+        },
+        .phdr = {
+            .p_type = PT_LOAD,
+            .p_flags = PF_X,
+        },
+        .shdr = {
+            [0] = { .sh_type = SHT_NULL },
+            /* Trick: The contents of code_gen_buffer are not present in
+               this fake ELF file; that got allocated elsewhere.  Therefore
+               we mark .text as SHT_NOBITS (similar to .bss) so that readers
+               will not look for contents.  We can record any address.  */
+            [1] = { /* .text */
+                .sh_type = SHT_NOBITS,
+                .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
+            },
+            [2] = { /* .debug_info */
+                .sh_type = SHT_PROGBITS,
+                .sh_offset = offsetof(struct ElfImage, di),
+                .sh_size = sizeof(struct DebugInfo),
+            },
+            [3] = { /* .debug_abbrev */
+                .sh_type = SHT_PROGBITS,
+                .sh_offset = offsetof(struct ElfImage, da),
+                .sh_size = sizeof(img->da),
+            },
+            [4] = { /* .debug_frame */
+                .sh_type = SHT_PROGBITS,
+                .sh_offset = sizeof(struct ElfImage),
+            },
+            [5] = { /* .symtab */
+                .sh_type = SHT_SYMTAB,
+                .sh_offset = offsetof(struct ElfImage, sym),
+                .sh_size = sizeof(img->sym),
+                .sh_info = 1,
+                .sh_link = ARRAY_SIZE(img->shdr) - 1,
+                .sh_entsize = sizeof(ElfW(Sym)),
+            },
+            [6] = { /* .strtab */
+                .sh_type = SHT_STRTAB,
+                .sh_offset = offsetof(struct ElfImage, str),
+                .sh_size = sizeof(img->str),
+            }
+        },
+        .sym = {
+            [1] = { /* code_gen_buffer */
+                .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
+                .st_shndx = 1,
+            }
+        },
+        .di = {
+            .len = sizeof(struct DebugInfo) - 4,
+            .version = 2,
+            .ptr_size = sizeof(void *),
+            .cu_die = 1,
+            .cu_lang = 0x8001,  /* DW_LANG_Mips_Assembler */
+            .fn_die = 2,
+            .fn_name = "code_gen_buffer"
+        },
+        .da = {
+            1,          /* abbrev number (the cu) */
+            0x11, 1,    /* DW_TAG_compile_unit, has children */
+            0x13, 0x5,  /* DW_AT_language, DW_FORM_data2 */
+            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
+            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
+            0, 0,       /* end of abbrev */
+            2,          /* abbrev number (the fn) */
+            0x2e, 0,    /* DW_TAG_subprogram, no children */
+            0x3, 0x8,   /* DW_AT_name, DW_FORM_string */
+            0x11, 0x1,  /* DW_AT_low_pc, DW_FORM_addr */
+            0x12, 0x1,  /* DW_AT_high_pc, DW_FORM_addr */
+            0, 0,       /* end of abbrev */
+            0           /* no more abbrev */
+        },
+        .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
+               ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
+    };
+
+    /* We only need a single jit entry; statically allocate it.  */
+    static struct jit_code_entry one_entry;
+
+    uintptr_t buf = (uintptr_t)buf_ptr;
+    size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
+
+    img = g_malloc(img_size);
+    *img = img_template;
+    memcpy(img + 1, debug_frame, debug_frame_size);
+
+    img->phdr.p_vaddr = buf;
+    img->phdr.p_paddr = buf;
+    img->phdr.p_memsz = buf_size;
+
+    img->shdr[1].sh_name = find_string(img->str, ".text");
+    img->shdr[1].sh_addr = buf;
+    img->shdr[1].sh_size = buf_size;
+
+    img->shdr[2].sh_name = find_string(img->str, ".debug_info");
+    img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
+
+    img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
+    img->shdr[4].sh_size = debug_frame_size;
+
+    img->shdr[5].sh_name = find_string(img->str, ".symtab");
+    img->shdr[6].sh_name = find_string(img->str, ".strtab");
+
+    img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
+    img->sym[1].st_value = buf;
+    img->sym[1].st_size = buf_size;
+
+    img->di.cu_low_pc = buf;
+    img->di.cu_high_pc = buf_size;
+    img->di.fn_low_pc = buf;
+    img->di.fn_high_pc = buf_size;
+
+#ifdef DEBUG_JIT
+    /* Enable this block to be able to debug the ELF image file creation.
+       One can use readelf, objdump, or other inspection utilities.  */
+    {
+        FILE *f = fopen("/tmp/qemu.jit", "w+b");
+        if (f) {
+            if (fwrite(img, img_size, 1, f) != img_size) {
+                /* Avoid stupid unused return value warning for fwrite.  */
+            }
+            fclose(f);
+        }
+    }
+#endif
+
+    one_entry.symfile_addr = img;
+    one_entry.symfile_size = img_size;
+
+    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
+    __jit_debug_descriptor.relevant_entry = &one_entry;
+    __jit_debug_descriptor.first_entry = &one_entry;
+    __jit_debug_register_code();
+}
+#else
+/* No support for the feature.  Provide the entry point expected by exec.c,
+   and implement the internal function we declared earlier.  */
+
+static void tcg_register_jit_int(void *buf, size_t size,
+                                 void *debug_frame, size_t debug_frame_size)
+{
+}
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+}
+#endif /* ELF_HOST_MACHINE */
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 5f6c647ea5..a83bdddba4 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -586,3 +586,5 @@ extern uint8_t code_gen_prologue[];
 # define tcg_qemu_tb_exec(env, tb_ptr) \
     ((tcg_target_ulong (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
 #endif
+
+void tcg_register_jit(void *buf, size_t buf_size);
diff --git a/tci.c b/tci.c
index 70e7bfb759..c43fe7d260 100644
--- a/tci.c
+++ b/tci.c
@@ -63,6 +63,17 @@ void *tci_tb_ptr;
 
 static tcg_target_ulong tci_reg[TCG_TARGET_NB_REGS];
 
+#if !defined(CONFIG_TCG_PASS_AREG0)
+# define helper_ldb_mmu(env, addr, mmu_idx) __ldb_mmu(addr, mmu_idx)
+# define helper_ldw_mmu(env, addr, mmu_idx) __ldw_mmu(addr, mmu_idx)
+# define helper_ldl_mmu(env, addr, mmu_idx) __ldl_mmu(addr, mmu_idx)
+# define helper_ldq_mmu(env, addr, mmu_idx) __ldq_mmu(addr, mmu_idx)
+# define helper_stb_mmu(env, addr, val, mmu_idx) __stb_mmu(addr, val, mmu_idx)
+# define helper_stw_mmu(env, addr, val, mmu_idx) __stw_mmu(addr, val, mmu_idx)
+# define helper_stl_mmu(env, addr, val, mmu_idx) __stl_mmu(addr, val, mmu_idx)
+# define helper_stq_mmu(env, addr, val, mmu_idx) __stq_mmu(addr, val, mmu_idx)
+#endif /* !CONFIG_TCG_PASS_AREG0 */
+
 static tcg_target_ulong tci_read_reg(TCGReg index)
 {
     assert(index < ARRAY_SIZE(tci_reg));
@@ -1049,7 +1060,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp8 = __ldb_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1061,7 +1072,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp8 = __ldb_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1073,7 +1084,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp16 = __ldw_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1085,7 +1096,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp16 = __ldw_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1098,7 +1109,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp32 = __ldl_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1110,7 +1121,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp32 = __ldl_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1123,7 +1134,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp32 = __ldl_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1138,7 +1149,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
 #endif
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp64 = __ldq_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp64 = helper_ldq_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1154,7 +1165,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stb_mmu(taddr, t0, t2);
+            helper_stb_mmu(env, taddr, t0, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1166,7 +1177,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stw_mmu(taddr, t0, t2);
+            helper_stw_mmu(env, taddr, t0, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1178,7 +1189,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stl_mmu(taddr, t0, t2);
+            helper_stl_mmu(env, taddr, t0, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1190,7 +1201,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stq_mmu(taddr, tmp64, t2);
+            helper_stq_mmu(env, taddr, tmp64, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
diff --git a/tests/Makefile b/tests/Makefile
index c78ade122e..a98a848ec9 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,57 +1,141 @@
 export SRC_PATH
 
-CHECKS = check-qdict check-qfloat check-qint check-qstring check-qlist
-CHECKS += check-qjson test-qmp-output-visitor test-qmp-input-visitor
-CHECKS += test-string-input-visitor test-string-output-visitor test-coroutine
-CHECKS += $(SRC_PATH)/tests/qemu-iotests-quick.sh
-
-check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o test-coroutine.o: $(GENERATED_HEADERS)
-
-check-qint: check-qint.o qint.o $(tools-obj-y)
-check-qstring: check-qstring.o qstring.o $(tools-obj-y)
-check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(tools-obj-y)
-check-qlist: check-qlist.o qlist.o qint.o $(tools-obj-y)
-check-qfloat: check-qfloat.o qfloat.o $(tools-obj-y)
-check-qjson: check-qjson.o $(qobject-obj-y) $(tools-obj-y)
-test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y) $(tools-obj-y)
-
-test-qmp-input-visitor.o test-qmp-output-visitor.o \
-test-string-input-visitor.o test-string-output-visitor.o \
-	test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
-
-$(qapi-dir)/test-qapi-types.c $(qapi-dir)/test-qapi-types.h :\
+check-unit-y = tests/check-qdict$(EXESUF)
+check-unit-y += tests/check-qfloat$(EXESUF)
+check-unit-y += tests/check-qint$(EXESUF)
+check-unit-y += tests/check-qstring$(EXESUF)
+check-unit-y += tests/check-qlist$(EXESUF)
+check-unit-y += tests/check-qjson$(EXESUF)
+check-unit-y += tests/test-qmp-output-visitor$(EXESUF)
+check-unit-y += tests/test-qmp-input-visitor$(EXESUF)
+check-unit-y += tests/test-qmp-input-strict$(EXESUF)
+check-unit-y += tests/test-qmp-commands$(EXESUF)
+check-unit-y += tests/test-string-input-visitor$(EXESUF)
+check-unit-y += tests/test-string-output-visitor$(EXESUF)
+check-unit-y += tests/test-coroutine$(EXESUF)
+
+check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
+
+# All QTests for now are POSIX-only, but the dependencies are
+# really in libqtest, not in the testcases themselves.
+check-qtest-i386-y = tests/rtc-test
+check-qtest-x86_64-y = $(check-qtest-i386-y)
+
+GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
+
+test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
+	tests/check-qlist.o tests/check-qfloat.o tests/check-qjson.o \
+	tests/test-coroutine.o tests/test-string-output-visitor.o \
+	tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
+	tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \
+	tests/test-qmp-commands.o
+
+test-qapi-obj-y =  $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y)
+test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o
+test-qapi-obj-y += module.o
+
+$(test-obj-y): $(GENERATED_HEADERS)
+$(test-obj-y): QEMU_INCLUDES += -Itests
+
+tests/check-qint$(EXESUF): tests/check-qint.o qint.o $(tools-obj-y)
+tests/check-qstring$(EXESUF): tests/check-qstring.o qstring.o $(tools-obj-y)
+tests/check-qdict$(EXESUF): tests/check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(tools-obj-y)
+tests/check-qlist$(EXESUF): tests/check-qlist.o qlist.o qint.o $(tools-obj-y)
+tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o $(tools-obj-y)
+tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) $(tools-obj-y)
+tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y)
+
+tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "$(qapi-dir)" -p "test-" < $<, "  GEN   $@")
-$(qapi-dir)/test-qapi-visit.c $(qapi-dir)/test-qapi-visit.h :\
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o tests -p "test-" < $<, "  GEN   $@")
+tests/test-qapi-visit.c tests/test-qapi-visit.h :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "$(qapi-dir)" -p "test-" < $<, "  GEN   $@")
-$(qapi-dir)/test-qmp-commands.h $(qapi-dir)/test-qmp-marshal.c :\
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o tests -p "test-" < $<, "  GEN   $@")
+tests/test-qmp-commands.h tests/test-qmp-marshal.c :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
-	    $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o "$(qapi-dir)" -p "test-" < $<, "  GEN   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p "test-" < $<, "  GEN   $@")
 
 
-test-string-output-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
-test-string-output-visitor: test-string-output-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y)
+tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
+tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y)
+tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y)
+tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y)
+tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y)
 
-test-string-input-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
-test-string-input-visitor: test-string-input-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y)
 
-test-qmp-output-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
-test-qmp-output-visitor: test-qmp-output-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+# QTest rules
 
-test-qmp-input-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
-test-qmp-input-visitor: test-qmp-input-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS)))
+QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), $(TARGET),))
+check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y))
 
-test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y)
-test-qmp-commands: test-qmp-commands.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
+qtest-obj-y = tests/libqtest.o $(oslib-obj-y)
+$(check-qtest-y): $(qtest-obj-y)
 
-$(SRC_PATH)/tests/qemu-iotests-quick.sh: qemu-img qemu-io
+.PHONY: check-help
+check-help:
+	@echo "Regression testing targets:"
+	@echo
+	@echo " make check                Run all tests"
+	@echo " make check-qtest-TARGET   Run qtest tests for given target"
+	@echo " make check-qtest          Run qtest tests"
+	@echo " make check-unit           Run qobject tests"
+	@echo " make check-block          Run block tests"
+	@echo " make check-report.html    Generates an HTML test report"
+	@echo
+	@echo "Please note that HTML reports do not regenerate if the unit tests"
+	@echo "has not changed."
+	@echo
+	@echo "The variable SPEED can be set to control the gtester speed setting."
+	@echo "Default options are -k and (for make V=1) --verbose; they can be"
+	@echo "changed with variable GTESTER_OPTIONS."
 
+.SECONDARY:
 
-.PHONY: check check-block
+SPEED = quick
+GTESTER_OPTIONS = -k $(if $(V),--verbose,-q)
 
-check: $(CHECKS)
-	$(call quiet-command, gtester $(CHECKS), "  CHECK")
+# gtester tests, possibly with verbose output
 
-check-block:
-	$(call quiet-command, $(SHELL) $(SRC_PATH)/tests/check-block.sh , "  CHECK")
+.PHONY: $(patsubst %, check-qtest-%, $(QTEST_TARGETS))
+$(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y)
+	$(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \
+		gtester $(GTESTER_OPTIONS) -m=$(SPEED) $(check-qtest-$*-y),"GTESTER $@")
+
+.PHONY: $(patsubst %, check-%, $(check-unit-y))
+$(patsubst %, check-%, $(check-unit-y)): check-%: %
+	$(call quiet-command,gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER $*")
+
+# gtester tests with XML output
+
+$(patsubst %, check-report-qtest-%.xml, $(QTEST_TARGETS)): check-report-qtest-%.xml: $(check-qtest-y)
+	$(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \
+	  gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $(check-qtest-$*-y),"GTESTER $@")
+
+check-report-unit.xml: $(check-unit-y)
+	$(call quiet-command,gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $^, "GTESTER $@")
+
+# Reports and overall runs
+
+check-report.xml: $(patsubst %,check-report-qtest-%.xml, $(QTEST_TARGETS)) check-report-unit.xml
+	$(call quiet-command,$(SRC_PATH)/scripts/gtester-cat $^ > $@, "  GEN    $@")
+
+check-report.html: check-report.xml
+	$(call quiet-command,gtester-report $< > $@, "  GEN    $@")
+
+
+# Other tests
+
+.PHONY: check-tests/qemu-iotests-quick.sh
+check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF)
+	$<
+
+# Consolidated targets
+
+.PHONY: check-qtest check-unit check
+check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
+check-unit: $(patsubst %,check-%, $(check-unit-y))
+check-block: $(patsubst %,check-%, $(check-block-y))
+check: check-unit check-qtest
diff --git a/check-qdict.c b/tests/check-qdict.c
index fc0d276538..fc0d276538 100644
--- a/check-qdict.c
+++ b/tests/check-qdict.c
diff --git a/check-qfloat.c b/tests/check-qfloat.c
index cdc66ea10b..cdc66ea10b 100644
--- a/check-qfloat.c
+++ b/tests/check-qfloat.c
diff --git a/check-qint.c b/tests/check-qint.c
index 5a27119ae2..5a27119ae2 100644
--- a/check-qint.c
+++ b/tests/check-qint.c
diff --git a/check-qjson.c b/tests/check-qjson.c
index 526e25ef6d..526e25ef6d 100644
--- a/check-qjson.c
+++ b/tests/check-qjson.c
diff --git a/check-qlist.c b/tests/check-qlist.c
index 501ba262da..501ba262da 100644
--- a/check-qlist.c
+++ b/tests/check-qlist.c
diff --git a/check-qstring.c b/tests/check-qstring.c
index addad6c673..addad6c673 100644
--- a/check-qstring.c
+++ b/tests/check-qstring.c
diff --git a/tests/libqtest.c b/tests/libqtest.c
new file mode 100644
index 0000000000..d47969eae5
--- /dev/null
+++ b/tests/libqtest.c
@@ -0,0 +1,387 @@
+/*
+ * QTest
+ *
+ * Copyright IBM, Corp. 2012
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *  Paolo Bonzini     <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include "libqtest.h"
+
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "osdep.h"
+
+#define MAX_IRQ 256
+
+QTestState *global_qtest;
+
+struct QTestState
+{
+    int fd;
+    bool irq_level[MAX_IRQ];
+    GString *rx;
+    gchar *pid_file;
+};
+
+#define g_assert_no_errno(ret) do { \
+    g_assert_cmpint(ret, !=, -1); \
+} while (0)
+
+QTestState *qtest_init(const char *extra_args)
+{
+    QTestState *s;
+    struct sockaddr_un addr;
+    int sock, ret, i;
+    gchar *socket_path;
+    gchar *pid_file;
+    gchar *command;
+    const char *qemu_binary;
+    pid_t pid;
+    socklen_t addrlen;
+
+    qemu_binary = getenv("QTEST_QEMU_BINARY");
+    g_assert(qemu_binary != NULL);
+
+    socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
+    pid_file = g_strdup_printf("/tmp/qtest-%d.pid", getpid());
+
+    s = g_malloc(sizeof(*s));
+
+    sock = socket(PF_UNIX, SOCK_STREAM, 0);
+    g_assert_no_errno(sock);
+
+    addr.sun_family = AF_UNIX;
+    snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socket_path);
+    qemu_set_cloexec(sock);
+
+    do {
+        ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+    } while (ret == -1 && errno == EINTR);
+    g_assert_no_errno(ret);
+    listen(sock, 1);
+
+    pid = fork();
+    if (pid == 0) {
+        command = g_strdup_printf("%s "
+                                  "-qtest unix:%s,nowait "
+                                  "-qtest-log /dev/null "
+                                  "-pidfile %s "
+                                  "-machine accel=qtest "
+                                  "%s", qemu_binary, socket_path,
+                                  pid_file,
+                                  extra_args ?: "");
+
+        ret = system(command);
+        exit(ret);
+        g_free(command);
+    }
+
+    do {
+        ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
+    } while (ret == -1 && errno == EINTR);
+    g_assert_no_errno(ret);
+    close(sock);
+
+    s->fd = ret;
+    s->rx = g_string_new("");
+    s->pid_file = pid_file;
+    for (i = 0; i < MAX_IRQ; i++) {
+        s->irq_level[i] = false;
+    }
+
+    g_free(socket_path);
+
+    return s;
+}
+
+void qtest_quit(QTestState *s)
+{
+    FILE *f;
+    char buffer[1024];
+
+    f = fopen(s->pid_file, "r");
+    if (f) {
+        if (fgets(buffer, sizeof(buffer), f)) {
+            pid_t pid = atoi(buffer);
+            int status = 0;
+
+            kill(pid, SIGTERM);
+            waitpid(pid, &status, 0);
+        }
+
+        fclose(f);
+    }
+}
+
+static void qtest_sendf(QTestState *s, const char *fmt, ...)
+{
+    va_list ap;
+    gchar *str;
+    size_t size, offset;
+
+    va_start(ap, fmt);
+    str = g_strdup_vprintf(fmt, ap);
+    va_end(ap);
+    size = strlen(str);
+
+    offset = 0;
+    while (offset < size) {
+        ssize_t len;
+
+        len = write(s->fd, str + offset, size - offset);
+        if (len == -1 && errno == EINTR) {
+            continue;
+        }
+
+        g_assert_no_errno(len);
+        g_assert_cmpint(len, >, 0);
+
+        offset += len;
+    }
+}
+
+static GString *qtest_recv_line(QTestState *s)
+{
+    GString *line;
+    size_t offset;
+    char *eol;
+
+    while ((eol = strchr(s->rx->str, '\n')) == NULL) {
+        ssize_t len;
+        char buffer[1024];
+
+        len = read(s->fd, buffer, sizeof(buffer));
+        if (len == -1 && errno == EINTR) {
+            continue;
+        }
+
+        if (len == -1 || len == 0) {
+            fprintf(stderr, "Broken pipe\n");
+            exit(1);
+        }
+
+        g_string_append_len(s->rx, buffer, len);
+    }
+
+    offset = eol - s->rx->str;
+    line = g_string_new_len(s->rx->str, offset);
+    g_string_erase(s->rx, 0, offset + 1);
+
+    return line;
+}
+
+static gchar **qtest_rsp(QTestState *s, int expected_args)
+{
+    GString *line;
+    gchar **words;
+    int i;
+
+redo:
+    line = qtest_recv_line(s);
+    words = g_strsplit(line->str, " ", 0);
+    g_string_free(line, TRUE);
+
+    if (strcmp(words[0], "IRQ") == 0) {
+        int irq;
+
+        g_assert(words[1] != NULL);
+        g_assert(words[2] != NULL);
+
+        irq = strtoul(words[2], NULL, 0);
+        g_assert_cmpint(irq, >=, 0);
+        g_assert_cmpint(irq, <, MAX_IRQ);
+
+        if (strcmp(words[1], "raise") == 0) {
+            s->irq_level[irq] = true;
+        } else {
+            s->irq_level[irq] = false;
+        }
+
+        g_strfreev(words);
+        goto redo;
+    }
+
+    g_assert(words[0] != NULL);
+    g_assert_cmpstr(words[0], ==, "OK");
+
+    if (expected_args) {
+        for (i = 0; i < expected_args; i++) {
+            g_assert(words[i] != NULL);
+        }
+    } else {
+        g_strfreev(words);
+    }
+
+    return words;
+}
+
+const char *qtest_get_arch(void)
+{
+    const char *qemu = getenv("QTEST_QEMU_BINARY");
+    const char *end = strrchr(qemu, '/');
+
+    return end + strlen("/qemu-system-");
+}
+
+bool qtest_get_irq(QTestState *s, int num)
+{
+    /* dummy operation in order to make sure irq is up to date */
+    qtest_inb(s, 0);
+
+    return s->irq_level[num];
+}
+
+static int64_t qtest_clock_rsp(QTestState *s)
+{
+    gchar **words;
+    int64_t clock;
+    words = qtest_rsp(s, 2);
+    clock = g_ascii_strtoll(words[1], NULL, 0);
+    g_strfreev(words);
+    return clock;
+}
+
+int64_t qtest_clock_step_next(QTestState *s)
+{
+    qtest_sendf(s, "clock_step\n");
+    return qtest_clock_rsp(s);
+}
+
+int64_t qtest_clock_step(QTestState *s, int64_t step)
+{
+    qtest_sendf(s, "clock_step %"PRIi64"\n", step);
+    return qtest_clock_rsp(s);
+}
+
+int64_t qtest_clock_set(QTestState *s, int64_t val)
+{
+    qtest_sendf(s, "clock_set %"PRIi64"\n", val);
+    return qtest_clock_rsp(s);
+}
+
+void qtest_irq_intercept_out(QTestState *s, const char *qom_path)
+{
+    qtest_sendf(s, "irq_intercept_out %s\n", qom_path);
+    qtest_rsp(s, 0);
+}
+
+void qtest_irq_intercept_in(QTestState *s, const char *qom_path)
+{
+    qtest_sendf(s, "irq_intercept_in %s\n", qom_path);
+    qtest_rsp(s, 0);
+}
+
+static void qtest_out(QTestState *s, const char *cmd, uint16_t addr, uint32_t value)
+{
+    qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value);
+    qtest_rsp(s, 0);
+}
+
+void qtest_outb(QTestState *s, uint16_t addr, uint8_t value)
+{
+    qtest_out(s, "outb", addr, value);
+}
+
+void qtest_outw(QTestState *s, uint16_t addr, uint16_t value)
+{
+    qtest_out(s, "outw", addr, value);
+}
+
+void qtest_outl(QTestState *s, uint16_t addr, uint32_t value)
+{
+    qtest_out(s, "outl", addr, value);
+}
+
+static uint32_t qtest_in(QTestState *s, const char *cmd, uint16_t addr)
+{
+    gchar **args;
+    uint32_t value;
+
+    qtest_sendf(s, "%s 0x%x\n", cmd, addr);
+    args = qtest_rsp(s, 2);
+    value = strtoul(args[1], NULL, 0);
+    g_strfreev(args);
+
+    return value;
+}
+
+uint8_t qtest_inb(QTestState *s, uint16_t addr)
+{
+    return qtest_in(s, "inb", addr);
+}
+
+uint16_t qtest_inw(QTestState *s, uint16_t addr)
+{
+    return qtest_in(s, "inw", addr);
+}
+
+uint32_t qtest_inl(QTestState *s, uint16_t addr)
+{
+    return qtest_in(s, "inl", addr);
+}
+
+static int hex2nib(char ch)
+{
+    if (ch >= '0' && ch <= '9') {
+        return ch - '0';
+    } else if (ch >= 'a' && ch <= 'f') {
+        return 10 + (ch - 'a');
+    } else if (ch >= 'A' && ch <= 'F') {
+        return 10 + (ch - 'a');
+    } else {
+        return -1;
+    }
+}
+
+void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)
+{
+    uint8_t *ptr = data;
+    gchar **args;
+    size_t i;
+
+    qtest_sendf(s, "read 0x%x 0x%x\n", addr, size);
+    args = qtest_rsp(s, 2);
+
+    for (i = 0; i < size; i++) {
+        ptr[i] = hex2nib(args[1][2 + (i * 2)]) << 4;
+        ptr[i] |= hex2nib(args[1][2 + (i * 2) + 1]);
+    }
+
+    g_strfreev(args);
+}
+
+void qtest_add_func(const char *str, void (*fn))
+{
+    gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
+    g_test_add_func(path, fn);
+}
+
+void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)
+{
+    const uint8_t *ptr = data;
+    size_t i;
+
+    qtest_sendf(s, "write 0x%x 0x%x 0x", addr, size);
+    for (i = 0; i < size; i++) {
+        qtest_sendf(s, "%02x", ptr[i]);
+    }
+    qtest_sendf(s, "\n");
+    qtest_rsp(s, 0);
+}
diff --git a/tests/libqtest.h b/tests/libqtest.h
new file mode 100644
index 0000000000..2ca85a9ee9
--- /dev/null
+++ b/tests/libqtest.h
@@ -0,0 +1,335 @@
+/*
+ * QTest
+ *
+ * Copyright IBM, Corp. 2012
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *  Paolo Bonzini     <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#ifndef LIBQTEST_H
+#define LIBQTEST_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+typedef struct QTestState QTestState;
+
+extern QTestState *global_qtest;
+
+/**
+ * qtest_init:
+ * @extra_args: other arguments to pass to QEMU.
+ */
+QTestState *qtest_init(const char *extra_args);
+
+/**
+ * qtest_quit:
+ * @s: QTestState instance to operate on.
+ *
+ * Shut down the QEMU process associated to @s.
+ */
+void qtest_quit(QTestState *s);
+
+/**
+ * qtest_get_irq:
+ * @s: QTestState instance to operate on.
+ * @num: Interrupt to observe.
+ *
+ * Return the level of the @num interrupt.
+ */
+bool qtest_get_irq(QTestState *s, int num);
+
+/**
+ * qtest_irq_intercept_in:
+ * @s: QTestState instance to operate on.
+ * @string: QOM path of a device.
+ *
+ * Associate qtest irqs with the GPIO-in pins of the device
+ * whose path is specified by @string.
+ */
+void qtest_irq_intercept_in(QTestState *s, const char *string);
+
+/**
+ * qtest_irq_intercept_out:
+ * @s: QTestState instance to operate on.
+ * @string: QOM path of a device.
+ *
+ * Associate qtest irqs with the GPIO-out pins of the device
+ * whose path is specified by @string.
+ */
+void qtest_irq_intercept_out(QTestState *s, const char *string);
+
+/**
+ * qtest_outb:
+ * @s: QTestState instance to operate on.
+ * @addr: I/O port to write to.
+ * @value: Value being written.
+ *
+ * Write an 8-bit value to an I/O port.
+ */
+void qtest_outb(QTestState *s, uint16_t addr, uint8_t value);
+
+/**
+ * qtest_outw:
+ * @s: QTestState instance to operate on.
+ * @addr: I/O port to write to.
+ * @value: Value being written.
+ *
+ * Write a 16-bit value to an I/O port.
+ */
+void qtest_outw(QTestState *s, uint16_t addr, uint16_t value);
+
+/**
+ * qtest_outl:
+ * @s: QTestState instance to operate on.
+ * @addr: I/O port to write to.
+ * @value: Value being written.
+ *
+ * Write a 32-bit value to an I/O port.
+ */
+void qtest_outl(QTestState *s, uint16_t addr, uint32_t value);
+
+/**
+ * qtest_inb:
+ * @s: QTestState instance to operate on.
+ * @addr: I/O port to read from.
+ * @value: Value being written.
+ *
+ * Returns an 8-bit value from an I/O port.
+ */
+uint8_t qtest_inb(QTestState *s, uint16_t addr);
+
+/**
+ * qtest_inw:
+ * @s: QTestState instance to operate on.
+ * @addr: I/O port to read from.
+ * @value: Value being written.
+ *
+ * Returns a 16-bit value from an I/O port.
+ */
+uint16_t qtest_inw(QTestState *s, uint16_t addr);
+
+/**
+ * qtest_inl:
+ * @s: QTestState instance to operate on.
+ * @addr: I/O port to read from.
+ * @value: Value being written.
+ *
+ * Returns a 32-bit value from an I/O port.
+ */
+uint32_t qtest_inl(QTestState *s, uint16_t addr);
+
+/**
+ * qtest_memread:
+ * @s: QTestState instance to operate on.
+ * @addr: Guest address to read from.
+ * @data: Pointer to where memory contents will be stored.
+ * @size: Number of bytes to read.
+ *
+ * Read guest memory into a buffer.
+ */
+void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size);
+
+/**
+ * qtest_memwrite:
+ * @s: QTestState instance to operate on.
+ * @addr: Guest address to write to.
+ * @data: Pointer to the bytes that will be written to guest memory.
+ * @size: Number of bytes to write.
+ *
+ * Write a buffer to guest memory.
+ */
+void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size);
+
+/**
+ * qtest_clock_step_next:
+ * @s: QTestState instance to operate on.
+ *
+ * Advance the vm_clock to the next deadline.  Return the current
+ * value of the vm_clock in nanoseconds.
+ */
+int64_t qtest_clock_step_next(QTestState *s);
+
+/**
+ * qtest_clock_step:
+ * @s: QTestState instance to operate on.
+ * @step: Number of nanoseconds to advance the clock by.
+ *
+ * Advance the vm_clock by @step nanoseconds.  Return the current
+ * value of the vm_clock in nanoseconds.
+ */
+int64_t qtest_clock_step(QTestState *s, int64_t step);
+
+/**
+ * qtest_clock_set:
+ * @s: QTestState instance to operate on.
+ * @val: Nanoseconds value to advance the clock to.
+ *
+ * Advance the vm_clock to @val nanoseconds since the VM was launched.
+ * Return the current value of the vm_clock in nanoseconds.
+ */
+int64_t qtest_clock_set(QTestState *s, int64_t val);
+
+/**
+ * qtest_get_arch:
+ *
+ * Returns the architecture for the QEMU executable under test.
+ */
+const char *qtest_get_arch(void);
+
+/**
+ * qtest_add_func:
+ * @str: Test case path.
+ * @fn: Test case function
+ *
+ * Add a GTester testcase with the given name and function.
+ * The path is prefixed with the architecture under test, as
+ * returned by qtest_get_arch.
+ */
+void qtest_add_func(const char *str, void (*fn));
+
+/**
+ * qtest_start:
+ * @args: other arguments to pass to QEMU
+ *
+ * Start QEMU and assign the resulting QTestState to a global variable.
+ * The global variable is used by "shortcut" macros documented below.
+ */
+#define qtest_start(args) (            \
+    global_qtest = qtest_init((args)) \
+        )
+
+/**
+ * get_irq:
+ * @num: Interrupt to observe.
+ *
+ * Return the level of the @num interrupt.
+ */
+#define get_irq(num) qtest_get_irq(global_qtest, num)
+
+/**
+ * irq_intercept_in:
+ * @string: QOM path of a device.
+ *
+ * Associate qtest irqs with the GPIO-in pins of the device
+ * whose path is specified by @string.
+ */
+#define irq_intercept_in(string) qtest_irq_intercept_in(global_qtest, string)
+
+/**
+ * qtest_irq_intercept_out:
+ * @string: QOM path of a device.
+ *
+ * Associate qtest irqs with the GPIO-out pins of the device
+ * whose path is specified by @string.
+ */
+#define irq_intercept_out(string) qtest_irq_intercept_out(global_qtest, string)
+
+/**
+ * outb:
+ * @addr: I/O port to write to.
+ * @value: Value being written.
+ *
+ * Write an 8-bit value to an I/O port.
+ */
+#define outb(addr, val) qtest_outb(global_qtest, addr, val)
+
+/**
+ * outw:
+ * @addr: I/O port to write to.
+ * @value: Value being written.
+ *
+ * Write a 16-bit value to an I/O port.
+ */
+#define outw(addr, val) qtest_outw(global_qtest, addr, val)
+
+/**
+ * outl:
+ * @addr: I/O port to write to.
+ * @value: Value being written.
+ *
+ * Write a 32-bit value to an I/O port.
+ */
+#define outl(addr, val) qtest_outl(global_qtest, addr, val)
+
+/**
+ * inb:
+ * @addr: I/O port to read from.
+ * @value: Value being written.
+ *
+ * Returns an 8-bit value from an I/O port.
+ */
+#define inb(addr) qtest_inb(global_qtest, addr)
+
+/**
+ * inw:
+ * @addr: I/O port to read from.
+ * @value: Value being written.
+ *
+ * Returns a 16-bit value from an I/O port.
+ */
+#define inw(addr) qtest_inw(global_qtest, addr)
+
+/**
+ * inl:
+ * @addr: I/O port to read from.
+ * @value: Value being written.
+ *
+ * Returns a 32-bit value from an I/O port.
+ */
+#define inl(addr) qtest_inl(global_qtest, addr)
+
+/**
+ * memread:
+ * @addr: Guest address to read from.
+ * @data: Pointer to where memory contents will be stored.
+ * @size: Number of bytes to read.
+ *
+ * Read guest memory into a buffer.
+ */
+#define memread(addr, data, size) qtest_memread(global_qtest, addr, data, size)
+
+/**
+ * memwrite:
+ * @addr: Guest address to write to.
+ * @data: Pointer to the bytes that will be written to guest memory.
+ * @size: Number of bytes to write.
+ *
+ * Write a buffer to guest memory.
+ */
+#define memwrite(addr, data, size) qtest_memwrite(global_qtest, addr, data, size)
+
+/**
+ * clock_step_next:
+ *
+ * Advance the vm_clock to the next deadline.  Return the current
+ * value of the vm_clock in nanoseconds.
+ */
+#define clock_step_next() qtest_clock_step_next(global_qtest)
+
+/**
+ * clock_step:
+ * @step: Number of nanoseconds to advance the clock by.
+ *
+ * Advance the vm_clock by @step nanoseconds.  Return the current
+ * value of the vm_clock in nanoseconds.
+ */
+#define clock_step(step) qtest_clock_step(global_qtest, step)
+
+/**
+ * clock_set:
+ * @val: Nanoseconds value to advance the clock to.
+ *
+ * Advance the vm_clock to @val nanoseconds since the VM was launched.
+ * Return the current value of the vm_clock in nanoseconds.
+ */
+#define clock_set(val) qtest_clock_set(global_qtest, val)
+
+#endif
diff --git a/tests/rtc-test.c b/tests/rtc-test.c
new file mode 100644
index 0000000000..983a980bab
--- /dev/null
+++ b/tests/rtc-test.c
@@ -0,0 +1,263 @@
+/*
+ * QTest testcase for the MC146818 real-time clock
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include "libqtest.h"
+#include "hw/mc146818rtc_regs.h"
+
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static uint8_t base = 0x70;
+
+static int bcd2dec(int value)
+{
+    return (((value >> 4) & 0x0F) * 10) + (value & 0x0F);
+}
+
+static int dec2bcd(int value)
+{
+    return ((value / 10) << 4) | (value % 10);
+}
+
+static uint8_t cmos_read(uint8_t reg)
+{
+    outb(base + 0, reg);
+    return inb(base + 1);
+}
+
+static void cmos_write(uint8_t reg, uint8_t val)
+{
+    outb(base + 0, reg);
+    outb(base + 1, val);
+}
+
+static int tm_cmp(struct tm *lhs, struct tm *rhs)
+{
+    time_t a, b;
+    struct tm d1, d2;
+
+    memcpy(&d1, lhs, sizeof(d1));
+    memcpy(&d2, rhs, sizeof(d2));
+
+    a = mktime(&d1);
+    b = mktime(&d2);
+
+    if (a < b) {
+        return -1;
+    } else if (a > b) {
+        return 1;
+    }
+
+    return 0;
+}
+
+#if 0
+static void print_tm(struct tm *tm)
+{
+    printf("%04d-%02d-%02d %02d:%02d:%02d\n",
+           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+           tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_gmtoff);
+}
+#endif
+
+static void cmos_get_date_time(struct tm *date)
+{
+    int base_year = 2000, hour_offset;
+    int sec, min, hour, mday, mon, year;
+    time_t ts;
+    struct tm dummy;
+
+    sec = cmos_read(RTC_SECONDS);
+    min = cmos_read(RTC_MINUTES);
+    hour = cmos_read(RTC_HOURS);
+    mday = cmos_read(RTC_DAY_OF_MONTH);
+    mon = cmos_read(RTC_MONTH);
+    year = cmos_read(RTC_YEAR);
+
+    if ((cmos_read(RTC_REG_B) & REG_B_DM) == 0) {
+        sec = bcd2dec(sec);
+        min = bcd2dec(min);
+        hour = bcd2dec(hour);
+        mday = bcd2dec(mday);
+        mon = bcd2dec(mon);
+        year = bcd2dec(year);
+        hour_offset = 80;
+    } else {
+        hour_offset = 0x80;
+    }
+
+    if ((cmos_read(0x0B) & REG_B_24H) == 0) {
+        if (hour >= hour_offset) {
+            hour -= hour_offset;
+            hour += 12;
+        }
+    }
+
+    ts = time(NULL);
+    localtime_r(&ts, &dummy);
+
+    date->tm_isdst = dummy.tm_isdst;
+    date->tm_sec = sec;
+    date->tm_min = min;
+    date->tm_hour = hour;
+    date->tm_mday = mday;
+    date->tm_mon = mon - 1;
+    date->tm_year = base_year + year - 1900;
+    date->tm_gmtoff = 0;
+
+    ts = mktime(date);
+}
+
+static void check_time(int wiggle)
+{
+    struct tm start, date[4], end;
+    struct tm *datep;
+    time_t ts;
+
+    /*
+     * This check assumes a few things.  First, we cannot guarantee that we get
+     * a consistent reading from the wall clock because we may hit an edge of
+     * the clock while reading.  To work around this, we read four clock readings
+     * such that at least two of them should match.  We need to assume that one
+     * reading is corrupt so we need four readings to ensure that we have at
+     * least two consecutive identical readings
+     *
+     * It's also possible that we'll cross an edge reading the host clock so
+     * simply check to make sure that the clock reading is within the period of
+     * when we expect it to be.
+     */
+
+    ts = time(NULL);
+    gmtime_r(&ts, &start);
+
+    cmos_get_date_time(&date[0]);
+    cmos_get_date_time(&date[1]);
+    cmos_get_date_time(&date[2]);
+    cmos_get_date_time(&date[3]);
+
+    ts = time(NULL);
+    gmtime_r(&ts, &end);
+
+    if (tm_cmp(&date[0], &date[1]) == 0) {
+        datep = &date[0];
+    } else if (tm_cmp(&date[1], &date[2]) == 0) {
+        datep = &date[1];
+    } else if (tm_cmp(&date[2], &date[3]) == 0) {
+        datep = &date[2];
+    } else {
+        g_assert_not_reached();
+    }
+
+    if (!(tm_cmp(&start, datep) <= 0 && tm_cmp(datep, &end) <= 0)) {
+        long t, s;
+
+        start.tm_isdst = datep->tm_isdst;
+
+        t = (long)mktime(datep);
+        s = (long)mktime(&start);
+        if (t < s) {
+            g_test_message("RTC is %ld second(s) behind wall-clock\n", (s - t));
+        } else {
+            g_test_message("RTC is %ld second(s) ahead of wall-clock\n", (t - s));
+        }
+
+        g_assert_cmpint(ABS(t - s), <=, wiggle);
+    }
+}
+
+static int wiggle = 2;
+
+static void bcd_check_time(void)
+{
+    /* Set BCD mode */
+    cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_DM);
+    check_time(wiggle);
+}
+
+static void dec_check_time(void)
+{
+    /* Set DEC mode */
+    cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) | REG_B_DM);
+    check_time(wiggle);
+}
+
+static void set_alarm_time(struct tm *tm)
+{
+    int sec;
+
+    sec = tm->tm_sec;
+
+    if ((cmos_read(RTC_REG_B) & REG_B_DM) == 0) {
+        sec = dec2bcd(sec);
+    }
+
+    cmos_write(RTC_SECONDS_ALARM, sec);
+    cmos_write(RTC_MINUTES_ALARM, RTC_ALARM_DONT_CARE);
+    cmos_write(RTC_HOURS_ALARM, RTC_ALARM_DONT_CARE);
+}
+
+static void alarm_time(void)
+{
+    struct tm now;
+    time_t ts;
+    int i;
+
+    ts = time(NULL);
+    gmtime_r(&ts, &now);
+
+    /* set DEC mode */
+    cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) | REG_B_DM);
+
+    g_assert(!get_irq(RTC_ISA_IRQ));
+    cmos_read(RTC_REG_C);
+
+    now.tm_sec = (now.tm_sec + 2) % 60;
+    set_alarm_time(&now);
+    cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) | REG_B_AIE);
+
+    for (i = 0; i < 2 + wiggle; i++) {
+        if (get_irq(RTC_ISA_IRQ)) {
+            break;
+        }
+
+        clock_step(1000000000);
+    }
+
+    g_assert(get_irq(RTC_ISA_IRQ));
+    g_assert((cmos_read(RTC_REG_C) & REG_C_AF) != 0);
+    g_assert(cmos_read(RTC_REG_C) == 0);
+}
+
+int main(int argc, char **argv)
+{
+    QTestState *s = NULL;
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    s = qtest_start("-display none -rtc clock=vm");
+    qtest_irq_intercept_in(s, "ioapic");
+
+    qtest_add_func("/rtc/bcd/check-time", bcd_check_time);
+    qtest_add_func("/rtc/dec/check-time", dec_check_time);
+    qtest_add_func("/rtc/alarm-time", alarm_time);
+    ret = g_test_run();
+
+    if (s) {
+        qtest_quit(s);
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/lm32/Makefile b/tests/tcg/lm32/Makefile
index 03a1abbcfb..9a00ef7ea9 100644
--- a/tests/tcg/lm32/Makefile
+++ b/tests/tcg/lm32/Makefile
@@ -1,4 +1,4 @@
--include ../../config-host.mak
+-include ../../../config-host.mak
 
 CROSS=lm32-elf-
 
@@ -12,7 +12,10 @@ SIZE    = $(CROSS)size
 LD      = $(CC)
 OBJCOPY = $(CROSS)objcopy
 
-LDFLAGS = -Tlinker.ld
+TSRC_PATH = $(SRC_PATH)/tests/tcg/lm32
+
+LDFLAGS = -T$(TSRC_PATH)/linker.ld
+ASFLAGS += -Wa,-I,$(TSRC_PATH)/
 
 CRT        = crt.o
 TESTCASES += test_add.tst
@@ -82,13 +85,13 @@ TESTCASES += test_xori.tst
 
 all: build
 
-%.o: $(SRC_PATH)/tests/lm32/%.c
+%.o: $(TSRC_PATH)/%.c
 	$(CC) $(CFLAGS) -c $< -o $@
 
-%.o: $(SRC_PATH)/tests/lm32/%.S
+%.o: $(TSRC_PATH)/%.S
 	$(AS) $(ASFLAGS) -c $< -o $@
 
-%.tst: %.o macros.inc $(CRT)
+%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT)
 	$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@
 
 build: $(CRT) $(TESTCASES)
diff --git a/test-coroutine.c b/tests/test-coroutine.c
index e5d14eb696..e5d14eb696 100644
--- a/test-coroutine.c
+++ b/tests/test-coroutine.c
diff --git a/test-qmp-commands.c b/tests/test-qmp-commands.c
index fa5a7bd8dc..60cbf019bb 100644
--- a/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -46,7 +46,6 @@ static void test_dispatch_cmd(void)
     resp = qmp_dispatch(QOBJECT(req));
     assert(resp != NULL);
     assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
-    g_print("\nresp: %s\n", qstring_get_str(qobject_to_json(resp)));
 
     qobject_decref(resp);
     QDECREF(req);
@@ -63,7 +62,6 @@ static void test_dispatch_cmd_error(void)
     resp = qmp_dispatch(QOBJECT(req));
     assert(resp != NULL);
     assert(qdict_haskey(qobject_to_qdict(resp), "error"));
-    g_print("\nresp: %s\n", qstring_get_str(qobject_to_json_pretty(resp)));
 
     qobject_decref(resp);
     QDECREF(req);
@@ -92,7 +90,6 @@ static void test_dispatch_cmd_io(void)
     resp = qmp_dispatch(QOBJECT(req));
     assert(resp != NULL);
     assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
-    g_print("\nresp: %s\n", qstring_get_str(qobject_to_json_pretty(resp)));
 
     qobject_decref(resp);
     QDECREF(req);
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
new file mode 100644
index 0000000000..f6df8cbe1e
--- /dev/null
+++ b/tests/test-qmp-input-strict.c
@@ -0,0 +1,234 @@
+/*
+ * QMP Input Visitor unit-tests (strict mode).
+ *
+ * Copyright (C) 2011-2012 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *  Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <stdarg.h>
+
+#include "qapi/qmp-input-visitor.h"
+#include "test-qapi-types.h"
+#include "test-qapi-visit.h"
+#include "qemu-objects.h"
+
+typedef struct TestInputVisitorData {
+    QObject *obj;
+    QmpInputVisitor *qiv;
+} TestInputVisitorData;
+
+static void validate_teardown(TestInputVisitorData *data,
+                               const void *unused)
+{
+    qobject_decref(data->obj);
+    data->obj = NULL;
+
+    if (data->qiv) {
+        qmp_input_visitor_cleanup(data->qiv);
+        data->qiv = NULL;
+    }
+}
+
+/* This is provided instead of a test setup function so that the JSON
+   string used by the tests are kept in the test functions (and not
+   int main()) */
+static GCC_FMT_ATTR(2, 3)
+Visitor *validate_test_init(TestInputVisitorData *data,
+                             const char *json_string, ...)
+{
+    Visitor *v;
+    va_list ap;
+
+    va_start(ap, json_string);
+    data->obj = qobject_from_jsonv(json_string, &ap);
+    va_end(ap);
+
+    g_assert(data->obj != NULL);
+
+    data->qiv = qmp_input_visitor_new_strict(data->obj);
+    g_assert(data->qiv != NULL);
+
+    v = qmp_input_get_visitor(data->qiv);
+    g_assert(v != NULL);
+
+    return v;
+}
+
+typedef struct TestStruct
+{
+    int64_t integer;
+    bool boolean;
+    char *string;
+} TestStruct;
+
+static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
+                                  const char *name, Error **errp)
+{
+    visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
+                       errp);
+
+    visit_type_int(v, &(*obj)->integer, "integer", errp);
+    visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
+    visit_type_str(v, &(*obj)->string, "string", errp);
+
+    visit_end_struct(v, errp);
+}
+
+static void test_validate_struct(TestInputVisitorData *data,
+                                  const void *unused)
+{
+    TestStruct *p = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
+
+    visit_type_TestStruct(v, &p, NULL, &errp);
+    g_assert(!error_is_set(&errp));
+    g_free(p->string);
+    g_free(p);
+}
+
+static void test_validate_struct_nested(TestInputVisitorData *data,
+                                         const void *unused)
+{
+    UserDefNested *udp = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
+
+    visit_type_UserDefNested(v, &udp, NULL, &errp);
+    g_assert(!error_is_set(&errp));
+    qapi_free_UserDefNested(udp);
+}
+
+static void test_validate_list(TestInputVisitorData *data,
+                                const void *unused)
+{
+    UserDefOneList *head = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
+
+    visit_type_UserDefOneList(v, &head, NULL, &errp);
+    g_assert(!error_is_set(&errp));
+    qapi_free_UserDefOneList(head);
+}
+
+static void test_validate_union(TestInputVisitorData *data,
+                                 const void *unused)
+{
+    UserDefUnion *tmp = NULL;
+    Visitor *v;
+    Error *errp = NULL;
+
+    v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
+
+    visit_type_UserDefUnion(v, &tmp, NULL, &errp);
+    g_assert(!error_is_set(&errp));
+    qapi_free_UserDefUnion(tmp);
+}
+
+static void test_validate_fail_struct(TestInputVisitorData *data,
+                                       const void *unused)
+{
+    TestStruct *p = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
+
+    visit_type_TestStruct(v, &p, NULL, &errp);
+    g_assert(error_is_set(&errp));
+    if (p) {
+        g_free(p->string);
+    }
+    g_free(p);
+}
+
+static void test_validate_fail_struct_nested(TestInputVisitorData *data,
+                                              const void *unused)
+{
+    UserDefNested *udp = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
+
+    visit_type_UserDefNested(v, &udp, NULL, &errp);
+    g_assert(error_is_set(&errp));
+    qapi_free_UserDefNested(udp);
+}
+
+static void test_validate_fail_list(TestInputVisitorData *data,
+                                     const void *unused)
+{
+    UserDefOneList *head = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
+
+    visit_type_UserDefOneList(v, &head, NULL, &errp);
+    g_assert(error_is_set(&errp));
+    qapi_free_UserDefOneList(head);
+}
+
+static void test_validate_fail_union(TestInputVisitorData *data,
+                                      const void *unused)
+{
+    UserDefUnion *tmp = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 }, 'extra': 'yyy' }");
+
+    visit_type_UserDefUnion(v, &tmp, NULL, &errp);
+    g_assert(error_is_set(&errp));
+    qapi_free_UserDefUnion(tmp);
+}
+
+static void validate_test_add(const char *testpath,
+                               TestInputVisitorData *data,
+                               void (*test_func)(TestInputVisitorData *data, const void *user_data))
+{
+    g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
+               validate_teardown);
+}
+
+int main(int argc, char **argv)
+{
+    TestInputVisitorData testdata;
+
+    g_test_init(&argc, &argv, NULL);
+
+    validate_test_add("/visitor/input-strict/pass/struct",
+                       &testdata, test_validate_struct);
+    validate_test_add("/visitor/input-strict/pass/struct-nested",
+                       &testdata, test_validate_struct_nested);
+    validate_test_add("/visitor/input-strict/pass/list",
+                       &testdata, test_validate_list);
+    validate_test_add("/visitor/input-strict/pass/union",
+                       &testdata, test_validate_union);
+    validate_test_add("/visitor/input-strict/fail/struct",
+                       &testdata, test_validate_fail_struct);
+    validate_test_add("/visitor/input-strict/fail/struct-nested",
+                       &testdata, test_validate_fail_struct_nested);
+    validate_test_add("/visitor/input-strict/fail/list",
+                       &testdata, test_validate_fail_list);
+    validate_test_add("/visitor/input-strict/fail/union",
+                       &testdata, test_validate_fail_union);
+
+    g_test_run();
+
+    return 0;
+}
diff --git a/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 1996e49576..c30fdc4e59 100644
--- a/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -258,6 +258,23 @@ static void input_visitor_test_add(const char *testpath,
                visitor_input_teardown);
 }
 
+static void test_visitor_in_errors(TestInputVisitorData *data,
+                                   const void *unused)
+{
+    TestStruct *p = NULL;
+    Error *errp = NULL;
+    Visitor *v;
+
+    v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");
+
+    visit_type_TestStruct(v, &p, NULL, &errp);
+    g_assert(error_is_set(&errp));
+    g_assert(p->string == NULL);
+
+    g_free(p->string);
+    g_free(p);
+}
+
 int main(int argc, char **argv)
 {
     TestInputVisitorData in_visitor_data;
@@ -282,6 +299,8 @@ int main(int argc, char **argv)
                             &in_visitor_data, test_visitor_in_list);
     input_visitor_test_add("/visitor/input/union",
                             &in_visitor_data, test_visitor_in_union);
+    input_visitor_test_add("/visitor/input/errors",
+                            &in_visitor_data, test_visitor_in_errors);
 
     g_test_run();
 
diff --git a/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 4d6c4d4420..24a6359504 100644
--- a/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -274,6 +274,24 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
     qapi_free_UserDefNested(ud2);
 }
 
+static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
+                                           const void *unused)
+{
+    EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
+    UserDefOne u = { 0 }, *pu = &u;
+    Error *errp;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
+        errp = NULL;
+        u.has_enum1 = true;
+        u.enum1 = bad_values[i];
+        visit_type_UserDefOne(data->ov, &pu, "unused", &errp);
+        g_assert(error_is_set(&errp) == true);
+        error_free(errp);
+    }
+}
+
 typedef struct TestStructList
 {
     TestStruct *value;
@@ -444,6 +462,8 @@ int main(int argc, char **argv)
                             &out_visitor_data, test_visitor_out_struct);
     output_visitor_test_add("/visitor/output/struct-nested",
                             &out_visitor_data, test_visitor_out_struct_nested);
+    output_visitor_test_add("/visitor/output/struct-errors",
+                            &out_visitor_data, test_visitor_out_struct_errors);
     output_visitor_test_add("/visitor/output/list",
                             &out_visitor_data, test_visitor_out_list);
     output_visitor_test_add("/visitor/output/list-qapi-free",
diff --git a/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index 5370e32041..5370e32041 100644
--- a/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
diff --git a/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 22909b84ef..22909b84ef 100644
--- a/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
diff --git a/thunk.c b/thunk.c
index 06571889ae..8ebbbb46b6 100644
--- a/thunk.c
+++ b/thunk.c
@@ -46,6 +46,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
     case TYPE_LONG:
     case TYPE_ULONG:
     case TYPE_PTRVOID:
+    case TYPE_OLDDEVT:
         return type_ptr;
     case TYPE_PTR:
         return thunk_type_next_ptr(type_ptr);
@@ -188,6 +189,33 @@ const argtype *thunk_convert(void *dst, const void *src,
 #else
 #warning unsupported conversion
 #endif
+    case TYPE_OLDDEVT:
+    {
+        uint64_t val = 0;
+        switch (thunk_type_size(type_ptr - 1, !to_host)) {
+        case 2:
+            val = *(uint16_t *)src;
+            break;
+        case 4:
+            val = *(uint32_t *)src;
+            break;
+        case 8:
+            val = *(uint64_t *)src;
+            break;
+        }
+        switch (thunk_type_size(type_ptr - 1, to_host)) {
+        case 2:
+            *(uint16_t *)dst = tswap16(val);
+            break;
+        case 4:
+            *(uint32_t *)dst = tswap32(val);
+            break;
+        case 8:
+            *(uint64_t *)dst = tswap64(val);
+            break;
+        }
+        break;
+    }
     case TYPE_ARRAY:
         {
             int array_length, i, dst_size, src_size;
diff --git a/thunk.h b/thunk.h
index 9810743191..5be8f912f5 100644
--- a/thunk.h
+++ b/thunk.h
@@ -37,6 +37,7 @@ typedef enum argtype {
     TYPE_PTR,
     TYPE_ARRAY,
     TYPE_STRUCT,
+    TYPE_OLDDEVT,
 } argtype;
 
 #define MK_PTR(type) TYPE_PTR, type
@@ -104,6 +105,31 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
             return TARGET_ABI_BITS / 8;
         }
         break;
+    case TYPE_OLDDEVT:
+        if (is_host) {
+#if defined(HOST_X86_64)
+            return 8;
+#elif defined(HOST_ALPHA) || defined(HOST_IA64) || defined(HOST_MIPS) || \
+      defined(HOST_PARISC) || defined(HOST_SPARC64)
+            return 4;
+#elif defined(HOST_PPC)
+            return HOST_LONG_SIZE;
+#else
+            return 2;
+#endif
+        } else {
+#if defined(TARGET_X86_64)
+            return 8;
+#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \
+      defined(TARGET_PARISC) || defined(TARGET_SPARC64)
+            return 4;
+#elif defined(TARGET_PPC)
+            return TARGET_ABI_BITS / 8;
+#else
+            return 2;
+#endif
+        }
+        break;
     case TYPE_ARRAY:
         size = type_ptr[1];
         return size * thunk_type_size_array(type_ptr + 2, is_host);
@@ -141,6 +167,8 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
             return TARGET_ABI_BITS / 8;
         }
         break;
+    case TYPE_OLDDEVT:
+        return thunk_type_size(type_ptr, is_host);
     case TYPE_ARRAY:
         return thunk_type_align_array(type_ptr + 2, is_host);
     case TYPE_STRUCT:
diff --git a/trace-events b/trace-events
index c8317a0fa5..db2cd39950 100644
--- a/trace-events
+++ b/trace-events
@@ -722,3 +722,69 @@ displaysurface_resize(void *display_state, void *display_surface, int width, int
 
 # vga.c
 ppm_save(const char *filename, void *display_surface) "%s surface=%p"
+
+# hw/qxl.c
+disable qxl_interface_set_mm_time(int qid, uint32_t mm_time) "%d %d"
+disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
+qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position) "%d %ux%u mem=%" PRIx64 " %u,%u"
+qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags) "%d %d,%d,%d"
+qxl_destroy_primary(int qid) "%d"
+qxl_enter_vga_mode(int qid) "%d"
+qxl_exit_vga_mode(int qid) "%d"
+qxl_hard_reset(int qid, int64_t loadvm) "%d loadvm=%"PRId64""
+qxl_interface_async_complete_io(int qid, uint32_t current_async, void *cookie) "%d current=%d cookie=%p"
+qxl_interface_attach_worker(int qid) "%d"
+qxl_interface_get_init_info(int qid) "%d"
+qxl_interface_set_compression_level(int qid, int64_t level) "%d %"PRId64
+qxl_interface_update_area_complete(int qid, uint32_t surface_id, uint32_t dirty_left, uint32_t dirty_right, uint32_t dirty_top, uint32_t dirty_bottom) "%d surface=%d [%d,%d,%d,%d]"
+qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d #=%d"
+qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
+qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
+qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
+qxl_io_read_unexpected(int qid) "%d"
+qxl_io_unexpected_vga_mode(int qid, uint32_t io_port, const char *desc) "%d 0x%x (%s)"
+qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d"
+qxl_memslot_add_guest(int qid, uint32_t slot_id, uint64_t guest_start, uint64_t guest_end) "%d %u: guest phys 0x%"PRIx64 " - 0x%" PRIx64
+qxl_post_load(int qid, const char *mode) "%d %s"
+qxl_pre_load(int qid) "%d"
+qxl_pre_save(int qid) "%d"
+qxl_reset_surfaces(int qid) "%d"
+qxl_ring_command_check(int qid, const char *mode) "%d %s"
+qxl_ring_command_get(int qid, const char *mode) "%d %s"
+qxl_ring_command_req_notification(int qid) "%d"
+qxl_ring_cursor_check(int qid, const char *mode) "%d %s"
+qxl_ring_cursor_get(int qid, const char *mode) "%d %s"
+qxl_ring_cursor_req_notification(int qid) "%d"
+qxl_ring_res_push(int qid, const char *mode, uint32_t surface_count, uint32_t free_res, void *last_release, const char *notify) "%d %s s#=%d res#=%d last=%p notify=%s"
+qxl_ring_res_push_rest(int qid, uint32_t ring_has, uint32_t ring_size, uint32_t prod, uint32_t cons) "%d ring %d/%d [%d,%d]"
+qxl_ring_res_put(int qid, uint32_t free_res) "%d #res=%d"
+qxl_set_mode(int qid, int modenr, uint32_t x_res, uint32_t y_res, uint32_t bits, uint64_t devmem) "%d mode=%d [ x=%d y=%d @ bpp=%d devmem=0x%" PRIx64 " ]"
+qxl_soft_reset(int qid) "%d"
+qemu_spice_add_memslot(int qid, uint32_t slot_id, unsigned long virt_start, unsigned long virt_end, int async) "%d %u: host virt 0x%lx - 0x%lx async=%d"
+qemu_spice_del_memslot(int qid, uint32_t gid, uint32_t slot_id) "%d gid=%u sid=%u"
+qemu_spice_create_primary_surface(int qid, uint32_t sid, void *surface, int async) "%d sid=%u surface=%p async=%d"
+qemu_spice_destroy_primary_surface(int qid, uint32_t sid, int async) "%d sid=%u async=%d"
+qemu_spice_wakeup(uint32_t qid) "%d"
+qemu_spice_start(uint32_t qid) "%d"
+qemu_spice_stop(uint32_t qid) "%d"
+qemu_spice_create_update(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "lr %d -> %d,  tb -> %d -> %d"
+qxl_spice_destroy_surfaces_complete(int qid) "%d"
+qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
+qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id) "%d sid=%d"
+qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async) "%d sid=%d async=%d"
+qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res) "%d s#=%d, res#=%d"
+qxl_spice_loadvm_commands(int qid, void *ext, uint32_t count) "%d ext=%p count=%d"
+qxl_spice_oom(int qid) "%d"
+qxl_spice_reset_cursor(int qid) "%d"
+qxl_spice_reset_image_cache(int qid) "%d"
+qxl_spice_reset_memslots(int qid) "%d"
+qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
+qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
+qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
+qxl_vga_ioport_while_not_in_vga_mode(int qid) "%d (int qid, reset to VGA mode because of VGA io)"
+
+# hw/qxl-render.c
+qxl_render_blit_guest_primary_initialized(void) ""
+qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom) "stride=%d [%d, %d, %d, %d]"
+qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp) "%dx%d, stride %d, bpp %d, depth %d"
+qxl_render_update_area_done(void *cookie) "%p"
diff --git a/translate-all.c b/translate-all.c
index 8c7d303d86..5bd2d3711a 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -109,11 +109,11 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr
 /* The cpu state corresponding to 'searched_pc' is restored.
  */
 int cpu_restore_state(TranslationBlock *tb,
-                      CPUArchState *env, unsigned long searched_pc)
+                      CPUArchState *env, uintptr_t searched_pc)
 {
     TCGContext *s = &tcg_ctx;
     int j;
-    unsigned long tc_ptr;
+    uintptr_t tc_ptr;
 #ifdef CONFIG_PROFILER
     int64_t ti;
 #endif
@@ -133,7 +133,7 @@ int cpu_restore_state(TranslationBlock *tb,
     }
 
     /* find opc index corresponding to search_pc */
-    tc_ptr = (unsigned long)tb->tc_ptr;
+    tc_ptr = (uintptr_t)tb->tc_ptr;
     if (searched_pc < tc_ptr)
         return -1;
 
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 0711205cbe..e7d6e898ee 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -772,7 +772,7 @@ QemuCocoaView *cocoaView;
               modalForWindow:normalWindow modalDelegate:self
               didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
     } else {
-        // or Launch Qemu, with the global args
+        // or launch QEMU, with the global args
         [self startEmulationWithArgc:gArgc argv:(char **)gArgv];
     }
 }
diff --git a/ui/spice-core.c b/ui/spice-core.c
index c1091e1602..a468524799 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -19,6 +19,7 @@
 #include <spice-experimental.h>
 
 #include <netdb.h>
+#include "sysemu.h"
 
 #include "qemu-common.h"
 #include "qemu-spice.h"
@@ -553,7 +554,7 @@ void qemu_spice_init(void)
 
     qemu_thread_get_self(&me);
 
-   if (!opts) {
+    if (!opts) {
         return;
     }
     port = qemu_opt_get_number(opts, "port", 0);
@@ -688,6 +689,11 @@ void qemu_spice_init(void)
 
     qemu_opt_foreach(opts, add_channel, &tls_port, 0);
 
+#if SPICE_SERVER_VERSION >= 0x000a02 /* 0.10.2 */
+    spice_server_set_name(spice_server, qemu_name);
+    spice_server_set_uuid(spice_server, qemu_uuid);
+#endif
+
     if (0 != spice_server_init(spice_server, &core_interface)) {
         error_report("failed to initialize spice server");
         exit(1);
@@ -781,10 +787,3 @@ static void spice_register_config(void)
     qemu_add_opts(&qemu_spice_opts);
 }
 machine_init(spice_register_config);
-
-static void spice_register_types(void)
-{
-    qemu_spice_init();
-}
-
-type_init(spice_register_types)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index ab266aedc1..5418eb3c7c 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -22,6 +22,7 @@
 #include "monitor.h"
 #include "console.h"
 #include "sysemu.h"
+#include "trace.h"
 
 #include "spice-display.h"
 
@@ -73,10 +74,14 @@ QXLCookie *qxl_cookie_new(int type, uint64_t io)
 void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
                             qxl_async_io async)
 {
+    trace_qemu_spice_add_memslot(ssd->qxl.id, memslot->slot_id,
+                                memslot->virt_start, memslot->virt_end,
+                                async);
+
     if (async != QXL_SYNC) {
         spice_qxl_add_memslot_async(&ssd->qxl, memslot,
-                (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
-                                         QXL_IO_MEMSLOT_ADD_ASYNC));
+                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+                                          QXL_IO_MEMSLOT_ADD_ASYNC));
     } else {
         ssd->worker->add_memslot(ssd->worker, memslot);
     }
@@ -84,6 +89,7 @@ void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
 
 void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
 {
+    trace_qemu_spice_del_memslot(ssd->qxl.id, gid, sid);
     ssd->worker->del_memslot(ssd->worker, gid, sid);
 }
 
@@ -91,23 +97,24 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
                                        QXLDevSurfaceCreate *surface,
                                        qxl_async_io async)
 {
+    trace_qemu_spice_create_primary_surface(ssd->qxl.id, id, surface, async);
     if (async != QXL_SYNC) {
         spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface,
-                (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
-                                         QXL_IO_CREATE_PRIMARY_ASYNC));
+                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+                                          QXL_IO_CREATE_PRIMARY_ASYNC));
     } else {
         ssd->worker->create_primary_surface(ssd->worker, id, surface);
     }
 }
 
-
 void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
                                         uint32_t id, qxl_async_io async)
 {
+    trace_qemu_spice_destroy_primary_surface(ssd->qxl.id, id, async);
     if (async != QXL_SYNC) {
         spice_qxl_destroy_primary_surface_async(&ssd->qxl, id,
-                (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
-                                         QXL_IO_DESTROY_PRIMARY_ASYNC));
+                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+                                          QXL_IO_DESTROY_PRIMARY_ASYNC));
     } else {
         ssd->worker->destroy_primary_surface(ssd->worker, id);
     }
@@ -115,16 +122,19 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
 
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
 {
+    trace_qemu_spice_wakeup(ssd->qxl.id);
     ssd->worker->wakeup(ssd->worker);
 }
 
 void qemu_spice_start(SimpleSpiceDisplay *ssd)
 {
+    trace_qemu_spice_start(ssd->qxl.id);
     ssd->worker->start(ssd->worker);
 }
 
 void qemu_spice_stop(SimpleSpiceDisplay *ssd)
 {
+    trace_qemu_spice_stop(ssd->qxl.id);
     ssd->worker->stop(ssd->worker);
 }
 
@@ -142,7 +152,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
         return NULL;
     };
 
-    dprint(2, "%s: lr %d -> %d,  tb -> %d -> %d\n", __FUNCTION__,
+    trace_qemu_spice_create_update(
            ssd->dirty.left, ssd->dirty.right,
            ssd->dirty.top, ssd->dirty.bottom);
 
@@ -158,7 +168,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
     drawable->bbox            = ssd->dirty;
     drawable->clip.type       = SPICE_CLIP_TYPE_NONE;
     drawable->effect          = QXL_EFFECT_OPAQUE;
-    drawable->release_info.id = (intptr_t)update;
+    drawable->release_info.id = (uintptr_t)update;
     drawable->type            = QXL_DRAW_COPY;
     drawable->surfaces_dest[0] = -1;
     drawable->surfaces_dest[1] = -1;
@@ -169,7 +179,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
                       + time_space.tv_nsec / 1000 / 1000;
 
     drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
-    drawable->u.copy.src_bitmap      = (intptr_t)image;
+    drawable->u.copy.src_bitmap      = (uintptr_t)image;
     drawable->u.copy.src_area.right  = bw;
     drawable->u.copy.src_area.bottom = bh;
 
@@ -179,7 +189,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
     image->bitmap.stride     = bw * 4;
     image->descriptor.width  = image->bitmap.x = bw;
     image->descriptor.height = image->bitmap.y = bh;
-    image->bitmap.data = (intptr_t)(update->bitmap);
+    image->bitmap.data = (uintptr_t)(update->bitmap);
     image->bitmap.palette = 0;
     image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
 
@@ -200,7 +210,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
     }
 
     cmd->type = QXL_CMD_DRAW;
-    cmd->data = (intptr_t)drawable;
+    cmd->data = (uintptr_t)drawable;
 
     memset(&ssd->dirty, 0, sizeof(ssd->dirty));
     return update;
@@ -209,7 +219,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
 /*
  * Called from spice server thread context (via interface_release_ressource)
  * We do *not* hold the global qemu mutex here, so extra care is needed
- * when calling qemu functions.  Qemu interfaces used:
+ * when calling qemu functions.  QEMU interfaces used:
  *    - g_free (underlying glibc free is re-entrant).
  */
 void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
@@ -244,7 +254,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
     surface.mouse_mode = true;
     surface.flags      = 0;
     surface.type       = 0;
-    surface.mem        = (intptr_t)ssd->buf;
+    surface.mem        = (uintptr_t)ssd->buf;
     surface.group_id   = MEMSLOT_GROUP_HOST;
 
     qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
index e2045fc0b8..8fba7702c2 100644
--- a/ui/vnc-auth-sasl.c
+++ b/ui/vnc-auth-sasl.c
@@ -31,7 +31,9 @@
 void vnc_sasl_client_cleanup(VncState *vs)
 {
     if (vs->sasl.conn) {
-        vs->sasl.runSSF = vs->sasl.waitWriteSSF = vs->sasl.wantSSF = 0;
+        vs->sasl.runSSF = false;
+        vs->sasl.wantSSF = false;
+        vs->sasl.waitWriteSSF = 0;
         vs->sasl.encodedLength = vs->sasl.encodedOffset = 0;
         vs->sasl.encoded = NULL;
         g_free(vs->sasl.username);
diff --git a/ui/vnc-auth-sasl.h b/ui/vnc-auth-sasl.h
index fd9b18a8fe..ee243a9d64 100644
--- a/ui/vnc-auth-sasl.h
+++ b/ui/vnc-auth-sasl.h
@@ -37,9 +37,9 @@ typedef struct VncDisplaySASL VncDisplaySASL;
 struct VncStateSASL {
     sasl_conn_t *conn;
     /* If we want to negotiate an SSF layer with client */
-    int wantSSF :1;
+    bool wantSSF;
     /* If we are now running the SSF layer */
-    int runSSF :1;
+    bool runSSF;
     /*
      * If this is non-zero, then wait for that many bytes
      * to be written plain, before switching to SSF encoding
diff --git a/vl.c b/vl.c
index bd95539ff7..ae91a8ab01 100644
--- a/vl.c
+++ b/vl.c
@@ -152,6 +152,7 @@ int main(int argc, char **argv)
 #ifdef CONFIG_VIRTFS
 #include "fsdev/qemu-fsdev.h"
 #endif
+#include "qtest.h"
 
 #include "disas.h"
 
@@ -529,6 +530,8 @@ static void configure_rtc(QemuOpts *opts)
     if (value) {
         if (!strcmp(value, "host")) {
             rtc_clock = host_clock;
+        } else if (!strcmp(value, "rt")) {
+            rtc_clock = rt_clock;
         } else if (!strcmp(value, "vm")) {
             rtc_clock = vm_clock;
         } else {
@@ -1312,7 +1315,7 @@ int qemu_shutdown_requested(void)
 
 void qemu_kill_report(void)
 {
-    if (shutdown_signal != -1) {
+    if (!qtest_enabled() && shutdown_signal != -1) {
         fprintf(stderr, "qemu: terminating on signal %d", shutdown_signal);
         if (shutdown_pid == 0) {
             /* This happens for eg ^C at the terminal, so it's worth
@@ -2098,6 +2101,7 @@ static struct {
     { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
     { "xen", "Xen", xen_available, xen_init, &xen_allowed },
     { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
+    { "qtest", "QTest", qtest_available, qtest_init, &qtest_allowed },
 };
 
 static int configure_accelerator(void)
@@ -3099,6 +3103,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_incoming:
                 incoming = optarg;
+                runstate_set(RUN_STATE_INMIGRATE);
                 break;
             case QEMU_OPTION_nodefaults:
                 default_serial = 0;
@@ -3180,6 +3185,12 @@ int main(int argc, char **argv, char **envp)
                     fclose(fp);
                     break;
                 }
+            case QEMU_OPTION_qtest:
+                qtest_chrdev = optarg;
+                break;
+            case QEMU_OPTION_qtest_log:
+                qtest_log = optarg;
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
@@ -3195,7 +3206,7 @@ int main(int argc, char **argv, char **envp)
     cpudef_init();
 
     if (cpu_model && *cpu_model == '?') {
-        list_cpus(stdout, &fprintf, optarg);
+        list_cpus(stdout, &fprintf, cpu_model);
         exit(0);
     }
 
@@ -3369,6 +3380,11 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+#ifdef CONFIG_SPICE
+    /* spice needs the timers to be initialized by this point */
+    qemu_spice_init();
+#endif
+
     if (icount_option && (kvm_enabled() || xen_enabled())) {
         fprintf(stderr, "-icount is not allowed with kvm or xen\n");
         exit(1);
@@ -3611,7 +3627,6 @@ int main(int argc, char **argv, char **envp)
     }
 
     if (incoming) {
-        runstate_set(RUN_STATE_INMIGRATE);
         int ret = qemu_start_incoming_migration(incoming);
         if (ret < 0) {
             fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",
diff --git a/vmstate.h b/vmstate.h
index 9d3c49caca..82d97aead4 100644
--- a/vmstate.h
+++ b/vmstate.h
@@ -28,8 +28,7 @@
 
 typedef void SaveSetParamsHandler(int blk_enable, int shared, void * opaque);
 typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int SaveLiveStateHandler(Monitor *mon, QEMUFile *f, int stage,
-                                 void *opaque);
+typedef int SaveLiveStateHandler(QEMUFile *f, int stage, void *opaque);
 typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
 
 int register_savevm(DeviceState *dev,
diff --git a/xen-all.c b/xen-all.c
index 493112bfda..3e6de417ec 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -65,7 +65,7 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
 typedef struct XenPhysmap {
     target_phys_addr_t start_addr;
     ram_addr_t size;
-    MemoryRegion *mr;
+    char *name;
     target_phys_addr_t phys_offset;
 
     QLIST_ENTRY(XenPhysmap) list;
@@ -190,6 +190,14 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr)
     xen_pfn_t *pfn_list;
     int i;
 
+    if (runstate_check(RUN_STATE_INMIGRATE)) {
+        /* RAM already populated in Xen */
+        fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
+                " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
+                __func__, size, ram_addr); 
+        return;
+    }
+
     if (mr == &ram_memory) {
         return;
     }
@@ -225,6 +233,22 @@ static XenPhysmap *get_physmapping(XenIOState *state,
     return NULL;
 }
 
+static target_phys_addr_t xen_phys_offset_to_gaddr(target_phys_addr_t start_addr,
+                                                   ram_addr_t size, void *opaque)
+{
+    target_phys_addr_t addr = start_addr & TARGET_PAGE_MASK;
+    XenIOState *xen_io_state = opaque;
+    XenPhysmap *physmap = NULL;
+
+    QLIST_FOREACH(physmap, &xen_io_state->physmap, list) {
+        if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
+            return physmap->start_addr;
+        }
+    }
+
+    return start_addr;
+}
+
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
 static int xen_add_to_physmap(XenIOState *state,
                               target_phys_addr_t start_addr,
@@ -237,6 +261,7 @@ static int xen_add_to_physmap(XenIOState *state,
     XenPhysmap *physmap = NULL;
     target_phys_addr_t pfn, start_gpfn;
     target_phys_addr_t phys_offset = memory_region_get_ram_addr(mr);
+    char path[80], value[17];
 
     if (get_physmapping(state, start_addr, size)) {
         return 0;
@@ -275,6 +300,7 @@ go_physmap:
 
     physmap->start_addr = start_addr;
     physmap->size = size;
+    physmap->name = (char *)mr->name;
     physmap->phys_offset = phys_offset;
 
     QLIST_INSERT_HEAD(&state->physmap, physmap, list);
@@ -283,6 +309,30 @@ go_physmap:
                                    start_addr >> TARGET_PAGE_BITS,
                                    (start_addr + size) >> TARGET_PAGE_BITS,
                                    XEN_DOMCTL_MEM_CACHEATTR_WB);
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
+            xen_domid, (uint64_t)phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
+            xen_domid, (uint64_t)phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    if (mr->name) {
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
+                xen_domid, (uint64_t)phys_offset);
+        if (!xs_write(state->xenstore, 0, path, mr->name, strlen(mr->name))) {
+            return -1;
+        }
+    }
+
     return 0;
 }
 
@@ -942,6 +992,55 @@ int xen_init(void)
     return 0;
 }
 
+static void xen_read_physmap(XenIOState *state)
+{
+    XenPhysmap *physmap = NULL;
+    unsigned int len, num, i;
+    char path[80], *value = NULL;
+    char **entries = NULL;
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap", xen_domid);
+    entries = xs_directory(state->xenstore, 0, path, &num);
+    if (entries == NULL)
+        return;
+
+    for (i = 0; i < num; i++) {
+        physmap = g_malloc(sizeof (XenPhysmap));
+        physmap->phys_offset = strtoull(entries[i], NULL, 16);
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/start_addr",
+                xen_domid, entries[i]);
+        value = xs_read(state->xenstore, 0, path, &len);
+        if (value == NULL) {
+            free(physmap);
+            continue;
+        }
+        physmap->start_addr = strtoull(value, NULL, 16);
+        free(value);
+
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/size",
+                xen_domid, entries[i]);
+        value = xs_read(state->xenstore, 0, path, &len);
+        if (value == NULL) {
+            free(physmap);
+            continue;
+        }
+        physmap->size = strtoull(value, NULL, 16);
+        free(value);
+
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/name",
+                xen_domid, entries[i]);
+        physmap->name = xs_read(state->xenstore, 0, path, &len);
+
+        QLIST_INSERT_HEAD(&state->physmap, physmap, list);
+    }
+    free(entries);
+    return;
+}
+
 int xen_hvm_init(void)
 {
     int i, rc;
@@ -999,7 +1098,7 @@ int xen_hvm_init(void)
     }
 
     /* Init RAM management */
-    xen_map_cache_init();
+    xen_map_cache_init(xen_phys_offset_to_gaddr, state);
     xen_ram_init(ram_size);
 
     qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
@@ -1017,6 +1116,7 @@ int xen_hvm_init(void)
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
     xen_be_register("qdisk", &xen_blkdev_ops);
+    xen_read_physmap(state);
 
     return 0;
 }
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 585b559c73..a456479363 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -78,6 +78,9 @@ typedef struct MapCache {
     uint8_t *last_address_vaddr;
     unsigned long max_mcache_size;
     unsigned int mcache_bucket_shift;
+
+    phys_offset_to_gaddr_t phys_offset_to_gaddr;
+    void *opaque;
 } MapCache;
 
 static MapCache *mapcache;
@@ -91,13 +94,16 @@ static inline int test_bits(int nr, int size, const unsigned long *addr)
         return 0;
 }
 
-void xen_map_cache_init(void)
+void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
 {
     unsigned long size;
     struct rlimit rlimit_as;
 
     mapcache = g_malloc0(sizeof (MapCache));
 
+    mapcache->phys_offset_to_gaddr = f;
+    mapcache->opaque = opaque;
+
     QTAILQ_INIT(&mapcache->locked_entries);
     mapcache->last_address_index = -1;
 
@@ -193,9 +199,14 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
                        uint8_t lock)
 {
     MapCacheEntry *entry, *pentry = NULL;
-    target_phys_addr_t address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-    target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+    target_phys_addr_t address_index;
+    target_phys_addr_t address_offset;
     target_phys_addr_t __size = size;
+    bool translated = false;
+
+tryagain:
+    address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
 
     trace_xen_map_cache(phys_addr);
 
@@ -237,6 +248,11 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
     if(!test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
                 entry->valid_mapping)) {
         mapcache->last_address_index = -1;
+        if (!translated && mapcache->phys_offset_to_gaddr) {
+            phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
+            translated = true;
+            goto tryagain;
+        }
         trace_xen_map_cache_return(NULL);
         return NULL;
     }
diff --git a/xen-mapcache.h b/xen-mapcache.h
index da874ca23d..70301a57e4 100644
--- a/xen-mapcache.h
+++ b/xen-mapcache.h
@@ -11,9 +11,13 @@
 
 #include <stdlib.h>
 
+typedef target_phys_addr_t (*phys_offset_to_gaddr_t)(target_phys_addr_t start_addr,
+                                                     ram_addr_t size,
+                                                     void *opaque);
 #ifdef CONFIG_XEN
 
-void xen_map_cache_init(void);
+void xen_map_cache_init(phys_offset_to_gaddr_t f,
+                        void *opaque);
 uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
                        uint8_t lock);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
@@ -22,7 +26,8 @@ void xen_invalidate_map_cache(void);
 
 #else
 
-static inline void xen_map_cache_init(void)
+static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
+                                      void *opaque)
 {
 }